locking: Add temporary sanity checks.
[asterisk/asterisk.git] / utils / conf2ael.c
1 /*  
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Steve Murphy <murf@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*
20  *
21  * Reverse compile extensions.conf code into prototype AEL code
22  *
23  */
24
25 /*** MODULEINFO
26         <depend>res_ael_share</depend>
27         <support_level>extended</support_level>
28  ***/
29
30 #include "asterisk.h"
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include "asterisk/paths.h"     /* CONFIG_DIR */
34 #include <locale.h>
35 #include <ctype.h>
36 #if !defined(SOLARIS) && !defined(__CYGWIN__)
37 #include <err.h>
38 #endif
39 #include <regex.h>
40
41 #include "asterisk.h"
42 #include "asterisk/pbx.h"
43 #include "asterisk/ast_expr.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/chanvars.h"
46 #include "asterisk/module.h"
47 #include "asterisk/app.h"
48 #include "asterisk/config.h"
49 #include "asterisk/options.h"
50 #include "asterisk/callerid.h"
51 #include "asterisk/lock.h"
52 #include "asterisk/hashtab.h"
53 #include "asterisk/ael_structs.h"
54 #include "asterisk/devicestate.h"
55 #include "asterisk/stringfields.h"
56 #include "asterisk/pval.h"
57 #include "asterisk/extconf.h"
58
59 struct ast_flags ast_compat = { 7 };
60 const char *ast_config_AST_CONFIG_DIR = "/etc/asterisk";        /* placeholder */
61
62 void get_start_stop(unsigned int *word, int bitsperword, int totalbits, int *start, int *end);
63 int all_bits_set(unsigned int *word, int bitsperword, int totalbits);
64 extern char *days[];
65 extern char *months[];
66
67 char *config = "extensions.conf";
68
69 /* 
70 static char *registrar = "conf2ael";
71 static char userscontext[AST_MAX_EXTENSION] = "default";
72 static int static_config = 0;
73 static int write_protect_config = 1;
74 static int autofallthrough_config = 0;
75 static int clearglobalvars_config = 0;
76 char ast_config_AST_SYSTEM_NAME[20] = ""; */
77
78 /* static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function); */
79 //extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
80 int option_debug = 0;
81 int option_verbose = 0;
82
83 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function);
84 void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
85 {
86         /*! \todo BUGBUG Put here only to allow utils to compile in AST_DEVMODE */
87 }
88
89 void ast_register_file_version(const char *file, const char *version);
90 void ast_register_file_version(const char *file, const char *version)
91 {
92 }
93
94 void ast_unregister_file_version(const char *file);
95 void ast_unregister_file_version(const char *file)
96 {
97 }
98 #if !defined(LOW_MEMORY)
99 int ast_add_profile(const char *x, uint64_t scale) { return 0;}
100 #endif
101 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
102 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf,5,6)));
103
104 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
105 {
106         va_list vars;
107         va_start(vars,fmt);
108         
109         printf("LOG: lev:%d file:%s  line:%d func: %s  ",
110                    level, file, line, function);
111         vprintf(fmt, vars);
112         fflush(stdout);
113         va_end(vars);
114 }
115
116 /* stolen from pbx.c */
117 struct ast_context;
118 struct ast_app;
119 #ifdef LOW_MEMORY
120 #define EXT_DATA_SIZE 256
121 #else
122 #define EXT_DATA_SIZE 8192
123 #endif
124
125 #define SWITCH_DATA_LENGTH 256
126
127 #define VAR_BUF_SIZE 4096
128
129 #define VAR_NORMAL              1
130 #define VAR_SOFTTRAN    2
131 #define VAR_HARDTRAN    3
132
133 #define BACKGROUND_SKIP         (1 << 0)
134 #define BACKGROUND_NOANSWER     (1 << 1)
135 #define BACKGROUND_MATCHEXTEN   (1 << 2)
136 #define BACKGROUND_PLAYBACK     (1 << 3)
137
138 /*!
139    \brief ast_exten: An extension
140         The dialplan is saved as a linked list with each context
141         having it's own linked list of extensions - one item per
142         priority.
143 */
144 struct ast_exten {
145         char *exten;                    /*!< Extension name */
146         int matchcid;                   /*!< Match caller id ? */
147         const char *cidmatch;           /*!< Caller id to match for this extension */
148         int priority;                   /*!< Priority */
149         const char *label;              /*!< Label */
150         struct ast_context *parent;     /*!< The context this extension belongs to  */
151         const char *app;                /*!< Application to execute */
152         struct ast_app *cached_app;     /*!< Cached location of application */
153         void *data;                     /*!< Data to use (arguments) */
154         void (*datad)(void *);          /*!< Data destructor */
155         struct ast_exten *peer;         /*!< Next higher priority with our extension */
156         const char *registrar;          /*!< Registrar */
157         struct ast_exten *next;         /*!< Extension with a greater ID */
158         char stuff[0];
159 };
160
161
162 /*! \brief ast_include: include= support in extensions.conf */
163 struct ast_include {
164         const char *name;
165         const char *rname;                      /*!< Context to include */
166         const char *registrar;                  /*!< Registrar */
167         int hastime;                            /*!< If time construct exists */
168         struct ast_timing timing;               /*!< time construct */
169         struct ast_include *next;               /*!< Link them together */
170         char stuff[0];
171 };
172
173 /*! \brief ast_sw: Switch statement in extensions.conf */
174 struct ast_sw {
175         char *name;
176         const char *registrar;                  /*!< Registrar */
177         char *data;                             /*!< Data load */
178         int eval;
179         AST_LIST_ENTRY(ast_sw) list;
180         char *tmpdata;
181         char stuff[0];
182 };
183
184 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
185 struct ast_ignorepat {
186         const char *registrar;
187         struct ast_ignorepat *next;
188         const char pattern[0];
189 };
190
191 /*! \brief ast_context: An extension context */
192 struct ast_context {
193         ast_rwlock_t lock;                      /*!< A lock to prevent multiple threads from clobbering the context */
194         struct ast_exten *root;                 /*!< The root of the list of extensions */
195         struct ast_context *next;               /*!< Link them together */
196         struct ast_include *includes;           /*!< Include other contexts */
197         struct ast_ignorepat *ignorepats;       /*!< Patterns for which to continue playing dialtone */
198         const char *registrar;                  /*!< Registrar */
199         AST_LIST_HEAD_NOLOCK(, ast_sw) alts;    /*!< Alternative switches */
200         ast_mutex_t macrolock;                  /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
201         char name[0];                           /*!< Name of the context */
202 };
203
204
205 /*! \brief ast_app: A registered application */
206 struct ast_app {
207         int (*execute)(struct ast_channel *chan, void *data);
208         const char *synopsis;                   /*!< Synopsis text for 'show applications' */
209         const char *description;                /*!< Description (help text) for 'show application &lt;name&gt;' */
210         AST_RWLIST_ENTRY(ast_app) list;         /*!< Next app in list */
211         struct module *module;                  /*!< Module this app belongs to */
212         char name[0];                           /*!< Name of the application */
213 };
214
215 /*! \brief ast_state_cb: An extension state notify register item */
216 struct ast_state_cb {
217         int id;
218         void *data;
219         ast_state_cb_type callback;
220         struct ast_state_cb *next;
221 };
222
223 /*! \brief Structure for dial plan hints
224
225   \note Hints are pointers from an extension in the dialplan to one or
226   more devices (tech/name) 
227         - See \ref AstExtState
228 */
229 struct ast_hint {
230         struct ast_exten *exten;        /*!< Extension */
231         int laststate;                  /*!< Last known state */
232         struct ast_state_cb *callbacks; /*!< Callback list for this extension */
233         AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
234 };
235
236 struct store_hint {
237         char *context;
238         char *exten;
239         struct ast_state_cb *callbacks;
240         int laststate;
241         AST_LIST_ENTRY(store_hint) list;
242         char data[1];
243 };
244
245 AST_LIST_HEAD(store_hints, store_hint);
246
247 static const struct cfextension_states {
248         int extension_state;
249         const char * const text;
250 } extension_states[] = {
251         { AST_EXTENSION_NOT_INUSE,                     "Idle" },
252         { AST_EXTENSION_INUSE,                         "InUse" },
253         { AST_EXTENSION_BUSY,                          "Busy" },
254         { AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
255         { AST_EXTENSION_RINGING,                       "Ringing" },
256         { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
257         { AST_EXTENSION_ONHOLD,                        "Hold" },
258         { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
259 };
260 #define STATUS_NO_CONTEXT       1
261 #define STATUS_NO_EXTENSION     2
262 #define STATUS_NO_PRIORITY      3
263 #define STATUS_NO_LABEL         4
264 #define STATUS_SUCCESS          5
265
266 extern struct ast_context *local_contexts;
267 extern struct ast_context *contexts;
268
269
270 struct ast_custom_function *ast_custom_function_find(const char *name);
271
272
273 struct ast_custom_function *ast_custom_function_find(const char *name)
274 {
275         return 0; /* in "standalone" mode, functions are just not avail */
276 }
277
278
279 struct profile_entry {
280         const char *name;
281         uint64_t        scale;  /* if non-zero, values are scaled by this */
282         int64_t mark;
283         int64_t value;
284         int64_t events;
285 };
286
287 struct profile_data {
288         int entries;
289         int max_size;
290         struct profile_entry e[0];
291 };
292
293 static int bit_at(unsigned int *word, int bitsperword, int bitnum)
294 {
295         return word[bitnum/bitsperword] & (1 << (bitnum % bitsperword));
296 }
297
298 void get_start_stop(unsigned int *word, int bitsperword, int totalbits, int *start, int *end)
299 {
300         int i;
301         int thisbit, thatbit = bit_at(word, bitsperword, totalbits-1);
302         
303         for (i=0; i<totalbits; i++) {
304                 thisbit = bit_at(word, bitsperword, i);
305                 
306                 if (thisbit != thatbit ) {
307                         if (thisbit) {
308                                 *start = i;
309                         } else {
310                                 *end = i;
311                         }
312                 }
313                 thatbit = thisbit;
314         }
315 }
316
317 int all_bits_set(unsigned int *word, int bitsperword, int totalbits )
318 {
319         
320         int i, total=totalbits/bitsperword,bitmask = 0;
321         
322         for (i=0; i<bitsperword; i++)
323         {
324                 bitmask |= (1 << i);
325         }
326         
327         for (i=0; i<total; i++)
328         {
329                 if (word[i] != bitmask)
330                         return 0;
331         }
332         return 1;
333 }
334
335
336 int main(int argc, char **argv)
337 {
338         struct ast_context *tmp;
339         struct ast_exten *e, *eroot;
340         pval *tree, *tmptree, *sws;
341         struct ast_include *tmpi;
342         struct ast_sw *sw = 0;
343         struct ast_ignorepat *ipi;
344         pval *incl=0;
345         int localdir = 0, i;
346
347         tree = 0;
348         tmptree = 0;
349
350         /* process the command line args */
351         for (i=1; i<argc; i++)
352         {
353                 if (strcmp(argv[i],"-d")==0)
354                         localdir =1;
355         }
356         
357         /* 3 simple steps: */
358         /*   1. read in the extensions.conf config file 
359          *   2. traverse, and build an AEL tree
360          *   3. Output the AEL tree into a file
361          */
362         printf("WARNING: This is an EXTREMELY preliminary version of a program\n");
363         printf("         that will someday hopefully do a thoughful and intelligent\n");
364         printf("         job of transforming your extensions.conf file into an\n");
365         printf("         extensions.ael file.\n");
366         printf("         This version has absolutely no intelligence, and pretty\n");
367         printf("         much just does a direct conversion\n");
368         printf("         The result will most likely need careful attention to\n");
369         printf("         finish the job!!!!!\n");
370
371         if (!localdir)
372                 printf(" (You could use -d the use the extensions.conf in the current directory!)\n");
373
374         printf("Loading %s/%s...\n", ast_config_AST_CONFIG_DIR, config);
375
376         if (!localdir)
377                 localized_use_conf_dir();
378         localized_pbx_load_module();
379         
380         printf("... Done!\n");
381         
382         tmp = 0;
383         while ((tmp = localized_walk_contexts(tmp)) ) {
384                 printf("Context: %s\n", tmp->name);
385         }
386         printf("=========\n");
387         tmp = 0;
388         while ((tmp = localized_walk_contexts(tmp)) ) {
389                 /* printf("Context: %s\n", tmp->name); */
390                 tmptree = pvalCreateNode(PV_CONTEXT);
391                 if (!tree)
392                         tree = tmptree;
393                 else
394                         pvalTopLevAddObject(tree, tmptree);
395                 
396                 pvalContextSetName(tmptree, ast_strdup(tmp->name));
397                 
398                 if (tmp->includes) {
399                         incl = pvalCreateNode(PV_INCLUDES);
400                         pvalContextAddStatement(tmptree, incl);
401                         for (tmpi = tmp->includes; tmpi; ) { /* includes */
402                                 if (strchr(tmpi->name,'|')==0) {
403                                         if (tmpi->hastime)
404                                         {
405                                                 char timerange[15];
406                                                 char dowrange[10];
407                                                 char domrange[10];
408                                                 char monrange[10];
409                                                 int startbit=0, endbit=0;
410                                                 
411                                                 if (all_bits_set(tmpi->timing.minmask, 30, 720))
412                                                         strcpy(timerange, "*");
413                                                 else {
414                                                         int hr, min;
415                                                         char tbuf[20];
416                                                         get_start_stop(tmpi->timing.minmask, 30, 720, &startbit, &endbit);
417                                                         hr = startbit/30;
418                                                         min = (startbit % 30) * 2;
419                                                         sprintf(tbuf,"%02d:%02d", hr, min);
420                                                         strcpy(timerange, tbuf);
421                                                         hr = endbit/30;
422                                                         min = (endbit % 30) * 2;
423                                                         sprintf(tbuf,"%02d:%02d", hr, min);
424                                                         strcat(timerange,"-");
425                                                         strcat(timerange,tbuf);
426                                                 }
427                                                 
428                                                 if (all_bits_set(&tmpi->timing.dowmask, 7, 7))
429                                                         strcpy(dowrange, "*");
430                                                 else {
431                                                         get_start_stop(&tmpi->timing.dowmask, 7, 7, &startbit, &endbit);
432                                                         strcpy(dowrange, days[startbit]);
433                                                         strcat(dowrange,"-");
434                                                         strcat(dowrange, days[endbit]);
435                                                 }
436                                                 
437                                                 if (all_bits_set(&tmpi->timing.monthmask, 12, 12))
438                                                         strcpy(monrange, "*");
439                                                 else {
440                                                         get_start_stop(&tmpi->timing.monthmask, 12, 12, &startbit, &endbit);
441                                                         strcpy(monrange, months[startbit]);
442                                                         strcat(monrange,"-");
443                                                         strcat(monrange, months[endbit]);
444                                                 }
445                                                 
446                                                 if (all_bits_set(&tmpi->timing.daymask, 31, 31))
447                                                         strcpy(domrange, "*");
448                                                 else {
449                                                         char tbuf[20];
450                                                         get_start_stop(&tmpi->timing.daymask, 31, 31, &startbit, &endbit);
451                                                         sprintf(tbuf,"%d", startbit);
452                                                         strcpy(domrange, tbuf);
453                                                         strcat(domrange,"-");
454                                                         sprintf(tbuf,"%d", endbit);
455                                                         strcat(domrange, tbuf);
456                                                 }
457                                                 /* now all 4 fields are set; what do we do? */
458                                                 pvalIncludesAddIncludeWithTimeConstraints(incl, strdup(tmpi->name), strdup(timerange), strdup(domrange), strdup(dowrange), strdup(monrange));
459                                                 
460                                         } else {
461                                                 pvalIncludesAddInclude(incl, strdup(tmpi->name));
462                                         }
463                                 } else { /* it appears the timing constraint info is tacked onto the name, carve it up and divvy it out */
464                                         char *dow,*dom,*mon;
465                                         char *all = strdup(tmpi->name);
466                                         char *hr = strchr(all,'|');
467                                         if (hr) {
468                                                 *hr++ = 0;
469                                                 dow = strchr(hr,'|');
470                                                 if (dow) {
471                                                         *dow++ = 0;
472                                                         dom = strchr(dow,'|');
473                                                         if (dom) {
474                                                                 *dom++ = 0;
475                                                                 mon = strchr(dom,'|');
476                                                                 if (mon) {
477                                                                         *mon++ = 0;
478                                                                         /* now all 4 fields are set; what do we do? */
479                                                                         pvalIncludesAddIncludeWithTimeConstraints(incl, strdup(all), strdup(hr), strdup(dow), strdup(dom), strdup(mon));
480                                                                         /* the original data is always best to keep (no 2-min rounding) */
481                                                                 } else {
482                                                                         ast_log(LOG_ERROR,"No month spec attached to include!\n");
483                                                                 }
484                                                         } else {
485                                                                 ast_log(LOG_ERROR,"No day of month spec attached to include!\n");
486                                                         }
487                                                 } else {
488                                                         ast_log(LOG_ERROR,"No day of week spec attached to include!\n");
489                                                 }
490                                         }
491                                         free(all);
492                                 }
493                                 tmpi = tmpi->next;
494                         }
495                 }
496                 for (ipi = tmp->ignorepats; ipi; ) { /* ignorepats */
497                         incl = pvalCreateNode(PV_IGNOREPAT);
498                         pvalIgnorePatSetPattern(incl,(char *)ipi->pattern);
499                         pvalContextAddStatement(tmptree, incl);
500                         ipi = ipi->next;
501                 }
502                 eroot=0;
503                 while ( (eroot = localized_walk_context_extensions(tmp, eroot)) ) {
504                         pval *exten = pvalCreateNode(PV_EXTENSION);
505                         pvalContextAddStatement(tmptree, exten);
506                         pvalExtenSetName(exten, ast_strdup(eroot->exten));
507                 
508                         if (eroot->peer) {
509                                 pval *block = pvalCreateNode(PV_STATEMENTBLOCK);
510                                 pvalExtenSetStatement(exten, block);
511                                 
512                                 e = 0;
513                                 while ( (e = localized_walk_extension_priorities(eroot, e)) ) {
514                                         
515                                         pval *statemnt = pvalCreateNode(PV_APPLICATION_CALL);
516                                         pval *args = pvalCreateNode(PV_WORD);
517                                         
518                                         /* printf("           %s(%s)\n", e->app, (char*)e->data); */
519
520                                         pvalAppCallSetAppName(statemnt, ast_strdup(e->app));
521                                         pvalWordSetString(args, ast_strdup(e->data));
522                                         pvalAppCallAddArg(statemnt, args);
523                                         
524                                         pvalStatementBlockAddStatement(block, statemnt);
525                                 }
526                         } else if (eroot->priority == -1) {
527
528                                 pval *statemnt = pvalCreateNode(PV_APPLICATION_CALL);
529                                 pval *args = pvalCreateNode(PV_WORD);
530
531                                 /* printf("Mike, we have a hint on exten %s with data %s\n", eroot->exten, eroot->app); */
532
533                                 pvalAppCallSetAppName(statemnt, "NoOp");
534                                 pvalWordSetString(args, ast_strdup(eroot->app));
535
536
537                                 pvalExtenSetStatement(exten, statemnt);
538                                 pvalExtenSetHints(exten, ast_strdup(eroot->app));
539                         } else {
540
541                                 pval *statemnt = pvalCreateNode(PV_APPLICATION_CALL);
542                                 pval *args = pvalCreateNode(PV_WORD);
543         
544                                 /* printf("           %s (%s)\n", eroot->app, (char *)eroot->data); */
545                                 
546                                 pvalAppCallSetAppName(statemnt, ast_strdup(eroot->app));
547                                 pvalWordSetString(args, ast_strdup(eroot->data));
548
549                                 
550                                 pvalAppCallAddArg(statemnt, args);
551                                 pvalExtenSetStatement(exten, statemnt);
552                         }
553
554                         /* printf("   extension: %s\n", eroot->exten); */
555                 }
556                 if (AST_LIST_FIRST(&tmp->alts)) {
557                         sws = pvalCreateNode(PV_SWITCHES);
558                         pvalContextAddStatement(tmptree,sws);
559                         
560                         sw = 0;
561                         while ((sw = localized_walk_context_switches(tmp,sw)) ) {
562                                 pvalSwitchesAddSwitch(sws, ast_strdup(sw->name));
563                         }
564                 }
565         }
566         printf("Generating aelout.ael file...\n");
567         
568         ael2_print("aelout.ael", tree);
569         
570         printf("...Done!\n");
571         return 0;
572 }
573
574
575 /* ==================================== for linking internal stuff to external stuff */
576
577 int pbx_builtin_setvar(struct ast_channel *chan, const char *data)
578 {
579         return localized_pbx_builtin_setvar(chan, data);
580 }
581
582 void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
583 void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count)
584 {
585         if (cp1 && *cp1)
586                 strncpy(cp2,cp1,AST_MAX_EXTENSION); /* Right now, this routine is ONLY being called for 
587                                                                                            a possible var substitution on extension names,
588                                                                                            so....! */
589         else
590                 *cp2 = 0;
591 }
592
593 int ast_add_extension2(struct ast_context *con,
594                                            int replace, const char *extension, int priority, const char *label, const char *callerid,
595                                            const char *application, void *data, void (*datad)(void *),
596                                            const char *registrar)
597 {
598         return localized_add_extension2(con, replace, extension, priority, label, callerid, application, data, datad, registrar);
599 }
600
601 int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
602 {
603         
604         return localized_context_add_ignorepat2(con, value, registrar);
605 }
606
607 int ast_context_add_switch2(struct ast_context *con, const char *value,
608                                                                  const char *data, int eval, const char *registrar)
609 {
610         
611         return localized_context_add_switch2(con, value, data, eval, registrar);
612 }
613
614 int ast_context_add_include2(struct ast_context *con, const char *value,
615                                                                   const char *registrar)
616 {
617         
618         return localized_context_add_include2(con, value,registrar);
619 }
620
621 struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
622 {
623         printf("find/Creating context %s, registrar=%s\n", name, registrar);
624         
625         return localized_context_find_or_create(extcontexts, exttable, name, registrar);
626 }
627
628 void ast_cli_register_multiple(void);
629
630 void ast_cli_register_multiple(void)
631 {
632 }
633
634 void ast_module_register(const struct ast_module_info *x)
635 {
636 }
637
638 void ast_module_unregister(const struct ast_module_info *x)
639 {
640 }
641
642 void ast_cli_unregister_multiple(void);
643
644 void ast_cli_unregister_multiple(void)
645 {
646 }
647
648 struct ast_context *ast_walk_contexts(struct ast_context *con);
649 struct ast_context *ast_walk_contexts(struct ast_context *con)
650 {
651         return localized_walk_contexts(con);
652 }
653
654 void ast_context_destroy(struct ast_context *con, const char *registrar);
655
656 void ast_context_destroy(struct ast_context *con, const char *registrar)
657 {
658         return localized_context_destroy(con, registrar);
659 }
660
661 int ast_context_verify_includes(struct ast_context *con);
662
663 int ast_context_verify_includes(struct ast_context *con)
664 {
665         return  localized_context_verify_includes(con);
666 }
667
668 void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar);
669
670 void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
671 {
672         localized_merge_contexts_and_delete(extcontexts, exttable, registrar);
673 }
674
675 const char *ast_get_context_name(struct ast_context *con);
676 const char *ast_get_context_name(struct ast_context *con)
677 {
678         return con ? con->name : NULL;
679 }
680
681 struct ast_exten *ast_walk_context_extensions(struct ast_context *con, struct ast_exten *exten);
682 struct ast_exten *ast_walk_context_extensions(struct ast_context *con, struct ast_exten *exten)
683 {
684         return NULL;
685 }
686
687 struct ast_include *ast_walk_context_includes(struct ast_context *con, struct ast_include *inc);
688 struct ast_include *ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
689 {
690         return NULL;
691 }
692
693 struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip);
694 struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
695 {
696         return NULL;
697 }
698
699 struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw);
700 struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
701 {
702         return NULL;
703 }
704
705 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
706                                                                          struct ast_context *bypass,
707                                                                          struct pbx_find_info *q,
708                                                                          const char *context, 
709                                                                          const char *exten, 
710                                                                          int priority,
711                                                                          const char *label, 
712                                                                          const char *callerid, 
713                                                                          enum ext_match_t action);
714
715 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
716                                                                          struct ast_context *bypass,
717                                                                          struct pbx_find_info *q,
718                                                                          const char *context, 
719                                                                          const char *exten, 
720                                                                          int priority,
721                                                                          const char *label, 
722                                                                          const char *callerid, 
723                                                                          enum ext_match_t action)
724 {
725         return localized_find_extension(bypass, q, context, exten, priority, label, callerid, action);
726 }
727
728 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b);
729
730 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
731 {
732         return 0;
733 }
734
735 unsigned int ast_hashtab_hash_contexts(const void *obj);
736
737 unsigned int ast_hashtab_hash_contexts(const void *obj)
738 {
739         return 0;
740 }
741
742 #ifdef DEBUG_THREADS
743 #if !defined(LOW_MEMORY)
744 void ast_mark_lock_acquired(void *lock_addr)
745 {
746 }
747 #ifdef HAVE_BKTR
748 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
749 {
750 }
751
752 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
753         int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
754 {
755 }
756
757 int __ast_bt_get_addresses(struct ast_bt *bt)
758 {
759         return 0;
760 }
761
762 char **__ast_bt_get_symbols(void **addresses, size_t num_frames)
763 {
764         char **foo = calloc(num_frames, sizeof(char *) + 1);
765         if (foo) {
766                 int i;
767                 for (i = 0; i < num_frames; i++) {
768                         foo[i] = (char *) foo + sizeof(char *) * num_frames;
769                 }
770         }
771         return foo;
772 }
773
774 #else
775 void ast_remove_lock_info(void *lock_addr)
776 {
777 }
778
779 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
780         int line_num, const char *func, const char *lock_name, void *lock_addr)
781 {
782 }
783 #endif /* HAVE_BKTR */
784 void ast_suspend_lock_info(void *lock_addr)
785 {
786 }
787 void ast_restore_lock_info(void *lock_addr)
788 {
789 }
790 #endif /* !defined(LOW_MEMORY) */
791 #endif /* DEBUG_THREADS */