/* numeric.c	-parse numeric commands
   distributed as part of sula - an irc client for X

    (c) Tano Fotang 1997

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License , or
    (at your option) any later version.

    see the file COPYING for more info.

*/

#include <forms.h>
#include <errno.h>
#include <time.h>
#include <stdarg.h>
#include "aux.h"
#include "nicks.h"
#include "sula.h"
#include "chanwin.h"
#include "global.h"
#include "script.h"
#include "server-numerics.h"
#include "parser.h"
#include "mode.h"
#include "setting.h"
#include "dcc.h"
#include "cmd.h"
#include "lag.h"
#include "here.xpm"
#include "away.xpm"
extern Winstruct *Win;/* parser window */
char   *buf;
char    num[5];
void    p_numeric(int numeric)
{

	char   *sender;
	size_t  ll = strlen(Msg);

	sender = nextstr(Msg, 1);
	if (gflags & SHOW_NUMERIC)
		sprintf(num, "%4d ", numeric);
	else
		strcpy(num, "");
	buf = (char *) malloc(sizeof(char) * (1+ll));
	switch (numeric) {
	    case RPL_WELCOME:{	/*001 */
			    static void TryOldChannels(void);
			    static void cmds_oncon(void);
			    struct timeval now;

			    if (sscanf(Msg, "%*s %*s %s", buf) < 1)
				    break;
			    Win->server->connecting=0;
			    gettimeofday(&now,NULL);
			    ClearLag(Win->server);
			    #ifndef NOLAG
			    update_lag_display(Win->server,
			    now.tv_sec- Win->server->t.tv_sec+
		    (float)((now.tv_usec- Win->server->t.tv_usec)/ 1000000.0),
			    0);
			    #endif
			    Win->server->nick = strdup(buf);
			    aNickList[Win->server->iNick].current=
			    add_nick_to_list(Win->server->iNick,Win->server->nick);
			    connecting(Win->server->servname, Win->server->port,1);
			    if (Win->server->mode) {/* maintain previous mode */
				    sprintf(buf, "MODE %s %s\r\n", 
				    Win->server->nick, Win->server->mode);
				    Win->server->mode = NULL;
				    sendto_server(Win, buf);
			    }
			    cmds_oncon();
			    TryOldChannels();
			    #if 0
			    if(strcasecmp(sender, Win->server->servname)){
			    	free(Win->server->servname);
				Win->server->servname=strdup(sender);
			    }
			    #endif	
			    UpdateWindows(Win->server->fd, 1);
			    
			    berr_msg("@N");
		    }
	    case RPL_YOURHOST:	/* 002 */
	    case RPL_CREATED:	/* 003 */
	    case RPL_MYINFO:{	/* 004 */
			if(check_numeric(numeric, Msg)) break;
			if (gflags & SHOW_RAW_MSG)
			    	berr_msg(Msg);
			else{
			    char *pbuf;
			    sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf);
			    pbuf=buf;
			    if (numeric != RPL_MYINFO)
				    pbuf++;
			    berr_msg("@i%s%s", num, pbuf);
			    if (numeric == RPL_MYINFO)
				    berr_msg("@N ");
			}
		    }
		    break;
	    
	    case RPL_LUSEROP:	/*252 */
	    case RPL_LUSERUNKNOWN:	/*253 */
	    case RPL_LUSERCHANNELS:	/*254 */
		    if(!check_numeric(numeric, Msg))
		    {
			    if (gflags & SHOW_RAW_MSG) 	berr_msg(Msg);
			    else{
			    int     x;
			    if (sscanf(Msg, "%*s %*s %*s %d", &x) < 1)
				    break;
			    if (numeric == RPL_LUSERCHANNELS)
				    berr_msg("%s%s> %d channel%s been formed", num, sender, x,
					     x > 1 ? "s have" : " has");
			    else if (numeric == RPL_LUSERUNKNOWN)
				    berr_msg("%s%s> There %s %d unknown connection%s", num, sender,
					     x > 1 ? "are" : "is", x, x > 1 ? "s" : "");
			    else
				    berr_msg("%s%s> %d operator%s online", num, sender, x,
					     x > 1 ? "s are" : " is");
			}
		    }
		    break;

	    case RPL_UMODEIS:	/*          221 */
		    {
			    char   *who;
			    char *s=NULL;
			    who = (char *) malloc(sizeof(char) * ll);

			    if (sscanf(Msg, "%*s %*s %s %s", who, buf) < 2)
				   { goto fin;}
			    
			    if (!strcmp(who, Win->server->nick)) {
				    changemymode(Win, buf, 1);
				    if(check_numeric(numeric, Msg)) goto fin;
				    if (X == 1) {
					    
					    if (gflags & SHOW_RAW_MSG)
					    	s=strdup(Msg);
					    else{
					    s=(char *)malloc(sizeof(char)*(32+strlen(buf)));
					    sprintf(s, "%sYour user mode is \"%s\"", num, buf);
					    }
					    fl_addto_browser(Win->chanwin->brow2, s);
				    }
				    else
					    berr_msg("%s%s> Your user mode is \"%s\"", num, sender, buf);
				    
			    }
			    else {
				    if (X == 1) {
					    if (gflags & SHOW_RAW_MSG)
					    	s=strdup(Msg);
					    else{
					    s=(char *)malloc(sizeof(char)*(32+strlen(buf)+strlen(who)));
					    sprintf(s, "%sUser mode for %s is \"%s\"", num, who, buf);
					    }
					    fl_addto_browser(Win->chanwin->brow2, s);
					    free(s);
				    }
				    else  if (gflags & SHOW_RAW_MSG)  berr_msg(Msg);
					  else
					    berr_msg("%s%s> User mode for %s is \"%s\"", num, sender, who, buf);
			    }
		fin:
		    free(who); free(s);
		    }
		    break;
	    case 250:
	    case 265:
	    case 266:
	    case RPL_LUSERCLIENT:	/*251 */

	    case RPL_LUSERME:	/*255 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    if (gflags & SHOW_RAW_MSG)  berr_msg(Msg);
			    else{
			    sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf);
			    berr_msg("%s%s> %s", num, sender, buf);
			    }
		    }
		    break;
	    
	    case RPL_ADMINME:	/* 256 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    berr_msg("@N ");
			    sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf);
			    berr_msg("@i%s%s", num, buf);
		    }
		    break;
	    case RPL_ADMINLOC1:	/* 257 */
	    case RPL_ADMINLOC2:	/* 258 */
	    case RPL_ADMINEMAIL:	/* 259 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    if (gflags & SHOW_RAW_MSG)  berr_msg(Msg);
			    else{
			    sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf);
			    berr_msg("@i%s\t%s",num,buf);
			    }
			    if (numeric == RPL_ADMINEMAIL)
				    berr_msg("@N ");
		    }
		    break;

	    
	    case RPL_INFO:	/* 371 */
	    case RPL_MOTD:	/* 372 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    if(numeric==RPL_MOTD)
			      if((Win->server->flag&GOT_MOTD))
			      	if(sflags&SUPPRESS_MOTD)
			    		break;
			    if (gflags & SHOW_RAW_MSG)  berr_msg(Msg);
			    else{
			    sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf);
			    berr_msg("@f\t%s",  buf);
			    }
		    }
		    break;

	    case RPL_INFOSTART:	/*373 */
	    case RPL_MOTDSTART:	/*375 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    if(numeric==RPL_MOTDSTART)
			      if(sflags&SUPPRESS_MOTD && (Win->server->flag&GOT_MOTD))
			    		break;
			    berr_msg("@N ");
			    if (gflags & SHOW_RAW_MSG)  berr_msg(Msg);
			    else{
			    sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf);
			    berr_msg("%s%s", num, buf);
			    }
		    }
		    break;
	    case RPL_ENDOFNAMES:
	    case RPL_ENDOFINFO:	/*374 */
		    check_numeric(numeric, Msg);
		    break;	/*       366 */
	    
	    case RPL_ENDOFMOTD:	/*376 ignore */
		    Win->server->flag |= GOT_MOTD;/* this is confusing..*/
		    if(check_numeric(numeric, Msg)) break;
		    berr_msg("@N");
		    break;

	    case RPL_NONE:	/*     300 */
		    check_numeric(numeric, Msg);
		    break;	/* what's this numeric, anyway?- fotang */

	    case RPL_AWAY:	/*             301 */
		    if(!check_numeric(numeric, Msg))
		    {
			    Winstruct *win = NULL;
			    char   *nick, *s;
			    
			    nick = (char *) malloc(sizeof(char) * (ll));
			    s = (char *) malloc(sizeof(char) * (ll + 20));
			    if (!nick || !s) {
				    err_ret("%s (%d)", __FILE__, __LINE__);
				    break;
			    }
			    if (sscanf(Msg, "%*s %*s %*s %s %[^\n]\n", nick, buf) < 2)
				    {free(s); free(nick);break;}
			    if (X > 1)
				    win = getwinbycmd(Win->server, "WHOIS", nextstr(Msg, 4), 0);
			    if (!win)
				    win = Win;
			    if (gflags & SHOW_RAW_MSG)  strcpy(s,Msg);
			    else
			    sprintf(s, "%s\t%s is away %s", num, nick, buf);
			    fl_addto_browser(win->chanwin->brow2, s);
			    free(s); free(nick);
		    }
		    break;
	    case RPL_USERHOST:	/*         302 */
		    if(!check_numeric(numeric, Msg))
		    {
			if (gflags & SHOW_RAW_MSG){
			    if(X==1) fl_addto_browser(Win->chanwin->brow2, Msg);
			    else berr_msg(Msg);
			}
			else
			{
			    char    away = 0, ircop = 0;
			    size_t  l;
			    char   *nick, *pbuf;

			    nick = (char *) malloc(sizeof(char) * (ll));
			    if (sscanf(Msg, "%*s %*s %*s :%[^=]=%[^\n]\n", nick, buf) < 2)
				    {free(nick);break;}
			    pbuf=buf;
			    if (*buf == '-')
				    away = 1;
			    pbuf++;
			    l = strlen(nick) - 1;
			    if (*(nick + l) == '*') {
				    ircop = 1;
				    *(nick + l) = '\0';
			    }

			    if (X == 1) {
				    char *s=(char *)malloc(sizeof(char)*(64+strlen(nick)+strlen(pbuf)));
				    sprintf(s, "%s\t%s is %s%s%s", num, nick, pbuf,
					    ircop ? ", an IRC operator" : "", away ? " (now away)" : "");
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else {
				    berr_msg("%s%s> %s is %s%s%s", num, sender, nick, pbuf,
					     ircop ? ", an IRC operator" : "", away ? " (now away)" : "");
			    }
			    free(nick);
			}

		    }
		    break;
	/*
	
	if (gflags & SHOW_RAW_MSG) to be continued  from here
	19 oct 1997 -fotang
	
	*/

	    case RPL_ISON:	/*         303 */
		    {
			    if(check_numeric(numeric, Msg)) break;
			    if (sscanf(Msg, "%*s %*s %*s :%[^\r\n]\r\n", buf) < 1) {
				    if (X == 1)
					    fl_addto_browser(Win->chanwin->brow2, "Person currently not on IRC");
				    else
					    berr_msg("%s%s> Person currently not on IRC", num, sender);
				    break;
			    }
			    if (X == 1) {
				    char    *s=(char *)malloc(sizeof(char)*(strlen(buf)+32));

				    sprintf(s, "%sCurrently on IRC: %s", num, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> Currently on IRC: %s", num, sender, buf);
		    }
		    break;
	    case RPL_TEXT:	/*         304 */
		    if(check_numeric(numeric, Msg)) break;
		    if (sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf) < 1)
			    break;
		    if (X == 1)
			    fl_addto_browser(Win->chanwin->brow2, buf);
		    else
			    berr_msg("%s%s> %s", num, sender, buf);
		    break;

	    case RPL_UNAWAY:	/*           305 */
	    case RPL_NOWAWAY:	/*          306 */
		    {
			    WinList *p;
			    int nothing=check_numeric(numeric, Msg);
			    if(numeric == RPL_NOWAWAY)
				Win->server->flag|= SET_AWAY;
			    else
				Win->server->flag&= ~SET_AWAY;
			    if (build_winlistbyfd(Win->server->fd) == NULL)
				    break;
			    p = servWin;
			    while (p) {
				    if (Win->server->flag&SET_AWAY) {
					    fl_free_pixmapbutton_pixmap(p->win->chanwin->away);
					    fl_set_pixmapbutton_data(p->win->chanwin->away, away_xpm);
				    }
				    else {
					    fl_free_pixmapbutton_pixmap(p->win->chanwin->away);
					    fl_set_pixmapbutton_data(p->win->chanwin->away, here_xpm);
				    }
				    if(!nothing){
				      if(gflags & SHOW_RAW_MSG)
				      	fl_addto_browser(p->win->chanwin->brow2,Msg);
				      else
				    	if (sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf) > 0)
					    fl_addto_browser(p->win->chanwin->brow2, buf);
				    }
				    p = p->next;
			    }

		    }
		    break;
	    case RPL_WHOISUSER:	/*        311 */
	    case RPL_WHOWASUSER:	/*       314 */
		    if(!check_numeric(numeric, Msg))
		    {
			    char   *nick, *name, *host, *ircname, txt[] = "was";
			    int     i;
			    Winstruct *win = NULL;
			    free(buf);
			    nick = (char *) malloc(sizeof(char) * ll);
			    name = (char *) malloc(sizeof(char) * ll);
			    host = (char *) malloc(sizeof(char) * ll);
			    ircname = (char *) malloc(sizeof(char) * ll);
			    buf = (char *) malloc(sizeof(char) * (ll + 20));
			    if (!nick || !name || !host || !ircname || !buf) {
				    err_ret("%s (%d)", __FILE__, __LINE__);
				    break;
			    }
			    i = sscanf(Msg, "%*s %*s %*s %s %s %s %*s :%[^\n]\n", nick, name, host, ircname);
			    if (i < 3)
				    goto out;
			    if (X > 1)
				    win = getwinbycmd(Win->server, numeric == RPL_WHOISUSER ? "WHOIS" :
				     "WHOWAS", nextstr(Msg, 4), 0);
			    if (!win)
				    win = Win;
			    if (numeric == RPL_WHOISUSER)
				    strcpy(txt, "is");
			    if (i < 4)
				    sprintf(buf, "@b%s\t%s %s %s@%s", num, nick, txt, name, host);
			    else
				    sprintf(buf, "@b%s\t%s %s %s@%s (%s)", num, nick, txt, name, host, ircname);
			    fl_addto_browser(win->chanwin->brow2, buf);
		    out:
		    	free(nick);free(name);free(host); free(ircname);
		    }
		
		    break;

	    case RPL_WHOISSERVER:	/*      312 */
		    if(!check_numeric(numeric, Msg))
		    {
			    int     i;
			    Winstruct *win = NULL;
			    char   *des = (char *) malloc(sizeof(char) * ll);
			    char   *s = (char *) malloc(sizeof(char) * (ll + 50));

			    i = sscanf(Msg, "%*s %*s %*s %*s %s :%[^\n]\n", buf, des);
			    if (i < 1)
				    goto out0;
			    if (X > 1)
				    win = getwinbycmd(Win->server, "WHOIS", nextstr(Msg, 4), 0);
			    if (!win)
				    win = Win;
			    if (i < 2)
				    sprintf(s, "%s\ton IRC via server %s", num, buf);
			    else
				    sprintf(s, "%s\ton IRC via server %s (%s)", num, buf, des);
			    fl_addto_browser(win->chanwin->brow2, s);
			out0:    
			    free(des);free(s);
		    }
		    break;

	    case RPL_WHOISOPERATOR:	/*    313 */
		    if(!check_numeric(numeric, Msg))
		    {
			    Winstruct *win = NULL;
			    char   *nick = (char *) malloc(sizeof(char) * ll);
			    char   *s = (char *) malloc(sizeof(char) * (ll + 10));

			    if (sscanf(Msg, "%*s %*s %*s %s :%[^\n]\n", nick, buf) < 2)
				    goto fin0;
			    if (X > 1)
				    win = getwinbycmd(Win->server, "WHOIS", nick, 0);
			    if (!win)
				    win = Win;
			    sprintf(s, "%s\t%s %s", num, nick, buf);
			    fl_addto_browser(win->chanwin->brow2, s);
			fin0:    
			    free(nick);free(s);
		    }
		    break;

	    
	    case RPL_ENDOFWHOWAS:	/*      369 */
	    case RPL_WHOISCHANOP:
		    check_numeric(numeric, Msg); break;	
	    case RPL_WHOISIDLE:	/*        317 */
		    if(!check_numeric(numeric, Msg))
		    {
			    long    t;
			    long    idle;
			    int     i;
			    Winstruct *win = NULL;
			    char    s[512];

			    i = sscanf(Msg, "%*s %*s %*s %s %ld %ld", buf, &idle, &t);
			    if (i < 2)
				    break;
			    idle /= 60;
			    if (X > 1)
				    win = getwinbycmd(Win->server, "WHOIS", nextstr(Msg, 4), 0);
			    if (!win)
				    win = Win;
			    if (i == 2) {
				    /* server 2.9..beta */
				    sprintf(s, "%s\t%s has been idle for " \
					    "%ld minute%s (%ld hour%s)", num, buf, idle, idle > 1 ? "s" : "", idle / 60, idle / 60 != 1 ? "s" : "");
				    /* do we say "for 0 hrs"?? */
			    }
			    else {
				    sprintf(s, "%s\t%s signed on %s%s\tand has been idle for " \
					    "%ld minute%s (%ld hour%s)", num, buf, ctime(&((time_t) t)),
					    num, idle, idle != 1 ? "s" : "", idle / 60, idle / 60 != 1 ? "s" : "");
			    }
			    fl_addto_browser(win->chanwin->brow2, s);
		    }
		    break;
	    case RPL_ENDOFWHOIS:{
				/*       318 */
			    getwinbycmd(Win->server, "WHOIS", nextstr(Msg, 4), 1);
			    check_numeric(numeric, Msg);
			    break;
		    }

	    case RPL_WHOISCHANNELS:	/*    319 */
		    if(!check_numeric(numeric, Msg))
		    {
			    if (sscanf(Msg, "%*s %*s %*s %*s %[^\n]\n", buf) < 1)
				    break;
			    else {
				    Winstruct *win = NULL;
				    char *s;
				    if (X > 1)
					    win = getwinbycmd(Win->server, "WHOIS", nextstr(Msg, 4), 0);
				    if (!win)
					    win = Win;
				    s=(char *)malloc(sizeof(char)*(24+strlen(buf)));
				    sprintf(s, "%s\ton channels %s", num, buf);
				    fl_addto_browser(win->chanwin->brow2, s);
				    free(s);
			    }
		    }
		    break;

	    case RPL_LISTSTART:	/*        321 */
	    	if(check_numeric(numeric, Msg)) break;
		   if (gflags & SHOW_RAW_MSG) break;
		    berr_msg("@b%s%s\n@b@f@i%s%-*.*s%-8sTopic", num, sender,
		    (gflags & SHOW_NUMERIC)?"   ":"", MaxChanLen + 4,
		     MaxChanLen,    "Channel", "Users");
		    break;
	    case RPL_LIST:	/*           322 */
		    if(!check_numeric(numeric, Msg))
		    {
			 if (gflags & SHOW_RAW_MSG) berr_msg(Msg);
			 else{
			    char   *topic = (char *) malloc(sizeof(char) * ll);
			    unsigned n, i;

			    i = sscanf(Msg, "%*s %*s %*s %s %u :%[^\n]\n", buf, &n, topic);
			    if (i < 2)
				    {free(topic);break;}
			    berr_msg("@f%s%-*.*s%-7d%s", num, MaxChanLen + 5, MaxChanLen,
				     *buf == '*' ? "(private)" : buf, n, i > 2 ? topic : "");
			   free(topic);
			}
		    }
		    break;

	    case RPL_LISTEND:	/*          323 */
		    if(check_numeric(numeric, Msg)) break;
		    berr_msg("@N ");
		    break;
	    case RPL_CHANNELMODEIS:{	/*    324 */
		Winstruct *win;
		char   *channel = (char *) malloc(sizeof(char) * ll);
		char *buf=(char *) malloc(sizeof(char) * ll);
		    sscanf(Msg, "%*s %*s %*s %s %[^\n]\n", channel, buf);
		    *(buf + strlen(buf) - 1) = '\0';	/* buf:mode */

		    win = getwinbycmd(Win->server, "MODE", channel, 1);
		    if (win && !check_numeric(numeric, Msg)) {	/* we asked for chan mode */
			    char    *s=NULL;
			    if (gflags & SHOW_RAW_MSG) s=strdup(Msg);
			     else{
			       s=(char *) malloc(sizeof(char)*(40+strlen(channel)));
			       sprintf(s, "%sMode for channel %s is \"%s\"", num, channel, buf);
			    }
			    fl_addto_browser(win->chanwin->brow2, s);
			    free(s);
		    }
		    win = get_win_bychanname(Win->server->fd, channel);
		    if (!win)
			    goto done;
		    else {
			    Channel *p = win->chanStart->left;

			    changechanmode(win, channel, buf, 1);
			    while (p != win->chanStart)
				    if (strcasecmp(channel, p->name))
					    p = p->left;
				    else {	/* found channel */
					    if (strcmp(channel, p->name)) {	/* name mismatch #Test #tEst */
						    if (win->chanwin->chanusers->u_vdata) {
							    FD_chanusers *f=(FD_chanusers *)win->chanwin->chanusers->u_vdata;
							    int     total = fl_get_choice_maxitems(f->channel);
							    int     i;

							    for (i = 1; i <= total; i++)
								    if (!strcasecmp(p->name, fl_get_choice_item_text(f->channel, i))) {
									    fl_replace_choice(f->channel, i, channel);
									    goto done;
								    }
						    }
						    p->name = strdup(channel);
						    goto done;
					    }	/* if(strcmp(channel, p->name)) */
					    if (p == win->chanCur)
						    update_server_stuff(win->server->fd);
					    goto done;
				    }	/*else */
			    }
	       done:
		    free(channel);
		    }
		    break;
	    case 329:
	       if(!check_numeric(numeric, Msg))
	       {	    
		    long    t;
		    char   *channel = (char *) malloc(sizeof(char) * ll);
		    char *s=NULL;
		    char *buf;
		    if (sscanf(Msg, "%*s %*s %*s %s %ld", channel, &t) < 2)
			    break;
		    buf = strdup(ctime(&((time_t) t)));
		    *(buf + strlen(buf) - 1) = '\0';
		    if (gflags & SHOW_RAW_MSG) s=strdup(Msg);
		    else{
		    	s=(char *) malloc(sizeof(char) *(
			    strlen(channel)+strlen(buf)+strlen(num)+32));
			    sprintf(s, "%s%s was created on %s", num, channel, buf);
		    }	
		    if (X == 1) 
			    fl_addto_browser(Win->chanwin->brow2, s);
		    else{
		    	Winstruct *win = get_win_bychanname(Win->server->fd, channel);
			if (win)
				fl_addto_browser(win->chanwin->brow2, s);
			else
			    berr_msg("%s%s> %s was created on %s", 
			    num, sender, channel, buf);
		   }
		   free(channel); free(s);
		}
		    break;
	    case RPL_NOTOPIC:{	/*          331 */
	    	if(!check_numeric(numeric, Msg))
		{
		    	Winstruct *win;

			    sscanf(Msg, "%*s %*s %*s %s", buf);		/* buf:channel name */

			    if (X == 1)
				    win = Win;
			    else
				    win = get_win_bychanname(Win->server->fd, buf);
			    if (win) {
				    Channel *chan = get_chan_byname(win, buf);
				    char    *s=(char *) malloc(sizeof(char) *(
			    		strlen(buf)+strlen(num)+32));

				    if (chan) {
					    chan->topic = NULL;
					    update_topic(win, buf, 
					    "No topic is set (" sula_NAME sula_VERSION ").");
				    }
				    sprintf(s, "%s%s has no topic", num, buf);
				    fl_addto_browser(win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s has no topic set", num, sender, buf);
		    }
		}
		    break;
	    case RPL_TOPIC:	/*          332 */
		    {
			    Winstruct *win;
			    int just_update=check_numeric(numeric, Msg);
			    char   *channel = (char *) malloc(sizeof(char) * ll);

			    if (sscanf(Msg, "%*s %*s %*s %s %[^\n]\n ", channel, buf) < 2)
				    break;

			    if (X == 1)
				    win = Win;
			    else
				    win = get_win_bychanname(Win->server->fd, channel);
			    if (win) {
				    Channel *chan = get_chan_byname(win, channel);
				    if (chan) {
					    chan->topic = strdup(buf + 1);
					    update_topic(win, channel, buf + 1);
				    }
				    if(!just_update){
				    	char    *s=(char *) malloc(sizeof(char) *(
			    		strlen(channel)+strlen(buf)+strlen(num)+16));
				    	sprintf(s, "%sTopic for %s %s", num, channel, buf);
				    	fl_addto_browser(win->chanwin->brow2, s);
				    	free(s);
				   }
			    }
			    else if(!just_update)
				    berr_msg("%s%s> Topic for %s %s", num, sender, channel, buf);
		    	free(channel);
		    }
		    break;
	    case 333:
		    if(!check_numeric(numeric, Msg))
		    {
			    Winstruct *win;
			    long    t;
			    char   *by = (char *) malloc(sizeof(char) * ll);
			    char   *channel = (char *) malloc(sizeof(char) * ll);

			    if (sscanf(Msg, "%*s %*s %*s %s %s %ld", channel, by, &t) < 3)
				    break;
			    
			    free(buf);
			    buf = strdup(ctime(&((time_t) t)));
			    *(buf + strlen(buf) - 1) = '\0';

			    if (X == 1)
				    win = Win;
			    else
				    win = get_win_bychanname(Win->server->fd, channel);
			    if (win) {
				    char   *s = (char *) malloc(sizeof(char) * (ll+50));

				    sprintf(s, "%sTopic for %s was set by %s on %s", num, channel, by, buf);
				    fl_addto_browser(win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> Topic for %s was set by %s on %s", num,
					     sender, channel, by, buf);
			   free(by); free(channel);
		    }
		    break;
	    
	    case RPL_LISTUSAGE:/*        334       */ /* Undernet extension */
		    if(check_numeric(numeric, Msg)) break;
		    if(sscanf(Msg, "%*s %*s %*s :%[^\n]\n", buf)>0){
		    	if(strstr(Msg,"mIRC")) break;
		    	berr_msg(buf);
		    }
		    break;
	    case RPL_INVITING:	/*         341 */
		 {
		    struct timeval t;
		    if (sscanf(Msg, "%*s %*s %*s %*s __%u_%u", &t.tv_sec,&t.tv_usec)<2)
		    if(!check_numeric(numeric, Msg))
		    {
			    char   *nick = (char *) malloc(sizeof(char) * (ll));

			    if (sscanf(Msg, "%*s %*s %*s %s %s", nick, buf) < 2)
				    break;

			    if (X == 1) {
				    char   *s = (char *) malloc(sizeof(char) * (ll+32));
				    sprintf(s, "%sInviting %s to channel %s", num, nick, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> Inviting %s to channel %s", num, sender, nick, buf);
		    }
		 }
		    break;
	    case RPL_SUMMONING:	/*        342 */
		    /* never seeen summon in action, so this probably incorrect */
		    if(!check_numeric(numeric, Msg))
		    {
			    if (sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf) < 1)
				    break;

			    if (X == 1) {
				    char   *s = (char *) malloc(sizeof(char) * 
				    (strlen(buf)+8));
				    sprintf(s, "%s%s", num, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s", num, sender, buf);
		    }
		    break;
	    case RPL_VERSION:	/*          351 */
		    if(!check_numeric(numeric, Msg))
		    {
			    char   *version;
			    version = (char *) malloc(sizeof(char) * (ll+32));

			    if (sscanf(Msg, "%*s %*s %*s %s %*s :%[^\n]\n", version, buf) < 2)
				    break;

			    if (X == 1) {
				    char *s = (char *) malloc(sizeof(char) * (strlen(buf)+strlen(
				    version)+strlen(num)+24));

				    sprintf(s, "%sServer version: %s %s", num, version, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> Server version: %s %s", num, sender, version, buf);
			  free(version);
		    }
		    break;
	    case RPL_WHOREPLY:	/*         352 */
		    {
			    Winstruct *win = NULL;
			    char    mode[4];

			    char   *chan = (char *) malloc(sizeof(char) * ll);
			    char   *name = (char *) malloc(sizeof(char) * ll);
			    char   *host = (char *) malloc(sizeof(char) * ll);
			    char   *ircname = (char *) malloc(sizeof(char) * ll);
			    char   *nick = (char *) malloc(sizeof(char) * ll);
			    char    hop[4];

			    if (!chan || !name || !host || !ircname || !nick) {
				    err_ret("%s (%d)", __FILE__, __LINE__);
				    break;
			    }
			    if (sscanf(Msg, "%*s %*s %*s %s %s %s %*s %s %s :%s %[^\n]\n",
			    chan, name, host, nick, mode, hop, ircname) < 7)
			    	    goto freeall;
			    *(ircname + strlen(ircname) ) = '\0';
			    win = getwinbycmd(Win->server, "WHO_UPDATE", chan, 0);
			    if (win) {
				    Channel *p = get_chan_byname(win, chan);

				    if (p) {
					    User /**v=p->userStart,*/  * u;
					    u = (User *) malloc(sizeof(User));
					    if (!u) {
						    err_ret("%s %d", __FILE__, __LINE__);
						    goto freeall;
					    }
					    u->name = strdup(nick);
					    u->address = (char *) malloc(sizeof(char) * ll);
					    u->ircname = (char *) malloc(sizeof(char) * strlen(ircname));
					    sprintf(u->address, "%s@%s", name, host);
					    u->mode = strdup(mode);
					    u->ircname = strdup(ircname);
					    if (new_addto_chanusers(win, p->name, u))
						    getwinbycmd(win->server, "WHO_UPDATE", p->name, 1);
					    free(u->name);free(u->address);
					    free(u->ircname);free(u->mode);free(u);
				    }
#ifdef DEBUG
				    else
					    fprintf(stderr, "%s %d where's %s?!\n", __FILE__, __LINE__, chan);
#endif
				    goto freeall;
			    }
			    else
				    win = X == 1 ? Win : getwinbycmd(Win->server, "WHO", chan, 0);
			    if(!check_numeric(numeric, Msg))
			    if (win) {
				    char    s[512];

				    sprintf(s, "@f%s%-*.*s  %-10s %-4s %s@%s (%s) %s ", num,
					    MaxChanLen + 2, MaxChanLen,

					  *chan == '*' ? "(private)" : chan,
					    nick, mode, name, host,
					    ircname, hop);
				    fl_addto_browser(win->chanwin->browser, s);
			    }
			    else
				    berr_msg("%s%s> %-*.*s  %-10s %-4s  %s@%s (%s) %s ", num,
					     sender, MaxChanLen + 2, MaxChanLen, *chan == '*' ? "(private)" : chan,
					     nick, mode, name, host,
					     ircname, hop);
		freeall:
		    free(nick); free(ircname); free(name);free(chan); free(host);
		    }
		    break;
	    case RPL_ENDOFWHO:{/*         315 */
			    sscanf(Msg, "%*s %*s %*s %s", buf);
			    getwinbycmd(Win->server, "WHO", buf, 1);
			    load_userlist(getwinbycmd(Win->server, 
			    "WHO_UPDATE", buf, 1), buf, 1);
			    check_numeric(numeric, Msg);
			    break;
		    }

	    case RPL_NAMREPLY:{/* 353 */
			    static void p_namereply(const char *msg);

			    p_namereply(Msg);
			    break;
		    }
	    case RPL_ENDOFBANLIST:	/*     368 */
		    check_numeric(numeric, Msg);break;
	    case RPL_BANLIST:
	    if(!check_numeric(numeric, Msg))
	    {	/*          367 */
			    long    t = 0;
			    char   *by = (char *) malloc(sizeof(char) * ll);
			    char   *channel = (char *) malloc(sizeof(char) * ll);
			    char   *who = (char *) malloc(sizeof(char) * ll);
			    int     i;

			    if (!channel || !by || !who) {
				    err_ret("%s (%d)", __FILE__, __LINE__);
				    break;
			    }
			    i = sscanf(Msg, "%*s %*s %*s %s %s %s %ld", channel, who, by, &t);
			    if (i < 2)
				    goto fini;
			    strcpy(buf, "");
			    if (i > 3)
				    sscanf(ctime(&((time_t) t)), "%[^\n]\n", buf);
			    else *buf='\0';
			    if (i < 3)
				    *by='\0';
				    /*strcpy(by, "");*/

			    if (X == 1) {
				    char    *s= (char *) malloc(sizeof(char) * (ll+16));

				    sprintf(s, "@f%s%s\t%s\tby %s (%s)", num, channel, who, by, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("@f%s%s> %s %s by %s (%s)", num, sender, channel, who, by, buf);
			 fini:   
			    free(by); free(channel); free(who);
		    }
		    break;

	    case RPL_YOUREOPER:	/*        381 */
		    addmode(&Win->server->mode, 'o');
		    update_server_stuff(Win->server->fd);
		    check_numeric(numeric, Msg);
	    case RPL_REHASHING:	/*        382 */
	    case RPL_YOURESERVICE:	/*     383 */
	    case RPL_MYPORTIS:	/*         384 */
	    case RPL_NOTOPERANYMORE:	/*   385 */
		    if(!check_numeric(numeric, Msg))
		    {
			    char *pbuf;
			    if (sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf) < 1)
				    break;
			    pbuf=buf;
			    if (*buf == ':')
				    pbuf++;
			    if (X == 1) {
				    char    *s=(char *)malloc(sizeof(char)*(8+strlen(pbuf)));
				    sprintf(s, "%s%s", num, pbuf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s", num, sender, pbuf);

		    }
		    break;


	    case ERR_NOSUCHNICK:	/*       401 */
		    {
			    ChatReqSent *q = chatsentStart;
			    DCCFileS *p = filesendStart;
			    char   *nick = (char *) malloc(sizeof(char) * ll);

			    if (sscanf(Msg, "%*s %*s %*s %s %[^\r\n]\r\n", nick, buf) < 2)
				    break;
			    while (q != chatsentEnd) {
				    if (!strcasecmp(q->nick, nick)) {
					    remove_sentchatreq(q->id);
				    }
				    if (q != chatsentEnd)
					    q = q->next;
			    }
			    while (p != filesendEnd) {
				    if (!strcasecmp(p->nick, nick)) {
					    remove_file_offer(p->id);
				    }
				    if (p != filesendEnd)
					    p = p->next;
			    }
			    if(check_numeric(numeric, Msg)) break;
			    if (X == 1) {
				    char    *s= (char *) malloc(sizeof(char) * (
				    strlen(buf)+strlen(sender)+strlen(nick)+16));

				    sprintf(s, "%s%s> %s%s", num, sender, nick, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else {
				    berr_msg("%s%s> %s%s", num, sender, nick, buf);
			    }
			    if (gflags & BEEP_SERVER_ERR) fl_ringbell(0);
			    free(nick);
		    }
		    break;
	    case ERR_UNKNOWNCOMMAND:	/*   421 */
		    if(!check_numeric(numeric, Msg))
		    {
			    char *pbuf;
			    if (sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf) < 1)
				    break;
			    pbuf=buf;
			    if (*pbuf == ':')
				    pbuf++;
			    if (gflags & BEEP_SERVER_ERR) fl_ringbell(0);
			    if (X == 1) {
				    char *s=(char *)malloc(sizeof(char)*
				    (8+strlen(sender)+strlen(pbuf)));
				    sprintf(s, "%s%s> %s", num, sender, pbuf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s", num, sender, pbuf);

		    }
		    break;

	    case ERR_NOTREGISTERED:	/*    451 */
		    {		/* register again */
			    char    line[256];

			    sprintf(line, "NICK %s\n", Win->server->nick);
			    sendto_server(Win, line);
			    if (Win->server->password) {
				    sprintf(line, "PASS %s\n", Win->server->password);
				    sendto_server(Win, line);
			    }
			    if (Win->server->email) {
				char *name=strxstr(Win->server->email, "@");
				char *hhost=strsstr(Win->server->email, "@");
				if(!name) name=Name;
				if(!hhost) hhost=host;
				sprintf(line, "USER %s %s %s :%s\n", name,
					    hhost, Win->server->servname, 
					    Win->server->ircname ? Win->server->ircname : sula_NAME sula_VERSION);
			    }
			    else
				    sprintf(line, "USER %s %s %s :%s\n", Name, host, Win->server->servname,
					    Win->server->ircname ? Win->server->ircname : sula_NAME sula_VERSION);
#if DEBUG >1
			    fprintf(stderr, "correct? Name, host, server, ircname:[%s]\n", line);
#endif
			    sendto_server(Win, line);
			    ClearLag(Win->server);
			    fl_activate_object(Win->chanwin->lag);
			     check_numeric(numeric, Msg);
			    break;
		    }
	    case ERR_ALREADYREGISTRED:		/* 462 */
		    check_numeric(numeric, Msg);
		    break;

	    case ERR_NOSUCHSERVER:	/*     402 */
	    case ERR_NOSUCHCHANNEL:	/*    403 */
	    case ERR_CANNOTSENDTOCHAN:		/* 404 */
	    case ERR_TOOMANYCHANNELS:	/*  405 */
	    case ERR_WASNOSUCHNICK:	/*    406 */
	    case ERR_TOOMANYTARGETS:	/*   407 */
	    case ERR_NOSUCHSERVICE:	/*    408 */
	    case ERR_NOORIGIN:	/*         409 */
	    case ERR_NORECIPIENT:	/*      411 */
	    case ERR_NOTEXTTOSEND:	/*     412 */
	    case ERR_NOTOPLEVEL:	/*       413 */
	    case ERR_WILDTOPLEVEL:	/*     414 */

	    case ERR_NOMOTD:	/*           422 */
	    case ERR_NOADMININFO:	/*      423 */
	    case ERR_FILEERROR:	/*        424 */
	    case ERR_NICKTOOFAST: /*	     438       */	/* Undernet extension */
	    case ERR_TARGETTOOFAST:/*    439       */	/* Undernet extension */
	    case ERR_USERNOTINCHANNEL:		/* 441 */
	    case ERR_NOTONCHANNEL:	/*     442 */
	    case ERR_USERONCHANNEL:	/*    443 */
	    case ERR_NOLOGIN:	/*          444 */
	    case ERR_SUMMONDISABLED:	/*   445 */
	    case ERR_USERSDISABLED:	/*    446 */

	    case ERR_NONICKNAMEGIVEN:	/*  431 */
	    case ERR_SERVICENAMEINUSE:		/* 434 */
	    case ERR_SERVICECONFUSED:	/*  435 */

	    case ERR_NEEDMOREPARAMS:	/*   461 */

	    case ERR_NOPERMFORHOST:	/*    463 */
	    case ERR_PASSWDMISMATCH:	/*   464 */
	    case ERR_YOUREBANNEDCREEP:		/* 465 */
	    case ERR_YOUWILLBEBANNED:	/*  466 */
	    case ERR_KEYSET:	/*           467 */
	    case ERR_BADCHANMASK:	/*      476 */

/* continued further below */

	    case ERR_NOPRIVILEGES:	/*     481 */
	    case ERR_CHANOPRIVSNEEDED:		/* 482 */
	    case ERR_CANTKILLSERVER:	/*   483 */
	    case 484:		/* Your connectionis restricted */
	    case ERR_NOOPERHOST:	/*       491 */
	    case ERR_NOSERVICEHOST:	/*    492 */

	    case ERR_UMODEUNKNOWNFLAG:		/* 501 */
	    case ERR_USERSDONTMATCH:	/*   502 */
	    case ERR_BADPING:/*          513        *//* Undernet extension */
		    if(!check_numeric(numeric, Msg))
		    {
			    if (sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf) < 1)
				    break;
			    if (gflags & BEEP_SERVER_ERR) fl_ringbell(0);
			    if (X == 1) {
				    char    *s=(char *)malloc(sizeof(char)*(32+strlen(buf)));
				    sprintf(s, "%s%s%s", num,
					    buf, numeric == ERR_CANNOTSENDTOCHAN ? "(+moderated/+n/banned?)" : "");
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s%s", num,
					     sender, buf, numeric == ERR_CANNOTSENDTOCHAN ? "(+moderated/+n/banned?)" : "");

		    }
		    break;
	    case ERR_CHANNELISFULL:	/*    471 */
		    if(!check_numeric(numeric, Msg))
		{
		    if (sscanf(Msg, "%*s %*s %*s %[^\r\n]\r\n", buf) < 1)
			    break;

		    if (X == 1) {
			    char    *s=(char *)malloc(sizeof(char)*(32+strlen(buf)));
			    sprintf(s, "%s%s Channel is full.", num, buf);
			    fl_addto_browser(Win->chanwin->brow2, s);
			    free(s);
		    }
		    else
			    berr_msg("%s%s> %s Channel is full.", num, sender, buf);
		}
		    break;
	    case ERR_INVITEONLYCHAN:	/*   473 */
		    if(check_numeric(numeric, Msg)) break;
		    if (sscanf(Msg, "%*s %*s %*s %[^\r\n]\r\n", buf) < 1)
			    break;

		    if (X == 1) {
			    char    *s=(char *)malloc(sizeof(char)*(32+strlen(buf)));
			    sprintf(s, "%s%s You must be invited.", num, buf);
			    fl_addto_browser(Win->chanwin->brow2, s);
			    free(s);
		    }
		    else
			    berr_msg("%s%s> %s You must be invited.", num, sender, buf);
		    break;
	    case ERR_BANNEDFROMCHAN:	/*   474 */
	    	    
		    if(check_numeric(numeric, Msg)) break;	
		    if (sscanf(Msg, "%*s %*s %*s %[^\r\n]\r\n", buf) < 1)
			    break;

		    if (X == 1) {
			    char    *s=(char *)malloc(sizeof(char)*(40+strlen(buf)));
			    sprintf(s, "%s%s You are banned from channel.", num, buf);
			    fl_addto_browser(Win->chanwin->brow2, s);
			    free(s);
		    }
		    else
			    berr_msg("%s%s> %s You are banned.", num, sender, buf);
		    break;
	    case ERR_BADCHANNELKEY:	/*    475 */
		    if(check_numeric(numeric, Msg)) break;
		    if (sscanf(Msg, "%*s %*s %*s %[^\r\n]\r\n", buf) < 1)
			    break;

		    if (X == 1) {
			    char    *s=(char *)malloc(sizeof(char)*(40+strlen(buf)));
			    sprintf(s, "%s%s  Wrong channel password!", num, buf);
			    fl_addto_browser(Win->chanwin->brow2, s);
			    free(s);
		    }
		    else
			    berr_msg("%s%s> %s Wrong channel password!", num, sender, buf);

		    break;

case ERR_ERRONEUSNICKNAME:		/* 432 */
case ERR_NICKNAMEINUSE:	/*    433 */
/*ERR_BANNICKCHANGE    437	*//* Undernet extension */
case 437:		/* Nick is temporarily unavailable */
    {
    char  *line, *ptr=NULL;
     char *nick=nextstr(Msg,4);

  if(Win->server->connecting){
  NickList *nl;
  assert(Win->server->iNick>=0);
  nl=&aNickList[Win->server->iNick];
  if(nl->start!=nl->start->left){ /* list not empty */
  	Nicks *n;
	if(nl->start->left==nl->start->right)/*just 1 nick entry*/
		{ptr=nl->current->nick; goto cont;}
	#if DEBUG
	fprintf(stderr,"_curent:%s ",nl->current->nick);
	#endif
	n=strcasecmp(nick, nl->current->nick)? nl->current:nl->current->left;
	if(n==nl->start) n=n->left;
	ptr= n->nick;
	nl->current=  nl->current->left;
	if(nl->current==nl->start)  nl->current=  nl->current->left; 
	#if DEBUG
	fprintf(stderr,"now curent:%s\n",nl->current->nick);
	#endif
	line=malloc(sizeof(char)*(strlen(ptr)+12));
	sprintf(line,"NICK %s\n", ptr);
   }else{
 cont:
	if(!ptr) ptr=nick+1;
	line=malloc(sizeof(char)*(strlen(ptr)+40));
	srandom(time(NULL));
    	sprintf(line, "NICK _%s%ld\n", ptr, random());
	/* Note: '_' comes first, just in case old nick was too long*/
   }
   if(Win->server->fd>0)
		writen(Win->server->fd,line, strlen(line));
   if(Win->server->connecting){
   	Win->server->connecting=1;
	gettimeofday(&Win->server->t,NULL);
	#ifndef NOLAG
	send_lag_junk(Win->server,1,0);
	#endif
   }
   #if DEBUG
   fprintf(stderr,"%s taken;%s\n", nick, line);
   #endif
   free(line);
 }/* Win->server->connecting */
	if(!check_numeric(numeric, Msg) && !Win->server->connecting){
		if (gflags & BEEP_SERVER_ERR) fl_ringbell(0);
		if(gflags & SHOW_RAW_MSG){
			 if (X == 1) fl_addto_browser(Win->chanwin->brow2,Msg);
			 else berr_msg(Msg);
		}
		else{
		if (sscanf(Msg, "%*s %*s %*s %[^\r\n]\r\n", buf)<1)break;
		if (X == 1) {
			char *s=(char *)malloc(sizeof(char)*(strlen(buf)+strlen(sender)+12));
			sprintf(s, "%s%s> %s", num,sender, buf);
			fl_addto_browser(Win->chanwin->brow2, s);
			free(s);
		}else berr_msg("%s%s> %s", num, sender, buf);
		}
	}
     	break;
  }


	    case ERR_NICKCOLLISION:	/*    436 */
		    {
			    fl_ringbell(50);
			    fl_addto_browser(Win->chanwin->brow2,
			    "@b@C1You are dead. Collided.");
#warning (24.01.1998) reconnect after collision?
			    berr_msg(Msg);
			    fl_ringbell(50);
			    check_numeric(numeric, Msg);
		    }
		    break;
	    
	    case RPL_SILELIST:/*         271         Undernet extension */
	    	if(check_numeric(numeric, Msg)) break;
		
		if (gflags & SHOW_RAW_MSG) berr_msg(Msg);
		else
		berr_msg("%s%s's silence list from %s: %s",num, 
		nextstr(Msg,4),Win->server->servname, nextstr(Msg,5));
		break;
	    case RPL_ENDOFSILELIST:/*    272       */ /* Undernet extension */
	    default:
		    if(check_numeric(numeric, Msg)) break;
		    if (gflags & SHOW_RAW_MSG) berr_msg("%s", Msg);
		    else

		    if(sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf)>0)
		    	berr_msg("%s%s",num, *buf==':'? buf+1:buf);
		    break;

	    case ERR_UNKNOWNMODE:{
				/*      472 */
			    char    c;
			    if(check_numeric(numeric, Msg)) break;
			    if (sscanf(Msg, "%*s %*s %*s %s", &c) < 1)
				    break;
			    if (X == 1) {
				    char *s=(char *)malloc(sizeof(char)*(40));
				    sprintf(s, "%s%c is an unknown mode to me!", num, c);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %c is an unknown mode character to me!", 
				    num, sender, c);
		    }
		    break;

	    case RPL_TIME:{	/*             391 */
			    if(check_numeric(numeric, Msg)) break;
			    if (sscanf(Msg, "%*s %*s %*s %*s :%[^\r\n]\r\n", buf) < 1)
				    break;
			    if (X == 1) {
				    char *s=(char *)malloc(sizeof(char)*(
				    strlen(buf)+strlen(sender)+16));
				    sprintf(s, "%s-%s- It is %s", num, sender, buf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s-%s-%s", num, sender, buf);
			    break;
		    }
	/* the following will be just be quoted */
	case RPL_KILLDONE:/* 361*/
	case RPL_CLOSING:/* 362*/
	case RPL_CLOSEEND:/* 363*/
        case RPL_LINKS:/* 364*/
        case RPL_ENDOFLINKS:/* 365*/
        case RPL_USERSSTART:/* 392*/
        case RPL_USERS:/* 393*/
        case RPL_ENDOFUSERS:/* 394*/
        case RPL_NOUSERS:/* 395*/

        case RPL_TRACELINK:/* 200*/
        case RPL_TRACECONNECTING:/* 201*/
        case RPL_TRACEHANDSHAKE:/*E 202*/
        case RPL_TRACEUNKNOWN:/* 203*/
        case RPL_TRACEOPERATOR:/* 204*/
        case RPL_TRACEUSER:/* 205*/
        case RPL_TRACESERVER:/* 206*/
        case RPL_TRACESERVICE:/* 207*/
        case RPL_TRACENEWTYPE:/* 208*/
        case RPL_TRACECLASS:/* 209*/

        case RPL_STATSLINKINFO:/* 211*/
        case RPL_STATSCOMMANDS:/* 212*/
        case RPL_STATSCLINE:/* 213*/
        case RPL_STATSNLINE:/* 214*/
        case RPL_STATSILINE:/* 215*/
        case RPL_STATSKLINE:/* 216*/
        case RPL_STATSQLINE:/* 217*/
        case RPL_STATSYLINE:/* 218*/
        case RPL_ENDOFSTATS:/* 219*/

        case RPL_SERVICEINFO:/* 231*/
        case RPL_ENDOFSERVICES:/* 232*/
        case RPL_SERVICE:/* 233*/
        case RPL_SERVLIST:/* 234*/
        case RPL_SERVLISTEND:/* 235*/

        case RPL_STATSLLINE:/* 241*/
        case RPL_STATSUPTIME:/* 242*/
        case RPL_STATSOLINE:/* 243*/
        case RPL_STATSHLINE:/* 244*/
        case RPL_STATSSLINE:/* 245*/

        case RPL_STATSDEBUG:/* 249*/
        case RPL_TRACELOG:/* 261*/
		    if(!check_numeric(numeric, Msg))
		    {
			    char *pbuf;
			    if (sscanf(Msg, "%*s %*s %*s %[^\n]\n", buf) < 1)
				    break;
			    pbuf=buf;
			    if (*buf == ':')
				    pbuf++;
			    if (X == 1) {
				    char    *s=(char *)malloc(sizeof(char)*(
				    strlen(pbuf)+6));
				    sprintf(s, "%s%s", num,pbuf);
				    fl_addto_browser(Win->chanwin->brow2, s);
				    free(s);
			    }
			    else
				    berr_msg("%s%s> %s", num, sender, pbuf);

		    }
		    break;
	}			/* switch */
	free(buf); free(sender);
}				/* end of function ! */
/*-----------------------------------------------*/

static void cmds_oncon(void)
{
	CmdOnCon *p = cmdonconStart;

	while (p != cmdonconEnd)
		if ((!p->server && (p->port == Win->server->port || p->port < 1)) ||
		    (!strcasecmp(p->server, Win->server->servname) &&
		     (p->port == Win->server->port || p->port < 1))
		   ) {
			CmdOnCon *q = p->next;

			if(p->type==SERV_CMD)
				sendto_server(Win,p->cmd);
			else process_cmd(p->cmd, Win);
			free(p->cmd);
			free(p->server);
			if (q == cmdonconEnd)
				cmdonconEnd = p;
			else
				*p = *q;
			free(q);
		}
		else
			p = p->next;
	return;
}

static void TryOldChannels(void)
{
/* attempt to rejoin the channels u were on b4 server connection was lost/closed  *
 *  
 * -only if server closed down the connection on- */

	Channel *current;
	WinList *p;
	char   *buf=NULL;
		 
	build_winlistbyfd(Win->server->fd);
	p = servWin;
  while (p) {
	current = p->win->chanStart->right;
	while (current != p->win->chanStart ) {
		buf = (char *) malloc(sizeof(char) * (strlen(current->name)+
		(current->key ? strlen(current->key):0)+16));
		sprintf(buf, "JOIN %s %s\n", 
		current->name, current->key ? current->key : "");
	 	if(sendto_server(p->win,buf)){free(buf); break;}
		else addto_cmd_sent(p->win, "JOIN", current->name);
		current = current->right;
		free(buf);
	}
	ClearWinChanList(p->win);
	p = p->next;
   }/* while(p!=nULL*/

}
static void p_namereply(const char *msg)
{				/*   353 */
	Winstruct *win = NULL;
	char  *sender = NULL, *chan = NULL, *firstnick, *dummy = NULL,
	        *others;

	/*win = getwinbycmd(Win->server, "NAMES", NULL, 1);*//* for now 14.10.97*/
	sender=nextstr(msg,1);
	dummy=nextstr(msg,4);
	chan=nextstr(msg,5);
	if(!chan) return;
	if (*dummy == '*' || *chan == '*')	/*certainly a reply to NAMES cmd */
		goto do_names;
	firstnick=nextstr(msg,6);
	if(!firstnick) return;
	if ( *++firstnick == '@' &&
	!strcmp(Win->server->nick, ++firstnick)
	&& !nextstr(msg,7)) 	/* no other users->just created channel */
	{
		Channel *p = get_chan_byname(Win, chan);
		if (p)		/* channel is on Win */
		    {	/* just created channel */
			p->modes = strdup("o");
			update_server_stuff(Win->server->fd);
		}
	}
	if(check_numeric(353, Msg)){
		getwinbycmd(Win->server, "NAMES", NULL, 1);
	 	return;
	}
      do_names:
	others=(char*)malloc(sizeof(char)*strlen(msg));
	sscanf(msg, "%*[^:]:%[^\n]\n", others);

#if 0
	/*doesnt always work; but dont remove */
	win = getwinbycmd(Win->server, "NAMES", chan, 0);	/* names #test */
	if (!win)
#endif
		win = getwinbycmd(Win->server, "NAMES", NULL, 1);	/* names */
	if (!win)
		win = get_win_bychanname(Win->server->fd, chan);	/* just joined */
	if (win) {
		sprintf(buf, "%sUsers on %s: %s",num, 
		*dummy == '*' ? "(Private)" : chan, others);
		fl_addto_browser(win->chanwin->brow2, buf);
	}
	else
		berr_msg("%s%s> Users on %s: %s", num,sender,
		 *dummy == '*' ? "(Private)" : chan, others);
	free(others);
}


