commit - 3895b42d1bbcbe6537a01d7713ee18cb09632dae
commit + 4e56e5341f632827af3810e26cd59ac0c15b642b
blob - 490257eb20f2e456c8caa14fe7bd63a6f38db717
blob + 64807e7fec6e2367927f93b1e83c241a09e03f7b
--- ChangeLog
+++ ChangeLog
ngIRCd-dev
+ - Implemented IRC commands SERVICE, SERVLIST, and SQUERY as dummy functions
+ to be even more RFC-compliant. Closes bug 74.
- Fixed Bug 75: KICK now handles comma-delimited lists.
(Brandon Beresini, Bryan Caldwell)
- Fixed Bug 83: ngIRCd chokes on 1-character messages.
blob - dbeed978d056cd041525ed398bbb0eb6ece7c96a
blob + 93c43f6a35744f65c01ec054cec00f37d839be21
--- src/ngircd/irc-info.c
+++ src/ngircd/irc-info.c
IRC_SetPenalty( target, 1 );
return CONNECTED;
} /* IRC_LUSERS */
+
+
+/**
+ * List registered services.
+ * This function is a dummy that immediately returns RPL_SERVLISTEND.
+ */
+GLOBAL bool
+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);
+ return IRC_WriteStrClient(Client, RPL_SERVLISTEND_MSG, Client_ID(Client),
+ Req->argc > 0 ? Req->argv[0] : "*",
+ Req->argc > 1 ? Req->argv[1] : "0");
+} /* IRC_SERVLIST */
+
+
GLOBAL bool
IRC_MOTD( CLIENT *Client, REQUEST *Req )
{
blob - faef75ad9ac37c55021bcca15ab887a5b648a5ff
blob + fbebacc67d969d11617c874dcc41f22f0f58e496
--- src/ngircd/irc-info.h
+++ src/ngircd/irc-info.h
GLOBAL bool IRC_TIME PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERHOST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERS PARAMS(( CLIENT *Client, REQUEST *Req ));
+GLOBAL bool IRC_SERVLIST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_VERSION PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHO PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHOIS PARAMS(( CLIENT *Client, REQUEST *Req ));
blob - dd436192caa888c395572b91ea47d2aa10e30921
blob + e94b62fe00e35d01789e9382bfc533d4d0fd15d6
--- src/ngircd/irc-login.c
+++ src/ngircd/irc-login.c
}
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
} /* IRC_USER */
+
+
+/**
+ * Service registration.
+ * ngIRCd does not support services at the moment, so this function is a
+ * dummy that returns ERR_ERRONEUSNICKNAME on each call.
+ */
+GLOBAL bool
+IRC_SERVICE(CLIENT *Client, REQUEST *Req)
+{
+ assert(Client != NULL);
+ assert(Req != NULL);
+
+ if (Client_Type(Client) != CLIENT_GOTPASS)
+ return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
+ Client_ID(Client));
+ if (Req->argc != 6)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+ return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
+ Client_ID(Client), Req->argv[0]);
+} /* IRC_SERVICE */
+
+
GLOBAL bool
IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
blob - 28df23ea03bc6f39c0fa725ea42b2fca831c5a5a
blob + 0b920380ae919808acfae0f81cdd5620c1b9e5cd
--- src/ngircd/irc-login.h
+++ src/ngircd/irc-login.h
/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* 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
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * $Id: irc-login.h,v 1.6 2005/03/19 18:43:48 fw Exp $
- *
* Login and logout (header)
*/
#ifndef __irc_login_h__
#define __irc_login_h__
+GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_SERVICE PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
-GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req ));
-
-
#endif
blob - 86f5852779cf682f8b41989183cfa9a256453e1a
blob + 0418e7b4cb31cb82f4be6006c021c1af37c5f41a
--- src/ngircd/irc.c
+++ src/ngircd/irc.c
#include "irc.h"
-static char *Option_String PARAMS(( CONN_ID Idx ));
+static char *Option_String PARAMS((CONN_ID Idx));
+static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType));
GLOBAL bool
} /* IRC_NOTICE */
+/**
+ * Handler for the IRC command PRIVMSG.
+ */
GLOBAL bool
-IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
+IRC_PRIVMSG(CLIENT *Client, REQUEST *Req)
{
- CLIENT *cl, *from;
- CHANNEL *chan;
-
- assert( Client != NULL );
- assert( Req != NULL );
+ return Send_Message(Client, Req, CLIENT_USER);
+} /* IRC_PRIVMSG */
- /* Falsche Anzahl Parameter? */
- if( Req->argc == 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
- if( Req->argc == 1 ) return IRC_WriteStrClient( Client, ERR_NOTEXTTOSEND_MSG, Client_ID( Client ));
- if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- 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 );
-
- cl = Client_Search( Req->argv[0] );
- if( cl )
- {
- /* Okay, Ziel ist ein Client. Aber ist es auch ein User? */
- if( Client_Type( cl ) != CLIENT_USER ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
+/**
+ * Handler for the IRC command SQUERY.
+ */
+GLOBAL bool
+IRC_SQUERY(CLIENT *Client, REQUEST *Req)
+{
+ return Send_Message(Client, Req, CLIENT_SERVICE);
+} /* IRC_SQUERY */
- /* Okay, Ziel ist ein User */
- if(( Client_Type( Client ) != CLIENT_SERVER ) && ( strchr( Client_Modes( cl ), 'a' )))
- {
- /* Ziel-User ist AWAY: Meldung verschicken */
- if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( cl ), Client_Away( cl ))) return DISCONNECTED;
- }
- /* Text senden */
- if( Client_Conn( from ) > NONE ) Conn_UpdateIdle( Client_Conn( from ));
- return IRC_WriteStrClientPrefix( cl, from, "PRIVMSG %s :%s", Client_ID( cl ), Req->argv[1] );
- }
-
- chan = Channel_Search( Req->argv[0] );
- if( chan ) return Channel_Write( chan, from, Client, Req->argv[1] );
-
- return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
-} /* IRC_PRIVMSG */
-
-
GLOBAL bool
IRC_TRACE( CLIENT *Client, REQUEST *Req )
{
} /* Option_String */
+static bool
+Send_Message(CLIENT * Client, REQUEST * Req, int ForceType)
+{
+ CLIENT *cl, *from;
+ CHANNEL *chan;
+
+ assert(Client != NULL);
+ assert(Req != NULL);
+
+ if (Req->argc == 0)
+ return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
+ Client_ID(Client), Req->command);
+ if (Req->argc == 1)
+ return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
+ Client_ID(Client));
+ if (Req->argc > 2)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+
+ 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);
+
+ cl = Client_Search(Req->argv[0]);
+ if (cl) {
+ /* Target is a user, enforce type */
+ if (Client_Type(cl) != ForceType)
+ return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+ Client_ID(from),
+ Req->argv[0]);
+
+ if ((Client_Type(Client) != CLIENT_SERVER)
+ && (strchr(Client_Modes(cl), 'a'))) {
+ /* Target is away */
+ if (!IRC_WriteStrClient
+ (from, RPL_AWAY_MSG, Client_ID(from), Client_ID(cl),
+ Client_Away(cl)))
+ return DISCONNECTED;
+ }
+
+ if (Client_Conn(from) > NONE)
+ Conn_UpdateIdle(Client_Conn(from));
+ return IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
+ Client_ID(cl), Req->argv[1]);
+ }
+
+ chan = Channel_Search(Req->argv[0]);
+ if (chan)
+ return Channel_Write(chan, from, Client, Req->argv[1]);
+
+ return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+ Client_ID(from), Req->argv[0]);
+} /* Send_Message */
+
+
/* -eof- */
blob - a96c8e43b6c1b89b8e4f1566338c43bc658acb48
blob + 358d91ac5bc8032a0c5f1fc3809b348a51ffb142
--- src/ngircd/irc.h
+++ src/ngircd/irc.h
/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* 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
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * $Id: irc.h,v 1.39 2005/03/19 18:43:49 fw Exp $
- *
* IRC commands (header)
*/
-
#ifndef __irc_h__
#define __irc_h__
+GLOBAL bool IRC_ERROR PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_KILL PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_NOTICE PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_PRIVMSG PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_SQUERY PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_TRACE PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_HELP PARAMS((CLIENT *Client, REQUEST *Req));
-GLOBAL bool IRC_ERROR PARAMS(( CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_KILL PARAMS(( CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_NOTICE PARAMS(( CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_PRIVMSG PARAMS(( CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_TRACE PARAMS(( CLIENT *Client, REQUEST *Req ));
-GLOBAL bool IRC_HELP PARAMS(( CLIENT *Client, REQUEST *Req ));
-
-
#endif
-
/* -eof- */
blob - b8090d438e3e65fb698463b71849be67980bf0ef
blob + bde1c095fc73cf0a58e356c6ddea758f326dcdab
--- src/ngircd/messages.h
+++ src/ngircd/messages.h
#define RPL_STATSCOMMANDS_MSG "212 %s %s %ld %ld %ld"
#define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report"
#define RPL_UMODEIS_MSG "221 %s +%s"
+#define RPL_SERVLISTEND_MSG "235 %s %s %s :End of service listing"
+
#define RPL_STATSUPTIME "242 %s :Server Up %u days %u:%02u:%02u"
#define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers"
#define RPL_LUSEROP_MSG "252 %s %lu :operator(s) online"
blob - 5cfeaaa8a9fa05ba1c5e81a5cf612c6bb77c23d1
blob + ef2dbbba0bc6d874f886e6a311bef9a233887d6d
--- src/ngircd/parse.c
+++ src/ngircd/parse.c
{ "REHASH", IRC_REHASH, CLIENT_USER, 0, 0, 0 },
{ "RESTART", IRC_RESTART, CLIENT_USER, 0, 0, 0 },
{ "SERVER", IRC_SERVER, 0xFFFF, 0, 0, 0 },
+ { "SERVICE", IRC_SERVICE, 0xFFFF, 0, 0, 0 },
+ { "SERVLIST", IRC_SERVLIST, CLIENT_USER, 0, 0, 0 },
+ { "SQUERY", IRC_SQUERY, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_SERVER, 0, 0, 0 },
{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SUMMON", IRC_SUMMON, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },