parser: some more const-correctness for the other functions in msg_parser.[c,h]
[sip-router] / ppcfg.c
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com)
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * ppcfg.c - config preprocessor directives
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include "mem/mem.h"
28 #include "ut.h"
29 #include "re.h"
30 #include "dprint.h"
31
32 #include "ppcfg.h"
33
34 typedef struct _pp_subst_rule {
35         char *indata;
36         void *ppdata;
37         struct _pp_subst_rule *next;
38 } pp_subst_rule_t;
39
40 static pp_subst_rule_t *pp_subst_rules_head = NULL;
41 static pp_subst_rule_t *pp_subst_rules_tail = NULL;
42
43 int pp_subst_add(char *data)
44 {
45         struct subst_expr* se;
46         str subst;
47         pp_subst_rule_t *pr;
48
49         subst.s = data;
50         subst.len = strlen(subst.s);
51         /* check for early invalid rule */
52         if(subst.len<=0)
53                 return -1;
54         pr = (pp_subst_rule_t*)pkg_malloc(sizeof(pp_subst_rule_t));
55         if(pr==NULL)
56         {
57                 LM_ERR("no more pkg\n");
58                 return -1;
59         }
60         memset(pr, 0, sizeof(pp_subst_rule_t));
61
62         se=subst_parser(&subst);
63         if (se==0)
64         {
65                 LM_ERR("bad subst expression: %s\n", data);
66                 pkg_free(pr);
67                 return -2;
68         }
69         pr->indata = data;
70         pr->ppdata = (void*)se;
71         if(pp_subst_rules_head==NULL)
72         {
73                 pp_subst_rules_head = pr;
74         } else {
75                 pp_subst_rules_tail->next = pr;
76         }
77         pp_subst_rules_tail = pr;
78
79         LM_INFO("### added subst expression: %s\n", data);
80
81         return 0;
82 }
83
84 int pp_substdef_add(char *data, int mode)
85 {
86         char c;
87         char *p;
88         str defname;
89         str defvalue;
90
91         if(pp_subst_add(data)<0) {
92                 LM_ERR("subst rule cannot be added\n");
93                 goto error;
94         }
95
96         p=data;
97         c=*p;
98         if (c=='\\') {
99                 LM_ERR("invalid separator char [%c] in [%s]\n", c, data);
100                 goto error;
101         }
102         p++;
103         /* find regexp */
104         defname.s=p;
105         for ( ; *p; p++) {
106                 /* if unescaped sep. char */
107                 if ((*p==c) && (*(p-1)!='\\'))
108                         goto found_regexp;
109         }
110         LM_ERR("separator [%c] not found after regexp: [%s]\n", c, data);
111         goto error;
112
113 found_regexp:
114         defname.len = p - defname.s;
115         if(defname.len==0) {
116                 LM_ERR("define name too short\n");
117                 goto error;
118         }
119
120         p++;
121         defvalue.s = p;
122         /* find replacement */
123         for ( ; *p; p++) {
124                 /* if unescaped sep. char */
125                 if ((*p==c) && (*(p-1)!='\\'))
126                         goto found_repl;
127         }
128         LM_ERR("separator [%c] not found after replacement: [%s]\n", c, data);
129         goto error;
130
131 found_repl:
132         defvalue.len = p - defvalue.s;
133
134         pp_define_set_type(0);
135         if(pp_define(defname.len, defname.s)<0) {
136                 LM_ERR("cannot set define name\n");
137                 goto error;
138         }
139         if(mode==1) {
140                 /* define the value enclosed in double quotes */
141                 *(defvalue.s-1) = '"';
142                 defvalue.s[defvalue.len] = '"';
143                 defvalue.s--;
144                 defvalue.len += 2;
145         }
146         if(pp_define_set(defvalue.len, defvalue.s)<0) {
147                 LM_ERR("cannot set define value\n");
148                 goto error;
149         }
150         if(mode==1) {
151                 defvalue.s++;
152                 defvalue.len -= 2;
153                 *(defvalue.s-1) = c;
154                 defvalue.s[defvalue.len] = c;
155         }
156
157         LM_DBG("### added substdef: [%.*s]=[%.*s] (%d)\n", defname.len, defname.s,
158                         defvalue.len, defvalue.s, mode);
159
160         return 0;
161
162 error:
163         return 1;
164 }
165
166 int pp_subst_run(char **data)
167 {
168         str* result;
169         pp_subst_rule_t *pr;
170         int i;
171
172         if(pp_subst_rules_head==NULL)
173                 return 0;
174         if(data==NULL || *data==NULL)
175                 return 0;
176
177         if(strlen(*data)==0)
178                 return 0;
179         pr = pp_subst_rules_head;
180
181         i = 0;
182         while(pr)
183         {
184                 result=subst_str(*data, 0,
185                                 (struct subst_expr*)pr->ppdata, 0); /* pkg malloc'ed result */
186                 if(result!=NULL)
187                 {
188                         i++;
189                         LM_DBG("preprocess subst applied [#%d] to [%s]"
190                                         " - returning new string [%s]\n", i, *data, result->s);
191                         pkg_free(*data);
192                         *data = result->s;
193                         pkg_free(result);
194                 }
195                 pr = pr->next;
196         }
197
198         if(i!=0)
199                 return 1;
200         return 0;
201 }
202
203 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */