]> git.sur5r.net Git - openldap/blob - libraries/libldap/digest.c
Remove lint
[openldap] / libraries / libldap / digest.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /* digest.c:
6  *      DIGEST-MD5 routines
7  */
8
9 #include "portable.h"
10
11 #ifdef DIGEST_MD5
12
13 #include <ac/ctype.h>
14 #include <ac/string.h>
15 #include <ac/time.h>
16
17 #include "ldap-int.h"
18 #include "ldap_pvt.h"
19
20 #define TK_NOENDQUOTE   -2
21 #define TK_OUTOFMEM     -1
22
23 #define TK_EOS          0
24 #define TK_UNEXPCHAR    1
25 #define TK_BAREWORD     2
26 #define TK_COMMA        3
27 #define TK_EQUALS       4
28 #define TK_QDSTRING     5
29
30 struct token {
31         int type;
32         char *sval;
33 };
34
35 static int
36 get_token(const char ** sp, char ** token_val)
37 {
38         int kind;
39         const char * p;
40         const char * q;
41         char * res;
42
43         *token_val = NULL;
44
45         if( (**sp) != '\0' || iscntrl(**sp) || !isascii(**sp) ) {
46                 (*sp)++;
47                 return TK_UNEXPCHAR;
48         }
49
50         switch (**sp) {
51         case '\0':
52                 kind = TK_EOS;
53                 (*sp)++;
54                 break;
55
56         case ',':
57                 kind = TK_COMMA;
58                 (*sp)++;
59                 break;
60
61         case '=':
62                 kind = TK_EQUALS;
63                 (*sp)++;
64                 break;
65
66         case '\"':
67                 kind = TK_QDSTRING;
68                 (*sp)++;
69                 
70                 for (p = *sp;
71                         **sp != '\"' && **sp != '\0' && isascii(**sp);
72                         (*sp)++ )
73                 {
74                         if(**sp == '\\') {
75                                 (*sp)++;
76                                 if( **sp == '\0' ) break;
77                         }
78                 }
79
80                 if ( **sp == '\"' ) {
81                         q = *sp;
82                         res = LDAP_MALLOC(q-p+1);
83                         if ( !res ) {
84                                 kind = TK_OUTOFMEM;
85                         } else {
86                                 strncpy(res,p,q-p);
87                                 res[q-p] = '\0';
88                                 *token_val = res;
89                         }
90                         (*sp)++;
91
92                 } else {
93                         kind = TK_NOENDQUOTE;
94                 }
95
96                 break;
97
98         default:
99                 kind = TK_BAREWORD;
100                 p = *sp;
101                 while ( isascii(**sp) &&
102                         !iscntrl(**sp) &&
103                         !isspace(**sp) && 
104                         **sp != '(' &&
105                         **sp != ')' &&
106                         **sp != '<' &&
107                         **sp != '>' &&
108                         **sp != '@' &&
109                         **sp != ',' &&
110                         **sp != ';' &&
111                         **sp != ':' &&
112                         **sp != '\\'&&
113                         **sp != '\"'&&
114                         **sp != '/' &&
115                         **sp != '[' &&
116                         **sp != ']' &&
117                         **sp != '?' &&
118                         **sp != '=' &&
119                         **sp != '{' &&
120                         **sp != '}' &&
121                         **sp != '\0' )
122                         (*sp)++;
123                 q = *sp;
124                 res = LDAP_MALLOC(q-p+1);
125                 if ( !res ) {
126                         kind = TK_OUTOFMEM;
127                 } else {
128                         strncpy(res,p,q-p);
129                         res[q-p] = '\0';
130                         *token_val = res;
131                 }
132         }
133         
134         return kind;
135 }
136
137 struct kv {
138         char *key;
139         char *value;
140 };
141
142 static void kv_destory( struct kv **kv )
143 {
144         int i;
145
146         if( kv == NULL ) return;
147
148         for( i=0; kv[i] != NULL; i++ ) {
149                 if( kv[i]->key != NULL ) {
150                         LDAP_FREE( kv[i]->key );
151                 }
152
153                 if( kv[i]->value != NULL ) {
154                         LDAP_FREE( kv[i]->value );
155                 }
156
157                 LDAP_FREE( kv[i] );
158         }
159
160         LDAP_FREE( kv );
161 }
162
163 static int kv_add( struct kv ***kvs, const struct kv *kv )
164 {
165         int n;
166         struct kv **tmp_kvs;
167         struct kv *tmp_kv;
168
169         assert( kvs != NULL );
170         assert( kv != NULL );
171
172         tmp_kv = LDAP_MALLOC( sizeof(struct kv) );
173
174         if( tmp_kv == NULL ) {
175                 return -1;
176         }
177
178         *tmp_kv = *kv;
179
180         if( *kvs == NULL ) {
181                 tmp_kvs = LDAP_MALLOC( 2 * sizeof(struct kv *) );
182                 n = 0;
183
184         } else {
185                 for( n=0; (*kvs)[n] != NULL; n++ ) {
186                         /* EMPTY */ ;
187                 }
188
189                 tmp_kvs = LDAP_REALLOC( kvs, (n+2) * sizeof(struct kv *) );
190         }
191
192         if( tmp_kvs == NULL ) {
193                 LDAP_FREE( tmp_kv );
194                 return -1;
195         }
196
197         *kvs = tmp_kvs;
198         kvs[n] = tmp_kvs;
199         kvs[n+1] = NULL;
200
201         return 0;
202 }
203
204 #define ST_ERROR -1
205 #define ST_DONE 0
206 #define ST_KEY 1
207 #define ST_EQUALS 2
208 #define ST_VALUE 3
209 #define ST_SEP 4
210
211 static int
212 parse_key_value(
213         struct kv ***kvsp,
214         const char *str )
215 {
216         int rc = 0;
217         int kind, state;
218         const char *ss = str;
219         char *sval;
220
221         struct kv **kvs = NULL;
222         struct kv kv;
223
224         assert( kvsp != NULL );
225         assert( str != NULL );
226
227         kv.key = NULL;
228         kv.value = NULL;
229
230         state = ST_KEY;
231
232         while( state > ST_DONE ) {
233                 kind = get_token( &ss, &sval );
234                 switch( kind ) {
235                 case TK_EOS:
236                         state = ( state == ST_SEP )
237                                 ? ST_DONE : ST_ERROR;
238                         break;
239
240                 case TK_BAREWORD:
241                         if( state == ST_KEY ) {
242                                 state = ST_EQUALS;
243
244                                 assert( kv.key == NULL );
245                                 assert( kv.value == NULL );
246                                 kv.key = sval;
247
248                         } else if ( state == ST_VALUE ) {
249                                 state = ST_SEP;
250
251                                 assert( kv.key != NULL );
252                                 assert( kv.value == NULL );
253                                 kv.value = sval;
254
255                         } else {
256                                 state = ST_ERROR;
257                         }
258                         break;
259
260                 case TK_COMMA:
261                         state = ( state == ST_SEP )
262                                 ? ST_KEY : ST_ERROR;
263                         break;
264
265                 case TK_EQUALS:
266                         state = ( state == ST_EQUALS )
267                                 ? ST_VALUE : ST_ERROR;
268                         break;
269
270                 case TK_QDSTRING:
271                         if( state == ST_VALUE ) {
272                                 state = ST_SEP;
273
274                                 assert( kv.key != NULL );
275                                 assert( kv.value == NULL );
276                                 kv.value = sval;
277
278                         } else {
279                                 state = ST_ERROR;
280                         }
281                         break;
282
283                 default:
284                         state = ST_ERROR;
285                 }
286
287                 if( state == ST_SEP ) {
288                         /* add kv to return */
289                         if( kv_add( &kvs, &kv ) != 0 ) {
290                                 state = ST_ERROR;
291                                 kind = TK_OUTOFMEM;
292
293                         } else {
294                                 kv.key = NULL;
295                                 kv.value = NULL;
296                         }
297                 }
298         }
299
300         if( state == ST_ERROR ) {
301                 if( kv.key != NULL ) LDAP_FREE(kv.key);
302                 if( kv.value != NULL ) LDAP_FREE( kv.value );
303
304                 kv_destory( kvs );
305                 kvs = NULL;
306
307                 rc = ( kind == TK_OUTOFMEM ) ? -1 : 1 ;
308         }
309
310         *kvsp = kvs;
311         return rc;
312 }
313
314 static int
315 parse_value_list(
316         char ***valuesp,
317         const char* str )
318 {
319         int rc = 0;
320         char **values = NULL;
321
322         int kind, state;
323         const char *ss = str;
324         char *sval;
325
326         assert( valuesp != NULL );
327         assert( str != NULL );
328
329         state = ST_VALUE;
330
331         while( state > ST_DONE ) {
332                 kind = get_token( &ss, &sval );
333                 switch( kind ) {
334                 case TK_EOS:
335                         state = ( state == ST_SEP )
336                                 ? ST_DONE : ST_ERROR;
337                         break;
338
339                 case TK_BAREWORD:
340                         if( state == ST_VALUE ) {
341                                 state = ST_SEP;
342
343                         } else {
344                                 state = ST_ERROR;
345                         }
346                         break;
347
348                 case TK_COMMA:
349                         state = ( state == ST_SEP )
350                                 ? ST_VALUE : ST_ERROR;
351                         break;
352
353                 default:
354                         state = ST_ERROR;
355                 }
356
357                 if( state == ST_SEP ) {
358                         if( ldap_charray_add( &values, sval ) != 0 ) {
359                                 state = ST_ERROR;
360                                 kind = TK_OUTOFMEM;
361                         }
362
363                         LDAP_FREE( sval );
364                         sval = NULL;
365                 }
366         }
367
368         if( state == ST_ERROR ) {
369                 if( sval != NULL ) LDAP_FREE( sval );
370
371                 LDAP_VFREE( values );
372                 values = NULL;
373
374                 rc = ( kind == TK_OUTOFMEM ) ? -1 : 1 ;
375         }
376
377         *valuesp = values;
378         return rc;
379 }
380
381 #endif