Blob


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