xref: /netbsd-src/external/bsd/openldap/dist/libraries/librewrite/parse.c (revision 466a16a118933bd295a8a104f095714fadf9cf68)
1 /* $OpenLDAP: pkg/ldap/libraries/librewrite/parse.c,v 1.9.2.3 2008/02/11 23:26:42 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2000-2008 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* ACKNOWLEDGEMENT:
16  * This work was initially developed by Pierangelo Masarati for
17  * inclusion in OpenLDAP Software.
18  */
19 
20 #include <portable.h>
21 
22 #include <stdio.h>
23 
24 #include "rewrite-int.h"
25 
26 static int
27 parse_line(
28 		char **argv,
29 		int *argc,
30 		int maxargs,
31 		char *buf
32 )
33 {
34 	char *p, *begin;
35 	int in_quoted_field = 0, cnt = 0;
36 	char quote = '\0';
37 
38 	for ( p = buf; isspace( (unsigned char) p[ 0 ] ); p++ );
39 
40 	if ( p[ 0 ] == '#' ) {
41 		return 0;
42 	}
43 
44 	for ( begin = p;  p[ 0 ] != '\0'; p++ ) {
45 		if ( p[ 0 ] == '\\' && p[ 1 ] != '\0' ) {
46 			p++;
47 		} else if ( p[ 0 ] == '\'' || p[ 0 ] == '\"') {
48 			if ( in_quoted_field && p[ 0 ] == quote ) {
49 				in_quoted_field = 1 - in_quoted_field;
50 				quote = '\0';
51 				p[ 0 ] = '\0';
52 				argv[ cnt ] = begin;
53 				if ( ++cnt == maxargs ) {
54 					*argc = cnt;
55 					return 1;
56 				}
57 				for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
58 				begin = p;
59 				p--;
60 
61 			} else if ( !in_quoted_field ) {
62 				if ( p != begin ) {
63 					return -1;
64 				}
65 				begin++;
66 				in_quoted_field = 1 - in_quoted_field;
67 				quote = p[ 0 ];
68 			}
69 		} else if ( isspace( (unsigned char) p[ 0 ] ) && !in_quoted_field ) {
70 			p[ 0 ] = '\0';
71 			argv[ cnt ] = begin;
72 
73 			if ( ++cnt == maxargs ) {
74 				*argc = cnt;
75 				return 1;
76 			}
77 
78 			for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
79 			begin = p;
80 			p--;
81 		}
82 	}
83 
84 	*argc = cnt;
85 
86 	return 1;
87 }
88 
89 int
90 rewrite_read(
91 		FILE *fin,
92 		struct rewrite_info *info
93 )
94 {
95 	char buf[ 1024 ];
96 	char *argv[11];
97 	int argc, lineno;
98 
99 	/*
100 	 * Empty rule at the beginning of the context
101 	 */
102 
103 	for ( lineno = 0; fgets( buf, sizeof( buf ), fin ); lineno++ ) {
104 		switch ( parse_line( argv, &argc, sizeof( argv ) - 1, buf ) ) {
105 		case -1:
106 			return REWRITE_ERR;
107 		case 0:
108 			break;
109 		case 1:
110 			if ( strncasecmp( argv[ 0 ], "rewrite", 7 ) == 0 ) {
111 				int rc;
112 				rc = rewrite_parse( info, "file", lineno,
113 						argc, argv );
114 				if ( rc != REWRITE_SUCCESS ) {
115 					return rc;
116 				}
117 			}
118 			break;
119 		}
120 	}
121 
122 	return REWRITE_SUCCESS;
123 }
124 
125