]> git.sur5r.net Git - openldap/blob - libraries/librewrite/parse.c
better check of snprintf result
[openldap] / libraries / librewrite / parse.c
1 /******************************************************************************
2  *
3  * Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
4  * All rights reserved.
5  *
6  * Permission is granted to anyone to use this software for any purpose
7  * on any computer system, and to alter it and redistribute it, subject
8  * to the following restrictions:
9  *
10  * 1. The author is not responsible for the consequences of use of this
11  * software, no matter how awful, even if they arise from flaws in it.
12  *
13  * 2. The origin of this software must not be misrepresented, either by
14  * explicit claim or by omission.  Since few users ever read sources,
15  * credits should appear in the documentation.
16  *
17  * 3. Altered versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.  Since few users
19  * ever read sources, credits should appear in the documentation.
20  * 
21  * 4. This notice may not be removed or altered.
22  *
23  ******************************************************************************/
24
25 #include <portable.h>
26
27 #include <stdio.h>
28
29 #include "rewrite-int.h"
30
31 static int
32 parse_line(
33                 char **argv,
34                 int *argc,
35                 int maxargs, 
36                 char *buf
37 )
38 {
39         char *p, *begin;
40         int in_quoted_field = 0, cnt = 0;
41         char quote = '\0';
42         
43         for ( p = buf; isspace( (unsigned char) p[ 0 ] ); p++ );
44         
45         if ( p[ 0 ] == '#' ) {
46                 return 0;
47         }
48         
49         for ( begin = p;  p[ 0 ] != '\0'; p++ ) {
50                 if ( p[ 0 ] == '\\' && p[ 1 ] != '\0' ) {
51                         p++;
52                 } else if ( p[ 0 ] == '\'' || p[ 0 ] == '\"') {
53                         if ( in_quoted_field && p[ 0 ] == quote ) {
54                                 in_quoted_field = 1 - in_quoted_field;
55                                 quote = '\0';
56                                 p[ 0 ] = '\0';
57                                 argv[ cnt ] = begin;
58                                 if ( ++cnt == maxargs ) {
59                                         *argc = cnt;
60                                         return 1;
61                                 }
62                                 for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
63                                 begin = p;
64                                 p--;
65                                 
66                         } else if ( !in_quoted_field ) {
67                                 if ( p != begin ) {
68                                         return -1;
69                                 }
70                                 begin++;
71                                 in_quoted_field = 1 - in_quoted_field;
72                                 quote = p[ 0 ];
73                         }
74                 } else if ( isspace( (unsigned char) p[ 0 ] ) && !in_quoted_field ) {
75                         p[ 0 ] = '\0';
76                         argv[ cnt ] = begin;
77
78                         if ( ++cnt == maxargs ) {
79                                 *argc = cnt;
80                                 return 1;
81                         }
82
83                         for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
84                         begin = p;
85                         p--;
86                 }
87         }
88         
89         *argc = cnt;
90
91         return 1;
92 }
93
94 int
95 rewrite_read( 
96                 FILE *fin,
97                 struct rewrite_info *info
98 )
99 {
100         char buf[ 1024 ];
101         char *argv[11];
102         int argc, lineno;
103
104         /* 
105          * Empty rule at the beginning of the context
106          */
107
108         for ( lineno = 0; fgets( buf, sizeof( buf ), fin ); lineno++ ) {
109                 switch ( parse_line( argv, &argc, sizeof( argv ) - 1, buf ) ) {
110                 case -1:
111                         return REWRITE_ERR;
112                 case 0:
113                         break;
114                 case 1:
115                         if ( strncasecmp( argv[ 0 ], "rewrite", 7 ) == 0 ) {
116                                 int rc;
117                                 rc = rewrite_parse( info, "file", lineno, 
118                                                 argc, argv );
119                                 if ( rc != REWRITE_SUCCESS ) {
120                                         return rc;
121                                 }
122                         }
123                         break;
124                 }
125         }
126
127         return REWRITE_SUCCESS;
128 }
129