00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <ctype.h>
00029 #include "../../sr_module.h"
00030 #include "rule.h"
00031 #include "parse_config.h"
00032
00033
00034
00035
00036
00037
00038
00039 static int parse_expression_list(char *str, expression **e)
00040 {
00041 int start=0, i=-1, j=-1, apost=0;
00042 char str2[EXPRESSION_LENGTH];
00043 expression *e1=NULL, *e2;
00044
00045 if (!str || !e) return -1;
00046
00047 *e = NULL;
00048 do {
00049 i++;
00050 switch(str[i]) {
00051 case '"': apost = !apost;
00052 break;
00053 case ',': if (apost) break;
00054 case '\0':
00055 while ((str[start] == ' ') || (str[start] == '\t')) start++;
00056 if (str[start] == '"') start++;
00057 j = i-1;
00058 while ((0 < j) && ((str[j] == ' ') || (str[j] == '\t'))) j--;
00059 if ((0 < j) && (str[j] == '"')) j--;
00060 if (start<=j) {
00061
00062 if (j-start+1+1>EXPRESSION_LENGTH) {
00063 LM_ERR("expression too long "
00064 "<%.*s>(%d)\n",j-start+1,str+start,j-start+1);
00065 goto error;
00066 }
00067 strncpy(str2, str+start, j-start+1);
00068 str2[j-start+1] = '\0';
00069
00070 e2 = new_expression(str2);
00071 if (!e2)
00072
00073 goto error;
00074
00075 if (e1) {
00076
00077 e1->next = e2;
00078 e1 = e2;
00079 } else {
00080
00081 *e = e1 = e2;
00082 }
00083 } else {
00084
00085 goto error;
00086 }
00087
00088 start = i+1;
00089 }
00090 } while (str[i] != '\0');
00091
00092 return 0;
00093 error:
00094 if (*e) {
00095 free_expression(*e);
00096 *e = NULL;
00097 }
00098 return -1;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 static int parse_expression(char *str, expression **e, expression **e_exceptions)
00108 {
00109 char *except, str2[LINE_LENGTH+1];
00110 int i,j;
00111
00112 if (!str || !e || !e_exceptions) return -1;
00113
00114 except = strstr(str, " EXCEPT ");
00115 if (except) {
00116
00117 strncpy(str2, str, except-str);
00118 str2[except-str] = '\0';
00119
00120 if (parse_expression_list(except+8, e_exceptions)) {
00121
00122 *e = *e_exceptions = NULL;
00123 return -1;
00124 }
00125 } else {
00126
00127 strcpy(str2, str);
00128 *e_exceptions = NULL;
00129 }
00130
00131 for( i=0; isspace((int)str2[i]) ; i++);
00132 for( j=strlen(str2)-1 ; isspace((int)str2[j]) ; str2[j--]=0);
00133
00134 if (strcmp("ALL", str2+i) == 0) {
00135 *e = NULL;
00136 } else {
00137 if (parse_expression_list(str2+i, e)) {
00138
00139 if (*e_exceptions) free_expression(*e_exceptions);
00140 *e = *e_exceptions = NULL;
00141 return -1;
00142 }
00143 }
00144 return 0;
00145 }
00146
00147
00148
00149
00150
00151
00152 static rule *parse_config_line(char *line)
00153 {
00154 rule *rule1;
00155 expression *left, *left_exceptions, *right, *right_exceptions;
00156 int i=-1, exit=0, apost=0, colon=-1, eval=0;
00157 static char str1[LINE_LENGTH], str2[LINE_LENGTH+1];
00158
00159 if (!line) return 0;
00160
00161 rule1 = 0;
00162 left = left_exceptions = right = right_exceptions = 0;
00163
00164 while (!exit) {
00165 i++;
00166 switch(line[i]) {
00167 case '"': apost = !apost;
00168 eval = 1;
00169 break;
00170
00171 case ':': if (!apost) colon = i;
00172 eval = 1;
00173 break;
00174
00175 case '#': if (apost) break;
00176 case '\0':
00177 case '\n':
00178 exit = 1;
00179 break;
00180 case ' ': break;
00181 case '\t': break;
00182
00183 default: eval = 1;
00184
00185 }
00186 }
00187
00188 if (eval) {
00189 if ((0<colon) && (colon+1<i)) {
00190
00191
00192
00193 strncpy(str1, line, colon);
00194 str1[colon] = '\0';
00195 if (parse_expression(str1, &left, &left_exceptions)) {
00196
00197 LM_ERR("failed to parse line-left: %s\n", line);
00198 goto error;
00199 }
00200
00201
00202 strncpy(str2, line+colon+1, i-colon-1);
00203 str2[i-colon-1] = '\0';
00204 if (parse_expression(str2, &right, &right_exceptions)) {
00205
00206 LM_ERR("failed to parse line-right: %s\n", line);
00207 goto error;
00208 }
00209
00210 rule1 = new_rule();
00211 if (!rule1) {
00212 LM_ERR("can't create new rule\n");
00213 goto error;
00214 }
00215
00216 rule1->left = left;
00217 rule1->left_exceptions = left_exceptions;
00218 rule1->right = right;
00219 rule1->right_exceptions = right_exceptions;
00220 return rule1;
00221 } else {
00222
00223 LM_ERR("failed to parse line: %s\n", line);
00224 }
00225 }
00226 return 0;
00227
00228 error:
00229 if (left) free_expression(left);
00230 if (left_exceptions) free_expression(left_exceptions);
00231
00232 if (right) free_expression(right);
00233 if (right_exceptions) free_expression(right_exceptions);
00234
00235 return 0;
00236 }
00237
00238
00239
00240
00241
00242
00243 rule *parse_config_file(char *filename)
00244 {
00245 FILE *file;
00246 char line[LINE_LENGTH+1];
00247 rule *start_rule = NULL, *rule1 = NULL, *rule2 = NULL;
00248
00249 file = fopen(filename,"r");
00250 if (!file) {
00251 LM_WARN("file not found: %s\n", filename);
00252 return NULL;
00253 }
00254
00255 while (fgets(line, LINE_LENGTH, file)) {
00256 rule2 = parse_config_line(line);
00257 if (rule2) {
00258 if (rule1) {
00259
00260 rule1->next = rule2;
00261 } else {
00262
00263 start_rule = rule2;
00264 }
00265 rule1 = rule2;
00266 }
00267 }
00268
00269 fclose(file);
00270 return start_rule;
00271 }