dead1233bbdd25f12e60ccd96e2d83458c891518
[asterisk/asterisk.git] / res / res_config_odbc.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Copyright (C) 1999, Mark Spencer
5  *
6  * Mark Spencer <markster@linux-support.net>
7  *
8  * res_config_odbc.c <odbc+odbc plugin for portable configuration engine >
9  * Copyright (C) 2004 Anthony Minessale II <anthmct@yahoo.com>
10  */
11
12
13 #include <asterisk/file.h>
14 #include <asterisk/logger.h>
15 #include <asterisk/channel.h>
16 #include <asterisk/pbx.h>
17 #include <asterisk/config.h>
18 #include <asterisk/config_pvt.h>
19 #include <asterisk/module.h>
20 #include <asterisk/lock.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <asterisk/res_odbc.h>
25
26
27
28 static char *tdesc = "Odbc Configuration";
29 static struct ast_config_reg reg1;
30
31
32 STANDARD_LOCAL_USER;
33
34 LOCAL_USER_DECL;
35
36
37 static struct ast_config *config_odbc(char *file, struct ast_config *new_config_s,struct ast_category **new_cat_p,struct ast_variable **new_v_p,int recur
38 #ifdef PRESERVE_COMMENTS
39                                       ,struct ast_comment_struct *acs
40 #endif
41
42                                       ) {
43
44
45
46
47   struct ast_config *config,*new;
48   struct ast_variable *v,*cur_v,*new_v;
49   struct ast_category *cur_cat,*new_cat;
50   char table[128];
51   char connection[128];
52   int configured=0, res=0;
53   odbc_obj *obj;
54   SQLINTEGER err,commented,cat_metric,var_metric;
55   SQLBIGINT id;
56   char sql[255],filename[128],category[128],var_name[128],var_val[128];
57   SQLSMALLINT rowcount;
58   SQLHSTMT stmt;
59   char last[80];
60   int cat_started=0;
61   int var_started=0;
62
63
64   if(new_config_s) {
65     new = new_config_s;
66     cat_started++;
67   }
68   else 
69     new = ast_new_config();
70
71   last[0] = '\0';
72
73   if(!file || !strcmp(file,"res_config_odbc.conf"))
74     return NULL; // cant configure myself with myself !
75
76   config = ast_load("res_config_odbc.conf");
77
78   if(config) {
79     for(v = ast_variable_browse(config,"settings");v;v=v->next) {
80       if(!strcmp(v->name,"table")) {
81         strncpy(table,v->value,sizeof(table));
82         configured++;
83       }
84       else if(!strcmp(v->name,"connection")) {
85         strncpy(connection,v->value,sizeof(connection));
86         configured++;
87       }
88     }
89     ast_destroy(config);
90   }
91         
92   if(configured < 2)
93     return NULL;
94         
95   obj = fetch_odbc_obj(connection);
96   if(!obj)
97     return NULL;
98
99
100
101
102
103   res=SQLAllocHandle(SQL_HANDLE_STMT,obj->con, &stmt);
104
105   SQLBindCol(stmt,1,SQL_C_ULONG,&id,sizeof(id),&err);
106   SQLBindCol(stmt,2,SQL_C_ULONG,&cat_metric,sizeof(cat_metric),&err);
107   SQLBindCol(stmt,3,SQL_C_ULONG,&var_metric,sizeof(var_metric),&err);
108   SQLBindCol(stmt,4,SQL_C_ULONG,&commented,sizeof(commented),&err);
109   SQLBindCol(stmt,5,SQL_C_CHAR,&filename,sizeof(filename),&err);
110   SQLBindCol(stmt,6,SQL_C_CHAR,&category,sizeof(category),&err);
111   SQLBindCol(stmt,7,SQL_C_CHAR,&var_name,sizeof(var_name),&err);
112   SQLBindCol(stmt,8,SQL_C_CHAR,&var_val,sizeof(var_val),&err);
113         
114   sprintf(sql,"select * from %s where filename='%s' and commented=0 order by filename,cat_metric,var_metric,id",table,file);
115   res = SQLExecDirect(stmt,sql,SQL_NTS);
116         
117   if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
118     ast_log(LOG_WARNING,"SQL select error!\n[%s]\n\n",sql);
119     return NULL;
120   }
121         
122   res=SQLNumResultCols(stmt,&rowcount);
123         
124   if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
125     ast_log(LOG_WARNING,"SQL select error!\n[%s]\n\n",sql);
126     return NULL;
127   }
128
129
130   if(rowcount) {
131
132     res=SQLFetch(stmt);
133     cat_started=0;
134
135
136                 
137     cur_cat = *new_cat_p;
138     cur_v = *new_v_p;
139                 
140     if(cur_cat)
141       cat_started=1;
142     if(cur_v)
143       var_started=1;
144
145
146
147     while(res != SQL_NO_DATA) {
148       //ast_log(LOG_NOTICE,"found %s %s %s\n",filename,var_name,var_val);
149       // build the config sql table probably needs to be improved!
150
151       if(!strcmp(var_name,"#include") &&  recur < MAX_INCLUDE_LEVEL) {
152                                 
153         config_odbc(var_val,new,&cur_cat,&cur_v,recur + 1
154 #ifdef PRESERVE_COMMENTS
155                     ,acs
156 #endif
157                     );
158
159       }
160       else {                    
161
162                                 
163
164         if(strcmp(last,category)) {
165           strcpy(last,category);
166           new_cat = (struct ast_category *) ast_new_category(category);
167                                         
168           if(!cat_started) {
169             cat_started++;
170             new->root = new_cat;
171             cur_cat=new->root;
172           }
173           else {
174             cur_cat->next = new_cat;
175             cur_cat = cur_cat->next;
176           }
177           var_started=0;
178                                         
179         }
180
181         new_v = ast_new_variable(var_name,var_val);
182                                 
183                                 
184         if(!var_started) {
185           var_started++;
186           cur_cat->root = new_v;
187           cur_v = cur_cat->root;
188         }
189         else {
190           cur_v->next = new_v;
191           cur_v = cur_v->next;
192         }
193       }
194                         
195       // next row 
196       res=SQLFetch(stmt);
197     }
198
199     SQLFreeHandle(SQL_HANDLE_STMT,stmt);
200   }
201   else 
202     ast_log(LOG_NOTICE,"found nothing\n");
203
204         
205
206         
207         
208
209
210         
211   return new;
212         
213 }
214
215
216
217
218 int unload_module(void)
219 {
220     ast_cust_config_deregister(&reg1);
221         ast_log(LOG_NOTICE,"res_config_odbc unloaded.\n");
222         STANDARD_HANGUP_LOCALUSERS;
223         return 0;
224 }
225
226 int load_module(void)
227 {
228
229         memset(&reg1,0,sizeof(struct ast_config_reg));
230         strcpy(reg1.name,"odbc");
231         reg1.func = config_odbc;
232         ast_cust_config_register(&reg1);
233         ast_log(LOG_NOTICE,"res_config_odbc loaded.\n");
234         return 0;
235 }
236
237 char *description(void)
238 {
239   return tdesc;
240 }
241
242 int usecount(void)
243 {
244         /* never unload a config module */
245         return 1;
246 }
247
248 char *key()
249 {
250   return ASTERISK_GPL_KEY;
251 }
252
253