91e0e0b8109bccefe4c47add77c76b9452b253e2
[ngircd-alex.git] / src / ngircd / parse.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: parse.c,v 1.1 2001/12/21 23:53:16 alex Exp $
13  *
14  * parse.c: Parsen der Client-Anfragen
15  *
16  * $Log: parse.c,v $
17  * Revision 1.1  2001/12/21 23:53:16  alex
18  * - Modul zum Parsen von Client-Requests begonnen.
19  *
20  */
21
22
23 #include <portab.h>
24 #include "global.h"
25
26 #include <imp.h>
27 #include <assert.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "conn.h"
32 #include "log.h"
33
34 #include <exp.h>
35 #include "parse.h"
36
37
38 LOCAL VOID Init_Request( REQUEST *Req );
39
40 LOCAL BOOLEAN Parse_Error( CONN_ID Idx, CHAR *Error );
41
42 LOCAL BOOLEAN Validate_Prefix( REQUEST *Req );
43 LOCAL BOOLEAN Validate_Command( REQUEST *Req );
44 LOCAL BOOLEAN Validate_Args( REQUEST *Req );
45
46 LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req );
47
48
49 GLOBAL VOID Parse_Init( VOID )
50 {
51 } /* Parse_Init */
52
53
54 GLOBAL VOID Parse_Exit( VOID )
55 {
56 } /* Parse_Exit */
57
58
59 GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
60 {
61         /* Client-Request parsen und verarbeiten. Bei einem schwerwiegenden
62          * Fehler wird die Verbindung geschlossen und FALSE geliefert.
63          * Der Aufbau gueltiger Requests ist in RFC 2812, 2.3 definiert. */
64
65         REQUEST req;
66         CHAR *start, *ptr;
67
68         assert( Idx >= 0 );
69         assert( Request != NULL );
70         
71         Init_Request( &req );
72
73         /* gibt es ein Prefix? */
74         if( Request[0] == ':' )
75         {
76                 /* Prefix vorhanden */
77                 req.prefix = Request + 1;
78                 ptr = strchr( Request, ' ' );
79                 if( ! ptr ) return Parse_Error( Idx, "Invalid prefix (command missing!?)" );
80                 *ptr = '\0';
81                 start = ptr + 1;
82         }
83         else start = Request;
84
85         if( ! Validate_Prefix( &req )) return Parse_Error( Idx, "Invalid prefix");
86
87         /* Befehl */
88         ptr = strchr( start, ' ' );
89         if( ptr ) *ptr = '\0';
90         req.command = start;
91
92         if( ! Validate_Command( &req )) return Parse_Error( Idx, "Invalid command" );
93
94         /* Argumente, Parameter */
95         if( ptr )
96         {
97                 /* Prinzipiell gibt es welche :-) */
98                 start = ptr + 1;
99                 while( start )
100                 {
101                         /* Parameter-String "zerlegen" */
102                         ptr = strchr( start, ' ' );
103                         if( ptr ) *ptr = '\0';
104
105                         if( start[0] == ':' ) req.argv[req.argc] = start + 1;
106                         else req.argv[req.argc] = start;
107                         
108                         req.argc++;
109
110                         if( start[0] == ':' ) break;
111                         if( req.argc > 14 ) break;
112                         
113                         if( ptr ) start = ptr + 1;
114                         else start = NULL;
115                 }
116         }
117         
118         if( ! Validate_Args( &req )) return Parse_Error( Idx, "Invalid argument(s)" );
119
120         return Handle_Request( Idx, &req );
121 } /* Parse_Request */
122
123
124 LOCAL VOID Init_Request( REQUEST *Req )
125 {
126         /* Neue Request-Struktur initialisieren */
127
128         INT i;
129         
130         assert( Req != NULL );
131
132         Req->prefix = NULL;
133         Req->command = NULL;
134         for( i = 0; i < 15; Req->argv[i++] = NULL );
135         Req->argc = 0;
136 } /* Init_Request */
137
138
139 LOCAL BOOLEAN Parse_Error( CONN_ID Idx, CHAR *Error )
140 {
141         /* Fehler beim Parsen. Fehlermeldung an den Client schicken.
142          * TRUE: Connection wurde durch diese Funktion nicht geschlossen,
143          * FALSE: Connection wurde terminiert. */
144         
145         CHAR msg[256];
146         
147         assert( Idx >= 0 );
148         assert( Error != NULL );
149
150         sprintf( msg, "Parse error: %s!", Error );
151         return Conn_WriteStr( Idx, msg );
152 } /* Parse_Error */
153
154
155 LOCAL BOOLEAN Validate_Prefix( REQUEST *Req )
156 {
157         assert( Req != NULL );
158         return TRUE;
159 } /* Validate_Prefix */
160
161
162 LOCAL BOOLEAN Validate_Command( REQUEST *Req )
163 {
164         assert( Req != NULL );
165         return TRUE;
166 } /* Validate_Comman */
167
168
169 LOCAL BOOLEAN Validate_Args( REQUEST *Req )
170 {
171         assert( Req != NULL );
172         return TRUE;
173 } /* Validate_Args */
174
175
176 LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
177 {
178         assert( Idx >= 0 );
179         assert( Req != NULL );
180         assert( Req->command != NULL );
181
182 #ifdef DEBUG
183         Log( LOG_DEBUG, " -> connection %d: '%s', %d %s,%s prefix.", Idx, Req->command, Req->argc, Req->argc == 1 ? "parameter" : "parameters", Req->prefix ? "" : " no" );
184 #endif
185
186         return TRUE;
187 } /* Handle_Request */
188
189
190 /* -eof- */