Blame


1 2ee05c9a 2002-03-03 alex /*
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)
4 2ee05c9a 2002-03-03 alex *
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.
11 2ee05c9a 2002-03-03 alex *
12 bc4ed226 2002-03-25 alex * $Id: irc-channel.c,v 1.3 2002/03/25 17:08:54 alex Exp $
13 2ee05c9a 2002-03-03 alex *
14 2ee05c9a 2002-03-03 alex * irc-channel.c: IRC-Channel-Befehle
15 2ee05c9a 2002-03-03 alex */
16 2ee05c9a 2002-03-03 alex
17 2ee05c9a 2002-03-03 alex
18 ca33cbda 2002-03-12 alex #include "portab.h"
19 2ee05c9a 2002-03-03 alex
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>
23 2ee05c9a 2002-03-03 alex
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"
29 2ee05c9a 2002-03-03 alex
30 ca33cbda 2002-03-12 alex #include "exp.h"
31 2ee05c9a 2002-03-03 alex #include "irc-channel.h"
32 2ee05c9a 2002-03-03 alex
33 2ee05c9a 2002-03-03 alex
34 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
35 2ee05c9a 2002-03-03 alex {
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;
40 2ee05c9a 2002-03-03 alex
41 2ee05c9a 2002-03-03 alex assert( Client != NULL );
42 2ee05c9a 2002-03-03 alex assert( Req != NULL );
43 2ee05c9a 2002-03-03 alex
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 ));
45 2ee05c9a 2002-03-03 alex
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 );
48 2ee05c9a 2002-03-03 alex
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 );
53 2ee05c9a 2002-03-03 alex
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 )
57 2ee05c9a 2002-03-03 alex {
58 2ee05c9a 2002-03-03 alex /* wird der Channel neu angelegt? */
59 2ee05c9a 2002-03-03 alex flags = NULL;
60 2ee05c9a 2002-03-03 alex
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;
63 2ee05c9a 2002-03-03 alex
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 )
66 2ee05c9a 2002-03-03 alex {
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';
70 2ee05c9a 2002-03-03 alex }
71 2ee05c9a 2002-03-03 alex
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 ))
74 2ee05c9a 2002-03-03 alex {
75 2ee05c9a 2002-03-03 alex /* Dann soll der Client Channel-Operator werden! */
76 2ee05c9a 2002-03-03 alex flags = "o";
77 2ee05c9a 2002-03-03 alex }
78 2ee05c9a 2002-03-03 alex
79 2ee05c9a 2002-03-03 alex /* Channel joinen (und ggf. anlegen) */
80 2ee05c9a 2002-03-03 alex if( ! Channel_Join( target, channame ))
81 2ee05c9a 2002-03-03 alex {
82 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
83 2ee05c9a 2002-03-03 alex channame = strtok( NULL, "," );
84 2ee05c9a 2002-03-03 alex continue;
85 2ee05c9a 2002-03-03 alex }
86 2ee05c9a 2002-03-03 alex chan = Channel_Search( channame );
87 2ee05c9a 2002-03-03 alex assert( chan != NULL );
88 2ee05c9a 2002-03-03 alex
89 2ee05c9a 2002-03-03 alex /* Modes setzen (wenn vorhanden) */
90 2ee05c9a 2002-03-03 alex while( flags && *flags )
91 2ee05c9a 2002-03-03 alex {
92 2ee05c9a 2002-03-03 alex Channel_UserModeAdd( chan, target, *flags );
93 2ee05c9a 2002-03-03 alex flags++;
94 2ee05c9a 2002-03-03 alex }
95 2ee05c9a 2002-03-03 alex
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';
100 2ee05c9a 2002-03-03 alex
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 );
103 2ee05c9a 2002-03-03 alex
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] )
107 2ee05c9a 2002-03-03 alex {
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 ));
110 2ee05c9a 2002-03-03 alex }
111 2ee05c9a 2002-03-03 alex
112 2ee05c9a 2002-03-03 alex if( Client_Type( Client ) == CLIENT_USER )
113 2ee05c9a 2002-03-03 alex {
114 2ee05c9a 2002-03-03 alex /* an Client bestaetigen */
115 2ee05c9a 2002-03-03 alex IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame );
116 2ee05c9a 2002-03-03 alex
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 );
120 2ee05c9a 2002-03-03 alex
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 ));
124 2ee05c9a 2002-03-03 alex }
125 2ee05c9a 2002-03-03 alex
126 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
127 2ee05c9a 2002-03-03 alex channame = strtok( NULL, "," );
128 2ee05c9a 2002-03-03 alex }
129 2ee05c9a 2002-03-03 alex return CONNECTED;
130 2ee05c9a 2002-03-03 alex } /* IRC_JOIN */
131 2ee05c9a 2002-03-03 alex
132 2ee05c9a 2002-03-03 alex
133 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req )
134 2ee05c9a 2002-03-03 alex {
135 2ee05c9a 2002-03-03 alex CLIENT *target;
136 2ee05c9a 2002-03-03 alex CHAR *chan;
137 2ee05c9a 2002-03-03 alex
138 2ee05c9a 2002-03-03 alex assert( Client != NULL );
139 2ee05c9a 2002-03-03 alex assert( Req != NULL );
140 2ee05c9a 2002-03-03 alex
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 ));
142 2ee05c9a 2002-03-03 alex
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 );
145 2ee05c9a 2002-03-03 alex
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 );
150 2ee05c9a 2002-03-03 alex
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 )
154 2ee05c9a 2002-03-03 alex {
155 2ee05c9a 2002-03-03 alex if( ! Channel_Part( target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID( target )))
156 2ee05c9a 2002-03-03 alex {
157 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
158 2ee05c9a 2002-03-03 alex chan = strtok( NULL, "," );
159 2ee05c9a 2002-03-03 alex continue;
160 2ee05c9a 2002-03-03 alex }
161 2ee05c9a 2002-03-03 alex
162 2ee05c9a 2002-03-03 alex /* naechsten Namen ermitteln */
163 2ee05c9a 2002-03-03 alex chan = strtok( NULL, "," );
164 2ee05c9a 2002-03-03 alex }
165 2ee05c9a 2002-03-03 alex return CONNECTED;
166 2ee05c9a 2002-03-03 alex } /* IRC_PART */
167 2ee05c9a 2002-03-03 alex
168 2ee05c9a 2002-03-03 alex
169 2ee05c9a 2002-03-03 alex GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
170 2ee05c9a 2002-03-03 alex {
171 2ee05c9a 2002-03-03 alex CHANNEL *chan;
172 2ee05c9a 2002-03-03 alex CLIENT *from;
173 2ee05c9a 2002-03-03 alex CHAR *topic;
174 2ee05c9a 2002-03-03 alex
175 2ee05c9a 2002-03-03 alex assert( Client != NULL );
176 2ee05c9a 2002-03-03 alex assert( Req != NULL );
177 2ee05c9a 2002-03-03 alex
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 ));
179 2ee05c9a 2002-03-03 alex
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 );
182 2ee05c9a 2002-03-03 alex
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 );
186 2ee05c9a 2002-03-03 alex
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] );
190 2ee05c9a 2002-03-03 alex
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] );
193 2ee05c9a 2002-03-03 alex
194 2ee05c9a 2002-03-03 alex if( Req->argc == 1 )
195 2ee05c9a 2002-03-03 alex {
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 ));
200 2ee05c9a 2002-03-03 alex }
201 2ee05c9a 2002-03-03 alex
202 2ee05c9a 2002-03-03 alex if( strchr( Channel_Modes( chan ), 't' ))
203 2ee05c9a 2002-03-03 alex {
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 ));
206 2ee05c9a 2002-03-03 alex }
207 2ee05c9a 2002-03-03 alex
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>" );
211 2ee05c9a 2002-03-03 alex
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] );
215 2ee05c9a 2002-03-03 alex
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 */
219 2ee05c9a 2002-03-03 alex
220 2ee05c9a 2002-03-03 alex
221 2ee05c9a 2002-03-03 alex /* -eof- */