- bessere Fehler-Abfragen, diverse Bugfixes.
[ngircd-alex.git] / src / ngircd / irc.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001 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 comBase beteiligten Autoren finden Sie in der Datei AUTHORS.
11  *
12  * $Id: irc.c,v 1.4 2001/12/25 19:19:30 alex Exp $
13  *
14  * irc.c: IRC-Befehle
15  *
16  * $Log: irc.c,v $
17  * Revision 1.4  2001/12/25 19:19:30  alex
18  * - bessere Fehler-Abfragen, diverse Bugfixes.
19  * - Nicks werden nur einmal vergeben :-)
20  * - /MOTD wird unterstuetzt.
21  *
22  * Revision 1.3  2001/12/24 01:34:06  alex
23  * - USER und NICK wird nun in beliebiger Reihenfolge akzeptiert (wg. BitchX)
24  * - MOTD-Ausgabe begonnen zu implementieren.
25  *
26  * Revision 1.2  2001/12/23 21:57:16  alex
27  * - erste IRC-Befehle zu implementieren begonnen.
28  *
29  * Revision 1.1  2001/12/14 08:13:43  alex
30  * - neues Modul begonnen :-)
31  */
32
33
34 #include <portab.h>
35 #include "global.h"
36
37 #include <imp.h>
38 #include <assert.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <string.h>
42
43 #include "client.h"
44 #include "log.h"
45 #include "messages.h"
46 #include "parse.h"
47
48 #include <exp.h>
49 #include "irc.h"
50
51
52 #define CONNECTED TRUE
53 #define DISCONNECTED FALSE
54
55
56 LOCAL BOOLEAN Check_Valid_User( CLIENT *Client );
57
58 LOCAL BOOLEAN Hello_User( CLIENT *Client );
59 LOCAL BOOLEAN Show_MOTD( CLIENT *Client );
60
61
62 GLOBAL VOID IRC_Init( VOID )
63 {
64 } /* IRC_Init */
65
66
67 GLOBAL VOID IRC_Exit( VOID )
68 {
69 } /* IRC_Exit */
70
71
72 GLOBAL BOOLEAN IRC_WriteStr_Client( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
73 {
74         /* Text an Clients, lokal bzw. remote, senden. */
75
76         CHAR buffer[1000];
77         BOOLEAN ok = CONNECTED;
78         va_list ap;
79
80         assert( Client != NULL );
81         assert( Format != NULL );
82
83         va_start( ap, Format );
84
85         if( Client->conn_id != NONE )
86         {
87                 /* Lokaler Client */
88                 vsnprintf( buffer, 1000, Format, ap );
89                 if( Prefix ) ok = Conn_WriteStr( Client->conn_id, ":%s %s", Prefix->host, buffer );
90                 else ok = Conn_WriteStr( Client->conn_id, buffer );
91         }
92         else
93         {
94                 /* Remote-Client */
95                 Log( LOG_DEBUG, "not implemented: IRC_WriteStr_Client()" );
96         }
97
98         va_end( ap );
99         return ok;
100 } /* IRC_WriteStr_Client */
101
102
103 GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
104 {
105         assert( Client != NULL );
106         assert( Req != NULL );
107
108         return IRC_WriteStr_Client( Client, This_Server, ERR_UNKNOWNCOMMAND_MSG, Req->command );
109 } /* IRC_PASS */
110
111
112 GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
113 {
114         CLIENT *c;
115         
116         assert( Client != NULL );
117         assert( Req != NULL );
118
119         if( Client->type != CLIENT_SERVER && Client->type != CLIENT_SERVICE )
120         {
121                 /* Falsche Anzahl Parameter? */
122                 if( Req->argc != 1 ) return IRC_WriteStr_Client( Client, This_Server, ERR_NEEDMOREPARAMS_MSG );
123
124                 /* Nick zu lang? */
125                 if( strlen( Req->argv[0] ) > CLIENT_NICK_LEN ) return IRC_WriteStr_Client( Client, This_Server, ERR_ERRONEUSNICKNAME_MSG, Req->argv[0] );
126
127                 /* pruefen, ob Nick bereits vergeben */
128                 c = My_Clients;
129                 while( c )
130                 {
131                         if( strcasecmp( c->nick, Req->argv[0] ) == 0 )
132                         {
133                                 /* den Nick gibt es bereits */
134                                 return IRC_WriteStr_Client( Client, This_Server, ERR_NICKNAMEINUSE_MSG, Req->argv[0] );
135                         }
136                         c = c->next;
137                 }
138                 
139                 /* Client-Nick registrieren */
140                 strcpy( Client->nick, Req->argv[0] );
141
142                 if( Client->type != CLIENT_USER )
143                 {
144                         /* Neuer Client */
145                         if( Client->type == CLIENT_GOTUSER ) return Hello_User( Client );
146                         else Client->type = CLIENT_GOTNICK;
147                 }
148                 return CONNECTED;
149         }
150         else return IRC_WriteStr_Client( Client, This_Server, ERR_ALREADYREGISTRED_MSG );
151 } /* IRC_NICK */
152
153
154 GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req )
155 {
156         assert( Client != NULL );
157         assert( Req != NULL );
158
159         if( Client->type == CLIENT_UNKNOWN || Client->type == CLIENT_GOTNICK || Client->type == CLIENT_GOTPASS )
160         {
161                 /* Falsche Anzahl Parameter? */
162                 if( Req->argc != 4 ) return IRC_WriteStr_Client( Client, This_Server, ERR_NEEDMOREPARAMS_MSG );
163                 
164                 strncpy( Client->user, Req->argv[0], CLIENT_USER_LEN );
165                 Client->user[CLIENT_USER_LEN] = '\0';
166                 strncpy( Client->name, Req->argv[3], CLIENT_NAME_LEN );
167                 Client->name[CLIENT_NAME_LEN] = '\0';
168                 
169                 if( Client->type == CLIENT_GOTNICK ) return Hello_User( Client );
170                 else Client->type = CLIENT_GOTUSER;
171                 return CONNECTED;
172         }
173         else if( Client->type == CLIENT_USER || Client->type == CLIENT_SERVER || Client->type == CLIENT_SERVICE )
174         {
175                 return IRC_WriteStr_Client( Client, This_Server, ERR_ALREADYREGISTRED_MSG );
176         }
177         else return IRC_WriteStr_Client( Client, This_Server, ERR_NOTREGISTERED_MSG );
178 } /* IRC_USER */
179
180
181 GLOBAL BOOLEAN IRC_MOTD( CLIENT *Client, REQUEST *Req )
182 {
183         assert( Client != NULL );
184         assert( Req != NULL );
185
186         if( ! Check_Valid_User( Client )) return CONNECTED;
187
188         /* Falsche Anzahl Parameter? */
189         if( Req->argc != 0 ) return IRC_WriteStr_Client( Client, This_Server, ERR_NEEDMOREPARAMS_MSG );
190         
191         return Show_MOTD( Client );     
192 } /* IRC_MOTD */
193
194
195 LOCAL BOOLEAN Check_Valid_User( CLIENT *Client )
196 {
197         assert( Client != NULL );
198
199         if( Client->type != CLIENT_USER )
200         {
201                 IRC_WriteStr_Client( Client, This_Server, ERR_NOTREGISTERED_MSG );
202                 return FALSE;
203         }
204         else return TRUE;
205 } /* Check_Valid_User */
206
207
208 LOCAL BOOLEAN Hello_User( CLIENT *Client )
209 {
210         Log( LOG_INFO, "User \"%s!%s@%s\" (%s) registered.", Client->nick, Client->user, Client->host, Client->name );
211
212         IRC_WriteStr_Client( Client, This_Server, RPL_WELCOME_MSG, Client->nick, Client->nick, Client->user, Client->host );
213         IRC_WriteStr_Client( Client, This_Server, RPL_YOURHOST_MSG, Client->nick, This_Server->host );
214         IRC_WriteStr_Client( Client, This_Server, RPL_CREATED_MSG, Client->nick );
215         IRC_WriteStr_Client( Client, This_Server, RPL_MYINFO_MSG, Client->nick, This_Server->host );
216
217         Client->type = CLIENT_USER;
218
219         return Show_MOTD( Client );
220 } /* Hello_User */
221
222
223 LOCAL BOOLEAN Show_MOTD( CLIENT *Client )
224 {
225         IRC_WriteStr_Client( Client, This_Server, RPL_MOTDSTART_MSG, Client->nick, This_Server->host );
226         IRC_WriteStr_Client( Client, This_Server, RPL_MOTD_MSG, Client->nick, "Some cool IRC server welcome message ;-)" );
227         return IRC_WriteStr_Client( Client, This_Server, RPL_ENDOFMOTD_MSG, Client->nick );
228 } /* Show_MOTD */
229
230
231 /* -eof- */