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