X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-info.c;h=88455c74d9e85c770442aea1aa6f0c54e2e0ab9c;hp=fe8c5c2e9971fcb1e131eea265dcc4e099f48d36;hb=08f9d31d60220e8a389a2d24f42625be7749f090;hpb=4dc940f59e8499b929b8bad8791a7d337cc62a23 diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index fe8c5c2e..88455c74 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -38,6 +38,7 @@ #include "tool.h" #include "parse.h" #include "irc.h" +#include "irc-macros.h" #include "irc-write.h" #include "client-cap.h" @@ -86,14 +87,6 @@ write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *f flags, Client_Hops(c), Client_Info(c)); } -static const char * -who_flags_status(const char *client_modes) -{ - if (strchr(client_modes, 'a')) - return "G"; /* away */ - return "H"; -} - /** * Return channel user mode prefix(es). * @@ -151,7 +144,6 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) { bool is_visible, is_member, is_ircop; CL2CHAN *cl2chan; - const char *client_modes; char flags[10]; CLIENT *c; int count = 0; @@ -164,7 +156,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) is_member = Channel_IsMemberOf(Chan, Client); /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan)); @@ -172,17 +164,21 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) for (; cl2chan ; cl2chan = Channel_NextMember(Chan, cl2chan)) { c = Channel_GetClient(cl2chan); - client_modes = Client_Modes(c); - is_ircop = strchr(client_modes, 'o') != NULL; + is_ircop = Client_HasMode(c, 'o'); if (OnlyOps && !is_ircop) continue; - is_visible = strchr(client_modes, 'i') == NULL; + is_visible = Client_HasMode(c, 'i'); if (is_member || is_visible) { - strlcpy(flags, who_flags_status(client_modes), - sizeof(flags)); + memset(flags, 0, sizeof(flags)); + + if (Client_HasMode(c, 'a')) + flags[0] = 'G'; /* away */ + else + flags[0] = 'H'; + if (is_ircop) - strlcat(flags, "*", sizeof(flags)); + flags[1] = '*'; who_flags_qualifier(Client, Channel_UserModes(Chan, c), flags, sizeof(flags)); @@ -217,7 +213,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) CL2CHAN *cl2chan; CHANNEL *chan; bool client_match, is_visible; - char flags[4]; + char flags[3]; int count = 0; assert (Client != NULL); @@ -273,9 +269,15 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO")) break; - strlcpy(flags, who_flags_status(Client_Modes(c)), sizeof(flags)); - if (strchr(Client_Modes(c), 'o')) - strlcat(flags, "*", sizeof(flags)); + memset(flags, 0, sizeof(flags)); + + if (Client_HasMode(c, 'a')) + flags[0] = 'G'; /* away */ + else + flags[0] = 'H'; + + if (Client_HasMode(c, 'o')) + flags[1] = '*'; if (!write_whoreply(Client, c, "*", flags)) return DISCONNECTED; @@ -297,7 +299,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) static bool IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) { - char str[LINE_LEN + 1]; + char str[COMMAND_LEN]; CL2CHAN *cl2chan; CHANNEL *chan; @@ -329,7 +331,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) cl2chan = Channel_NextChannelOf(c, cl2chan); /* Secret channel? */ - if (strchr(Channel_Modes(chan), 's') + if (Channel_HasMode(chan, 's') && !Channel_IsMemberOf(chan, Client)) continue; @@ -346,7 +348,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) str, sizeof(str)); strlcat(str, Channel_Name(chan), sizeof(str)); - if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) { + if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) { /* Line becomes too long: send it! */ if (!IRC_WriteStrClient(Client, "%s", str)) return DISCONNECTED; @@ -360,8 +362,15 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) return DISCONNECTED; } + /* IRC-Services? */ + if (Client_Type(c) == CLIENT_SERVICE && + !IRC_WriteStrClient(from, RPL_WHOISSERVICE_MSG, + Client_ID(from), Client_ID(c))) + return DISCONNECTED; + /* IRC-Operator? */ - if (Client_HasMode(c, 'o') && + if (Client_Type(c) != CLIENT_SERVICE && + Client_HasMode(c, 'o') && !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG, Client_ID(from), Client_ID(c))) return DISCONNECTED; @@ -373,10 +382,19 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) return DISCONNECTED; /* Connected using SSL? */ - if (Conn_UsesSSL(Client_Conn(c)) && - !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from), - Client_ID(c))) - return DISCONNECTED; + if (Conn_UsesSSL(Client_Conn(c))) { + if (!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from), + Client_ID(c))) + return DISCONNECTED; + + /* Certificate fingerprint? */ + if (Conn_GetCertFp(Client_Conn(c)) && + from == c && + !IRC_WriteStrClient(from, RPL_WHOISCERTFP_MSG, + Client_ID(from), Client_ID(c), + Conn_GetCertFp(Client_Conn(c)))) + return DISCONNECTED; + } /* Registered nickname? */ if (Client_HasMode(c, 'R') && @@ -389,8 +407,8 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) (from == c || (!Conf_MorePrivacy && Client_HasMode(from, 'o')))) { /* Client hostname */ if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, - Client_ID(from), Client_ID(c), Client_Hostname(c), - Conn_GetIPAInfo(Client_Conn(c)))) + Client_ID(from), Client_ID(c), + Client_Hostname(c), Client_IPAText(c))) return DISCONNECTED; /* Client modes */ if (!IRC_WriteStrClient(from, RPL_WHOISMODES_MSG, @@ -431,51 +449,37 @@ WHOWAS_EntryWrite(CLIENT *prefix, WHOWAS *entry) entry->id, entry->server, t_str); } -static bool -Show_MOTD_Start(CLIENT *Client) -{ - return IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG, - Client_ID( Client ), Client_ID( Client_ThisServer( ))); -} - -static bool -Show_MOTD_Sendline(CLIENT *Client, const char *msg) -{ - return IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID( Client ), msg); -} - -static bool -Show_MOTD_End(CLIENT *Client) -{ - if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client))) - return DISCONNECTED; - - if (*Conf_CloakHost) - return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG, - Client_ID(Client), - Client_Hostname(Client)); - - return CONNECTED; -} - #ifdef SSL_SUPPORT -static bool Show_MOTD_SSLInfo(CLIENT *Client) +static bool +Show_MOTD_SSLInfo(CLIENT *Client) { - bool ret = true; - char buf[COMMAND_LEN] = "Connected using Cipher "; - - if (!Conn_GetCipherInfo(Client_Conn(Client), buf + 23, sizeof buf - 23)) - return true; + char buf[COMMAND_LEN]; + char c_str[128]; + + if (Conn_GetCipherInfo(Client_Conn(Client), c_str, sizeof(c_str))) { + snprintf(buf, sizeof(buf), "Connected using Cipher %s", c_str); + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, + Client_ID(Client), buf)) + return false; + } - if (!Show_MOTD_Sendline(Client, buf)) - ret = false; + if (Conn_GetCertFp(Client_Conn(Client))) { + snprintf(buf, sizeof(buf), + "Your client certificate fingerprint is: %s", + Conn_GetCertFp(Client_Conn(Client))); + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, + Client_ID(Client), buf)) + return false; + } - return ret; + return true; } #else -static inline bool +static bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) -{ return true; } +{ + return true; +} #endif /* Global functions */ @@ -495,34 +499,31 @@ IRC_ADMIN(CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - /* find target ... */ - if( Req->argc == 1 ) target = Client_Search( Req->argv[0] ); - else target = Client_ThisServer( ); - - /* find Prefix */ - if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix ); - else prefix = Client; - if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + IRC_SetPenalty(Client, 1); - /* forwad message to another server? */ - if( target != Client_ThisServer( )) - { - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( prefix, ERR_NOSUCHSERVER_MSG, Client_ID( prefix ), Req->argv[0] ); + _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) - /* forward */ - IRC_WriteStrClientPrefix( target, prefix, "ADMIN %s", Req->argv[0] ); + /* Forward? */ + if(target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, prefix, + "ADMIN %s", Client_ID(target)); return CONNECTED; } - /* mit Versionsinfo antworten */ - if( ! IRC_WriteStrClient( Client, RPL_ADMINME_MSG, Client_ID( prefix ), Conf_ServerName )) return DISCONNECTED; - if( ! IRC_WriteStrClient( Client, RPL_ADMINLOC1_MSG, Client_ID( prefix ), Conf_ServerAdmin1 )) return DISCONNECTED; - if( ! IRC_WriteStrClient( Client, RPL_ADMINLOC2_MSG, Client_ID( prefix ), Conf_ServerAdmin2 )) return DISCONNECTED; - if( ! IRC_WriteStrClient( Client, RPL_ADMINEMAIL_MSG, Client_ID( prefix ), Conf_ServerAdminMail )) return DISCONNECTED; + if (!IRC_WriteStrClient(Client, RPL_ADMINME_MSG, Client_ID(prefix), + Conf_ServerName)) + return DISCONNECTED; + if (!IRC_WriteStrClient(Client, RPL_ADMINLOC1_MSG, Client_ID(prefix), + Conf_ServerAdmin1)) + return DISCONNECTED; + if (!IRC_WriteStrClient(Client, RPL_ADMINLOC2_MSG, Client_ID(prefix), + Conf_ServerAdmin2)) + return DISCONNECTED; + if (!IRC_WriteStrClient(Client, RPL_ADMINEMAIL_MSG, Client_ID(prefix), + Conf_ServerAdminMail)) + return DISCONNECTED; - IRC_SetPenalty( Client, 1 ); return CONNECTED; } /* IRC_ADMIN */ @@ -542,38 +543,15 @@ IRC_INFO(CLIENT * Client, REQUEST * Req) assert(Client != NULL); assert(Req != NULL); - /* Wrong number of parameters? */ - if (Req->argc > 1) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - /* Determine prefix */ - if (Client_Type(Client) == CLIENT_SERVER) - prefix = Client_Search(Req->prefix); - else - prefix = Client; - if (!prefix) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); - - /* Look for a target */ - if (Req->argc > 0) - target = Client_Search(Req->argv[0]); - else - target = Client_ThisServer(); - - /* Make sure that the target is a server */ - if (target && Client_Type(target) != CLIENT_SERVER) - target = Client_Introducer(target); + IRC_SetPenalty(Client, 2); - if (!target) - return IRC_WriteStrClient(prefix, ERR_NOSUCHSERVER_MSG, - Client_ID(prefix), Req->argv[0]); + _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) - /* Pass on to another server? */ + /* Forward? */ if (target != Client_ThisServer()) { IRC_WriteStrClientPrefix(target, prefix, "INFO %s", - Req->argv[0]); + Client_ID(target)); return CONNECTED; } @@ -595,7 +573,6 @@ IRC_INFO(CLIENT * Client, REQUEST * Req) if (!IRC_WriteStrClient(Client, RPL_ENDOFINFO_MSG, Client_ID(prefix))) return DISCONNECTED; - IRC_SetPenalty(Client, 2); return CONNECTED; } /* IRC_INFO */ @@ -617,11 +594,6 @@ IRC_ISON( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - /* Bad number of arguments? */ - if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - strlcpy(rpl, RPL_ISON_MSG, sizeof rpl); for (i = 0; i < Req->argc; i++) { /* "All" ircd even parse ": ..." arguments and split @@ -660,9 +632,7 @@ IRC_LINKS(CLIENT *Client, REQUEST *Req) IRC_SetPenalty(Client, 1); - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) /* Get pointer to server mask or "*", if none given */ if (Req->argc > 0) @@ -670,26 +640,15 @@ IRC_LINKS(CLIENT *Client, REQUEST *Req) else mask = "*"; - if (Client_Type(Client) == CLIENT_SERVER) - from = Client_Search(Req->prefix); - else - from = Client; - if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); - /* Forward? */ if (Req->argc == 2) { - target = Client_Search(Req->argv[0]); - if (! target || Client_Type(target) != CLIENT_SERVER) - return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, - Client_ID(from), - Req->argv[0] ); - else - if (target != Client_ThisServer()) - return IRC_WriteStrClientPrefix(target, from, - "LINKS %s %s", Req->argv[0], - Req->argv[1]); + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from) + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, + "LINKS %s %s", Client_ID(target), + Req->argv[1]); + return CONNECTED; + } } c = Client_First(); @@ -725,30 +684,20 @@ IRC_LUSERS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + IRC_SetPenalty(Client, 1); - /* Absender ermitteln */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) - /* An anderen Server forwarden? */ - if( Req->argc == 2 ) - { - target = Client_Search( Req->argv[1] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] ); - else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LUSERS %s %s", Req->argv[0], Req->argv[1] ); + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, + "LUSERS %s %s", Req->argv[0], + Client_ID(target)); + return CONNECTED; } - /* Wer ist der Absender? */ - if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix ); - else target = Client; - if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); - - IRC_Send_LUSERS( target ); - - IRC_SetPenalty( target, 1 ); - return CONNECTED; + return IRC_Send_LUSERS(from); } /* IRC_LUSERS */ /** @@ -766,9 +715,7 @@ IRC_SERVLIST(CLIENT *Client, REQUEST *Req) assert(Client != NULL); assert(Req != NULL); - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + IRC_SetPenalty(Client, 1); if (Req->argc < 2 || strcmp(Req->argv[1], "0") == 0) { for (c = Client_First(); c!= NULL; c = Client_Next(c)) { @@ -805,28 +752,19 @@ IRC_MOTD( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - /* From aus Prefix ermitteln */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + IRC_SetPenalty(Client, 3); - if( Req->argc == 1 ) - { - /* forward? */ - target = Client_Search( Req->argv[0] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] ); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from) - if( target != Client_ThisServer( )) - { - /* Ok, anderer Server ist das Ziel: forwarden */ - return IRC_WriteStrClientPrefix( target, from, "MOTD %s", Req->argv[0] ); - } + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, "MOTD %s", + Client_ID(target)); + return CONNECTED; } - IRC_SetPenalty( from, 3 ); - return IRC_Show_MOTD( from ); + return IRC_Show_MOTD(from); } /* IRC_MOTD */ /** @@ -846,81 +784,67 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - /* use prefix to determine "From" */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + IRC_SetPenalty(Client, 1); - if( Req->argc == 2 ) - { - /* forward to another server? */ - target = Client_Search( Req->argv[1] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] ); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) - if( target != Client_ThisServer( )) { - /* target is another server, forward */ - return IRC_WriteStrClientPrefix( target, from, "NAMES %s :%s", Req->argv[0], Req->argv[1] ); - } + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, "NAMES %s :%s", + Req->argv[0], Client_ID(target)); + return CONNECTED; } - if( Req->argc > 0 ) - { - /* bestimmte Channels durchgehen */ - ptr = strtok( Req->argv[0], "," ); - while( ptr ) - { - chan = Channel_Search( ptr ); - if( chan ) - { - /* print name */ - if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED; - } - if( ! IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), ptr )) return DISCONNECTED; - - /* get next channel name */ + if (Req->argc > 0) { + /* Return NAMES list for specific channels */ + ptr = strtok(Req->argv[0], ","); + while(ptr) { + chan = Channel_Search(ptr); + if (chan && !IRC_Send_NAMES(from, chan)) + return DISCONNECTED; + if (!IRC_WriteStrClient(from, RPL_ENDOFNAMES_MSG, + Client_ID(from), ptr)) + return DISCONNECTED; ptr = strtok( NULL, "," ); } return CONNECTED; } - chan = Channel_First( ); - while( chan ) - { - if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED; - - chan = Channel_Next( chan ); + chan = Channel_First(); + while (chan) { + if (!IRC_Send_NAMES(from, chan)) + return DISCONNECTED; + chan = Channel_Next(chan); } /* Now print all clients which are not in any channel */ - c = Client_First( ); - snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" ); - while( c ) - { - if(( Client_Type( c ) == CLIENT_USER ) && ( Channel_FirstChannelOf( c ) == NULL ) && ( ! strchr( Client_Modes( c ), 'i' ))) + c = Client_First(); + snprintf(rpl, sizeof(rpl), RPL_NAMREPLY_MSG, Client_ID(from), "*", "*"); + while (c) { + if (Client_Type(c) == CLIENT_USER + && Channel_FirstChannelOf(c) == NULL + && !Client_HasMode(c, 'i')) { /* its a user, concatenate ... */ - if( rpl[strlen( rpl ) - 1] != ':' ) strlcat( rpl, " ", sizeof( rpl )); - strlcat( rpl, Client_ID( c ), sizeof( rpl )); + if (rpl[strlen(rpl) - 1] != ':') + strlcat(rpl, " ", sizeof(rpl)); + strlcat(rpl, Client_ID(c), sizeof(rpl)); - if( strlen( rpl ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 )) - { + if (strlen(rpl) > COMMAND_LEN - CLIENT_NICK_LEN - 4) { /* Line is gwoing too long, send now */ - if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED; - snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" ); + if (!IRC_WriteStrClient(from, "%s", rpl)) + return DISCONNECTED; + snprintf(rpl, sizeof(rpl), RPL_NAMREPLY_MSG, + Client_ID(from), "*", "*"); } } - - c = Client_Next( c ); - } - if( rpl[strlen( rpl ) - 1] != ':') - { - if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED; + c = Client_Next(c); } + if (rpl[strlen(rpl) - 1] != ':' && !IRC_WriteStrClient(from, "%s", rpl)) + return DISCONNECTED; - IRC_SetPenalty( from, 1 ); - return IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), "*" ); + return IRC_WriteStrClient(from, RPL_ENDOFNAMES_MSG, Client_ID(from), "*"); } /* IRC_NAMES */ /** @@ -945,32 +869,16 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); - - /* use prefix to determine "From" */ - if (Client_Type(Client) == CLIENT_SERVER) - from = Client_Search(Req->prefix); - else - from = Client; - - if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + IRC_SetPenalty(Client, 2); - if (Req->argc == 2) { - /* forward to another server? */ - target = Client_Search(Req->argv[1]); - if ((!target) || (Client_Type(target) != CLIENT_SERVER)) - return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, - Client_ID(from), Req->argv[1]); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) - if (target != Client_ThisServer()) { - /* forward to another server */ - return IRC_WriteStrClientPrefix(target, from, - "STATS %s %s", Req->argv[0], Req->argv[1]); - } + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, "STATS %s %s", + Req->argv[0], Client_ID(target)); + return CONNECTED; } if (Req->argc > 0) @@ -984,7 +892,7 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) case 'k': /* Server-local bans ("K-Lines") */ case 'K': if (!Client_HasMode(from, 'o')) - return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG, + return IRC_WriteErrClient(from, ERR_NOPRIVILEGES_MSG, Client_ID(from)); if (query == 'g' || query == 'G') list = Class_GetList(CLASS_GLINE); @@ -1062,7 +970,6 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) break; } - IRC_SetPenalty(from, 2); return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query); } /* IRC_STATS */ @@ -1077,7 +984,9 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) GLOBAL bool IRC_SUMMON(CLIENT * Client, UNUSED REQUEST * Req) { - return IRC_WriteStrClient(Client, ERR_SUMMONDISABLED_MSG, + assert(Client != NULL); + + return IRC_WriteErrClient(Client, ERR_SUMMONDISABLED_MSG, Client_ID(Client)); } /* IRC_SUMMON */ @@ -1095,29 +1004,25 @@ IRC_TIME( CLIENT *Client, REQUEST *Req ) char t_str[64]; time_t t; - assert( Client != NULL ); - assert( Req != NULL ); - - if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + assert(Client != NULL); + assert(Req != NULL); - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + IRC_SetPenalty(Client, 1); - if( Req->argc == 1 ) - { - target = Client_Search( Req->argv[0] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] ); + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from) - if( target != Client_ThisServer( )) - { - return IRC_WriteStrClientPrefix( target, from, "TIME %s", Req->argv[0] ); - } + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, "TIME %s", + Client_ID(target)); + return CONNECTED; } t = time( NULL ); - (void)strftime( t_str, 60, "%A %B %d %Y -- %H:%M %Z", localtime( &t )); - return IRC_WriteStrClient( from, RPL_TIME_MSG, Client_ID( from ), Client_ID( Client_ThisServer( )), t_str ); + (void)strftime(t_str, 60, "%A %B %d %Y -- %H:%M %Z", localtime(&t)); + return IRC_WriteStrClient(from, RPL_TIME_MSG, Client_ID(from), + Client_ID(Client_ThisServer()), t_str); } /* IRC_TIME */ /** @@ -1137,9 +1042,7 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req) assert(Client != NULL); assert(Req != NULL); - if ((Req->argc < 1)) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + IRC_SetPenalty(Client, 1); if (Req->argc > 5) max = 5; @@ -1180,7 +1083,9 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req) GLOBAL bool IRC_USERS(CLIENT * Client, UNUSED REQUEST * Req) { - return IRC_WriteStrClient(Client, ERR_USERSDISABLED_MSG, + assert(Client != NULL); + + return IRC_WriteErrClient(Client, ERR_USERSDISABLED_MSG, Client_ID(Client)); } /* IRC_USERS */ @@ -1199,29 +1104,19 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - /* Ziel suchen */ - if( Req->argc == 1 ) target = Client_Search( Req->argv[0] ); - else target = Client_ThisServer( ); - - /* Prefix ermitteln */ - if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix ); - else prefix = Client; - if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); + IRC_SetPenalty(Client, 1); - /* An anderen Server weiterleiten? */ - if( target != Client_ThisServer( )) - { - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( prefix, ERR_NOSUCHSERVER_MSG, Client_ID( prefix ), Req->argv[0] ); + _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) - /* forwarden */ - IRC_WriteStrClientPrefix( target, prefix, "VERSION %s", Req->argv[0] ); + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, prefix, "VERSION %s", + Client_ID(target)); return CONNECTED; } /* send version information */ - IRC_SetPenalty(Client, 1); return IRC_WriteStrClient(Client, RPL_VERSION_MSG, Client_ID(prefix), PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_DebugLevel, Conf_ServerName, @@ -1244,25 +1139,21 @@ IRC_WHO(CLIENT *Client, REQUEST *Req) assert (Client != NULL); assert (Req != NULL); - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + IRC_SetPenalty(Client, 1); only_ops = false; - if (Req->argc == 2) { if (strcmp(Req->argv[1], "o") == 0) only_ops = true; #ifdef STRICT_RFC else - return IRC_WriteStrClient(Client, + return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); #endif } - IRC_SetPenalty(Client, 1); if (Req->argc >= 1) { /* Channel or mask given */ chan = Channel_Search(Req->argv[0]); @@ -1301,40 +1192,30 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - /* Bad number of parameters? */ - if (Req->argc < 1 || Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + IRC_SetPenalty(Client, 1); - /* Search sender of the WHOIS */ - if (Client_Type(Client) == CLIENT_SERVER) { - from = Client_Search(Req->prefix); - } else { - IRC_SetPenalty(Client, 1); - from = Client; - } - if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + /* Wrong number of parameters? */ + if (Req->argc < 1) + return IRC_WriteErrClient(Client, ERR_NONICKNAMEGIVEN_MSG, + Client_ID(Client)); + + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) + _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) /* Get target server for this command */ if (Req->argc > 1) { - /* Search the target server, which can be specified as a - * nickname on that server as well: */ - target = Client_Search(Req->argv[0]); - if (!target) - return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, - Client_ID(from), Req->argv[0]); + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, Client) } else target = Client_ThisServer(); + assert(target != NULL); - /* Forward to other server? */ - if (Client_NextHop(target) != Client_ThisServer() && - Client_Type(Client_NextHop(target)) == CLIENT_SERVER) - return IRC_WriteStrClientPrefix(target, from, - "WHOIS %s :%s", - Req->argv[0], Req->argv[1]); + /* Forward? */ + if (target != Client_ThisServer()) { + IRC_WriteStrClientPrefix(target, from, "WHOIS %s :%s", + Req->argv[0], Req->argv[1]); + return CONNECTED; + } is_remote = Client_Conn(from) < 0; strlcpy(mask, Req->argv[Req->argc - 1], sizeof(mask)); @@ -1353,11 +1234,12 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) */ if (!has_wildcards || is_remote) { c = Client_Search(query); - if (c && Client_Type(c) == CLIENT_USER) { + if (c && (Client_Type(c) == CLIENT_USER + || Client_Type(c) == CLIENT_SERVICE)) { if (!IRC_WHOIS_SendReply(Client, from, c)) return DISCONNECTED; } else { - if (!IRC_WriteStrClient(Client, + if (!IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), query)) @@ -1367,7 +1249,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) } if (got_wildcard) { /* we already handled one wildcard query */ - if (!IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + if (!IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), query)) return DISCONNECTED; continue; @@ -1391,7 +1273,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) } if (match_count == 0) - IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[Req->argc - 1]); } @@ -1418,43 +1300,24 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - /* Do not reveal any info on disconnected users? */ - if (Conf_MorePrivacy) - return CONNECTED; - /* Wrong number of parameters? */ - if (Req->argc > 3) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NONICKNAMEGIVEN_MSG, Client_ID(Client)); - - /* Search target */ - if (Req->argc == 3) - target = Client_Search(Req->argv[2]); - else - target = Client_ThisServer(); + return IRC_WriteErrClient(Client, ERR_NONICKNAMEGIVEN_MSG, + Client_ID(Client)); - /* Get prefix */ - if (Client_Type(Client) == CLIENT_SERVER) - prefix = Client_Search(Req->prefix); - else - prefix = Client; + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 3) + _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) + _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 2, prefix) - if (!prefix) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, - Client_ID(Client), Req->prefix); + /* Do not reveal any info on disconnected users? */ + if (Conf_MorePrivacy) + return CONNECTED; - /* Forward to other server? */ + /* Forward? */ if (target != Client_ThisServer()) { - if (!target || (Client_Type(target) != CLIENT_SERVER)) - return IRC_WriteStrClient(prefix, ERR_NOSUCHSERVER_MSG, - Client_ID(prefix), Req->argv[2]); - - /* Forward */ - IRC_WriteStrClientPrefix( target, prefix, "WHOWAS %s %s %s", - Req->argv[0], Req->argv[1], - Req->argv[2] ); + IRC_WriteStrClientPrefix(target, prefix, "WHOWAS %s %s %s", + Req->argv[0], Req->argv[1], + Client_ID(target)); return CONNECTED; } @@ -1498,11 +1361,12 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) break; } while (i != last); - if (nc == 0 && !IRC_WriteStrClient(prefix, ERR_WASNOSUCHNICK_MSG, + if (nc == 0 && !IRC_WriteErrClient(prefix, ERR_WASNOSUCHNICK_MSG, Client_ID(prefix), nick)) return DISCONNECTED; } - return IRC_WriteStrClient(prefix, RPL_ENDOFWHOWAS_MSG, Client_ID(prefix), Req->argv[0]); + return IRC_WriteStrClient(prefix, RPL_ENDOFWHOWAS_MSG, + Client_ID(prefix), Req->argv[0]); } /* IRC_WHOWAS */ /** @@ -1521,7 +1385,7 @@ IRC_Send_LUSERS(CLIENT *Client) assert(Client != NULL); - /* Users, services and serevers in the network */ + /* Users, services and servers in the network */ if (!IRC_WriteStrClient(Client, RPL_LUSERCLIENT_MSG, Client_ID(Client), Client_UserCount(), Client_ServiceCount(), Client_ServerCount())) @@ -1587,9 +1451,10 @@ IRC_Show_MOTD( CLIENT *Client ) len_tot = array_bytes(&Conf_Motd); if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client))) - return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client)); + return IRC_WriteErrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client)); - if (!Show_MOTD_Start(Client)) + if (!IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG, Client_ID(Client), + Client_ID(Client_ThisServer()))) return DISCONNECTED; line = array_start(&Conf_Motd); @@ -1599,14 +1464,23 @@ IRC_Show_MOTD( CLIENT *Client ) assert(len_tot >= len_str); len_tot -= len_str; - if (!Show_MOTD_Sendline(Client, line)) + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID(Client), line)) return DISCONNECTED; line += len_str; } if (!Show_MOTD_SSLInfo(Client)) return DISCONNECTED; - return Show_MOTD_End(Client); + + if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client))) + return DISCONNECTED; + + if (*Conf_CloakHost) + return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG, + Client_ID(Client), + Client_Hostname(Client)); + + return CONNECTED; } /* IRC_Show_MOTD */ /** @@ -1620,7 +1494,7 @@ GLOBAL bool IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) { bool is_visible, is_member; - char str[LINE_LEN + 1]; + char str[COMMAND_LEN]; CL2CHAN *cl2chan; CLIENT *cl; @@ -1637,7 +1511,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) return CONNECTED; /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return CONNECTED; snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, Client_ID(Client), "=", @@ -1646,7 +1520,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) while (cl2chan) { cl = Channel_GetClient(cl2chan); - if (strchr(Client_Modes(cl), 'i')) + if (Client_HasMode(cl, 'i')) is_visible = false; else is_visible = true; @@ -1659,7 +1533,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) str, sizeof(str)); strlcat(str, Client_ID(cl), sizeof(str)); - if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 4)) { + if (strlen(str) > (COMMAND_LEN - CLIENT_NICK_LEN - 4)) { if (!IRC_WriteStrClient(Client, "%s", str)) return DISCONNECTED; snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, @@ -1687,7 +1561,7 @@ GLOBAL bool IRC_Send_ISUPPORT(CLIENT * Client) { if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client), - Conf_MaxJoins)) + CHANTYPES, CHANTYPES, Conf_MaxJoins)) return DISCONNECTED; return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client), CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,