- #define CFG_INPUT_SHIFT is used instead of a hardwired value
[sip-router] / cfg / cfg_select.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2008 iptelorg GmbH
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History
28  * -------
29  *  2008-01-10  Initial version (Miklos)
30  */
31 #include <stdio.h>
32
33 #include "../select.h"
34 #include "../ut.h"
35 #include "cfg_struct.h"
36 #include "cfg_select.h"
37
38 int select_cfg_var(str *res, select_t *s, struct sip_msg *msg)
39 {
40         cfg_group_t     *group;
41         cfg_mapping_t   *var;
42         void            *p;
43         int             i;
44         static char     buf[INT2STR_MAX_LEN];
45
46         if (msg == NULL) {
47                 /* fixup call */
48
49                 /* two parameters are mandatory, group name and variable name */
50                 if (s->n != 3) {
51                         LOG(L_ERR, "ERROR: select_cfg_var(): two parameters are expected\n");
52                         return -1;
53                 }
54
55                 if ((s->params[1].type != SEL_PARAM_STR)
56                 || (s->params[2].type != SEL_PARAM_STR)) {
57                         LOG(L_ERR, "ERROR: select_cfg_var(): string parameters are expected\n");
58                         return -1;
59                 }
60
61                 /* look-up the group and the variable */
62                 if (cfg_lookup_var(&s->params[1].v.s, &s->params[2].v.s, &group, &var)) {
63                         LOG(L_ERR, "ERROR: select_cfg_var(): unknown variable\n");
64                         return -1;
65                 }
66
67                 if (var->def->on_change_cb) {
68                         /* fixup function is defined -- safer to return an error
69                         than an incorrect value */
70                         LOG(L_ERR, "ERROR: select_cfg_var(): variable cannot be retrieved\n");
71                         return -1;
72                 }
73
74                 s->params[1].type = SEL_PARAM_PTR;
75                 s->params[1].v.p = (void *)group;
76
77                 s->params[2].type = SEL_PARAM_PTR;
78                 s->params[2].v.p = (void *)var;
79                 return 1;
80         }
81
82         group = (cfg_group_t *)s->params[1].v.p;
83         var = (cfg_mapping_t *)s->params[2].v.p;
84
85         /* use the module's handle to access the variable, so the variables
86         are read from private memory */
87         p = *(group->handle) + var->offset;
88
89         switch (CFG_VAR_TYPE(var)) {
90         case CFG_VAR_INT:
91                 memcpy(&i, p, sizeof(int));
92                 res->len = snprintf(buf, sizeof(buf)-1, "%d", i);
93                 buf[res->len] = '\0';
94                 res->s = buf;
95                 break;
96
97         case CFG_VAR_STRING:
98                 memcpy(&res->s, p, sizeof(char *));
99                 res->len = strlen(res->s);
100                 break;
101
102         case CFG_VAR_STR:
103                 memcpy(res, p, sizeof(str));
104                 break;
105
106         }
107         return 0;
108 }