1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 2000-2011 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 26static int 27parse_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 89int 90rewrite_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