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