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