]> git.sur5r.net Git - openldap/blob - libraries/libldap/dsparse.c
19446e0ee4f0ac059654dc525f3bfd08995b7dba
[openldap] / libraries / libldap / dsparse.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*  Portions
6  * Copyright (c) 1993, 1994 Regents of the University of Michigan.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms are permitted
10  * provided that this notice is preserved and that due credit is given
11  * to the University of Michigan at Ann Arbor. The name of the University
12  * may not be used to endorse or promote products derived from this
13  * software without specific prior written permission. This software
14  * is provided ``as is'' without express or implied warranty.
15  *
16  * dsparse.c:  parsing routines used by display template and search 
17  * preference file library routines for LDAP clients.
18  *
19  * 7 March 1994 by Mark C Smith
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include <ac/stdlib.h>
26
27 #include <ac/ctype.h>
28 #include <ac/string.h>
29 #include <ac/time.h>
30
31 #ifdef HAVE_SYS_FILE_H
32 #include <sys/file.h>
33 #endif
34
35 #include "ldap-int.h"
36
37 static int next_line LDAP_P(( char **bufp, long *blenp, char **linep ));
38 static char *next_token LDAP_P(( char ** sp ));
39
40
41
42 int
43 next_line_tokens( char **bufp, long *blenp, char ***toksp )
44 {
45     char        *p, *line, *token, **toks;
46     int         rc, tokcnt;
47
48     *toksp = NULL;
49
50     if (( rc = next_line( bufp, blenp, &line )) <= 0 ) {
51         return( rc );
52     }
53
54     if (( toks = (char **)LDAP_CALLOC( 1, sizeof( char * ))) == NULL ) {
55         LBER_FREE( line );
56         return( -1 );
57     }
58     tokcnt = 0;
59
60     p = line;
61     while (( token = next_token( &p )) != NULL ) {
62         if (( toks = (char **)LDAP_REALLOC( toks, ( tokcnt + 2 ) *
63                 sizeof( char * ))) == NULL ) {
64             LBER_FREE( (char *)toks );
65             LBER_FREE( line );
66             return( -1 );
67         }
68         toks[ tokcnt ] = token;
69         toks[ ++tokcnt ] = NULL;
70     }
71
72     if ( tokcnt == 1 && strcasecmp( toks[ 0 ], "END" ) == 0 ) {
73         tokcnt = 0;
74         free_strarray( toks );
75         toks = NULL;
76     }
77
78     LBER_FREE( line );
79
80     if ( tokcnt == 0 ) {
81         if ( toks != NULL ) {
82             LBER_FREE( (char *)toks );
83         }
84     } else {
85         *toksp = toks;
86     }
87
88     return( tokcnt );
89 }
90
91
92 static int
93 next_line( char **bufp, long *blenp, char **linep )
94 {
95     char        *linestart, *line, *p;
96     long        plen;
97
98     linestart = *bufp;
99     p = *bufp;
100     plen = *blenp;
101
102     do {
103         for ( linestart = p; plen > 0; ++p, --plen ) {
104             if ( *p == '\r' ) {
105                 if ( plen > 1 && *(p+1) == '\n' ) {
106                     ++p;
107                     --plen;
108                 }
109                 break;
110             }
111
112             if ( *p == '\n' ) {
113                 if ( plen > 1 && *(p+1) == '\r' ) {
114                     ++p;
115                     --plen;
116                 }
117                 break;
118             }
119         }
120         ++p;
121         --plen;
122     } while ( plen > 0 && ( *linestart == '#' || linestart + 1 == p ));
123
124
125     *bufp = p;
126     *blenp = plen;
127
128
129     if ( plen <= 0 ) {
130         *linep = NULL;
131         return( 0 );    /* end of file */
132     }
133
134     if (( line = LDAP_MALLOC( p - linestart )) == NULL ) {
135         *linep = NULL;
136         return( -1 );   /* fatal error */
137     }
138
139     (void) memcpy( line, linestart, p - linestart );
140     line[ p - linestart - 1 ] = '\0';
141     *linep = line;
142     return( strlen( line ));
143 }
144
145
146 static char *
147 next_token( char **sp )
148 {
149     int         in_quote = 0;
150     char        *p, *tokstart, *t;
151
152     if ( **sp == '\0' ) {
153         return( NULL );
154     }
155
156     p = *sp;
157
158     while ( isspace( (unsigned char) *p )) {    /* skip leading white space */
159         ++p;
160     }
161
162     if ( *p == '\0' ) {
163         return( NULL );
164     }
165
166     if ( *p == '\"' ) {
167         in_quote = 1;
168         ++p;
169     }
170     t = tokstart = p;
171
172     for ( ;; ) {
173         if ( *p == '\0' || ( isspace( (unsigned char) *p ) && !in_quote )) {
174             if ( *p != '\0' ) {
175                 ++p;
176             }
177             *t++ = '\0';                /* end of token */
178             break;
179         }
180
181         if ( *p == '\"' ) {
182             in_quote = !in_quote;
183             ++p;
184         } else {
185             *t++ = *p++;
186         }
187     }
188
189     *sp = p;
190
191     if ( t == tokstart ) {
192         return( NULL );
193     }
194
195     return( LDAP_STRDUP( tokstart ));
196 }
197
198
199 void
200 free_strarray( char **sap )
201 {
202     int         i;
203
204     if ( sap != NULL ) {
205         for ( i = 0; sap[ i ] != NULL; ++i ) {
206             LBER_FREE( sap[ i ] );
207         }
208         LBER_FREE( (char *)sap );
209     }
210 }