First working release
[sip-router] / cfg_parser.c
1 /*
2  * $Id$
3  */
4
5 #include <errno.h>
6 #include <string.h>
7 #include <stdio.h>
8
9 #include "cfg_parser.h"
10 #include "msg_parser.h" /* parse_hostport */
11 #include "dprint.h"
12 #include "parser_f.h"
13 #include "route.h"
14
15
16
17
18 /* params: null terminated text line => fills cl
19  * returns 0, or on error -1. */
20 int cfg_parse_line(char* line, struct cfg_line* cl)
21 {
22         /* format:
23                 line = rule | comment
24                 comment = SP* '#'.*
25                 rule = SP* method_re SP* uri_re SP* ip_address comment?
26         */
27                 
28         char* tmp;
29         char* end;
30         
31         end=line+strlen(line);
32         tmp=eat_space(line, end-line);
33         if ((tmp==end)||(is_empty(tmp, end-tmp))) {
34                 cl->type=CFG_EMPTY;
35                 goto skip;
36         }
37         if (*tmp=='#'){
38                 cl->type=CFG_COMMENT;
39                 goto skip;
40         }
41         cl->method=tmp;
42         tmp=eat_token(cl->method,end-cl->method);
43         if (tmp==end) goto error;
44         *tmp=0;
45         tmp++;
46         cl->uri=eat_space(tmp,end-tmp);
47         if (tmp==end) goto error;
48         tmp=eat_token(cl->uri,end-cl->uri);
49         if (tmp==end) goto error;
50         *tmp=0;
51         tmp++;
52         cl->address=eat_space(tmp,end-tmp);
53         if (tmp==end) goto error;
54         tmp=eat_token(cl->address, end-cl->address);
55         if (tmp<end) {
56                 *tmp=0;
57                 if (tmp+1<end){
58                         if (!is_empty(tmp+1,end-tmp-1)){
59                                 /* check if comment */
60                                 tmp=eat_space(tmp+1, end-tmp-1);
61                                 if (*tmp!='#'){
62                                         /* extra chars at the end of line */
63                                         goto error;
64                                 }
65                         }
66                 }
67         }
68         /* find port */
69         if (parse_hostport(cl->address, &tmp, &cl->port)==0){
70                         goto error;
71         }
72         
73         cl->type=CFG_RULE;
74 skip:
75         return 0;
76 error:
77         cl->type=CFG_ERROR;
78         return -1;
79 }
80
81
82
83 /* parses the cfg, returns 0 on success, line no otherwise */
84 int cfg_parse_stream(FILE* stream)
85 {
86         int line;
87         struct cfg_line cl;
88         char buf[MAX_LINE_SIZE];
89         int ret;
90
91         line=1;
92         while(!feof(stream)){
93                 if (fgets(buf, MAX_LINE_SIZE, stream)){
94                         cfg_parse_line(buf, &cl);
95                         switch (cl.type){
96                                 case CFG_RULE:
97                                         if ((ret=add_rule(&cl, &rlist))!=0){
98                                                 DPrint("ERROR: could not compile rule at line %d\n",
99                                                         line);
100                                                 DPrint(" ----: add_rule returned %d\n", ret);
101                                                 goto error;
102                                         }
103                                         break;
104                                 case CFG_COMMENT:
105                                 case CFG_SKIP:
106                                         break;
107                                 case CFG_ERROR:
108                                         DPrint("ERROR: bad config line (%d):%s\n", line, buf);
109                                         goto error;
110                                         break;
111                         }
112                         line++;
113                 }else{
114                         if (ferror(stream)){
115                                 DPrint("ERROR: reading configuration: %s\n", strerror(errno));
116                                 goto error;
117                         }
118                         break;
119                 }
120         }
121         return 0;
122
123 error:
124         return line;
125 }
126