2 2ee05c9a 2002-03-03 alex * ngIRCd -- The Next Generation IRC Daemon
3 2ee05c9a 2002-03-03 alex * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
5 2ee05c9a 2002-03-03 alex * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
6 2ee05c9a 2002-03-03 alex * der GNU General Public License (GPL), wie von der Free Software Foundation
7 2ee05c9a 2002-03-03 alex * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
8 2ee05c9a 2002-03-03 alex * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
9 2ee05c9a 2002-03-03 alex * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
10 2ee05c9a 2002-03-03 alex * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
12 bc4ed226 2002-03-25 alex * $Id: irc-channel.c,v 1.3 2002/03/25 17:08:54 alex Exp $
14 2ee05c9a 2002-03-03 alex * irc-channel.c: IRC-Channel-Befehle
18 ca33cbda 2002-03-12 alex #include "portab.h"
20 ca33cbda 2002-03-12 alex #include "imp.h"
21 2ee05c9a 2002-03-03 alex #include <assert.h>
22 2ee05c9a 2002-03-03 alex #include <string.h>
24 ca33cbda 2002-03-12 alex #include "defines.h"
25 2ee05c9a 2002-03-03 alex #include "irc.h"
26 2ee05c9a 2002-03-03 alex #include "irc-write.h"
27 2ee05c9a 2002-03-03 alex #include "log.h"
28 2ee05c9a 2002-03-03 alex #include "messages.h"
30 ca33cbda 2002-03-12 alex #include "exp.h"
31 2ee05c9a 2002-03-03 alex #include "irc-channel.h"
34 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
36 2ee05c9a 2002-03-03 alex CHAR *channame, *flags, *topic, modes[8];
37 2ee05c9a 2002-03-03 alex BOOLEAN is_new_chan;
38 2ee05c9a 2002-03-03 alex CLIENT *target;
39 2ee05c9a 2002-03-03 alex CHANNEL *chan;
41 2ee05c9a 2002-03-03 alex assert( Client != NULL );
42 2ee05c9a 2002-03-03 alex assert( Req != NULL );
44 2ee05c9a 2002-03-03 alex if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
46 2ee05c9a 2002-03-03 alex /* Falsche Anzahl Parameter? */
47 2ee05c9a 2002-03-03 alex if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
49 2ee05c9a 2002-03-03 alex /* Wer ist der Absender? */
50 bc4ed226 2002-03-25 alex if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
51 2ee05c9a 2002-03-03 alex else target = Client;
52 2ee05c9a 2002-03-03 alex if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
54 2ee05c9a 2002-03-03 alex /* Channel-Namen durchgehen */
55 2ee05c9a 2002-03-03 alex channame = strtok( Req->argv[0], "," );
56 2ee05c9a 2002-03-03 alex while( channame )
58 2ee05c9a 2002-03-03 alex /* wird der Channel neu angelegt? */
59 2ee05c9a 2002-03-03 alex flags = NULL;
61 2ee05c9a 2002-03-03 alex if( Channel_Search( channame )) is_new_chan = FALSE;
62 2ee05c9a 2002-03-03 alex else is_new_chan = TRUE;
64 2ee05c9a 2002-03-03 alex /* Hat ein Server Channel-User-Modes uebergeben? */
65 2ee05c9a 2002-03-03 alex if( Client_Type( Client ) == CLIENT_SERVER )
67 2ee05c9a 2002-03-03 alex /* Channel-Flags extrahieren */
68 2ee05c9a 2002-03-03 alex flags = strchr( channame, 0x7 );
69 2ee05c9a 2002-03-03 alex if( flags ) *flags++ = '\0';
72 2ee05c9a 2002-03-03 alex /* neuer Channel udn lokaler Client? */
73 2ee05c9a 2002-03-03 alex if( is_new_chan && ( Client_Type( Client ) == CLIENT_USER ))
75 2ee05c9a 2002-03-03 alex /* Dann soll der Client Channel-Operator werden! */
76 2ee05c9a 2002-03-03 alex flags = "o";
79 2ee05c9a 2002-03-03 alex /* Channel joinen (und ggf. anlegen) */
80 2ee05c9a 2002-03-03 alex if( ! Channel_Join( target, channame ))
82 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
83 2ee05c9a 2002-03-03 alex channame = strtok( NULL, "," );
86 2ee05c9a 2002-03-03 alex chan = Channel_Search( channame );
87 2ee05c9a 2002-03-03 alex assert( chan != NULL );
89 2ee05c9a 2002-03-03 alex /* Modes setzen (wenn vorhanden) */
90 2ee05c9a 2002-03-03 alex while( flags && *flags )
92 2ee05c9a 2002-03-03 alex Channel_UserModeAdd( chan, target, *flags );
96 2ee05c9a 2002-03-03 alex /* Muessen Modes an andere Server gemeldet werden? */
97 2ee05c9a 2002-03-03 alex strcpy( &modes[1], Channel_UserModes( chan, target ));
98 2ee05c9a 2002-03-03 alex if( modes[1] ) modes[0] = 0x7;
99 2ee05c9a 2002-03-03 alex else modes[0] = '\0';
101 2ee05c9a 2002-03-03 alex /* An andere Server weiterleiten */
102 2ee05c9a 2002-03-03 alex IRC_WriteStrServersPrefix( Client, target, "JOIN :%s%s", channame, modes );
104 2ee05c9a 2002-03-03 alex /* im Channel bekannt machen */
105 2ee05c9a 2002-03-03 alex IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "JOIN :%s", channame );
106 2ee05c9a 2002-03-03 alex if( modes[1] )
108 2ee05c9a 2002-03-03 alex /* Modes im Channel bekannt machen */
109 2ee05c9a 2002-03-03 alex IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "MODE %s %s :%s", channame, modes, Client_ID( target ));
112 2ee05c9a 2002-03-03 alex if( Client_Type( Client ) == CLIENT_USER )
114 2ee05c9a 2002-03-03 alex /* an Client bestaetigen */
115 2ee05c9a 2002-03-03 alex IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame );
117 2ee05c9a 2002-03-03 alex /* Topic an Client schicken */
118 2ee05c9a 2002-03-03 alex topic = Channel_Topic( chan );
119 2ee05c9a 2002-03-03 alex if( *topic ) IRC_WriteStrClient( Client, RPL_TOPIC_MSG, Client_ID( Client ), channame, topic );
121 2ee05c9a 2002-03-03 alex /* Mitglieder an Client Melden */
122 2ee05c9a 2002-03-03 alex IRC_Send_NAMES( Client, chan );
123 2ee05c9a 2002-03-03 alex IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( chan ));
126 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
127 2ee05c9a 2002-03-03 alex channame = strtok( NULL, "," );
129 2ee05c9a 2002-03-03 alex return CONNECTED;
130 2ee05c9a 2002-03-03 alex } /* IRC_JOIN */
133 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req )
135 2ee05c9a 2002-03-03 alex CLIENT *target;
136 2ee05c9a 2002-03-03 alex CHAR *chan;
138 2ee05c9a 2002-03-03 alex assert( Client != NULL );
139 2ee05c9a 2002-03-03 alex assert( Req != NULL );
141 2ee05c9a 2002-03-03 alex if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
143 2ee05c9a 2002-03-03 alex /* Falsche Anzahl Parameter? */
144 2ee05c9a 2002-03-03 alex if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
146 2ee05c9a 2002-03-03 alex /* Wer ist der Absender? */
147 bc4ed226 2002-03-25 alex if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
148 2ee05c9a 2002-03-03 alex else target = Client;
149 2ee05c9a 2002-03-03 alex if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
151 2ee05c9a 2002-03-03 alex /* Channel-Namen durchgehen */
152 2ee05c9a 2002-03-03 alex chan = strtok( Req->argv[0], "," );
153 2ee05c9a 2002-03-03 alex while( chan )
155 2ee05c9a 2002-03-03 alex if( ! Channel_Part( target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID( target )))
157 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
158 2ee05c9a 2002-03-03 alex chan = strtok( NULL, "," );
162 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
163 2ee05c9a 2002-03-03 alex chan = strtok( NULL, "," );
165 2ee05c9a 2002-03-03 alex return CONNECTED;
166 2ee05c9a 2002-03-03 alex } /* IRC_PART */
169 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
171 2ee05c9a 2002-03-03 alex CHANNEL *chan;
172 2ee05c9a 2002-03-03 alex CLIENT *from;
173 2ee05c9a 2002-03-03 alex CHAR *topic;
175 2ee05c9a 2002-03-03 alex assert( Client != NULL );
176 2ee05c9a 2002-03-03 alex assert( Req != NULL );
178 2ee05c9a 2002-03-03 alex if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
180 2ee05c9a 2002-03-03 alex /* Falsche Anzahl Parameter? */
181 2ee05c9a 2002-03-03 alex if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
183 bc4ed226 2002-03-25 alex if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
184 2ee05c9a 2002-03-03 alex else from = Client;
185 2ee05c9a 2002-03-03 alex if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
187 2ee05c9a 2002-03-03 alex /* Welcher Channel? */
188 2ee05c9a 2002-03-03 alex chan = Channel_Search( Req->argv[0] );
189 2ee05c9a 2002-03-03 alex if( ! chan ) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
191 2ee05c9a 2002-03-03 alex /* Ist der User Mitglied in dem Channel? */
192 2ee05c9a 2002-03-03 alex if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
194 2ee05c9a 2002-03-03 alex if( Req->argc == 1 )
196 2ee05c9a 2002-03-03 alex /* Topic erfragen */
197 2ee05c9a 2002-03-03 alex topic = Channel_Topic( chan );
198 2ee05c9a 2002-03-03 alex if( *topic ) return IRC_WriteStrClient( from, RPL_TOPIC_MSG, Client_ID( from ), Channel_Name( chan ), topic );
199 2ee05c9a 2002-03-03 alex else return IRC_WriteStrClient( from, RPL_NOTOPIC_MSG, Client_ID( from ), Channel_Name( chan ));
202 2ee05c9a 2002-03-03 alex if( strchr( Channel_Modes( chan ), 't' ))
204 2ee05c9a 2002-03-03 alex /* Topic Lock. Ist der User ein Channel Operator? */
205 2ee05c9a 2002-03-03 alex if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
208 2ee05c9a 2002-03-03 alex /* Topic setzen */
209 2ee05c9a 2002-03-03 alex Channel_SetTopic( chan, Req->argv[1] );
210 2ee05c9a 2002-03-03 alex Log( LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s", Client_Mask( from ), Channel_Name( chan ), Req->argv[1][0] ? Req->argv[1] : "<none>" );
212 2ee05c9a 2002-03-03 alex /* im Channel bekannt machen und an Server weiterleiten */
213 2ee05c9a 2002-03-03 alex IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
214 2ee05c9a 2002-03-03 alex IRC_WriteStrChannelPrefix( Client, chan, from, FALSE, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
216 2ee05c9a 2002-03-03 alex if( Client_Type( Client ) == CLIENT_USER ) return IRC_WriteStrClientPrefix( Client, Client, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
217 2ee05c9a 2002-03-03 alex else return CONNECTED;
218 2ee05c9a 2002-03-03 alex } /* IRC_TOPIC */
221 2ee05c9a 2002-03-03 alex /* -eof- */