assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- /* Ziel suchen */
+ /* find target ... */
if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
else target = Client_ThisServer( );
- /* Prefix ermitteln */
+ /* 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 );
- /* An anderen Server weiterleiten? */
+ /* 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] );
- /* forwarden */
+ /* forward */
IRC_WriteStrClientPrefix( target, prefix, "ADMIN %s", Req->argv[0] );
return CONNECTED;
}
if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix),
NGIRCd_Version))
return DISCONNECTED;
-
- strlcpy(msg, "Server has been started ", sizeof(msg));
+
+#if defined(__DATE__) && defined(__TIME__)
+ snprintf(msg, sizeof(msg), "Birth Date: %s at %s", __DATE__, __TIME__);
+ if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
+ return DISCONNECTED;
+#endif
+
+ strlcpy(msg, "On-line since ", sizeof(msg));
strlcat(msg, NGIRCd_StartStr, sizeof(msg));
if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
return DISCONNECTED;
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Server-Mask ermitteln */
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Absender ermitteln */
/**
- * List registered services.
- * This function is a dummy that immediately returns RPL_SERVLISTEND.
+ * Handler for the IRC command "SERVLIST".
+ * List registered services, see RFC 2811, section 3.5.1: the syntax is
+ * "SERVLIST [<mask> [<type>]]".
*/
GLOBAL bool
IRC_SERVLIST(CLIENT *Client, REQUEST *Req)
{
+ CLIENT *c;
+
assert(Client != NULL);
assert(Req != NULL);
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
+ if (Req->argc < 2 || strcmp(Req->argv[1], "0") == 0) {
+ for (c = Client_First(); c!= NULL; c = Client_Next(c)) {
+ if (Client_Type(c) != CLIENT_SERVICE)
+ continue;
+ if (Req->argc > 0 && !MatchCaseInsensitive(Req->argv[0],
+ Client_ID(c)))
+ continue;
+ if (!IRC_WriteStrClient(Client, RPL_SERVLIST_MSG,
+ Client_ID(Client), Client_Mask(c),
+ Client_Mask(Client_Introducer(c)), "*",
+ 0, Client_Hops(c), Client_Info(c)))
+ return DISCONNECTED;
+ }
+ }
+
return IRC_WriteStrClient(Client, RPL_SERVLISTEND_MSG, Client_ID(Client),
Req->argc > 0 ? Req->argv[0] : "*",
Req->argc > 1 ? Req->argv[1] : "0");
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* From aus Prefix ermitteln */
if( Req->argc == 1 )
{
- /* an anderen Server forwarden */
+ /* 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] );
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- /* From aus Prefix ermitteln */
+ /* 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 );
if( Req->argc == 2 )
{
- /* an anderen Server forwarden */
+ /* 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] );
- if( target != Client_ThisServer( ))
- {
- /* Ok, anderer Server ist das Ziel: forwarden */
+ if( target != Client_ThisServer( )) {
+ /* target is another server, forward */
return IRC_WriteStrClientPrefix( target, from, "NAMES %s :%s", Req->argv[0], Req->argv[1] );
}
}
chan = Channel_Search( ptr );
if( chan )
{
- /* Namen ausgeben */
+ /* print name */
if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
}
if( ! IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), ptr )) return DISCONNECTED;
- /* naechsten Namen ermitteln */
+ /* get next channel name */
ptr = strtok( NULL, "," );
}
return CONNECTED;
}
- /* alle Channels durchgehen */
chan = Channel_First( );
while( chan )
{
- /* Namen ausgeben */
if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
- /* naechster Channel */
chan = Channel_Next( chan );
}
- /* Nun noch alle Clients ausgeben, die in keinem Channel sind */
+ /* 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' )))
{
- /* Okay, das ist ein User: anhaengen */
+ /* its a user, concatenate ... */
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 ))
{
- /* Zeile wird zu lang: senden! */
+ /* 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 ), "*", "*" );
}
}
- /* naechster Client */
c = Client_Next( c );
}
if( rpl[strlen( rpl ) - 1] != ':')
{
- /* es wurden User gefunden */
if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
}
static unsigned int
-t_diff(time_t *t, const time_t div)
+t_diff(time_t *t, const time_t d)
{
time_t diff, remain;
- diff = *t / div;
-
- remain = diff * div;
+ diff = *t / d;
+ remain = diff * d;
*t -= remain;
return diff;
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
- /* From aus Prefix ermitteln */
+ /* use prefix to determine "From" */
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix);
if (Req->argc == 2) {
- /* an anderen Server forwarden */
+ /* 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] );
if( target != Client_ThisServer()) {
- /* Ok, anderer Server ist das Ziel: forwarden */
+ /* forward to another server */
return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
}
}
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
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 );
if( Req->argc == 1 )
{
- /* an anderen Server forwarden */
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] );
if( target != Client_ThisServer( ))
{
- /* Ok, anderer Server ist das Ziel: forwarden */
return IRC_WriteStrClientPrefix( target, from, "TIME %s", Req->argv[0] );
}
}
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if( Req->argc > 5 ) max = 5;
c = Client_Search( Req->argv[i] );
if( c && ( Client_Type( c ) == CLIENT_USER ))
{
- /* Dieser Nick ist "online" */
+ /* This Nick is "online" */
strlcat( rpl, Client_ID( c ), sizeof( rpl ));
if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
strlcat( rpl, "=", sizeof( rpl ));
assert( Client != NULL );
assert( Req != NULL );
- /* Falsche Anzahl Parameter? */
if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ziel suchen */
cl2chan = Channel_NextChannelOf( c, cl2chan );
/* Secret channel? */
- if( strchr( Channel_Modes( chan ), 's' ) && ! Channel_IsMemberOf( chan, Client )) continue;
+ if (strchr(Channel_Modes(chan), 's')
+ && !Channel_IsMemberOf(chan, Client))
+ continue;
+
+ /* Local channel and request is not from a user? */
+ if (Client_Type(Client) == CLIENT_SERVER
+ && Channel_IsLocal(chan))
+ continue;
/* Concatenate channel names */
if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
}
+#ifdef SSL_SUPPORT
+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;
+
+ if (!Show_MOTD_Sendline(Client, buf))
+ ret = false;
+
+ return ret;
+}
+#else
+static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
+#endif
GLOBAL bool
IRC_Show_MOTD( CLIENT *Client )
return DISCONNECTED;
if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
return DISCONNECTED;
-
- return Show_MOTD_End(Client);
+ goto out;
}
fd = fopen( Conf_MotdFile, "r" );
if( ! fd ) {
Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
+ if (Conn_UsesSSL(Client_Conn(Client))) {
+ if (!Show_MOTD_Start(Client))
+ return DISCONNECTED;
+ goto out;
+ }
return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
}
}
}
fclose(fd);
+out:
+ if (!Show_MOTD_SSLInfo(Client))
+ return DISCONNECTED;
return Show_MOTD_End(Client);
} /* IRC_Show_MOTD */