about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/irc-info.c20
-rw-r--r--src/ngircd/irc-info.h1
-rw-r--r--src/ngircd/irc-login.c24
-rw-r--r--src/ngircd/irc-login.h19
-rw-r--r--src/ngircd/irc.c113
-rw-r--r--src/ngircd/irc.h21
-rw-r--r--src/ngircd/messages.h2
-rw-r--r--src/ngircd/parse.c3
8 files changed, 141 insertions, 62 deletions
diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c
index dbeed978..93c43f6a 100644
--- a/src/ngircd/irc-info.c
+++ b/src/ngircd/irc-info.c
@@ -269,6 +269,26 @@ IRC_LUSERS( CLIENT *Client, REQUEST *Req )
 } /* 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 )
 {
diff --git a/src/ngircd/irc-info.h b/src/ngircd/irc-info.h
index faef75ad..fbebacc6 100644
--- a/src/ngircd/irc-info.h
+++ b/src/ngircd/irc-info.h
@@ -30,6 +30,7 @@ GLOBAL bool IRC_SUMMON PARAMS(( CLIENT *Client, REQUEST *Req ));
 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 ));
diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c
index dd436192..e94b62fe 100644
--- a/src/ngircd/irc-login.c
+++ b/src/ngircd/irc-login.c
@@ -393,6 +393,30 @@ IRC_USER( CLIENT *Client, REQUEST *Req )
 } /* 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 )
 {
diff --git a/src/ngircd/irc-login.h b/src/ngircd/irc-login.h
index 28df23ea..0b920380 100644
--- a/src/ngircd/irc-login.h
+++ b/src/ngircd/irc-login.h
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -8,8 +8,6 @@
  * (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)
  */
 
@@ -17,14 +15,13 @@
 #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_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_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));
 
 #endif
 
diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c
index 86f58527..0418e7b4 100644
--- a/src/ngircd/irc.c
+++ b/src/ngircd/irc.c
@@ -37,7 +37,8 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
 #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
@@ -201,47 +202,24 @@ IRC_NOTICE( CLIENT *Client, REQUEST *Req )
 } /* 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 );
-
-	/* 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] );
-
-		/* 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] );
-	}
+	return Send_Message(Client, Req, CLIENT_USER);
+} /* IRC_PRIVMSG */
 
-	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 */
+/**
+ * Handler for the IRC command SQUERY.
+ */
+GLOBAL bool
+IRC_SQUERY(CLIENT *Client, REQUEST *Req)
+{
+	return Send_Message(Client, Req, CLIENT_SERVICE);
+} /* IRC_SQUERY */
 
 
 GLOBAL bool
@@ -351,4 +329,63 @@ Option_String( CONN_ID Idx )
 } /* 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- */
diff --git a/src/ngircd/irc.h b/src/ngircd/irc.h
index a96c8e43..358d91ac 100644
--- a/src/ngircd/irc.h
+++ b/src/ngircd/irc.h
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -8,25 +8,20 @@
  * (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_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_SQUERY 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- */
diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h
index b8090d43..bde1c095 100644
--- a/src/ngircd/messages.h
+++ b/src/ngircd/messages.h
@@ -32,6 +32,8 @@
 #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"
diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c
index 5cfeaaa8..ef2dbbba 100644
--- a/src/ngircd/parse.c
+++ b/src/ngircd/parse.c
@@ -92,6 +92,9 @@ static COMMAND My_Commands[] =
 	{ "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 },