Asterisk - The Open Source Telephony Project  GIT-master-a24979a
extconf.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2006, 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  * \file
22  * A condensation of the pbx_config stuff, to read into extensions.conf, and provide an interface to the data there,
23  * for operations outside of asterisk. A huge, awful hack.
24  *
25  */
26 
27 /*!
28  * \li \ref extconf.c uses the configuration file \ref extconfig.conf and \ref extensions.conf and \ref asterisk.conf
29  * \addtogroup configuration_file Configuration Files
30  */
31 
32 /*!
33  * \page extconfig.conf extconfig.conf
34  * \verbinclude extconfig.conf.sample
35  */
36 
37 /*!
38  * \page extensions.conf extensions.conf
39  * \verbinclude extensions.conf.sample
40  */
41 
42 /*** MODULEINFO
43  <support_level>extended</support_level>
44  ***/
45 
46 #define ASTMM_LIBC ASTMM_IGNORE
47 #include "asterisk.h"
48 
49 #undef DEBUG_THREADS
50 
51 #include "asterisk/compat.h"
52 #include "asterisk/paths.h" /* we use AST_CONFIG_DIR */
53 
54 #include <errno.h>
55 #include <time.h>
56 #include <sys/stat.h>
57 #include <sys/types.h>
58 #include <sys/time.h>
59 #include <sys/resource.h>
60 #include <sys/wait.h>
61 #include <stdarg.h>
62 #include <string.h>
63 #include <locale.h>
64 #include <ctype.h>
65 #if !defined(SOLARIS) && !defined(__CYGWIN__)
66 #include <err.h>
67 #endif
68 #include <regex.h>
69 #include <limits.h>
70 #include <pthread.h>
71 #include <netdb.h>
72 #include <sys/param.h>
73 #include <signal.h>
74 
75 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
76 void ast_verbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
77 
78 #define AST_API_MODULE 1 /* gimme the inline defs! */
79 struct ast_channel
80 {
81  char x; /* basically empty! */
82 };
83 
84 
85 
86 #include "asterisk/inline_api.h"
87 #include "asterisk/endian.h"
88 #include "asterisk/ast_expr.h"
89 #include "asterisk/extconf.h"
90 
91 /* logger.h */
92 
93 #define EVENTLOG "event_log"
94 #define QUEUELOG "queue_log"
95 
96 #define DEBUG_M(a) { \
97  a; \
98 }
99 
100 #define VERBOSE_PREFIX_1 " "
101 #define VERBOSE_PREFIX_2 " == "
102 #define VERBOSE_PREFIX_3 " -- "
103 #define VERBOSE_PREFIX_4 " > "
104 
105 void ast_log_backtrace(void);
106 
107 void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
108  __attribute__((format(printf, 5, 6)));
109 
110 /* IN CONFLICT: void ast_verbose(const char *fmt, ...)
111  __attribute__((format(printf, 1, 2))); */
112 
113 void ast_console_puts(const char *string);
114 
115 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
116 
117 #ifdef LOG_DEBUG
118 #undef LOG_DEBUG
119 #endif
120 #define __LOG_DEBUG 0
121 #define LOG_DEBUG __LOG_DEBUG, _A_
122 
123 #ifdef LOG_EVENT
124 #undef LOG_EVENT
125 #endif
126 #define __LOG_EVENT 1
127 #define LOG_EVENT __LOG_EVENT, _A_
128 
129 #ifdef LOG_NOTICE
130 #undef LOG_NOTICE
131 #endif
132 #define __LOG_NOTICE 2
133 #define LOG_NOTICE __LOG_NOTICE, _A_
134 
135 #ifdef LOG_WARNING
136 #undef LOG_WARNING
137 #endif
138 #define __LOG_WARNING 3
139 #define LOG_WARNING __LOG_WARNING, _A_
140 
141 #ifdef LOG_ERROR
142 #undef LOG_ERROR
143 #endif
144 #define __LOG_ERROR 4
145 #define LOG_ERROR __LOG_ERROR, _A_
146 
147 #ifdef LOG_VERBOSE
148 #undef LOG_VERBOSE
149 #endif
150 #define __LOG_VERBOSE 5
151 #define LOG_VERBOSE __LOG_VERBOSE, _A_
152 
153 #ifdef LOG_DTMF
154 #undef LOG_DTMF
155 #endif
156 #define __LOG_DTMF 6
157 #define LOG_DTMF __LOG_DTMF, _A_
158 
159 /* lock.h */
160 #define _ASTERISK_LOCK_H /* A small indication that this is horribly wrong. */
161 
162 #ifndef HAVE_MTX_PROFILE
163 #define __MTX_PROF(a) return pthread_mutex_lock((a))
164 #else
165 int mtx_prof = -1;
166 
167 #define __MTX_PROF(a) do { \
168  int i; \
169  /* profile only non-blocking events */ \
170  ast_mark(mtx_prof, 1); \
171  i = pthread_mutex_trylock((a)); \
172  ast_mark(mtx_prof, 0); \
173  if (!i) \
174  return i; \
175  else \
176  return pthread_mutex_lock((a)); \
177  } while (0)
178 #endif /* HAVE_MTX_PROFILE */
179 
180 #define AST_PTHREADT_NULL (pthread_t) -1
181 #define AST_PTHREADT_STOP (pthread_t) -2
182 
183 #if defined(SOLARIS) || defined(BSD)
184 #define AST_MUTEX_INIT_W_CONSTRUCTORS
185 #endif /* SOLARIS || BSD */
186 
187 /* Asterisk REQUIRES recursive (not error checking) mutexes
188  and will not run without them. */
189 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(PTHREAD_MUTEX_RECURSIVE_NP)
190 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
191 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
192 #else
193 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
194 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
195 #endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
196 
197 #ifdef DEBUG_THREADS
198 
199 #define log_mutex_error(canlog, ...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
200 
201 #ifdef THREAD_CRASH
202 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
203 #else
204 #define DO_THREAD_CRASH do { } while (0)
205 #endif
206 
207 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
208 
209 #define AST_MAX_REENTRANCY 10
210 
211 struct ast_mutex_info {
213  /*! Track which thread holds this lock */
214  unsigned int track:1;
215  const char *file[AST_MAX_REENTRANCY];
216  int lineno[AST_MAX_REENTRANCY];
217  int reentrancy;
218  const char *func[AST_MAX_REENTRANCY];
219  pthread_t thread[AST_MAX_REENTRANCY];
220 };
221 
222 typedef struct ast_mutex_info ast_mutex_t;
223 
224 typedef pthread_cond_t ast_cond_t;
225 
226 static pthread_mutex_t empty_mutex;
227 
228 static void __attribute__((constructor)) init_empty_mutex(void)
229 {
230  memset(&empty_mutex, 0, sizeof(empty_mutex));
231 }
232 
233 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
234  const char *mutex_name, ast_mutex_t *t,
235  pthread_mutexattr_t *attr)
236 {
237 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
238  int canlog = strcmp(filename, "logger.c");
239 
240  if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
241  if ((t->mutex) != (empty_mutex)) {
242  log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is already initialized.\n",
243  filename, lineno, func, mutex_name);
244  log_mutex_error(canlog, "%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
245  t->file[0], t->lineno[0], t->func[0], mutex_name);
246  DO_THREAD_CRASH;
247  return 0;
248  }
249  }
250 #endif
251 
252  t->file[0] = filename;
253  t->lineno[0] = lineno;
254  t->func[0] = func;
255  t->thread[0] = 0;
256  t->reentrancy = 0;
257 
258  return pthread_mutex_init(&t->mutex, attr);
259 }
260 
261 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
262  const char *mutex_name, ast_mutex_t *t)
263 {
264  static pthread_mutexattr_t attr;
265 
266  pthread_mutexattr_init(&attr);
267  pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
268 
269  return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
270 }
271 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
272 
273 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
274  const char *mutex_name, ast_mutex_t *t)
275 {
276  int res;
277  int canlog = strcmp(filename, "logger.c");
278 
279 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
280  if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
281  log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
282  filename, lineno, func, mutex_name);
283  }
284 #endif
285 
286  res = pthread_mutex_trylock(&t->mutex);
287  switch (res) {
288  case 0:
290  break;
291  case EINVAL:
292  log_mutex_error(canlog, "%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
293  filename, lineno, func, mutex_name);
294  break;
295  case EBUSY:
296  log_mutex_error(canlog, "%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
297  filename, lineno, func, mutex_name);
298  log_mutex_error(canlog, "%s line %d (%s): Error: '%s' was locked here.\n",
299  t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
300  break;
301  }
302 
303  if ((res = pthread_mutex_destroy(&t->mutex)))
304  log_mutex_error(canlog, "%s line %d (%s): Error destroying mutex: %s\n",
305  filename, lineno, func, strerror(res));
306 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
307  else
309 #endif
310  t->file[0] = filename;
311  t->lineno[0] = lineno;
312  t->func[0] = func;
313 
314  return res;
315 }
316 
317 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
318  const char* mutex_name, ast_mutex_t *t)
319 {
320  int res;
321  int canlog = strcmp(filename, "logger.c");
322 
323 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
324  if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
325  log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
326  filename, lineno, func, mutex_name);
327  ast_mutex_init(t);
328  }
329 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
330 
331 #ifdef DETECT_DEADLOCKS
332  {
333  time_t seconds = time(NULL);
334  time_t current;
335  do {
336 #ifdef HAVE_MTX_PROFILE
337  ast_mark(mtx_prof, 1);
338 #endif
339  res = pthread_mutex_trylock(&t->mutex);
340 #ifdef HAVE_MTX_PROFILE
341  ast_mark(mtx_prof, 0);
342 #endif
343  if (res == EBUSY) {
344  current = time(NULL);
345  if ((current - seconds) && (!((current - seconds) % 5))) {
346  log_mutex_error(canlog, "%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
347  filename, lineno, func, (int)(current - seconds), mutex_name);
348  log_mutex_error(canlog, "%s line %d (%s): '%s' was locked here.\n",
349  t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
350  t->func[t->reentrancy-1], mutex_name);
351  }
352  usleep(200);
353  }
354  } while (res == EBUSY);
355  }
356 #else
357 #ifdef HAVE_MTX_PROFILE
358  ast_mark(mtx_prof, 1);
359  res = pthread_mutex_trylock(&t->mutex);
360  ast_mark(mtx_prof, 0);
361  if (res)
362 #endif
363  res = pthread_mutex_lock(&t->mutex);
364 #endif /* DETECT_DEADLOCKS */
365 
366  if (!res) {
367  if (t->reentrancy < AST_MAX_REENTRANCY) {
368  t->file[t->reentrancy] = filename;
369  t->lineno[t->reentrancy] = lineno;
370  t->func[t->reentrancy] = func;
371  t->thread[t->reentrancy] = pthread_self();
372  t->reentrancy++;
373  } else {
374  log_mutex_error(canlog, "%s line %d (%s): '%s' really deep reentrancy!\n",
375  filename, lineno, func, mutex_name);
376  }
377  } else {
378  log_mutex_error(canlog, "%s line %d (%s): Error obtaining mutex: %s\n",
379  filename, lineno, func, strerror(errno));
380  DO_THREAD_CRASH;
381  }
382 
383  return res;
384 }
385 
386 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
387  const char* mutex_name, ast_mutex_t *t)
388 {
389  int res;
390  int canlog = strcmp(filename, "logger.c");
391 
392 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
393  if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
394  log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
395  filename, lineno, func, mutex_name);
396  ast_mutex_init(t);
397  }
398 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
399 
400  if (!(res = pthread_mutex_trylock(&t->mutex))) {
401  if (t->reentrancy < AST_MAX_REENTRANCY) {
402  t->file[t->reentrancy] = filename;
403  t->lineno[t->reentrancy] = lineno;
404  t->func[t->reentrancy] = func;
405  t->thread[t->reentrancy] = pthread_self();
406  t->reentrancy++;
407  } else {
408  log_mutex_error(canlog, "%s line %d (%s): '%s' really deep reentrancy!\n",
409  filename, lineno, func, mutex_name);
410  }
411  } else {
412  log_mutex_error(canlog, "%s line %d (%s): Warning: '%s' was locked here.\n",
413  t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
414  }
415 
416  return res;
417 }
418 
419 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
420  const char *mutex_name, ast_mutex_t *t)
421 {
422  int res;
423  int canlog = strcmp(filename, "logger.c");
424 
425 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
426  if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
427  log_mutex_error(canlog, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
428  filename, lineno, func, mutex_name);
429  }
430 #endif
431 
432  if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
433  log_mutex_error(canlog, "%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
434  filename, lineno, func, mutex_name);
435  log_mutex_error(canlog, "%s line %d (%s): '%s' was locked here.\n",
436  t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
437  DO_THREAD_CRASH;
438  }
439 
440  if (--t->reentrancy < 0) {
441  log_mutex_error(canlog, "%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
442  filename, lineno, func, mutex_name);
443  t->reentrancy = 0;
444  }
445 
446  if (t->reentrancy < AST_MAX_REENTRANCY) {
447  t->file[t->reentrancy] = NULL;
448  t->lineno[t->reentrancy] = 0;
449  t->func[t->reentrancy] = NULL;
450  t->thread[t->reentrancy] = 0;
451  }
452 
453  if ((res = pthread_mutex_unlock(&t->mutex))) {
454  log_mutex_error(canlog, "%s line %d (%s): Error releasing mutex: %s\n",
455  filename, lineno, func, strerror(res));
456  DO_THREAD_CRASH;
457  }
458 
459  return res;
460 }
461 
462 #else /* !DEBUG_THREADS */
463 
464 
466 
467 #define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
468 
469 static inline int ast_mutex_init(ast_mutex_t *pmutex)
470 {
471  pthread_mutexattr_t attr;
472 
473  pthread_mutexattr_init(&attr);
474  pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
475 
476  return pthread_mutex_init(pmutex, &attr);
477 }
478 
479 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
480 
482 
483 #endif /* !DEBUG_THREADS */
484 
485 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
486 /* If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
487  constructors/destructors to create/destroy mutexes. */
488 #define __AST_MUTEX_DEFINE(scope, mutex) \
489  scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
490 static void __attribute__((constructor)) init_##mutex(void) \
491 { \
492  ast_mutex_init(&mutex); \
493 }
494 #else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
495 /* By default, use static initialization of mutexes. */
496 #define __AST_MUTEX_DEFINE(scope, mutex) \
497  scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
498 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
499 
500 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
501 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
502 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
503 
504 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex)
505 
506 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
507 
508 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
509 
510 #ifndef __linux__
511 #define pthread_create __use_ast_pthread_create_instead__
512 #endif
513 
514 typedef pthread_rwlock_t ast_rwlock_t;
515 
516 static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
517 {
518  pthread_rwlockattr_t attr;
519 
520  pthread_rwlockattr_init(&attr);
521 
522 #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
523  pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
524 #endif
525 
526  return pthread_rwlock_init(prwlock, &attr);
527 }
528 
529 static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
530 {
531  return pthread_rwlock_destroy(prwlock);
532 }
533 
534 static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
535 {
536  return pthread_rwlock_unlock(prwlock);
537 }
538 
539 static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
540 {
541  return pthread_rwlock_rdlock(prwlock);
542 }
543 
544 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
545 {
546  return pthread_rwlock_wrlock(prwlock);
547 }
548 
549 /* Statically declared read/write locks */
550 
551 #ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
552 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
553  scope ast_rwlock_t rwlock; \
554 static void __attribute__((constructor)) init_##rwlock(void) \
555 { \
556  ast_rwlock_init(&rwlock); \
557 } \
558 static void __attribute__((destructor)) fini_##rwlock(void) \
559 { \
560  ast_rwlock_destroy(&rwlock); \
561 }
562 #else
563 #define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
564 #define __AST_RWLOCK_DEFINE(scope, rwlock) \
565  scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
566 #endif
567 
568 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
569 
570 /*
571  * Initial support for atomic instructions.
572  * For platforms that have it, use the native cpu instruction to
573  * implement them. For other platforms, resort to a 'slow' version
574  * (defined in utils.c) that protects the atomic instruction with
575  * a single lock.
576  * The slow versions is always available, for testing purposes,
577  * as ast_atomic_fetchadd_int_slow()
578  */
579 
580 #if defined(HAVE_OSX_ATOMICS)
581 #include "libkern/OSAtomic.h"
582 #endif
583 
584 /*! \brief Atomically add v to *p and return * the previous value of *p.
585  * This can be used to handle reference counts, and the return value
586  * can be used to generate unique identifiers.
587  */
588 
589 #if defined(HAVE_GCC_ATOMICS)
590 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
591 {
592  return __sync_fetch_and_add(p, v);
593 })
594 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
595 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
596 {
597  return OSAtomicAdd32(v, (int32_t *) p);
598 })
599 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
600 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
601 {
602  return OSAtomicAdd64(v, (int64_t *) p);
603 #elif defined (__i386__) || defined(__x86_64__)
604 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
605 {
606  __asm __volatile (
607  " lock xaddl %0, %1 ; "
608  : "+r" (v), /* 0 (result) */
609  "=m" (*p) /* 1 */
610  : "m" (*p)); /* 2 */
611  return (v);
612 })
613 #else
614 static int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
615 {
616  int ret;
617  ret = *p;
618  *p += v;
619  return ret;
620 }
621 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
622 {
623  return ast_atomic_fetchadd_int_slow(p, v);
624 })
625 #endif
626 
627 /*! \brief decrement *p by 1 and return true if the variable has reached 0.
628  * Useful e.g. to check if a refcount has reached 0.
629  */
630 #if defined(HAVE_GCC_ATOMICS)
631 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
632 {
633  return __sync_sub_and_fetch(p, 1) == 0;
634 })
635 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
636 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
637 {
638  return OSAtomicAdd32( -1, (int32_t *) p) == 0;
639 })
640 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
641 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
642 {
643  return OSAtomicAdd64( -1, (int64_t *) p) == 0;
644 #else
645 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
646 {
647  int a = ast_atomic_fetchadd_int(p, -1);
648  return a == 1; /* true if the value is 0 now (so it was 1 previously) */
649 })
650 #endif
651 
652 #ifdef DEBUG_CHANNEL_LOCKS
653 /*! \brief Lock AST channel (and print debugging output)
654 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
655 int ast_channel_lock(struct ast_channel *chan);
656 
657 /*! \brief Unlock AST channel (and print debugging output)
658 \note You need to enable DEBUG_CHANNEL_LOCKS for this function
659 */
660 int ast_channel_unlock(struct ast_channel *chan);
661 
662 /*! \brief Lock AST channel (and print debugging output)
663 \note You need to enable DEBUG_CHANNEL_LOCKS for this function */
664 int ast_channel_trylock(struct ast_channel *chan);
665 #endif
666 
667 
668 #include "asterisk/hashtab.h"
669 #include "asterisk/ael_structs.h"
670 #include "asterisk/pval.h"
671 
672 /* from utils.h */
673 
674 struct ast_flags { /* stolen from utils.h */
675  unsigned int flags;
676 };
677 #define ast_test_flag(p,flag) ({ \
678  typeof ((p)->flags) __p = (p)->flags; \
679  unsigned int __x = 0; \
680  (void) (&__p == &__x); \
681  ((p)->flags & (flag)); \
682  })
683 
684 #define ast_set2_flag(p,value,flag) do { \
685  typeof ((p)->flags) __p = (p)->flags; \
686  unsigned int __x = 0; \
687  (void) (&__p == &__x); \
688  if (value) \
689  (p)->flags |= (flag); \
690  else \
691  (p)->flags &= ~(flag); \
692  } while (0)
693 
694 /* from config.c */
695 
696 #define MAX_NESTED_COMMENTS 128
697 #define COMMENT_START ";--"
698 #define COMMENT_END "--;"
699 #define COMMENT_META ';'
700 #define COMMENT_TAG '-'
701 
702 static char *extconfig_conf = "extconfig.conf";
703 
704 /*! Growable string buffer */
705 static char *comment_buffer; /*!< this will be a comment collector.*/
706 static int comment_buffer_size; /*!< the amount of storage so far alloc'd for the comment_buffer */
707 
708 static char *lline_buffer; /*!< A buffer for stuff behind the ; */
709 static int lline_buffer_size;
710 
711 #define CB_INCR 250
712 
713 struct ast_comment {
714  struct ast_comment *next;
715  char cmt[0];
716 };
717 
718 static void CB_INIT(void)
719 {
720  if (!comment_buffer) {
722  if (!comment_buffer)
723  return;
724  comment_buffer[0] = 0;
727  if (!lline_buffer)
728  return;
729  lline_buffer[0] = 0;
731  } else {
732  comment_buffer[0] = 0;
733  lline_buffer[0] = 0;
734  }
735 }
736 
737 static void CB_ADD(char *str)
738 {
739  int rem = comment_buffer_size - strlen(comment_buffer) - 1;
740  int siz = strlen(str);
741  if (rem < siz+1) {
743  if (!comment_buffer)
744  return;
745  comment_buffer_size += CB_INCR+siz+1;
746  }
747  strcat(comment_buffer,str);
748 }
749 
750 static void CB_ADD_LEN(char *str, int len)
751 {
752  int cbl = strlen(comment_buffer) + 1;
753  int rem = comment_buffer_size - cbl;
754  if (rem < len+1) {
756  if (!comment_buffer)
757  return;
759  }
760  strncat(comment_buffer,str,len); /* safe */
761  comment_buffer[cbl+len-1] = 0;
762 }
763 
764 static void LLB_ADD(char *str)
765 {
766  int rem = lline_buffer_size - strlen(lline_buffer) - 1;
767  int siz = strlen(str);
768  if (rem < siz+1) {
770  if (!lline_buffer)
771  return;
772  lline_buffer_size += CB_INCR + siz + 1;
773  }
774  strcat(lline_buffer,str);
775 }
776 
777 static void CB_RESET(void )
778 {
779  comment_buffer[0] = 0;
780  lline_buffer[0] = 0;
781 }
782 
783 /*! \brief Keep track of how many threads are currently trying to wait*() on
784  * a child process */
785 static unsigned int safe_system_level = 0;
786 static struct sigaction safe_system_prev_handler;
787 
788 /*! \brief NULL handler so we can collect the child exit status */
789 static void _null_sig_handler(int sig)
790 {
791 
792 }
793 
794 static struct sigaction null_sig_handler = {
795  .sa_handler = _null_sig_handler,
796  .sa_flags = SA_RESTART,
797 };
798 
799 void ast_replace_sigchld(void);
800 
802 {
803  unsigned int level;
804 
805  level = safe_system_level++;
806 
807  /* only replace the handler if it has not already been done */
808  if (level == 0) {
809  sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
810  }
811 }
812 
813 void ast_unreplace_sigchld(void);
814 
816 {
817  unsigned int level;
818 
819  level = --safe_system_level;
820 
821  /* only restore the handler if we are the last one */
822  if (level == 0) {
823  sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
824  }
825 }
826 
827 int ast_safe_system(const char *s);
828 
829 int ast_safe_system(const char *s)
830 {
831  pid_t pid;
832 #ifdef HAVE_WORKING_FORK
833  int x;
834 #endif
835  int res;
836  int status;
837 
838 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
840 
841 #ifdef HAVE_WORKING_FORK
842  pid = fork();
843 #else
844  pid = vfork();
845 #endif
846 
847  if (pid == 0) {
848 #ifdef HAVE_WORKING_FORK
849  /* Close file descriptors and launch system command */
850  for (x = STDERR_FILENO + 1; x < 4096; x++)
851  close(x);
852 #endif
853  execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
854  _exit(1);
855  } else if (pid > 0) {
856  for(;;) {
857  res = waitpid(pid, &status, 0);
858  if (res > -1) {
859  res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
860  break;
861  } else if (errno != EINTR)
862  break;
863  }
864  } else {
865  ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
866  res = -1;
867  }
868 
870 #else
871  res = -1;
872 #endif
873 
874  return res;
875 }
876 
877 static struct ast_comment *ALLOC_COMMENT(const char *buffer)
878 {
879  struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
880  strcpy(x->cmt, buffer);
881  return x;
882 }
883 
884 static struct ast_config_map {
885  struct ast_config_map *next;
886  char *name;
887  char *driver;
888  char *database;
889  char *table;
890  char stuff[0];
892 
894 
895 #define MAX_INCLUDE_LEVEL 10
896 
897 
898 struct ast_category {
899  char name[80];
900  int ignored; /*!< do not let user of the config see this category */
901  int include_level;
902  char *file; /*!< the file name from whence this declaration was read */
903  int lineno;
904  struct ast_comment *precomments;
905  struct ast_comment *sameline;
906  struct ast_variable *root;
907  struct ast_variable *last;
908  struct ast_category *next;
909 };
910 
911 struct ast_config {
912  struct ast_category *root;
913  struct ast_category *last;
914  struct ast_category *current;
915  struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
916  int include_level;
917  int max_include_level;
918  struct ast_config_include *includes; /*!< a list of inclusions, which should describe the entire tree */
919 };
920 
921 struct ast_config_include {
922  char *include_location_file; /*!< file name in which the include occurs */
923  int include_location_lineno; /*!< lineno where include occurred */
924  int exec; /*!< set to non-zero if itsa #exec statement */
925  char *exec_file; /*!< if it's an exec, you'll have both the /var/tmp to read, and the original script */
926  char *included_file; /*!< file name included */
927  int inclusion_count; /*!< if the file is included more than once, a running count thereof -- but, worry not,
928  we explode the instances and will include those-- so all entries will be unique */
929  int output; /*!< a flag to indicate if the inclusion has been output */
930  struct ast_config_include *next; /*!< ptr to next inclusion in the list */
931 };
932 
933 typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments, const char *suggested_include_file);
934 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
935 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
936 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
937 
938 /*! \brief Configuration engine structure, used to define realtime drivers */
939 struct ast_config_engine {
940  char *name;
945  struct ast_config_engine *next;
946 };
947 
949 
950 /* taken from strings.h */
951 
952 static force_inline int ast_strlen_zero(const char *s)
953 {
954  return (!s || (*s == '\0'));
955 }
956 
957 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
958 
960 void ast_copy_string(char *dst, const char *src, size_t size),
961 {
962  while (*src && size) {
963  *dst++ = *src++;
964  size--;
965  }
966  if (__builtin_expect(!size, 0))
967  dst--;
968  *dst = '\0';
969 }
970 )
971 
973 char *ast_skip_blanks(const char *str),
974 {
975  while (*str && *str < 33)
976  str++;
977  return (char *)str;
978 }
979 )
980 
981 /*!
982  \brief Trims trailing whitespace characters from a string.
983  \param str the input string
984  \return a pointer to the modified string
985  */
987 char *ast_trim_blanks(char *str),
988 {
989  char *work = str;
990 
991  if (work) {
992  work += strlen(work) - 1;
993  /* It's tempting to only want to erase after we exit this loop,
994  but since ast_trim_blanks *could* receive a constant string
995  (which we presumably wouldn't have to touch), we shouldn't
996  actually set anything unless we must, and it's easier just
997  to set each position to \0 than to keep track of a variable
998  for it */
999  while ((work >= str) && *work < 33)
1000  *(work--) = '\0';
1001  }
1002  return str;
1003 }
1005 
1006 /*!
1007  \brief Strip leading/trailing whitespace from a string.
1008  \param s The string to be stripped (will be modified).
1009  \return The stripped string.
1010 
1011  This functions strips all leading and trailing whitespace
1012  characters from the input string, and returns a pointer to
1013  the resulting string. The string is modified in place.
1014 */
1016 char *ast_strip(char *s),
1017 {
1018  s = ast_skip_blanks(s);
1019  if (s)
1020  ast_trim_blanks(s);
1021  return s;
1022 }
1024 
1025 
1026 /* from config.h */
1027 
1028 struct ast_variable {
1029  char *name;
1030  char *value;
1031  char *file;
1032  int lineno;
1033  int object; /*!< 0 for variable, 1 for object */
1034  int blanklines; /*!< Number of blanklines following entry */
1035  struct ast_comment *precomments;
1036  struct ast_comment *sameline;
1037  struct ast_variable *next;
1038  char stuff[0];
1039 };
1040 
1041 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
1042 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file);
1043 
1044 struct ast_config *localized_config_load_with_comments(const char *filename);
1045 static char *ast_category_browse(struct ast_config *config, const char *prev);
1046 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
1047 static void ast_variables_destroy(struct ast_variable *v);
1048 static void ast_config_destroy(struct ast_config *cfg);
1049 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size);
1050 static struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
1051 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
1052 
1053 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
1054 
1055 static struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename)
1056 {
1057  struct ast_variable *variable;
1058  int name_len = strlen(name) + 1;
1059  size_t value_len = strlen(value) + 1;
1060  size_t filename_len = strlen(filename) + 1;
1061 
1062  if ((variable = ast_calloc(1, name_len + value_len + filename_len + sizeof(*variable)))) {
1063  variable->name = variable->stuff;
1064  variable->value = variable->stuff + name_len;
1065  variable->file = variable->value + value_len;
1066  strcpy(variable->name,name);
1067  ast_copy_string(variable->value, value, value_len);
1068  ast_copy_string(variable->file, filename, filename_len);
1069  }
1070 
1071  return variable;
1072 }
1073 
1074 static struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
1075 {
1076  /* a file should be included ONCE. Otherwise, if one of the instances is changed,
1077  then all be changed. -- how do we know to include it? -- Handling modified
1078  instances is possible, I'd have
1079  to create a new master for each instance. */
1080  struct ast_config_include *inc;
1081 
1083  if (inc)
1084  {
1085  inc->inclusion_count++;
1086  snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
1087  ast_log(LOG_WARNING,"'%s', line %d: Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
1088  } else
1089  *real_included_file_name = 0;
1090 
1091  inc = ast_calloc(1,sizeof(struct ast_config_include));
1092  inc->include_location_file = ast_strdup(from_file);
1093  inc->include_location_lineno = from_lineno;
1094  if (!ast_strlen_zero(real_included_file_name))
1095  inc->included_file = ast_strdup(real_included_file_name);
1096  else
1098 
1099  inc->exec = is_exec;
1100  if (is_exec)
1101  inc->exec_file = ast_strdup(exec_file);
1102 
1103  /* attach this new struct to the conf struct */
1104  inc->next = conf->includes;
1105  conf->includes = inc;
1106 
1107  return inc;
1108 }
1109 
1110 void localized_ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
1111 {
1112  struct ast_config_include *incl;
1113  struct ast_category *cat;
1114  struct ast_variable *v;
1115 
1116  int from_len = strlen(from_file);
1117  int to_len = strlen(to_file);
1118 
1119  if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
1120  return;
1121 
1122  /* the manager code allows you to read in one config file, then
1123  write it back out under a different name. But, the new arrangement
1124  ties output lines to the file name. So, before you try to write
1125  the config file to disk, better riffle thru the data and make sure
1126  the file names are changed.
1127  */
1128  /* file names are on categories, includes (of course), and on variables. So,
1129  traverse all this and swap names */
1130 
1131  for (incl = conf->includes; incl; incl=incl->next) {
1132  if (strcmp(incl->include_location_file,from_file) == 0) {
1133  if (from_len >= to_len)
1134  strcpy(incl->include_location_file, to_file);
1135  else {
1136  free(incl->include_location_file);
1137  incl->include_location_file = strdup(to_file);
1138  }
1139  }
1140  }
1141  for (cat = conf->root; cat; cat = cat->next) {
1142  if (strcmp(cat->file,from_file) == 0) {
1143  if (from_len >= to_len)
1144  strcpy(cat->file, to_file);
1145  else {
1146  free(cat->file);
1147  cat->file = strdup(to_file);
1148  }
1149  }
1150  for (v = cat->root; v; v = v->next) {
1151  if (strcmp(v->file,from_file) == 0) {
1152  if (from_len >= to_len)
1153  strcpy(v->file, to_file);
1154  else {
1155  free(v->file);
1156  v->file = strdup(to_file);
1157  }
1158  }
1159  }
1160  }
1161 }
1162 
1164 {
1165  struct ast_config_include *x;
1166  for (x=conf->includes;x;x=x->next)
1167  {
1168  if (strcmp(x->included_file,included_file) == 0)
1169  return x;
1170  }
1171  return 0;
1172 }
1173 
1174 
1175 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
1176 
1177 static void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
1178 {
1179  if (!variable)
1180  return;
1181  if (category->last)
1182  category->last->next = variable;
1183  else
1184  category->root = variable;
1185  category->last = variable;
1186  while (category->last->next)
1187  category->last = category->last->next;
1188 }
1189 
1190 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored);
1191 
1192 static struct ast_category *category_get(const struct ast_config *config, const char *category_name, int ignored)
1193 {
1194  struct ast_category *cat;
1195 
1196  /* try exact match first, then case-insensitive match */
1197  for (cat = config->root; cat; cat = cat->next) {
1198  if (cat->name == category_name && (ignored || !cat->ignored))
1199  return cat;
1200  }
1201 
1202  for (cat = config->root; cat; cat = cat->next) {
1203  if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
1204  return cat;
1205  }
1206 
1207  return NULL;
1208 }
1209 
1210 static struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name)
1211 {
1212  return category_get(config, category_name, 0);
1213 }
1214 
1215 static struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category)
1216 {
1217  struct ast_category *cat = NULL;
1218 
1219  if (category && config->last_browse && (config->last_browse->name == category))
1220  cat = config->last_browse;
1221  else
1222  cat = ast_category_get(config, category);
1223 
1224  return (cat) ? cat->root : NULL;
1225 }
1226 
1227 static const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
1228 {
1229  struct ast_variable *v;
1230 
1231  if (category) {
1232  for (v = ast_variable_browse(config, category); v; v = v->next) {
1233  if (!strcasecmp(variable, v->name))
1234  return v->value;
1235  }
1236  } else {
1237  struct ast_category *cat;
1238 
1239  for (cat = config->root; cat; cat = cat->next)
1240  for (v = cat->root; v; v = v->next)
1241  if (!strcasecmp(variable, v->name))
1242  return v->value;
1243  }
1244 
1245  return NULL;
1246 }
1247 
1248 static struct ast_variable *variable_clone(const struct ast_variable *old)
1249 {
1250  struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
1251 
1252  if (new) {
1253  new->lineno = old->lineno;
1254  new->object = old->object;
1255  new->blanklines = old->blanklines;
1256  /* TODO: clone comments? */
1257  }
1258 
1259  return new;
1260 }
1261 
1262 static void ast_variables_destroy(struct ast_variable *v)
1263 {
1264  struct ast_variable *vn;
1265 
1266  while (v) {
1267  vn = v;
1268  v = v->next;
1269  free(vn);
1270  }
1271 }
1272 
1273 static void ast_includes_destroy(struct ast_config_include *incls)
1274 {
1275  struct ast_config_include *incl,*inclnext;
1276 
1277  for (incl=incls; incl; incl = inclnext) {
1278  inclnext = incl->next;
1279  if (incl->include_location_file)
1280  free(incl->include_location_file);
1281  if (incl->exec_file)
1282  free(incl->exec_file);
1283  if (incl->included_file)
1284  free(incl->included_file);
1285  free(incl);
1286  }
1287 }
1288 
1289 static void ast_config_destroy(struct ast_config *cfg)
1290 {
1291  struct ast_category *cat, *catn;
1292 
1293  if (!cfg)
1294  return;
1295 
1297 
1298  cat = cfg->root;
1299  while (cat) {
1301  catn = cat;
1302  cat = cat->next;
1303  free(catn);
1304  }
1305  free(cfg);
1306 }
1307 
1309  /*! Allow \#exec in config files */
1311  /*! Do not fork() */
1313  /*! Keep quiet */
1315  /*! Console mode */
1317  /*! Run in realtime Linux priority */
1319  /*! Initialize keys for RSA authentication */
1321  /*! Remote console */
1323  /*! Execute an asterisk CLI command upon startup */
1324  AST_OPT_FLAG_EXEC = (1 << 7),
1325  /*! Don't use termcap colors */
1327  /*! Are we fully started yet? */
1329  /*! Trascode via signed linear */
1331  /*! Dump core on a seg fault */
1333  /*! Cache sound files */
1335  /*! Display timestamp in CLI verbose output */
1337  /*! Override config */
1339  /*! Reconnect */
1341  /*! Transmit Silence during Record() and DTMF Generation */
1343  /*! Suppress some warnings */
1345  /*! Always fork, even if verbose or debug settings are non-zero */
1347  /*! Disable log/verbose output to remote consoles */
1348  AST_OPT_FLAG_MUTE = (1 << 22),
1349  /*! There is a per-file debug setting */
1351  /*! Terminal colors should be adjusted for a light-colored background */
1353  /*! Force black background */
1355 };
1356 
1357 /* options.h declares ast_options extern; I need it static? */
1358 #define AST_CACHE_DIR_LEN 512
1359 #define AST_FILENAME_MAX 80
1360 
1361 /*! These are the options that set by default when Asterisk starts */
1362 #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
1363 
1365 
1366 #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
1367 #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
1368 #define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
1369 #define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
1370 #define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
1371 #define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
1372 #define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
1373 #define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
1374 #define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
1375 #define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
1376 #define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
1377 #define ast_opt_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
1378 #define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
1379 #define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
1380 #define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
1381 #define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
1382 #define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
1383 #define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
1384 #define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
1385 #define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
1386 #define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
1387 
1388 extern int option_verbose;
1389 extern int option_debug; /*!< Debugging */
1390 extern int ast_option_maxcalls; /*!< Maximum number of simultaneous channels */
1391 extern double ast_option_maxload;
1392 extern char ast_defaultlanguage[];
1393 
1394 extern pid_t ast_mainpid;
1395 
1396 extern char record_cache_dir[AST_CACHE_DIR_LEN];
1397 extern char debug_filename[AST_FILENAME_MAX];
1398 
1399 extern int ast_language_is_prefix;
1400 
1401 
1402 
1403 /* linkedlists.h */
1404 
1405 /*!
1406  \brief Write locks a list.
1407  \param head This is a pointer to the list head structure
1408 
1409  This macro attempts to place an exclusive write lock in the
1410  list head structure pointed to by head.
1411  Returns non-zero on success, 0 on failure
1412 */
1413 #define AST_RWLIST_WRLOCK(head) \
1414  ast_rwlock_wrlock(&(head)->lock)
1415 
1416 /*!
1417  \brief Read locks a list.
1418  \param head This is a pointer to the list head structure
1419 
1420  This macro attempts to place a read lock in the
1421  list head structure pointed to by head.
1422  Returns non-zero on success, 0 on failure
1423 */
1424 #define AST_RWLIST_RDLOCK(head) \
1425  ast_rwlock_rdlock(&(head)->lock)
1426 
1427 /*!
1428  \brief Attempts to unlock a read/write based list.
1429  \param head This is a pointer to the list head structure
1430 
1431  This macro attempts to remove a read or write lock from the
1432  list head structure pointed to by head. If the list
1433  was not locked by this thread, this macro has no effect.
1434 */
1435 #define AST_RWLIST_UNLOCK(head) \
1436  ast_rwlock_unlock(&(head)->lock)
1437 
1438 /*!
1439  \brief Defines a structure to be used to hold a list of specified type.
1440  \param name This will be the name of the defined structure.
1441  \param type This is the type of each list entry.
1442 
1443  This macro creates a structure definition that can be used
1444  to hold a list of the entries of type \a type. It does not actually
1445  declare (allocate) a structure; to do that, either follow this
1446  macro with the desired name of the instance you wish to declare,
1447  or use the specified \a name to declare instances elsewhere.
1448 
1449  Example usage:
1450  \code
1451  static AST_LIST_HEAD(entry_list, entry) entries;
1452  \endcode
1453 
1454  This would define \c struct \c entry_list, and declare an instance of it named
1455  \a entries, all intended to hold a list of type \c struct \c entry.
1456 */
1457 #define AST_LIST_HEAD(name, type) \
1458 struct name { \
1459  struct type *first; \
1460  struct type *last; \
1461  ast_mutex_t lock; \
1462 }
1463 
1464 /*!
1465  \brief Defines a structure to be used to hold a read/write list of specified type.
1466  \param name This will be the name of the defined structure.
1467  \param type This is the type of each list entry.
1468 
1469  This macro creates a structure definition that can be used
1470  to hold a list of the entries of type \a type. It does not actually
1471  declare (allocate) a structure; to do that, either follow this
1472  macro with the desired name of the instance you wish to declare,
1473  or use the specified \a name to declare instances elsewhere.
1474 
1475  Example usage:
1476  \code
1477  static AST_RWLIST_HEAD(entry_list, entry) entries;
1478  \endcode
1479 
1480  This would define \c struct \c entry_list, and declare an instance of it named
1481  \a entries, all intended to hold a list of type \c struct \c entry.
1482 */
1483 #define AST_RWLIST_HEAD(name, type) \
1484 struct name { \
1485  struct type *first; \
1486  struct type *last; \
1487  ast_rwlock_t lock; \
1488 }
1489 
1490 /*!
1491  \brief Defines a structure to be used to hold a list of specified type (with no lock).
1492  \param name This will be the name of the defined structure.
1493  \param type This is the type of each list entry.
1494 
1495  This macro creates a structure definition that can be used
1496  to hold a list of the entries of type \a type. It does not actually
1497  declare (allocate) a structure; to do that, either follow this
1498  macro with the desired name of the instance you wish to declare,
1499  or use the specified \a name to declare instances elsewhere.
1500 
1501  Example usage:
1502  \code
1503  static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
1504  \endcode
1505 
1506  This would define \c struct \c entry_list, and declare an instance of it named
1507  \a entries, all intended to hold a list of type \c struct \c entry.
1508 */
1509 #define AST_LIST_HEAD_NOLOCK(name, type) \
1510 struct name { \
1511  struct type *first; \
1512  struct type *last; \
1513 }
1514 
1515 /*!
1516  \brief Defines initial values for a declaration of AST_LIST_HEAD
1517 */
1518 #define AST_LIST_HEAD_INIT_VALUE { \
1519  .first = NULL, \
1520  .last = NULL, \
1521  .lock = AST_MUTEX_INIT_VALUE, \
1522  }
1523 
1524 /*!
1525  \brief Defines initial values for a declaration of AST_RWLIST_HEAD
1526 */
1527 #define AST_RWLIST_HEAD_INIT_VALUE { \
1528  .first = NULL, \
1529  .last = NULL, \
1530  .lock = AST_RWLOCK_INIT_VALUE, \
1531  }
1532 
1533 /*!
1534  \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
1535 */
1536 #define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
1537  .first = NULL, \
1538  .last = NULL, \
1539  }
1540 
1541 /*!
1542  \brief Defines a structure to be used to hold a list of specified type, statically initialized.
1543  \param name This will be the name of the defined structure.
1544  \param type This is the type of each list entry.
1545 
1546  This macro creates a structure definition that can be used
1547  to hold a list of the entries of type \a type, and allocates an instance
1548  of it, initialized to be empty.
1549 
1550  Example usage:
1551  \code
1552  static AST_LIST_HEAD_STATIC(entry_list, entry);
1553  \endcode
1554 
1555  This would define \c struct \c entry_list, intended to hold a list of
1556  type \c struct \c entry.
1557 */
1558 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
1559 #define AST_LIST_HEAD_STATIC(name, type) \
1560 struct name { \
1561  struct type *first; \
1562  struct type *last; \
1563  ast_mutex_t lock; \
1564 } name; \
1565 static void __attribute__((constructor)) init_##name(void) \
1566 { \
1567  AST_LIST_HEAD_INIT(&name); \
1568 } \
1569 static void __attribute__((destructor)) fini_##name(void) \
1570 { \
1571  AST_LIST_HEAD_DESTROY(&name); \
1572 } \
1573 struct __dummy_##name
1574 #else
1575 #define AST_LIST_HEAD_STATIC(name, type) \
1576 struct name { \
1577  struct type *first; \
1578  struct type *last; \
1579  ast_mutex_t lock; \
1580 } name = AST_LIST_HEAD_INIT_VALUE
1581 #endif
1582 
1583 /*!
1584  \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
1585  \param name This will be the name of the defined structure.
1586  \param type This is the type of each list entry.
1587 
1588  This macro creates a structure definition that can be used
1589  to hold a list of the entries of type \a type, and allocates an instance
1590  of it, initialized to be empty.
1591 
1592  Example usage:
1593  \code
1594  static AST_RWLIST_HEAD_STATIC(entry_list, entry);
1595  \endcode
1596 
1597  This would define \c struct \c entry_list, intended to hold a list of
1598  type \c struct \c entry.
1599 */
1600 #ifndef AST_RWLOCK_INIT_VALUE
1601 #define AST_RWLIST_HEAD_STATIC(name, type) \
1602 struct name { \
1603  struct type *first; \
1604  struct type *last; \
1605  ast_rwlock_t lock; \
1606 } name; \
1607 static void __attribute__((constructor)) init_##name(void) \
1608 { \
1609  AST_RWLIST_HEAD_INIT(&name); \
1610 } \
1611 static void __attribute__((destructor)) fini_##name(void) \
1612 { \
1613  AST_RWLIST_HEAD_DESTROY(&name); \
1614 } \
1615 struct __dummy_##name
1616 #else
1617 #define AST_RWLIST_HEAD_STATIC(name, type) \
1618 struct name { \
1619  struct type *first; \
1620  struct type *last; \
1621  ast_rwlock_t lock; \
1622 } name = AST_RWLIST_HEAD_INIT_VALUE
1623 #endif
1624 
1625 /*!
1626  \brief Defines a structure to be used to hold a list of specified type, statically initialized.
1627 
1628  This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
1629 */
1630 #define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
1631 struct name { \
1632  struct type *first; \
1633  struct type *last; \
1634 } name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
1635 
1636 /*!
1637  \brief Initializes a list head structure with a specified first entry.
1638  \param head This is a pointer to the list head structure
1639  \param entry pointer to the list entry that will become the head of the list
1640 
1641  This macro initializes a list head structure by setting the head
1642  entry to the supplied value and recreating the embedded lock.
1643 */
1644 #define AST_LIST_HEAD_SET(head, entry) do { \
1645  (head)->first = (entry); \
1646  (head)->last = (entry); \
1647  ast_mutex_init(&(head)->lock); \
1648 } while (0)
1649 
1650 /*!
1651  \brief Initializes an rwlist head structure with a specified first entry.
1652  \param head This is a pointer to the list head structure
1653  \param entry pointer to the list entry that will become the head of the list
1654 
1655  This macro initializes a list head structure by setting the head
1656  entry to the supplied value and recreating the embedded lock.
1657 */
1658 #define AST_RWLIST_HEAD_SET(head, entry) do { \
1659  (head)->first = (entry); \
1660  (head)->last = (entry); \
1661  ast_rwlock_init(&(head)->lock); \
1662 } while (0)
1663 
1664 /*!
1665  \brief Initializes a list head structure with a specified first entry.
1666  \param head This is a pointer to the list head structure
1667  \param entry pointer to the list entry that will become the head of the list
1668 
1669  This macro initializes a list head structure by setting the head
1670  entry to the supplied value.
1671 */
1672 #define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
1673  (head)->first = (entry); \
1674  (head)->last = (entry); \
1675 } while (0)
1676 
1677 /*!
1678  \brief Declare a forward link structure inside a list entry.
1679  \param type This is the type of each list entry.
1680 
1681  This macro declares a structure to be used to link list entries together.
1682  It must be used inside the definition of the structure named in
1683  \a type, as follows:
1684 
1685  \code
1686  struct list_entry {
1687  ...
1688  AST_LIST_ENTRY(list_entry) list;
1689  }
1690  \endcode
1691 
1692  The field name \a list here is arbitrary, and can be anything you wish.
1693 */
1694 #define AST_LIST_ENTRY(type) \
1695 struct { \
1696  struct type *next; \
1697 }
1698 
1699 #define AST_RWLIST_ENTRY AST_LIST_ENTRY
1700 
1701 /*!
1702  \brief Returns the first entry contained in a list.
1703  \param head This is a pointer to the list head structure
1704  */
1705 #define AST_LIST_FIRST(head) ((head)->first)
1706 
1707 #define AST_RWLIST_FIRST AST_LIST_FIRST
1708 
1709 /*!
1710  \brief Returns the last entry contained in a list.
1711  \param head This is a pointer to the list head structure
1712  */
1713 #define AST_LIST_LAST(head) ((head)->last)
1714 
1715 #define AST_RWLIST_LAST AST_LIST_LAST
1716 
1717 /*!
1718  \brief Returns the next entry in the list after the given entry.
1719  \param elm This is a pointer to the current entry.
1720  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1721  used to link entries of this list together.
1722 */
1723 #define AST_LIST_NEXT(elm, field) ((elm)->field.next)
1724 
1725 #define AST_RWLIST_NEXT AST_LIST_NEXT
1726 
1727 /*!
1728  \brief Checks whether the specified list contains any entries.
1729  \param head This is a pointer to the list head structure
1730 
1731  Returns non-zero if the list has entries, zero if not.
1732  */
1733 #define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
1734 
1735 #define AST_RWLIST_EMPTY AST_LIST_EMPTY
1736 
1737 /*!
1738  \brief Loops over (traverses) the entries in a list.
1739  \param head This is a pointer to the list head structure
1740  \param var This is the name of the variable that will hold a pointer to the
1741  current list entry on each iteration. It must be declared before calling
1742  this macro.
1743  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1744  used to link entries of this list together.
1745 
1746  This macro is use to loop over (traverse) the entries in a list. It uses a
1747  \a for loop, and supplies the enclosed code with a pointer to each list
1748  entry as it loops. It is typically used as follows:
1749  \code
1750  static AST_LIST_HEAD(entry_list, list_entry) entries;
1751  ...
1752  struct list_entry {
1753  ...
1754  AST_LIST_ENTRY(list_entry) list;
1755  }
1756  ...
1757  struct list_entry *current;
1758  ...
1759  AST_LIST_TRAVERSE(&entries, current, list) {
1760  (do something with current here)
1761  }
1762  \endcode
1763  \warning If you modify the forward-link pointer contained in the \a current entry while
1764  inside the loop, the behavior will be unpredictable. At a minimum, the following
1765  macros will modify the forward-link pointer, and should not be used inside
1766  AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
1767  careful consideration of their consequences:
1768  \li AST_LIST_NEXT() (when used as an lvalue)
1769  \li AST_LIST_INSERT_AFTER()
1770  \li AST_LIST_INSERT_HEAD()
1771  \li AST_LIST_INSERT_TAIL()
1772 */
1773 #define AST_LIST_TRAVERSE(head,var,field) \
1774  for((var) = (head)->first; (var); (var) = (var)->field.next)
1775 
1776 #define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
1777 
1778 /*!
1779  \brief Loops safely over (traverses) the entries in a list.
1780  \param head This is a pointer to the list head structure
1781  \param var This is the name of the variable that will hold a pointer to the
1782  current list entry on each iteration. It must be declared before calling
1783  this macro.
1784  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1785  used to link entries of this list together.
1786 
1787  This macro is used to safely loop over (traverse) the entries in a list. It
1788  uses a \a for loop, and supplies the enclosed code with a pointer to each list
1789  entry as it loops. It is typically used as follows:
1790 
1791  \code
1792  static AST_LIST_HEAD(entry_list, list_entry) entries;
1793  ...
1794  struct list_entry {
1795  ...
1796  AST_LIST_ENTRY(list_entry) list;
1797  }
1798  ...
1799  struct list_entry *current;
1800  ...
1801  AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
1802  (do something with current here)
1803  }
1804  AST_LIST_TRAVERSE_SAFE_END;
1805  \endcode
1806 
1807  It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
1808  (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
1809  the \a current pointer without affecting the loop traversal.
1810 */
1811 #define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
1812  typeof((head)->first) __list_next; \
1813  typeof((head)->first) __list_prev = NULL; \
1814  typeof((head)->first) __new_prev = NULL; \
1815  for ((var) = (head)->first, __new_prev = (var), \
1816  __list_next = (var) ? (var)->field.next : NULL; \
1817  (var); \
1818  __list_prev = __new_prev, (var) = __list_next, \
1819  __new_prev = (var), \
1820  __list_next = (var) ? (var)->field.next : NULL \
1821  )
1822 
1823 #define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
1824 
1825 /*!
1826  \brief Removes the \a current entry from a list during a traversal.
1827  \param head This is a pointer to the list head structure
1828  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1829  used to link entries of this list together.
1830 
1831  \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
1832  block; it is used to unlink the current entry from the list without affecting
1833  the list traversal (and without having to re-traverse the list to modify the
1834  previous entry, if any).
1835  */
1836 #define AST_LIST_REMOVE_CURRENT(head, field) \
1837  __new_prev->field.next = NULL; \
1838  __new_prev = __list_prev; \
1839  if (__list_prev) \
1840  __list_prev->field.next = __list_next; \
1841  else \
1842  (head)->first = __list_next; \
1843  if (!__list_next) \
1844  (head)->last = __list_prev;
1845 
1846 #define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
1847 
1848 /*!
1849  \brief Inserts a list entry before the current entry during a traversal.
1850  \param head This is a pointer to the list head structure
1851  \param elm This is a pointer to the entry to be inserted.
1852  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1853  used to link entries of this list together.
1854 
1855  \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
1856  block.
1857  */
1858 #define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
1859  if (__list_prev) { \
1860  (elm)->field.next = __list_prev->field.next; \
1861  __list_prev->field.next = elm; \
1862  } else { \
1863  (elm)->field.next = (head)->first; \
1864  (head)->first = (elm); \
1865  } \
1866  __new_prev = (elm); \
1867 } while (0)
1868 
1869 #define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
1870 
1871 /*!
1872  \brief Closes a safe loop traversal block.
1873  */
1874 #define AST_LIST_TRAVERSE_SAFE_END }
1875 
1876 #define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
1877 
1878 /*!
1879  \brief Initializes a list head structure.
1880  \param head This is a pointer to the list head structure
1881 
1882  This macro initializes a list head structure by setting the head
1883  entry to \a NULL (empty list) and recreating the embedded lock.
1884 */
1885 #define AST_LIST_HEAD_INIT(head) { \
1886  (head)->first = NULL; \
1887  (head)->last = NULL; \
1888  ast_mutex_init(&(head)->lock); \
1889 }
1890 
1891 /*!
1892  \brief Initializes an rwlist head structure.
1893  \param head This is a pointer to the list head structure
1894 
1895  This macro initializes a list head structure by setting the head
1896  entry to \a NULL (empty list) and recreating the embedded lock.
1897 */
1898 #define AST_RWLIST_HEAD_INIT(head) { \
1899  (head)->first = NULL; \
1900  (head)->last = NULL; \
1901  ast_rwlock_init(&(head)->lock); \
1902 }
1903 
1904 /*!
1905  \brief Destroys an rwlist head structure.
1906  \param head This is a pointer to the list head structure
1907 
1908  This macro destroys a list head structure by setting the head
1909  entry to \a NULL (empty list) and destroying the embedded lock.
1910  It does not free the structure from memory.
1911 */
1912 #define AST_RWLIST_HEAD_DESTROY(head) { \
1913  (head)->first = NULL; \
1914  (head)->last = NULL; \
1915  ast_rwlock_destroy(&(head)->lock); \
1916 }
1917 
1918 /*!
1919  \brief Initializes a list head structure.
1920  \param head This is a pointer to the list head structure
1921 
1922  This macro initializes a list head structure by setting the head
1923  entry to \a NULL (empty list). There is no embedded lock handling
1924  with this macro.
1925 */
1926 #define AST_LIST_HEAD_INIT_NOLOCK(head) { \
1927  (head)->first = NULL; \
1928  (head)->last = NULL; \
1929 }
1930 
1931 /*!
1932  \brief Inserts a list entry after a given entry.
1933  \param head This is a pointer to the list head structure
1934  \param listelm This is a pointer to the entry after which the new entry should
1935  be inserted.
1936  \param elm This is a pointer to the entry to be inserted.
1937  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1938  used to link entries of this list together.
1939  */
1940 #define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
1941  (elm)->field.next = (listelm)->field.next; \
1942  (listelm)->field.next = (elm); \
1943  if ((head)->last == (listelm)) \
1944  (head)->last = (elm); \
1945 } while (0)
1946 
1947 #define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
1948 
1949 /*!
1950  \brief Inserts a list entry at the head of a list.
1951  \param head This is a pointer to the list head structure
1952  \param elm This is a pointer to the entry to be inserted.
1953  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1954  used to link entries of this list together.
1955  */
1956 #define AST_LIST_INSERT_HEAD(head, elm, field) do { \
1957  (elm)->field.next = (head)->first; \
1958  (head)->first = (elm); \
1959  if (!(head)->last) \
1960  (head)->last = (elm); \
1961 } while (0)
1962 
1963 #define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
1964 
1965 /*!
1966  \brief Appends a list entry to the tail of a list.
1967  \param head This is a pointer to the list head structure
1968  \param elm This is a pointer to the entry to be appended.
1969  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1970  used to link entries of this list together.
1971 
1972  Note: The link field in the appended entry is \b not modified, so if it is
1973  actually the head of a list itself, the entire list will be appended
1974  temporarily (until the next AST_LIST_INSERT_TAIL is performed).
1975  */
1976 #define AST_LIST_INSERT_TAIL(head, elm, field) do { \
1977  if (!(head)->first) { \
1978  (head)->first = (elm); \
1979  (head)->last = (elm); \
1980  } else { \
1981  (head)->last->field.next = (elm); \
1982  (head)->last = (elm); \
1983  } \
1984 } while (0)
1985 
1986 #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
1987 
1988 /*!
1989  \brief Appends a whole list to the tail of a list.
1990  \param head This is a pointer to the list head structure
1991  \param list This is a pointer to the list to be appended.
1992  \param field This is the name of the field (declared using AST_LIST_ENTRY())
1993  used to link entries of this list together.
1994  */
1995 #define AST_LIST_APPEND_LIST(head, list, field) do { \
1996  if (!(head)->first) { \
1997  (head)->first = (list)->first; \
1998  (head)->last = (list)->last; \
1999  } else { \
2000  (head)->last->field.next = (list)->first; \
2001  (head)->last = (list)->last; \
2002  } \
2003 } while (0)
2004 
2005 #define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
2006 
2007 /*!
2008  \brief Removes and returns the head entry from a list.
2009  \param head This is a pointer to the list head structure
2010  \param field This is the name of the field (declared using AST_LIST_ENTRY())
2011  used to link entries of this list together.
2012 
2013  Removes the head entry from the list, and returns a pointer to it.
2014  This macro is safe to call on an empty list.
2015  */
2016 #define AST_LIST_REMOVE_HEAD(head, field) ({ \
2017  typeof((head)->first) cur = (head)->first; \
2018  if (cur) { \
2019  (head)->first = cur->field.next; \
2020  cur->field.next = NULL; \
2021  if ((head)->last == cur) \
2022  (head)->last = NULL; \
2023  } \
2024  cur; \
2025  })
2026 
2027 #define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
2028 
2029 /*!
2030  \brief Removes a specific entry from a list.
2031  \param head This is a pointer to the list head structure
2032  \param elm This is a pointer to the entry to be removed.
2033  \param field This is the name of the field (declared using AST_LIST_ENTRY())
2034  used to link entries of this list together.
2035  \warning The removed entry is \b not freed nor modified in any way.
2036  */
2037 #define AST_LIST_REMOVE(head, elm, field) do { \
2038  if ((head)->first == (elm)) { \
2039  (head)->first = (elm)->field.next; \
2040  if ((head)->last == (elm)) \
2041  (head)->last = NULL; \
2042  } else { \
2043  typeof(elm) curelm = (head)->first; \
2044  while (curelm && (curelm->field.next != (elm))) \
2045  curelm = curelm->field.next; \
2046  if (curelm) { \
2047  curelm->field.next = (elm)->field.next; \
2048  if ((head)->last == (elm)) \
2049  (head)->last = curelm; \
2050  } \
2051  } \
2052  (elm)->field.next = NULL; \
2053 } while (0)
2054 
2055 #define AST_RWLIST_REMOVE AST_LIST_REMOVE
2056 
2057 /* chanvars.h */
2058 
2059 struct ast_var_t {
2061  char *value;
2062  char name[0];
2063 };
2064 
2066 
2069 
2070 
2071 /* IN CONFLICT: struct ast_var_t *ast_var_assign(const char *name, const char *value); */
2072 
2073 static struct ast_var_t *ast_var_assign(const char *name, const char *value);
2074 
2075 static void ast_var_delete(struct ast_var_t *var);
2076 
2077 /*from channel.h */
2078 #define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
2079 
2080 
2081 /* from pbx.h */
2082 #define PRIORITY_HINT -1 /*!< Special Priority for a hint */
2083 
2085  AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
2086  AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
2087  AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
2088  AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
2089  AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
2090  AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
2091  AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
2092  AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
2093 };
2094 
2095 struct ast_custom_function {
2096  const char *name; /*!< Name */
2097  const char *synopsis; /*!< Short description for "show functions" */
2098  const char *desc; /*!< Help text that explains it all */
2099  const char *syntax; /*!< Syntax description */
2100  int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
2101  int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
2103 };
2104 
2105 typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
2106  const char *exten, int priority, const char *callerid, const char *data);
2107 
2108 struct ast_switch {
2110  const char *name; /*!< Name of the switch */
2111  const char *description; /*!< Description of the switch */
2112 
2115  ast_switch_f *exec;
2117 };
2118 
2119 
2120 static char *config_filename = "extensions.conf";
2121 static char *global_registrar = "conf2ael";
2122 static char userscontext[AST_MAX_EXTENSION] = "default";
2123 static int static_config = 0;
2124 static int write_protect_config = 1;
2125 static int autofallthrough_config = 0;
2126 static int clearglobalvars_config = 0;
2127 static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
2128 
2129 
2130 /* stolen from callerid.c */
2131 
2132 /*! \brief Clean up phone string
2133  * remove '(', ' ', ')', non-trailing '.', and '-' not in square brackets.
2134  * Basically, remove anything that could be invalid in a pattern.
2135  */
2136 static void ast_shrink_phone_number(char *n)
2137 {
2138  int x, y=0;
2139  int bracketed = 0;
2140 
2141  for (x=0; n[x]; x++) {
2142  switch(n[x]) {
2143  case '[':
2144  bracketed++;
2145  n[y++] = n[x];
2146  break;
2147  case ']':
2148  bracketed--;
2149  n[y++] = n[x];
2150  break;
2151  case '-':
2152  if (bracketed)
2153  n[y++] = n[x];
2154  break;
2155  case '.':
2156  if (!n[x+1])
2157  n[y++] = n[x];
2158  break;
2159  default:
2160  if (!strchr("()", n[x]))
2161  n[y++] = n[x];
2162  }
2163  }
2164  n[y] = '\0';
2165 }
2166 
2167 
2168 /* stolen from chanvars.c */
2169 
2170 static const char *ast_var_name(const struct ast_var_t *var)
2171 {
2172  const char *name;
2173 
2174  if (var == NULL || (name = var->name) == NULL)
2175  return NULL;
2176  /* Return the name without the initial underscores */
2177  if (name[0] == '_') {
2178  name++;
2179  if (name[0] == '_')
2180  name++;
2181  }
2182  return name;
2183 }
2184 
2185 /* experiment 1: see if it's easier just to use existing config code
2186  * to read in the extensions.conf file. In this scenario,
2187  I have to rip/copy code from other modules, because they
2188  are staticly declared as-is. A solution would be to move
2189  the ripped code to another location and make them available
2190  to other modules and standalones */
2191 
2192 /* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
2193 
2194 static void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
2195 {
2196  va_list vars;
2197  va_start(vars,fmt);
2198 
2199  printf("LOG: lev:%d file:%s line:%d func: %s ",
2200  level, file, line, function);
2201  vprintf(fmt, vars);
2202  fflush(stdout);
2203  va_end(vars);
2204 }
2205 
2206 void __attribute__((format(printf, 1, 2))) ast_verbose(const char *fmt, ...)
2207 {
2208  va_list vars;
2209  va_start(vars,fmt);
2210 
2211  printf("VERBOSE: ");
2212  vprintf(fmt, vars);
2213  fflush(stdout);
2214  va_end(vars);
2215 }
2216 
2217 /* stolen from main/utils.c */
2218 static char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
2219 {
2220  char *dataPut = start;
2221  int inEscape = 0;
2222  int inQuotes = 0;
2223 
2224  for (; *start; start++) {
2225  if (inEscape) {
2226  *dataPut++ = *start; /* Always goes verbatim */
2227  inEscape = 0;
2228  } else {
2229  if (*start == '\\') {
2230  inEscape = 1; /* Do not copy \ into the data */
2231  } else if (*start == '\'') {
2232  inQuotes = 1 - inQuotes; /* Do not copy ' into the data */
2233  } else {
2234  /* Replace , with |, unless in quotes */
2235  *dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
2236  }
2237  }
2238  }
2239  if (start != dataPut)
2240  *dataPut = 0;
2241  return dataPut;
2242 }
2243 
2244 static int ast_true(const char *s)
2245 {
2246  if (ast_strlen_zero(s))
2247  return 0;
2248 
2249  /* Determine if this is a true value */
2250  if (!strcasecmp(s, "yes") ||
2251  !strcasecmp(s, "true") ||
2252  !strcasecmp(s, "y") ||
2253  !strcasecmp(s, "t") ||
2254  !strcasecmp(s, "1") ||
2255  !strcasecmp(s, "on"))
2256  return -1;
2257 
2258  return 0;
2259 }
2260 
2261 #define ONE_MILLION 1000000
2262 /*
2263  * put timeval in a valid range. usec is 0..999999
2264  * negative values are not allowed and truncated.
2265  */
2266 static struct timeval tvfix(struct timeval a)
2267 {
2268  if (a.tv_usec >= ONE_MILLION) {
2269  ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
2270  (long)a.tv_sec, (long int) a.tv_usec);
2271  a.tv_sec += a.tv_usec / ONE_MILLION;
2272  a.tv_usec %= ONE_MILLION;
2273  } else if (a.tv_usec < 0) {
2274  ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
2275  (long)a.tv_sec, (long int) a.tv_usec);
2276  a.tv_usec = 0;
2277  }
2278  return a;
2279 }
2280 
2281 struct timeval ast_tvadd(struct timeval a, struct timeval b);
2282 struct timeval ast_tvadd(struct timeval a, struct timeval b)
2283 {
2284  /* consistency checks to guarantee usec in 0..999999 */
2285  a = tvfix(a);
2286  b = tvfix(b);
2287  a.tv_sec += b.tv_sec;
2288  a.tv_usec += b.tv_usec;
2289  if (a.tv_usec >= ONE_MILLION) {
2290  a.tv_sec++;
2291  a.tv_usec -= ONE_MILLION;
2292  }
2293  return a;
2294 }
2295 
2296 struct timeval ast_tvsub(struct timeval a, struct timeval b);
2297 struct timeval ast_tvsub(struct timeval a, struct timeval b)
2298 {
2299  /* consistency checks to guarantee usec in 0..999999 */
2300  a = tvfix(a);
2301  b = tvfix(b);
2302  a.tv_sec -= b.tv_sec;
2303  a.tv_usec -= b.tv_usec;
2304  if (a.tv_usec < 0) {
2305  a.tv_sec-- ;
2306  a.tv_usec += ONE_MILLION;
2307  }
2308  return a;
2309 }
2310 #undef ONE_MILLION
2311 
2312 void ast_mark_lock_failed(void *lock_addr);
2313 void ast_mark_lock_failed(void *lock_addr)
2314 {
2315  /* Pretend to do something. */
2316 }
2317 
2318 /* stolen from pbx.c */
2319 #define VAR_BUF_SIZE 4096
2320 
2321 #define VAR_NORMAL 1
2322 #define VAR_SOFTTRAN 2
2323 #define VAR_HARDTRAN 3
2324 
2325 #define BACKGROUND_SKIP (1 << 0)
2326 #define BACKGROUND_NOANSWER (1 << 1)
2327 #define BACKGROUND_MATCHEXTEN (1 << 2)
2328 #define BACKGROUND_PLAYBACK (1 << 3)
2329 
2330 /*!
2331  \brief ast_exten: An extension
2332  The dialplan is saved as a linked list with each context
2333  having it's own linked list of extensions - one item per
2334  priority.
2335 */
2336 struct ast_exten {
2337  char *exten; /*!< Extension name */
2338  int matchcid; /*!< Match caller id ? */
2339  const char *cidmatch; /*!< Caller id to match for this extension */
2340  int priority; /*!< Priority */
2341  const char *label; /*!< Label */
2342  struct ast_context *parent; /*!< The context this extension belongs to */
2343  const char *app; /*!< Application to execute */
2344  struct ast_app *cached_app; /*!< Cached location of application */
2345  void *data; /*!< Data to use (arguments) */
2346  void (*datad)(void *); /*!< Data destructor */
2347  struct ast_exten *peer; /*!< Next higher priority with our extension */
2348  const char *registrar; /*!< Registrar */
2349  struct ast_exten *next; /*!< Extension with a greater ID */
2350  char stuff[0];
2351 };
2352 /* from pbx.h */
2353 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
2354 struct ast_timing {
2355  int hastime; /*!< If time construct exists */
2356  unsigned int monthmask; /*!< Mask for month */
2357  unsigned int daymask; /*!< Mask for date */
2358  unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
2359  unsigned int minmask[48]; /*!< Mask for minute */
2360  char *timezone; /*!< NULL, or zoneinfo style timezone */
2361 };
2362 /* end of pbx.h */
2363 /*! \brief ast_include: include= support in extensions.conf */
2364 struct ast_include {
2365  const char *name;
2366  const char *rname; /*!< Context to include */
2367  const char *registrar; /*!< Registrar */
2368  int hastime; /*!< If time construct exists */
2369  struct ast_timing timing; /*!< time construct */
2370  struct ast_include *next; /*!< Link them together */
2371  char stuff[0];
2372 };
2373 
2374 /*! \brief ast_sw: Switch statement in extensions.conf */
2375 struct ast_sw {
2376  char *name;
2377  const char *registrar; /*!< Registrar */
2378  char *data; /*!< Data load */
2379  int eval;
2381  char *tmpdata;
2382  char stuff[0];
2383 };
2384 
2385 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
2386 struct ast_ignorepat {
2387  const char *registrar;
2389  char pattern[0];
2390 };
2391 
2392 /*! \brief ast_context: An extension context */
2393 struct ast_context {
2394  ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
2395  struct ast_exten *root; /*!< The root of the list of extensions */
2396  struct ast_context *next; /*!< Link them together */
2397  struct ast_include *includes; /*!< Include other contexts */
2398  struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
2399  const char *registrar; /*!< Registrar */
2400  AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
2401  ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
2402  char name[0]; /*!< Name of the context */
2403 };
2404 
2405 
2406 /*! \brief ast_app: A registered application */
2407 struct ast_app {
2408  int (*execute)(struct ast_channel *chan, void *data);
2409  const char *synopsis; /*!< Synopsis text for 'show applications' */
2410  const char *description; /*!< Description (help text) for 'show application &lt;name&gt;' */
2411  AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
2412  void *module; /*!< Module this app belongs to */
2413  char name[0]; /*!< Name of the application */
2414 };
2415 
2416 
2417 /*! \brief ast_state_cb: An extension state notify register item */
2418 struct ast_state_cb {
2419  int id;
2420  void *data;
2422  struct ast_state_cb *next;
2423 };
2424 
2425 /*! \brief Structure for dial plan hints
2426 
2427  \note Hints are pointers from an extension in the dialplan to one or
2428  more devices (tech/name)
2429  - See \ref AstExtState
2430 */
2431 struct ast_hint {
2432  struct ast_exten *exten; /*!< Extension */
2433  int laststate; /*!< Last known state */
2434  struct ast_state_cb *callbacks; /*!< Callback list for this extension */
2435  AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
2436 };
2437 
2438 struct store_hint {
2439  char *context;
2440  char *exten;
2444  char data[1];
2445 };
2446 
2448 
2449 #define STATUS_NO_CONTEXT 1
2450 #define STATUS_NO_EXTENSION 2
2451 #define STATUS_NO_PRIORITY 3
2452 #define STATUS_NO_LABEL 4
2453 #define STATUS_SUCCESS 5
2454 
2455 static struct ast_var_t *ast_var_assign(const char *name, const char *value)
2456 {
2457  struct ast_var_t *var;
2458  int name_len = strlen(name) + 1;
2459  int value_len = strlen(value) + 1;
2460 
2461  if (!(var = ast_calloc(sizeof(*var) + name_len + value_len, sizeof(char)))) {
2462  return NULL;
2463  }
2464 
2465  ast_copy_string(var->name, name, name_len);
2466  var->value = var->name + name_len;
2467  ast_copy_string(var->value, value, value_len);
2468 
2469  return var;
2470 }
2471 
2472 static void ast_var_delete(struct ast_var_t *var)
2473 {
2474  free(var);
2475 }
2476 
2477 
2478 /* chopped this one off at the knees! */
2479 static int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
2480 {
2481 
2482  /* ast_log(LOG_ERROR, "Function %s not registered\n", function); we are not interested in the details here */
2483 
2484  return -1;
2485 }
2486 
2487 static unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
2488 {
2489  int argc;
2490  char *scan;
2491  int paren = 0, quote = 0;
2492 
2493  if (!buf || !array || !arraylen)
2494  return 0;
2495 
2496  memset(array, 0, arraylen * sizeof(*array));
2497 
2498  scan = buf;
2499 
2500  for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2501  array[argc] = scan;
2502  for (; *scan; scan++) {
2503  if (*scan == '(')
2504  paren++;
2505  else if (*scan == ')') {
2506  if (paren)
2507  paren--;
2508  } else if (*scan == '"' && delim != '"') {
2509  quote = quote ? 0 : 1;
2510  /* Remove quote character from argument */
2511  memmove(scan, scan + 1, strlen(scan));
2512  scan--;
2513  } else if (*scan == '\\') {
2514  /* Literal character, don't parse */
2515  memmove(scan, scan + 1, strlen(scan));
2516  } else if ((*scan == delim) && !paren && !quote) {
2517  *scan++ = '\0';
2518  break;
2519  }
2520  }
2521  }
2522 
2523  if (*scan)
2524  array[argc++] = scan;
2525 
2526  return argc;
2527 }
2528 
2529 static void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
2530 {
2531  struct ast_var_t *newvariable;
2532  struct varshead *headp;
2533  const char *nametail = name;
2534 
2535  /* XXX may need locking on the channel ? */
2536  if (name[strlen(name)-1] == ')') {
2537  char *function = ast_strdupa(name);
2538 
2539  ast_func_write(chan, function, value);
2540  return;
2541  }
2542 
2543  headp = &globals;
2544 
2545  /* For comparison purposes, we have to strip leading underscores */
2546  if (*nametail == '_') {
2547  nametail++;
2548  if (*nametail == '_')
2549  nametail++;
2550  }
2551 
2552  AST_LIST_TRAVERSE (headp, newvariable, entries) {
2553  if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
2554  /* there is already such a variable, delete it */
2555  AST_LIST_REMOVE(headp, newvariable, entries);
2556  ast_var_delete(newvariable);
2557  break;
2558  }
2559  }
2560 
2561  if (value && (newvariable = ast_var_assign(name, value))) {
2562  if ((option_verbose > 1) && (headp == &globals))
2563  ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
2564  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
2565  }
2566 
2567 }
2568 
2569 static int pbx_builtin_setvar(struct ast_channel *chan, const void *data)
2570 {
2571  char *name, *value, *mydata;
2572  int argc;
2573  char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
2574  int global = 0;
2575  int x;
2576 
2577  if (ast_strlen_zero(data)) {
2578  ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
2579  return 0;
2580  }
2581 
2582  mydata = ast_strdupa(data);
2583  argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
2584 
2585  /* check for a trailing flags argument */
2586  if ((argc > 1) && !strchr(argv[argc-1], '=')) {
2587  argc--;
2588  if (strchr(argv[argc], 'g'))
2589  global = 1;
2590  }
2591 
2592  for (x = 0; x < argc; x++) {
2593  name = argv[x];
2594  if ((value = strchr(name, '='))) {
2595  *value++ = '\0';
2597  } else
2598  ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
2599  }
2600 
2601  return(0);
2602 }
2603 
2604 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data);
2605 
2606 int localized_pbx_builtin_setvar(struct ast_channel *chan, const void *data)
2607 {
2608  return pbx_builtin_setvar(chan, data);
2609 }
2610 
2611 
2612 /*! \brief Helper for get_range.
2613  * return the index of the matching entry, starting from 1.
2614  * If names is not supplied, try numeric values.
2615  */
2616 static int lookup_name(const char *s, char *const names[], int max)
2617 {
2618  int i;
2619 
2620  if (names && *s > '9') {
2621  for (i = 0; names[i]; i++) {
2622  if (!strcasecmp(s, names[i])) {
2623  return i;
2624  }
2625  }
2626  }
2627 
2628  /* Allow months and weekdays to be specified as numbers, as well */
2629  if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
2630  /* What the array offset would have been: "1" would be at offset 0 */
2631  return i - 1;
2632  }
2633  return -1; /* error return */
2634 }
2635 
2636 /*! \brief helper function to return a range up to max (7, 12, 31 respectively).
2637  * names, if supplied, is an array of names that should be mapped to numbers.
2638  */
2639 static unsigned get_range(char *src, int max, char *const names[], const char *msg)
2640 {
2641  int start, end; /* start and ending position */
2642  unsigned int mask = 0;
2643  char *part;
2644 
2645  /* Check for whole range */
2646  if (ast_strlen_zero(src) || !strcmp(src, "*")) {
2647  return (1 << max) - 1;
2648  }
2649 
2650  while ((part = strsep(&src, "&"))) {
2651  /* Get start and ending position */
2652  char *endpart = strchr(part, '-');
2653  if (endpart) {
2654  *endpart++ = '\0';
2655  }
2656  /* Find the start */
2657  if ((start = lookup_name(part, names, max)) < 0) {
2658  ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
2659  continue;
2660  }
2661  if (endpart) { /* find end of range */
2662  if ((end = lookup_name(endpart, names, max)) < 0) {
2663  ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
2664  continue;
2665  }
2666  } else {
2667  end = start;
2668  }
2669  /* Fill the mask. Remember that ranges are cyclic */
2670  mask |= (1 << end); /* initialize with last element */
2671  while (start != end) {
2672  if (start >= max) {
2673  start = 0;
2674  }
2675  mask |= (1 << start);
2676  start++;
2677  }
2678  }
2679  return mask;
2680 }
2681 
2682 /*! \brief store a bitmask of valid times, one bit each 2 minute */
2683 static void get_timerange(struct ast_timing *i, char *times)
2684 {
2685  char *endpart, *part;
2686  int x;
2687  int st_h, st_m;
2688  int endh, endm;
2689  int minute_start, minute_end;
2690 
2691  /* start disabling all times, fill the fields with 0's, as they may contain garbage */
2692  memset(i->minmask, 0, sizeof(i->minmask));
2693 
2694  /* 1-minute per bit */
2695  /* Star is all times */
2696  if (ast_strlen_zero(times) || !strcmp(times, "*")) {
2697  /* 48, because each hour takes 2 integers; 30 bits each */
2698  for (x = 0; x < 48; x++) {
2699  i->minmask[x] = 0x3fffffff; /* 30 bits */
2700  }
2701  return;
2702  }
2703  /* Otherwise expect a range */
2704  while ((part = strsep(&times, "&"))) {
2705  if (!(endpart = strchr(part, '-'))) {
2706  if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2707  ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
2708  continue;
2709  }
2710  i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
2711  continue;
2712  }
2713  *endpart++ = '\0';
2714  /* why skip non digits? Mostly to skip spaces */
2715  while (*endpart && !isdigit(*endpart)) {
2716  endpart++;
2717  }
2718  if (!*endpart) {
2719  ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
2720  continue;
2721  }
2722  if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
2723  ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
2724  continue;
2725  }
2726  if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
2727  ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
2728  continue;
2729  }
2730  minute_start = st_h * 60 + st_m;
2731  minute_end = endh * 60 + endm;
2732  /* Go through the time and enable each appropriate bit */
2733  for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
2734  i->minmask[x / 30] |= (1 << (x % 30));
2735  }
2736  /* Do the last one */
2737  i->minmask[x / 30] |= (1 << (x % 30));
2738  }
2739  /* All done */
2740  return;
2741 }
2742 
2743 static void null_datad(void *foo)
2744 {
2745 }
2746 
2747 /*! \brief Find realtime engine for realtime family */
2748 static struct ast_config_engine *find_engine(const char *family, char *database, int dbsiz, char *table, int tabsiz)
2749 {
2750  struct ast_config_engine *eng, *ret = NULL;
2751  struct ast_config_map *map;
2752 
2753 
2754  for (map = config_maps; map; map = map->next) {
2755  if (!strcasecmp(family, map->name)) {
2756  if (database)
2757  ast_copy_string(database, map->database, dbsiz);
2758  if (table)
2759  ast_copy_string(table, map->table ? map->table : family, tabsiz);
2760  break;
2761  }
2762  }
2763 
2764  /* Check if the required driver (engine) exist */
2765  if (map) {
2766  for (eng = config_engine_list; !ret && eng; eng = eng->next) {
2767  if (!strcasecmp(eng->name, map->driver))
2768  ret = eng;
2769  }
2770  }
2771 
2772 
2773  /* if we found a mapping, but the engine is not available, then issue a warning */
2774  if (map && !ret)
2775  ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
2776 
2777  return ret;
2778 }
2779 
2780 struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
2781 
2783 {
2784  return cfg->current;
2785 }
2786 
2787 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
2788 
2789 static struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno)
2790 {
2791  struct ast_category *category;
2792 
2793  if ((category = ast_calloc(1, sizeof(*category))))
2794  ast_copy_string(category->name, name, sizeof(category->name));
2795  category->file = strdup(in_file);
2796  category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
2797  return category;
2798 }
2799 
2800 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
2801 
2802 struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name)
2803 {
2804  return category_get(config, category_name, 0);
2805 }
2806 
2807 static void move_variables(struct ast_category *old, struct ast_category *new)
2808 {
2809  struct ast_variable *var = old->root;
2810  old->root = NULL;
2811 #if 1
2812  /* we can just move the entire list in a single op */
2813  ast_variable_append(new, var);
2814 #else
2815  while (var) {
2816  struct ast_variable *next = var->next;
2817  var->next = NULL;
2818  ast_variable_append(new, var);
2819  var = next;
2820  }
2821 #endif
2822 }
2823 
2824 static void inherit_category(struct ast_category *new, const struct ast_category *base)
2825 {
2826  struct ast_variable *var;
2827 
2828  for (var = base->root; var; var = var->next)
2830 }
2831 
2832 static void ast_category_append(struct ast_config *config, struct ast_category *category);
2833 
2834 static void ast_category_append(struct ast_config *config, struct ast_category *category)
2835 {
2836  if (config->last)
2837  config->last->next = category;
2838  else
2839  config->root = category;
2840  config->last = category;
2841  config->current = category;
2842 }
2843 
2844 static void ast_category_destroy(struct ast_category *cat);
2845 
2846 static void ast_category_destroy(struct ast_category *cat)
2847 {
2849  if (cat->file)
2850  free(cat->file);
2851 
2852  free(cat);
2853 }
2854 
2855 static struct ast_config_engine text_file_engine = {
2856  .name = "text",
2857  .load_func = config_text_file_load,
2858 };
2859 
2860 
2861 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file);
2862 
2863 static struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_incl_file)
2864 {
2865  char db[256] = "";
2866  char table[256] = "";
2867  struct ast_config_engine *loader = &text_file_engine;
2868  struct ast_config *result;
2869 
2870  if (cfg->include_level == cfg->max_include_level) {
2871  ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
2872  return NULL;
2873  }
2874 
2875  cfg->include_level++;
2876  /* silence is golden!
2877  ast_log(LOG_WARNING, "internal loading file %s level=%d\n", filename, cfg->include_level);
2878  */
2879 
2880  if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
2881  struct ast_config_engine *eng;
2882 
2883  eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
2884 
2885 
2886  if (eng && eng->load_func) {
2887  loader = eng;
2888  } else {
2889  eng = find_engine("global", db, sizeof(db), table, sizeof(table));
2890  if (eng && eng->load_func)
2891  loader = eng;
2892  }
2893  }
2894 
2895  result = loader->load_func(db, table, filename, cfg, withcomments, suggested_incl_file);
2896  /* silence is golden
2897  ast_log(LOG_WARNING, "finished internal loading file %s level=%d\n", filename, cfg->include_level);
2898  */
2899 
2900  if (result)
2901  result->include_level--;
2902 
2903  return result;
2904 }
2905 
2906 
2907 static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments, const char *suggested_include_file)
2908 {
2909  char *c;
2910  char *cur = buf;
2911  struct ast_variable *v;
2912  char exec_file[512];
2913  int object, do_exec, do_include;
2914 
2915  /* Actually parse the entry */
2916  if (cur[0] == '[') {
2917  struct ast_category *newcat = NULL;
2918  char *catname;
2919 
2920  /* A category header */
2921  c = strchr(cur, ']');
2922  if (!c) {
2923  ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
2924  return -1;
2925  }
2926  *c++ = '\0';
2927  cur++;
2928  if (*c++ != '(')
2929  c = NULL;
2930  catname = cur;
2931  if (!(*cat = newcat = ast_category_new(catname, ast_strlen_zero(suggested_include_file)?configfile:suggested_include_file, lineno))) {
2932  return -1;
2933  }
2934  (*cat)->lineno = lineno;
2935 
2936  /* add comments */
2937  if (withcomments && comment_buffer && comment_buffer[0] ) {
2939  }
2940  if (withcomments && lline_buffer && lline_buffer[0] ) {
2941  newcat->sameline = ALLOC_COMMENT(lline_buffer);
2942  }
2943  if( withcomments )
2944  CB_RESET();
2945 
2946  /* If there are options or categories to inherit from, process them now */
2947  if (c) {
2948  if (!(cur = strchr(c, ')'))) {
2949  ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
2950  return -1;
2951  }
2952  *cur = '\0';
2953  while ((cur = strsep(&c, ","))) {
2954  if (!strcasecmp(cur, "!")) {
2955  (*cat)->ignored = 1;
2956  } else if (!strcasecmp(cur, "+")) {
2957  *cat = category_get(cfg, catname, 1);
2958  if (!*cat) {
2959  ast_config_destroy(cfg);
2960  if (newcat)
2961  ast_category_destroy(newcat);
2962  ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
2963  return -1;
2964  }
2965  if (newcat) {
2966  move_variables(newcat, *cat);
2967  ast_category_destroy(newcat);
2968  newcat = NULL;
2969  }
2970  } else {
2971  struct ast_category *base;
2972 
2973  base = category_get(cfg, cur, 1);
2974  if (!base) {
2975  ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
2976  return -1;
2977  }
2978  inherit_category(*cat, base);
2979  }
2980  }
2981  }
2982  if (newcat)
2983  ast_category_append(cfg, *cat);
2984  } else if (cur[0] == '#') {
2985  /* A directive */
2986  cur++;
2987  c = cur;
2988  while(*c && (*c > 32)) c++;
2989  if (*c) {
2990  *c = '\0';
2991  /* Find real argument */
2992  c = ast_skip_blanks(c + 1);
2993  if (!*c)
2994  c = NULL;
2995  } else
2996  c = NULL;
2997  do_include = !strcasecmp(cur, "include");
2998  if(!do_include)
2999  do_exec = !strcasecmp(cur, "exec");
3000  else
3001  do_exec = 0;
3002  if (do_exec && !ast_opt_exec_includes) {
3003  ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
3004  do_exec = 0;
3005  }
3006  if (do_include || do_exec) {
3007  if (c) {
3008  char *cur2;
3009  char real_inclusion_name[525];
3010 
3011  /* Strip off leading and trailing "'s and <>'s */
3012  while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
3013  /* Get rid of leading mess */
3014  cur = c;
3015  cur2 = cur;
3016  while (!ast_strlen_zero(cur)) {
3017  c = cur + strlen(cur) - 1;
3018  if ((*c == '>') || (*c == '<') || (*c == '\"'))
3019  *c = '\0';
3020  else
3021  break;
3022  }
3023  /* #exec </path/to/executable>
3024  We create a tmp file, then we #include it, then we delete it. */
3025  if (do_exec) {
3026  char cmd[1024];
3027 
3028  snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
3029  if (snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file) >= sizeof(cmd)) {
3030  ast_log(LOG_ERROR, "Failed to construct command string to execute %s.\n", cur);
3031 
3032  return -1;
3033  }
3034  ast_safe_system(cmd);
3035  cur = exec_file;
3036  } else
3037  exec_file[0] = '\0';
3038  /* A #include */
3039  /* ast_log(LOG_WARNING, "Reading in included file %s withcomments=%d\n", cur, withcomments); */
3040 
3041  /* record this inclusion */
3042  ast_include_new(cfg, configfile, cur, do_exec, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
3043 
3044  do_include = ast_config_internal_load(cur, cfg, withcomments, real_inclusion_name) ? 1 : 0;
3045  if(!ast_strlen_zero(exec_file))
3046  unlink(exec_file);
3047  if(!do_include)
3048  return 0;
3049  /* ast_log(LOG_WARNING, "Done reading in included file %s withcomments=%d\n", cur, withcomments); */
3050 
3051  } else {
3052  ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
3053  do_exec ? "exec" : "include",
3054  do_exec ? "/path/to/executable" : "filename",
3055  lineno,
3056  configfile);
3057  }
3058  }
3059  else
3060  ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
3061  } else {
3062  /* Just a line (variable = value) */
3063  if (!*cat) {
3065  "parse error: No category context for line %d of %s\n", lineno, configfile);
3066  return -1;
3067  }
3068  c = strchr(cur, '=');
3069  if (c) {
3070  *c = 0;
3071  c++;
3072  /* Ignore > in => */
3073  if (*c== '>') {
3074  object = 1;
3075  c++;
3076  } else
3077  object = 0;
3078  if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), configfile))) {
3079  v->lineno = lineno;
3080  v->object = object;
3081  /* Put and reset comments */
3082  v->blanklines = 0;
3083  ast_variable_append(*cat, v);
3084  /* add comments */
3085  if (withcomments && comment_buffer && comment_buffer[0] ) {
3087  }
3088  if (withcomments && lline_buffer && lline_buffer[0] ) {
3090  }
3091  if( withcomments )
3092  CB_RESET();
3093 
3094  } else {
3095  return -1;
3096  }
3097  } else {
3098  ast_log(LOG_WARNING, "EXTENSIONS.CONF: No '=' (equal sign) in line %d of %s\n", lineno, configfile);
3099  }
3100  }
3101  return 0;
3102 }
3103 
3104 static int use_local_dir = 1;
3105 
3106 void localized_use_local_dir(void);
3107 void localized_use_conf_dir(void);
3108 
3110 {
3111  use_local_dir = 1;
3112 }
3113 
3115 {
3116  use_local_dir = 0;
3117 }
3118 
3119 
3120 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *suggested_include_file)
3121 {
3122  char fn[256];
3123  char buf[8192];
3124  char *new_buf, *comment_p, *process_buf;
3125  FILE *f;
3126  int lineno=0;
3127  int comment = 0, nest[MAX_NESTED_COMMENTS];
3128  struct ast_category *cat = NULL;
3129  int count = 0;
3130  struct stat statbuf;
3131 
3133 
3134  if (filename[0] == '/') {
3135  ast_copy_string(fn, filename, sizeof(fn));
3136  } else {
3137  if (use_local_dir)
3138  snprintf(fn, sizeof(fn), "./%s", filename);
3139  else
3140  snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
3141  }
3142 
3143  if (withcomments && cfg && cfg->include_level < 2 ) {
3144  CB_INIT();
3145  }
3146 
3147  do {
3148  if (stat(fn, &statbuf))
3149  continue;
3150 
3151  if (!S_ISREG(statbuf.st_mode)) {
3152  ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
3153  continue;
3154  }
3155  if (option_verbose > 1) {
3156  ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
3157  fflush(stdout);
3158  }
3159  if (!(f = fopen(fn, "r"))) {
3160  if (option_debug)
3161  ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
3162  if (option_verbose > 1)
3163  ast_verbose( "Not found (%s)\n", strerror(errno));
3164  continue;
3165  }
3166  count++;
3167  if (option_debug)
3168  ast_log(LOG_DEBUG, "Parsing %s\n", fn);
3169  if (option_verbose > 1)
3170  ast_verbose("Found\n");
3171  while(!feof(f)) {
3172  lineno++;
3173  if (fgets(buf, sizeof(buf), f)) {
3174  if ( withcomments ) {
3175  CB_ADD(lline_buffer); /* add the current lline buffer to the comment buffer */
3176  lline_buffer[0] = 0; /* erase the lline buffer */
3177  }
3178 
3179  new_buf = buf;
3180  if (comment)
3181  process_buf = NULL;
3182  else
3183  process_buf = buf;
3184 
3185  while ((comment_p = strchr(new_buf, COMMENT_META))) {
3186  if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
3187  /* Yuck, gotta memmove */
3188  memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
3189  new_buf = comment_p;
3190  } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
3191  /* Meta-Comment start detected ";--" */
3192  if (comment < MAX_NESTED_COMMENTS) {
3193  *comment_p = '\0';
3194  new_buf = comment_p + 3;
3195  comment++;
3196  nest[comment-1] = lineno;
3197  } else {
3198  ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
3199  }
3200  } else if ((comment_p >= new_buf + 2) &&
3201  (*(comment_p - 1) == COMMENT_TAG) &&
3202  (*(comment_p - 2) == COMMENT_TAG)) {
3203  /* Meta-Comment end detected */
3204  comment--;
3205  new_buf = comment_p + 1;
3206  if (!comment) {
3207  /* Back to non-comment now */
3208  if (process_buf) {
3209  /* Actually have to move what's left over the top, then continue */
3210  char *oldptr;
3211  oldptr = process_buf + strlen(process_buf);
3212  if ( withcomments ) {
3213  CB_ADD(";");
3214  CB_ADD_LEN(oldptr+1,new_buf-oldptr-1);
3215  }
3216 
3217  memmove(oldptr, new_buf, strlen(new_buf) + 1);
3218  new_buf = oldptr;
3219  } else
3220  process_buf = new_buf;
3221  }
3222  } else {
3223  if (!comment) {
3224  /* If ; is found, and we are not nested in a comment,
3225  we immediately stop all comment processing */
3226  if ( withcomments ) {
3227  LLB_ADD(comment_p);
3228  }
3229  *comment_p = '\0';
3230  new_buf = comment_p;
3231  } else
3232  new_buf = comment_p + 1;
3233  }
3234  }
3235  if( withcomments && comment && !process_buf )
3236  {
3237  CB_ADD(buf); /* the whole line is a comment, store it */
3238  }
3239 
3240  if (process_buf) {
3241  char *stripped_process_buf = ast_strip(process_buf);
3242  if (!ast_strlen_zero(stripped_process_buf)) {
3243  if (process_text_line(cfg, &cat, stripped_process_buf, lineno, filename, withcomments, suggested_include_file)) {
3244  cfg = NULL;
3245  break;
3246  }
3247  }
3248  }
3249  }
3250  }
3251  fclose(f);
3252  } while(0);
3253  if (comment) {
3254  ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment]);
3255  }
3256  if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) {
3257  if (comment_buffer) {
3259  free(lline_buffer);
3260  comment_buffer=0;
3261  lline_buffer=0;
3264  }
3265  }
3266  if (count == 0)
3267  return NULL;
3268 
3269  return cfg;
3270 }
3271 
3272 
3273 static struct ast_config *ast_config_new(void) ;
3274 
3275 static struct ast_config *ast_config_new(void)
3276 {
3277  struct ast_config *config;
3278 
3279  if ((config = ast_calloc(1, sizeof(*config))))
3280  config->max_include_level = MAX_INCLUDE_LEVEL;
3281  return config;
3282 }
3283 
3284 struct ast_config *localized_config_load(const char *filename);
3285 
3286 struct ast_config *localized_config_load(const char *filename)
3287 {
3288  struct ast_config *cfg;
3289  struct ast_config *result;
3290 
3291  cfg = ast_config_new();
3292  if (!cfg)
3293  return NULL;
3294 
3295  result = ast_config_internal_load(filename, cfg, 0, "");
3296  if (!result)
3297  ast_config_destroy(cfg);
3298 
3299  return result;
3300 }
3301 
3302 struct ast_config *localized_config_load_with_comments(const char *filename);
3303 
3305 {
3306  struct ast_config *cfg;
3307  struct ast_config *result;
3308 
3309  cfg = ast_config_new();
3310  if (!cfg)
3311  return NULL;
3312 
3313  result = ast_config_internal_load(filename, cfg, 1, "");
3314  if (!result)
3315  ast_config_destroy(cfg);
3316 
3317  return result;
3318 }
3319 
3321 {
3322  for (; cat && cat->ignored; cat = cat->next);
3323 
3324  return cat;
3325 }
3326 
3327 static char *ast_category_browse(struct ast_config *config, const char *prev)
3328 {
3329  struct ast_category *cat = NULL;
3330 
3331  if (prev && config->last_browse && (config->last_browse->name == prev))
3332  cat = config->last_browse->next;
3333  else if (!prev && config->root)
3334  cat = config->root;
3335  else if (prev) {
3336  for (cat = config->root; cat; cat = cat->next) {
3337  if (cat->name == prev) {
3338  cat = cat->next;
3339  break;
3340  }
3341  }
3342  if (!cat) {
3343  for (cat = config->root; cat; cat = cat->next) {
3344  if (!strcasecmp(cat->name, prev)) {
3345  cat = cat->next;
3346  break;
3347  }
3348  }
3349  }
3350  }
3351 
3352  if (cat)
3353  cat = next_available_category(cat);
3354 
3355  config->last_browse = cat;
3356  return (cat) ? cat->name : NULL;
3357 }
3358 
3359 
3360 
3361 void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat);
3362 
3363 void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
3364 {
3365  /* cast below is just to silence compiler warning about dropping "const" */
3366  cfg->current = (struct ast_category *) cat;
3367 }
3368 
3369 /* NOTE: categories and variables each have a file and lineno attribute. On a save operation, these are used to determine
3370  which file and line number to write out to. Thus, an entire hierarchy of config files (via #include statements) can be
3371  recreated. BUT, care must be taken to make sure that every cat and var has the proper file name stored, or you may
3372  be shocked and mystified as to why things are not showing up in the files!
3373 
3374  Also, All #include/#exec statements are recorded in the "includes" LL in the ast_config structure. The file name
3375  and line number are stored for each include, plus the name of the file included, so that these statements may be
3376  included in the output files on a file_save operation.
3377 
3378  The lineno's are really just for relative placement in the file. There is no attempt to make sure that blank lines
3379  are included to keep the lineno's the same between input and output. The lineno fields are used mainly to determine
3380  the position of the #include and #exec directives. So, blank lines tend to disappear from a read/rewrite operation,
3381  and a header gets added.
3382 
3383  vars and category heads are output in the order they are stored in the config file. So, if the software
3384  shuffles these at all, then the placement of #include directives might get a little mixed up, because the
3385  file/lineno data probably won't get changed.
3386 
3387 */
3388 
3389 static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
3390 {
3391  char date[256]="";
3392  time_t t;
3393  time(&t);
3394  ast_copy_string(date, ctime(&t), sizeof(date));
3395 
3396  fprintf(f1, ";!\n");
3397  fprintf(f1, ";! Automatically generated configuration file\n");
3398  if (strcmp(configfile, fn))
3399  fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
3400  else
3401  fprintf(f1, ";! Filename: %s\n", configfile);
3402  fprintf(f1, ";! Generator: %s\n", generator);
3403  fprintf(f1, ";! Creation Date: %s", date);
3404  fprintf(f1, ";!\n");
3405 }
3406 
3407 static void set_fn(char *fn, int fn_size, const char *file, const char *configfile)
3408 {
3409  if (!file || file[0] == 0) {
3410  if (configfile[0] == '/')
3411  ast_copy_string(fn, configfile, fn_size);
3412  else
3413  snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
3414  } else if (file[0] == '/')
3415  ast_copy_string(fn, file, fn_size);
3416  else
3417  snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
3418 }
3419 
3420 int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator);
3421 
3422 int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
3423 {
3424  FILE *f;
3425  char fn[256];
3426  struct ast_variable *var;
3427  struct ast_category *cat;
3428  struct ast_comment *cmt;
3429  struct ast_config_include *incl;
3430  int blanklines = 0;
3431 
3432  /* reset all the output flags, in case this isn't our first time saving this data */
3433 
3434  for (incl=cfg->includes; incl; incl = incl->next)
3435  incl->output = 0;
3436 
3437  /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
3438  are all truncated to zero bytes and have that nice header*/
3439 
3440  for (incl=cfg->includes; incl; incl = incl->next)
3441  {
3442  if (!incl->exec) { /* leave the execs alone -- we'll write out the #exec directives, but won't zero out the include files or exec files*/
3443  FILE *f1;
3444 
3445  set_fn(fn, sizeof(fn), incl->included_file, configfile); /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
3446  f1 = fopen(fn,"w");
3447  if (f1) {
3448  gen_header(f1, configfile, fn, generator);
3449  fclose(f1); /* this should zero out the file */
3450  } else {
3451  ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
3452  }
3453  }
3454  }
3455 
3456  set_fn(fn, sizeof(fn), 0, configfile); /* just set fn to absolute ver of configfile */
3457 #ifdef __CYGWIN__
3458  if ((f = fopen(fn, "w+"))) {
3459 #else
3460  if ((f = fopen(fn, "w"))) {
3461 #endif
3462  if (option_verbose > 1)
3463  ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
3464 
3465  gen_header(f, configfile, fn, generator);
3466  cat = cfg->root;
3467  fclose(f);
3468 
3469  /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
3470  /* since each var, cat, and associated comments can come from any file, we have to be
3471  mobile, and open each file, print, and close it on an entry-by-entry basis */
3472 
3473  while(cat) {
3474  set_fn(fn, sizeof(fn), cat->file, configfile);
3475  f = fopen(fn, "a");
3476  if (!f)
3477  {
3478  ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
3479  return -1;
3480  }
3481 
3482  /* dump any includes that happen before this category header */
3483  for (incl=cfg->includes; incl; incl = incl->next) {
3484  if (strcmp(incl->include_location_file, cat->file) == 0){
3485  if (cat->lineno > incl->include_location_lineno && !incl->output) {
3486  if (incl->exec)
3487  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
3488  else
3489  fprintf(f,"#include \"%s\"\n", incl->included_file);
3490  incl->output = 1;
3491  }
3492  }
3493  }
3494 
3495  /* Dump section with any appropriate comment */
3496  for (cmt = cat->precomments; cmt; cmt=cmt->next) {
3497  if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
3498  fprintf(f,"%s", cmt->cmt);
3499  }
3500  if (!cat->precomments)
3501  fprintf(f,"\n");
3502  fprintf(f, "[%s]", cat->name);
3503  for(cmt = cat->sameline; cmt; cmt=cmt->next) {
3504  fprintf(f,"%s", cmt->cmt);
3505  }
3506  if (!cat->sameline)
3507  fprintf(f,"\n");
3508  fclose(f);
3509 
3510  var = cat->root;
3511  while(var) {
3512  set_fn(fn, sizeof(fn), var->file, configfile);
3513  f = fopen(fn, "a");
3514  if (!f)
3515  {
3516  ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
3517  return -1;
3518  }
3519 
3520  /* dump any includes that happen before this category header */
3521  for (incl=cfg->includes; incl; incl = incl->next) {
3522  if (strcmp(incl->include_location_file, var->file) == 0){
3523  if (var->lineno > incl->include_location_lineno && !incl->output) {
3524  if (incl->exec)
3525  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
3526  else
3527  fprintf(f,"#include \"%s\"\n", incl->included_file);
3528  incl->output = 1;
3529  }
3530  }
3531  }
3532 
3533  for (cmt = var->precomments; cmt; cmt=cmt->next) {
3534  if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
3535  fprintf(f,"%s", cmt->cmt);
3536  }
3537  if (var->sameline)
3538  fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
3539  else
3540  fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
3541  if (var->blanklines) {
3542  blanklines = var->blanklines;
3543  while (blanklines--)
3544  fprintf(f, "\n");
3545  }
3546 
3547  fclose(f);
3548 
3549 
3550  var = var->next;
3551  }
3552  cat = cat->next;
3553  }
3554  if ((option_verbose > 1) && !option_debug)
3555  ast_verbose("Saved\n");
3556  } else {
3557  if (option_debug)
3558  ast_log(LOG_DEBUG, "Unable to open for writing: %s\n", fn);
3559  if (option_verbose > 1)
3560  ast_verbose(VERBOSE_PREFIX_2 "Unable to write (%s)", strerror(errno));
3561  return -1;
3562  }
3563 
3564  /* Now, for files with trailing #include/#exec statements,
3565  we have to make sure every entry is output */
3566 
3567  for (incl=cfg->includes; incl; incl = incl->next) {
3568  if (!incl->output) {
3569  /* open the respective file */
3570  set_fn(fn, sizeof(fn), incl->include_location_file, configfile);
3571  f = fopen(fn, "a");
3572  if (!f)
3573  {
3574  ast_verbose(VERBOSE_PREFIX_2 "Unable to write %s (%s)", fn, strerror(errno));
3575  return -1;
3576  }
3577 
3578  /* output the respective include */
3579  if (incl->exec)
3580  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
3581  else
3582  fprintf(f,"#include \"%s\"\n", incl->included_file);
3583  fclose(f);
3584  incl->output = 1;
3585  }
3586  }
3587 
3588  return 0;
3589 }
3590 
3591 /* ================ the Line ========================================
3592  above this line, you have what you need to load a config file,
3593  and below it, you have what you need to process the extensions.conf
3594  file into the context/exten/prio stuff. They are both in one file
3595  to make things simpler */
3596 
3598 static struct ast_context *contexts = NULL;
3599 struct ast_context;
3600 struct ast_app;
3601 #ifdef LOW_MEMORY
3602 #define EXT_DATA_SIZE 256
3603 #else
3604 #define EXT_DATA_SIZE 8192
3605 #endif
3606 
3607 #ifdef NOT_ANYMORE
3609 #endif
3610 
3611 #define SWITCH_DATA_LENGTH 256
3612 
3613 static const char *ast_get_extension_app(struct ast_exten *e)
3614 {
3615  return e ? e->app : NULL;
3616 }
3617 
3618 static const char *ast_get_extension_name(struct ast_exten *exten)
3619 {
3620  return exten ? exten->exten : NULL;
3621 }
3622 
3624 
3625 /*! \brief ast_change_hint: Change hint for an extension */
3626 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
3627 {
3628  struct ast_hint *hint;
3629  int res = -1;
3630 
3631  AST_RWLIST_TRAVERSE(&hints, hint, list) {
3632  if (hint->exten == oe) {
3633  hint->exten = ne;
3634  res = 0;
3635  break;
3636  }
3637  }
3638 
3639  return res;
3640 }
3641 
3642 /*! \brief ast_add_hint: Add hint to hint list, check initial extension state */
3643 static int ast_add_hint(struct ast_exten *e)
3644 {
3645  struct ast_hint *hint;
3646 
3647  if (!e)
3648  return -1;
3649 
3650 
3651  /* Search if hint exists, do nothing */
3652  AST_RWLIST_TRAVERSE(&hints, hint, list) {
3653  if (hint->exten == e) {
3654  if (option_debug > 1)
3655  ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
3656  return -1;
3657  }
3658  }
3659 
3660  if (option_debug > 1)
3661  ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
3662 
3663  if (!(hint = ast_calloc(1, sizeof(*hint)))) {
3664  return -1;
3665  }
3666  /* Initialize and insert new item at the top */
3667  hint->exten = e;
3668  AST_RWLIST_INSERT_HEAD(&hints, hint, list);
3669 
3670  return 0;
3671 }
3672 
3673 /*! \brief add the extension in the priority chain.
3674  * returns 0 on success, -1 on failure
3675  */
3676 static int add_pri(struct ast_context *con, struct ast_exten *tmp,
3677  struct ast_exten *el, struct ast_exten *e, int replace)
3678 {
3679  struct ast_exten *ep;
3680 
3681  for (ep = NULL; e ; ep = e, e = e->peer) {
3682  if (e->priority >= tmp->priority)
3683  break;
3684  }
3685  if (!e) { /* go at the end, and ep is surely set because the list is not empty */
3686  ep->peer = tmp;
3687  return 0; /* success */
3688  }
3689  if (e->priority == tmp->priority) {
3690  /* Can't have something exactly the same. Is this a
3691  replacement? If so, replace, otherwise, bonk. */
3692  if (!replace) {
3693  ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
3694  tmp->datad(tmp->data);
3695  free(tmp);
3696  return -1;
3697  }
3698  /* we are replacing e, so copy the link fields and then update
3699  * whoever pointed to e to point to us
3700  */
3701  tmp->next = e->next; /* not meaningful if we are not first in the peer list */
3702  tmp->peer = e->peer; /* always meaningful */
3703  if (ep) /* We're in the peer list, just insert ourselves */
3704  ep->peer = tmp;
3705  else if (el) /* We're the first extension. Take over e's functions */
3706  el->next = tmp;
3707  else /* We're the very first extension. */
3708  con->root = tmp;
3709  if (tmp->priority == PRIORITY_HINT)
3710  ast_change_hint(e,tmp);
3711  /* Destroy the old one */
3712  e->datad(e->data);
3713  free(e);
3714  } else { /* Slip ourselves in just before e */
3715  tmp->peer = e;
3716  tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */
3717  if (ep) /* Easy enough, we're just in the peer list */
3718  ep->peer = tmp;
3719  else { /* we are the first in some peer list, so link in the ext list */
3720  if (el)
3721  el->next = tmp; /* in the middle... */
3722  else
3723  con->root = tmp; /* ... or at the head */
3724  e->next = NULL; /* e is no more at the head, so e->next must be reset */
3725  }
3726  /* And immediately return success. */
3727  if (tmp->priority == PRIORITY_HINT)
3728  ast_add_hint(tmp);
3729  }
3730  return 0;
3731 }
3732 
3733 /*! \brief ast_remove_hint: Remove hint from extension */
3734 static int ast_remove_hint(struct ast_exten *e)
3735 {
3736  /* Cleanup the Notifys if hint is removed */
3737  struct ast_hint *hint;
3738  struct ast_state_cb *cblist, *cbprev;
3739  int res = -1;
3740 
3741  if (!e)
3742  return -1;
3743 
3744  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
3745  if (hint->exten == e) {
3746  cbprev = NULL;
3747  cblist = hint->callbacks;
3748  while (cblist) {
3749  /* Notify with -1 and remove all callbacks */
3750  cbprev = cblist;
3751  cblist = cblist->next;
3752  free(cbprev);
3753  }
3754  hint->callbacks = NULL;
3756  free(hint);
3757  res = 0;
3758  break;
3759  }
3760  }
3762 
3763  return res;
3764 }
3765 
3766 static void destroy_exten(struct ast_exten *e)
3767 {
3768  if (e->priority == PRIORITY_HINT)
3769  ast_remove_hint(e);
3770 
3771  if (e->datad)
3772  e->datad(e->data);
3773  free(e);
3774 }
3775 
3776 char *days[] =
3777 {
3778  "sun",
3779  "mon",
3780  "tue",
3781  "wed",
3782  "thu",
3783  "fri",
3784  "sat",
3785  NULL,
3786 };
3787 
3788 char *months[] =
3789 {
3790  "jan",
3791  "feb",
3792  "mar",
3793  "apr",
3794  "may",
3795  "jun",
3796  "jul",
3797  "aug",
3798  "sep",
3799  "oct",
3800  "nov",
3801  "dec",
3802  NULL,
3803 };
3804 
3805 int ast_build_timing(struct ast_timing *i, const char *info_in);
3806 
3807 int ast_build_timing(struct ast_timing *i, const char *info_in)
3808 {
3809  char *info;
3810  int j, num_fields, last_sep = -1;
3811 
3812  i->timezone = NULL;
3813 
3814  /* Check for empty just in case */
3815  if (ast_strlen_zero(info_in)) {
3816  return 0;
3817  }
3818 
3819  /* make a copy just in case we were passed a static string */
3820  info = ast_strdupa(info_in);
3821 
3822  /* count the number of fields in the timespec */
3823  for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
3824  if (info[j] == '|' || info[j] == ',') {
3825  last_sep = j;
3826  num_fields++;
3827  }
3828  }
3829 
3830  /* save the timezone, if it is specified */
3831  if (num_fields == 5) {
3832  i->timezone = ast_strdup(info + last_sep + 1);
3833  }
3834 
3835  /* Assume everything except time */
3836  i->monthmask = 0xfff; /* 12 bits */
3837  i->daymask = 0x7fffffffU; /* 31 bits */
3838  i->dowmask = 0x7f; /* 7 bits */
3839  /* on each call, use strsep() to move info to the next argument */
3840  get_timerange(i, strsep(&info, "|,"));
3841  if (info)
3842  i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
3843  if (info)
3844  i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
3845  if (info)
3846  i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
3847  return 1;
3848 }
3849 
3850 /*!
3851  * \brief helper functions to sort extensions and patterns in the desired way,
3852  * so that more specific patterns appear first.
3853  *
3854  * ext_cmp1 compares individual characters (or sets of), returning
3855  * an int where bits 0-7 are the ASCII code of the first char in the set,
3856  * while bit 8-15 are the cardinality of the set minus 1.
3857  * This way more specific patterns (smaller cardinality) appear first.
3858  * Wildcards have a special value, so that we can directly compare them to
3859  * sets by subtracting the two values. In particular:
3860  * 0x000xx one character, xx
3861  * 0x0yyxx yy character set starting with xx
3862  * 0x10000 '.' (one or more of anything)
3863  * 0x20000 '!' (zero or more of anything)
3864  * 0x30000 NUL (end of string)
3865  * 0x40000 error in set.
3866  * The pointer to the string is advanced according to needs.
3867  * NOTES:
3868  * 1. the empty set is equivalent to NUL.
3869  * 2. given that a full set has always 0 as the first element,
3870  * we could encode the special cases as 0xffXX where XX
3871  * is 1, 2, 3, 4 as used above.
3872  */
3873 static int ext_cmp1(const char **p)
3874 {
3875  uint32_t chars[8];
3876  int c, cmin = 0xff, count = 0;
3877  const char *end;
3878 
3879  /* load, sign extend and advance pointer until we find
3880  * a valid character.
3881  */
3882  while ( (c = *(*p)++) && (c == ' ' || c == '-') )
3883  ; /* ignore some characters */
3884 
3885  /* always return unless we have a set of chars */
3886  switch (c) {
3887  default: /* ordinary character */
3888  return 0x0000 | (c & 0xff);
3889 
3890  case 'N': /* 2..9 */
3891  return 0x0700 | '2' ;
3892 
3893  case 'X': /* 0..9 */
3894  return 0x0900 | '0';
3895 
3896  case 'Z': /* 1..9 */
3897  return 0x0800 | '1';
3898 
3899  case '.': /* wildcard */
3900  return 0x10000;
3901 
3902  case '!': /* earlymatch */
3903  return 0x20000; /* less specific than NULL */
3904 
3905  case '\0': /* empty string */
3906  *p = NULL;
3907  return 0x30000;
3908 
3909  case '[': /* pattern */
3910  break;
3911  }
3912  /* locate end of set */
3913  end = strchr(*p, ']');
3914 
3915  if (end == NULL) {
3916  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
3917  return 0x40000; /* XXX make this entry go last... */
3918  }
3919 
3920  memset(chars, '\0', sizeof(chars)); /* clear all chars in the set */
3921  for (; *p < end ; (*p)++) {
3922  unsigned char c1, c2; /* first-last char in range */
3923  c1 = (unsigned char)((*p)[0]);
3924  if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
3925  c2 = (unsigned char)((*p)[2]);
3926  *p += 2; /* skip a total of 3 chars */
3927  } else /* individual character */
3928  c2 = c1;
3929  if (c1 < cmin)
3930  cmin = c1;
3931  for (; c1 <= c2; c1++) {
3932  uint32_t mask = 1 << (c1 % 32);
3933  if ( (chars[ c1 / 32 ] & mask) == 0)
3934  count += 0x100;
3935  chars[ c1 / 32 ] |= mask;
3936  }
3937  }
3938  (*p)++;
3939  return count == 0 ? 0x30000 : (count | cmin);
3940 }
3941 
3942 /*!
3943  * \brief the full routine to compare extensions in rules.
3944  */
3945 static int ext_cmp(const char *a, const char *b)
3946 {
3947  /* make sure non-patterns come first.
3948  * If a is not a pattern, it either comes first or
3949  * we use strcmp to compare the strings.
3950  */
3951  int ret = 0;
3952 
3953  if (a[0] != '_')
3954  return (b[0] == '_') ? -1 : strcmp(a, b);
3955 
3956  /* Now we know a is a pattern; if b is not, a comes first */
3957  if (b[0] != '_')
3958  return 1;
3959 #if 0 /* old mode for ext matching */
3960  return strcmp(a, b);
3961 #endif
3962  /* ok we need full pattern sorting routine */
3963  while (!ret && a && b)
3964  ret = ext_cmp1(&a) - ext_cmp1(&b);
3965  if (ret == 0)
3966  return 0;
3967  else
3968  return (ret > 0) ? 1 : -1;
3969 }
3970 
3971 /*! \brief copy a string skipping whitespace */
3972 static int ext_strncpy(char *dst, const char *src, int len)
3973 {
3974  int count=0;
3975 
3976  while (*src && (count < len - 1)) {
3977  switch(*src) {
3978  case ' ':
3979  /* otherwise exten => [a-b],1,... doesn't work */
3980  /* case '-': */
3981  /* Ignore */
3982  break;
3983  default:
3984  *dst = *src;
3985  dst++;
3986  }
3987  src++;
3988  count++;
3989  }
3990  *dst = '\0';
3991 
3992  return count;
3993 }
3994 
3995 /*
3996  * Wrapper around _extension_match_core() to do performance measurement
3997  * using the profiling code.
3998  */
3999 int ast_check_timing(const struct ast_timing *i);
4000 
4001 int ast_check_timing(const struct ast_timing *i)
4002 {
4003  /* sorry, but this feature will NOT be available
4004  in the standalone version */
4005  return 0;
4006 }
4007 
4008 #ifdef NOT_ANYMORE
4009 static struct ast_switch *pbx_findswitch(const char *sw)
4010 {
4011  struct ast_switch *asw;
4012 
4014  if (!strcasecmp(asw->name, sw))
4015  break;
4016  }
4017 
4018  return asw;
4019 }
4020 #endif
4021 
4022 
4023 static struct ast_context *ast_walk_contexts(struct ast_context *con);
4024 
4025 static struct ast_context *ast_walk_contexts(struct ast_context *con)
4026 {
4027  return con ? con->next : contexts;
4028 }
4029 
4030 struct ast_context *localized_walk_contexts(struct ast_context *con);
4032 {
4033  return ast_walk_contexts(con);
4034 }
4035 
4036 
4037 
4038 static struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
4039  struct ast_exten *exten);
4040 
4042  struct ast_exten *exten)
4043 {
4044  if (!exten)
4045  return con ? con->root : NULL;
4046  else
4047  return exten->next;
4048 }
4049 
4051  struct ast_exten *exten);
4053  struct ast_exten *exten)
4054 {
4055  return ast_walk_context_extensions(con,exten);
4056 }
4057 
4058 
4060  struct ast_exten *priority);
4061 
4063  struct ast_exten *priority)
4064 {
4065  return priority ? priority->peer : exten;
4066 }
4067 
4069  struct ast_exten *priority);
4071  struct ast_exten *priority)
4072 {
4074 }
4075 
4076 
4077 
4078 static struct ast_include *ast_walk_context_includes(struct ast_context *con,
4079  struct ast_include *inc);
4080 
4082  struct ast_include *inc)
4083 {
4084  if (!inc)
4085  return con ? con->includes : NULL;
4086  else
4087  return inc->next;
4088 }
4089 
4090 int ast_context_includes_count(struct ast_context *con);
4092 {
4093  int c = 0;
4094  struct ast_include *inc = NULL;
4095 
4096  while ((inc = ast_walk_context_includes(con, inc))) {
4097  c++;
4098  }
4099 
4100  return c;
4101 }
4102 
4104  struct ast_include *inc);
4106  struct ast_include *inc)
4107 {
4108  return ast_walk_context_includes(con, inc);
4109 }
4110 
4111 static struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
4112  struct ast_ignorepat *ip);
4113 
4115  struct ast_ignorepat *ip)
4116 {
4117  if (!ip)
4118  return con ? con->ignorepats : NULL;
4119  else
4120  return ip->next;
4121 }
4122 
4123 int ast_context_ignorepats_count(struct ast_context *con);
4125 {
4126  int c = 0;
4127  struct ast_ignorepat *ip = NULL;
4128 
4129  while ((ip = ast_walk_context_ignorepats(con, ip))) {
4130  c++;
4131  }
4132 
4133  return c;
4134 }
4135 
4136 
4137 static struct ast_sw *ast_walk_context_switches(struct ast_context *con,
4138  struct ast_sw *sw);
4139 
4140 static struct ast_sw *ast_walk_context_switches(struct ast_context *con,
4141  struct ast_sw *sw)
4142 {
4143  if (!sw)
4144  return con ? AST_LIST_FIRST(&con->alts) : NULL;
4145  else
4146  return AST_LIST_NEXT(sw, list);
4147 }
4148 
4150  struct ast_sw *sw);
4152  struct ast_sw *sw)
4153 {
4154  return ast_walk_context_switches(con, sw);
4155 }
4156 
4157 int ast_context_switches_count(struct ast_context *con);
4159 {
4160  int c = 0;
4161  struct ast_sw *sw = NULL;
4162 
4163  while ((sw = ast_walk_context_switches(con, sw))) {
4164  c++;
4165  }
4166 
4167  return c;
4168 }
4169 
4170 
4171 static struct ast_context *ast_context_find(const char *name);
4172 
4173 static struct ast_context *ast_context_find(const char *name)
4174 {
4175  struct ast_context *tmp = NULL;
4176  while ( (tmp = ast_walk_contexts(tmp)) ) {
4177  if (!name || !strcasecmp(name, tmp->name))
4178  break;
4179  }
4180  return tmp;
4181 }
4182 
4183 /*
4184  * Internal function for ast_extension_{match|close}
4185  * return 0 on no-match, 1 on match, 2 on early match.
4186  * mode is as follows:
4187  * E_MATCH success only on exact match
4188  * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
4189  * E_CANMATCH either of the above.
4190  */
4191 
4192 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
4193 {
4194  mode &= E_MATCH_MASK; /* only consider the relevant bits */
4195 
4196  if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
4197  return 1;
4198 
4199  if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
4200  int ld = strlen(data), lp = strlen(pattern);
4201 
4202  if (lp < ld) /* pattern too short, cannot match */
4203  return 0;
4204  /* depending on the mode, accept full or partial match or both */
4205  if (mode == E_MATCH)
4206  return !strcmp(pattern, data); /* 1 on match, 0 on fail */
4207  if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
4208  return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
4209  else
4210  return 0;
4211  }
4212  pattern++; /* skip leading _ */
4213  /*
4214  * XXX below we stop at '/' which is a separator for the CID info. However we should
4215  * not store '/' in the pattern at all. When we insure it, we can remove the checks.
4216  */
4217  while (*data && *pattern && *pattern != '/') {
4218  const char *end;
4219 
4220  if (*data == '-') { /* skip '-' in data (just a separator) */
4221  data++;
4222  continue;
4223  }
4224  switch (toupper(*pattern)) {
4225  case '[': /* a range */
4226  end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
4227  if (end == NULL) {
4228  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
4229  return 0; /* unconditional failure */
4230  }
4231  for (pattern++; pattern != end; pattern++) {
4232  if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
4233  if (*data >= pattern[0] && *data <= pattern[2])
4234  break; /* match found */
4235  else {
4236  pattern += 2; /* skip a total of 3 chars */
4237  continue;
4238  }
4239  } else if (*data == pattern[0])
4240  break; /* match found */
4241  }
4242  if (pattern == end)
4243  return 0;
4244  pattern = end; /* skip and continue */
4245  break;
4246  case 'N':
4247  if (*data < '2' || *data > '9')
4248  return 0;
4249  break;
4250  case 'X':
4251  if (*data < '0' || *data > '9')
4252  return 0;
4253  break;
4254  case 'Z':
4255  if (*data < '1' || *data > '9')
4256  return 0;
4257  break;
4258  case '.': /* Must match, even with more digits */
4259  return 1;
4260  case '!': /* Early match */
4261  return 2;
4262  case ' ':
4263  case '-': /* Ignore these in patterns */
4264  data--; /* compensate the final data++ */
4265  break;
4266  default:
4267  if (*data != *pattern)
4268  return 0;
4269  }
4270  data++;
4271  pattern++;
4272  }
4273  if (*data) /* data longer than pattern, no match */
4274  return 0;
4275  /*
4276  * match so far, but ran off the end of the data.
4277  * Depending on what is next, determine match or not.
4278  */
4279  if (*pattern == '\0' || *pattern == '/') /* exact match */
4280  return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
4281  else if (*pattern == '!') /* early match */
4282  return 2;
4283  else /* partial match */
4284  return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
4285 }
4286 
4287 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
4288 {
4289  int i;
4290  i = _extension_match_core(pattern, data, mode);
4291  return i;
4292 }
4293 
4294 static int ast_extension_match(const char *pattern, const char *data);
4295 
4296 static int ast_extension_match(const char *pattern, const char *data)
4297 {
4298  return extension_match_core(pattern, data, E_MATCH);
4299 }
4300 
4301 static int matchcid(const char *cidpattern, const char *callerid)
4302 {
4303  /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
4304  failing to get a number should count as a match, otherwise not */
4305 
4306  if (ast_strlen_zero(callerid))
4307  return ast_strlen_zero(cidpattern) ? 1 : 0;
4308 
4309  return ast_extension_match(cidpattern, callerid);
4310 }
4311 
4312 static inline int include_valid(struct ast_include *i)
4313 {
4314  if (!i->hastime)
4315  return 1;
4316 
4317  return ast_check_timing(&(i->timing));
4318 }
4319 
4320 
4321 
4322 static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
4323  struct ast_context *bypass,
4324  struct pbx_find_info *q,
4325  const char *context,
4326  const char *exten,
4327  int priority,
4328  const char *label,
4329  const char *callerid,
4330  enum ext_match_t action);
4331 
4332 
4333 static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
4334  struct ast_context *bypass,
4335  struct pbx_find_info *q,
4336  const char *context,
4337  const char *exten,
4338  int priority,
4339  const char *label,
4340  const char *callerid,
4341  enum ext_match_t action)
4342 {
4343  int x;
4344  struct ast_context *tmp;
4345  struct ast_exten *e, *eroot;
4346  struct ast_include *i;
4347 
4348  if (!context) {
4349  return NULL;
4350  }
4351 
4352  /* Initialize status if appropriate */
4353  if (q->stacklen == 0) {
4355  q->swo = NULL;
4356  q->data = NULL;
4357  q->foundcontext = NULL;
4358  } else if (q->stacklen >= AST_PBX_MAX_STACK) {
4359  ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
4360  return NULL;
4361  }
4362  /* Check first to see if we've already been checked */
4363  for (x = 0; x < q->stacklen; x++) {
4364  if (!strcasecmp(q->incstack[x], context))
4365  return NULL;
4366  }
4367  if (bypass) /* bypass means we only look there */
4368  tmp = bypass;
4369  else { /* look in contexts */
4370  tmp = NULL;
4371  while ((tmp = ast_walk_contexts(tmp)) ) {
4372  if (!strcmp(tmp->name, context))
4373  break;
4374  }
4375  if (!tmp)
4376  return NULL;
4377  }
4378  if (q->status < STATUS_NO_EXTENSION)
4380 
4381  /* scan the list trying to match extension and CID */
4382  eroot = NULL;
4383  while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
4384  int match = extension_match_core(eroot->exten, exten, action);
4385  /* 0 on fail, 1 on match, 2 on earlymatch */
4386 
4387  if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
4388  continue; /* keep trying */
4389  if (match == 2 && action == E_MATCHMORE) {
4390  /* We match an extension ending in '!'.
4391  * The decision in this case is final and is NULL (no match).
4392  */
4393  return NULL;
4394  }
4395  /* found entry, now look for the right priority */
4396  if (q->status < STATUS_NO_PRIORITY)
4398  e = NULL;
4399  while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
4400  /* Match label or priority */
4401  if (action == E_FINDLABEL) {
4402  if (q->status < STATUS_NO_LABEL)
4403  q->status = STATUS_NO_LABEL;
4404  if (label && e->label && !strcmp(label, e->label))
4405  break; /* found it */
4406  } else if (e->priority == priority) {
4407  break; /* found it */
4408  } /* else keep searching */
4409  }
4410  if (e) { /* found a valid match */
4411  q->status = STATUS_SUCCESS;
4412  q->foundcontext = context;
4413  return e;
4414  }
4415  }
4416 #ifdef NOT_RIGHT_NOW
4417  /* Check alternative switches??? */
4418  AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
4419  struct ast_switch *asw = pbx_findswitch(sw->name);
4420  ast_switch_f *aswf = NULL;
4421  char *datap;
4422 
4423  if (!asw) {
4424  ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
4425  continue;
4426  }
4427  /* No need to Substitute variables now; we shouldn't be here if there's any */
4428 
4429  /* equivalent of extension_match_core() at the switch level */
4430  if (action == E_CANMATCH)
4431  aswf = asw->canmatch;
4432  else if (action == E_MATCHMORE)
4433  aswf = asw->matchmore;
4434  else /* action == E_MATCH */
4435  aswf = asw->exists;
4436  datap = sw->eval ? sw->tmpdata : sw->data;
4437  res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
4438  if (res) { /* Got a match */
4439  q->swo = asw;
4440  q->data = datap;
4441  q->foundcontext = context;
4442  /* XXX keep status = STATUS_NO_CONTEXT ? */
4443  return NULL;
4444  }
4445  }
4446 #endif
4447  q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
4448  /* Now try any includes we have in this context */
4449  for (i = tmp->includes; i; i = i->next) {
4450  if (include_valid(i)) {
4451  if ((e = pbx_find_extension(NULL, bypass, q, i->rname, exten, priority, label, callerid, action)))
4452  return e;
4453  if (q->swo)
4454  return NULL;
4455  }
4456  }
4457  return NULL;
4458 }
4459 
4460 struct ast_exten *localized_find_extension(struct ast_context *bypass,
4461  struct pbx_find_info *q,
4462  const char *context,
4463  const char *exten,
4464  int priority,
4465  const char *label,
4466  const char *callerid,
4467  enum ext_match_t action);
4468 
4470  struct pbx_find_info *q,
4471  const char *context,
4472  const char *exten,
4473  int priority,
4474  const char *label,
4475  const char *callerid,
4476  enum ext_match_t action)
4477 {
4478  return pbx_find_extension(NULL, bypass, q, context, exten, priority, label, callerid, action);
4479 }
4480 
4481 
4482 static struct ast_context *contexts;
4483 AST_RWLOCK_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
4484 
4485 static const char *ast_get_context_name(struct ast_context *con);
4486 
4487 static const char *ast_get_context_name(struct ast_context *con)
4488 {
4489  return con ? con->name : NULL;
4490 }
4491 
4492 /*
4493  * errno values
4494  * ENOMEM - out of memory
4495  * EBUSY - can't lock
4496  * EEXIST - already included
4497  * EINVAL - there is no existence of context for inclusion
4498  */
4499 static int ast_context_add_include2(struct ast_context *con, const char *value,
4500  const char *registrar);
4501 
4502 static int ast_context_add_include2(struct ast_context *con, const char *value,
4503  const char *registrar)
4504 {
4505  struct ast_include *new_include;
4506  char *c;
4507  struct ast_include *i, *il = NULL; /* include, include_last */
4508  int length;
4509  char *p;
4510 
4511  length = sizeof(struct ast_include);
4512  length += 2 * (strlen(value) + 1);
4513 
4514  /* allocate new include structure ... */
4515  if (!(new_include = ast_calloc(1, length)))
4516  return -1;
4517  /* Fill in this structure. Use 'p' for assignments, as the fields
4518  * in the structure are 'const char *'
4519  */
4520  p = new_include->stuff;
4521  new_include->name = p;
4522  strcpy(p, value);
4523  p += strlen(value) + 1;
4524  new_include->rname = p;
4525  strcpy(p, value);
4526  /* Strip off timing info, and process if it is there */
4527  if ( (c = strchr(p, '|')) || (c = strchr(p, ',')) ) {
4528  *c++ = '\0';
4529  new_include->hastime = ast_build_timing(&(new_include->timing), c);
4530  }
4531  new_include->next = NULL;
4532  new_include->registrar = registrar;
4533 
4534 
4535  /* ... go to last include and check if context is already included too... */
4536  for (i = con->includes; i; i = i->next) {
4537  if (!strcasecmp(i->name, new_include->name)) {
4538  free(new_include);
4539  errno = EEXIST;
4540  return -1;
4541  }
4542  il = i;
4543  }
4544 
4545  /* ... include new context into context list, unlock, return */
4546  if (il)
4547  il->next = new_include;
4548  else
4549  con->includes = new_include;
4550  if (option_verbose > 2)
4551  ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
4552 
4553  return 0;
4554 }
4555 
4556 int localized_context_add_include2(struct ast_context *con, const char *value,
4557  const char *registrar);
4558 int localized_context_add_include2(struct ast_context *con, const char *value,
4559  const char *registrar)
4560 {
4562 }
4563 
4564 
4565 
4566 static int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
4567 
4568 static int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
4569 {
4570  struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
4571  int length;
4572  length = sizeof(struct ast_ignorepat);
4573  length += strlen(value) + 1;
4574  if (!(ignorepat = ast_calloc(1, length)))
4575  return -1;
4576  /* The cast to char * is because we need to write the initial value.
4577  * The field is not supposed to be modified otherwise
4578  */
4579  strcpy((char *)ignorepat->pattern, value);
4580  ignorepat->next = NULL;
4581  ignorepat->registrar = registrar;
4582  for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
4583  ignorepatl = ignorepatc;
4584  if (!strcasecmp(ignorepatc->pattern, value)) {
4585  /* Already there */
4586  errno = EEXIST;
4587  return -1;
4588  }
4589  }
4590  if (ignorepatl)
4591  ignorepatl->next = ignorepat;
4592  else
4593  con->ignorepats = ignorepat;
4594  return 0;
4595 
4596 }
4597 
4598 int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
4599 
4600 int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
4601 {
4603 }
4604 
4605 
4606 /*
4607  * Lock context list functions ...
4608  */
4609 
4610 static int ast_wrlock_contexts(void)
4611 {
4612  return ast_rwlock_wrlock(&conlock);
4613 }
4614 
4615 static int ast_unlock_contexts(void)
4616 {
4617  return ast_rwlock_unlock(&conlock);
4618 }
4619 
4620 static int ast_wrlock_context(struct ast_context *con)
4621 {
4622  return ast_rwlock_wrlock(&con->lock);
4623 }
4624 
4625 static int ast_unlock_context(struct ast_context *con)
4626 {
4627  return ast_rwlock_unlock(&con->lock);
4628 }
4629 
4630 /*
4631  * errno values
4632  * ENOMEM - out of memory
4633  * EBUSY - can't lock
4634  * EEXIST - already included
4635  * EINVAL - there is no existence of context for inclusion
4636  */
4637 static int ast_context_add_switch2(struct ast_context *con, const char *value,
4638  const char *data, int eval, const char *registrar);
4639 
4640 static int ast_context_add_switch2(struct ast_context *con, const char *value,
4641  const char *data, int eval, const char *registrar)
4642 {
4643  struct ast_sw *new_sw;
4644  struct ast_sw *i;
4645  int length;
4646  char *p;
4647 
4648  length = sizeof(struct ast_sw);
4649  length += strlen(value) + 1;
4650  if (data)
4651  length += strlen(data);
4652  length++;
4653  if (eval) {
4654  /* Create buffer for evaluation of variables */
4655  length += SWITCH_DATA_LENGTH;
4656  length++;
4657  }
4658 
4659  /* allocate new sw structure ... */
4660  if (!(new_sw = ast_calloc(1, length)))
4661  return -1;
4662  /* ... fill in this structure ... */
4663  p = new_sw->stuff;
4664  new_sw->name = p;
4665  strcpy(new_sw->name, value);
4666  p += strlen(value) + 1;
4667  new_sw->data = p;
4668  if (data) {
4669  strcpy(new_sw->data, data);
4670  p += strlen(data) + 1;
4671  } else {
4672  strcpy(new_sw->data, "");
4673  p++;
4674  }
4675  if (eval)
4676  new_sw->tmpdata = p;
4677  new_sw->eval = eval;
4678  new_sw->registrar = registrar;
4679 
4680  /* ... go to last sw and check if context is already swd too... */
4681  AST_LIST_TRAVERSE(&con->alts, i, list) {
4682  if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
4683  free(new_sw);
4684  errno = EEXIST;
4685  return -1;
4686  }
4687  }
4688 
4689  /* ... sw new context into context list, unlock, return */
4690  AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
4691 
4692  if (option_verbose > 2)
4693  ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
4694 
4695  return 0;
4696 }
4697 
4698 int localized_context_add_switch2(struct ast_context *con, const char *value,
4699  const char *data, int eval, const char *registrar);
4700 
4701 int localized_context_add_switch2(struct ast_context *con, const char *value,
4702  const char *data, int eval, const char *registrar)
4703 {
4705 }
4706 
4707 static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
4708 {
4709  struct ast_context *tmp, **loc_contexts;
4710  int length = sizeof(struct ast_context) + strlen(name) + 1;
4711 
4712  if (!extcontexts) {
4714  loc_contexts = &contexts;
4715  } else
4716  loc_contexts = extcontexts;
4717 
4718  for (tmp = *loc_contexts; tmp; tmp = tmp->next) {
4719  if (!strcasecmp(tmp->name, name)) {
4720  if (!existsokay) {
4721  ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
4722  tmp = NULL;
4723  }
4724  if (!extcontexts)
4726  return tmp;
4727  }
4728  }
4729  if ((tmp = ast_calloc(1, length))) {
4730  ast_rwlock_init(&tmp->lock);
4731  ast_mutex_init(&tmp->macrolock);
4732  strcpy(tmp->name, name);
4733  tmp->root = NULL;
4734  tmp->registrar = registrar;
4735  tmp->next = *loc_contexts;
4736  tmp->includes = NULL;
4737  tmp->ignorepats = NULL;
4738  *loc_contexts = tmp;
4739  if (option_debug)
4740  ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
4741  if (option_verbose > 2)
4742  ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
4743  }
4744 
4745  if (!extcontexts)
4747  return tmp;
4748 }
4749 
4750 /*! \brief
4751  * Main interface to add extensions to the list for out context.
4752  *
4753  * We sort extensions in order of matching preference, so that we can
4754  * stop the search as soon as we find a suitable match.
4755  * This ordering also takes care of wildcards such as '.' (meaning
4756  * "one or more of any character") and '!' (which is 'earlymatch',
4757  * meaning "zero or more of any character" but also impacts the
4758  * return value from CANMATCH and EARLYMATCH.
4759  *
4760  * The extension match rules defined in the devmeeting 2006.05.05 are
4761  * quite simple: WE SELECT THE LONGEST MATCH.
4762  * In detail, "longest" means the number of matched characters in
4763  * the extension. In case of ties (e.g. _XXX and 333) in the length
4764  * of a pattern, we give priority to entries with the smallest cardinality
4765  * (e.g, [5-9] comes before [2-8] before the former has only 5 elements,
4766  * while the latter has 7, etc.
4767  * In case of same cardinality, the first element in the range counts.
4768  * If we still have a tie, any final '!' will make this as a possibly
4769  * less specific pattern.
4770  *
4771  * EBUSY - can't lock
4772  * EEXIST - extension with the same priority exist and no replace is set
4773  *
4774  */
4775 static int ast_add_extension2(struct ast_context *con,
4776  int replace, const char *extension, int priority, const char *label, const char *callerid,
4777  const char *application, void *data, void (*datad)(void *),
4778  const char *registrar)
4779 {
4780  /*
4781  * Sort extensions (or patterns) according to the rules indicated above.
4782  * These are implemented by the function ext_cmp()).
4783  * All priorities for the same ext/pattern/cid are kept in a list,
4784  * using the 'peer' field as a link field..
4785  */
4786  struct ast_exten *tmp, *e, *el = NULL;
4787  int res;
4788  int length;
4789  char *p;
4790 
4791  /* if we are adding a hint, and there are global variables, and the hint
4792  contains variable references, then expand them --- NOT In this situation!!!
4793  */
4794 
4795  length = sizeof(struct ast_exten);
4796  length += strlen(extension) + 1;
4797  length += strlen(application) + 1;
4798  if (label)
4799  length += strlen(label) + 1;
4800  if (callerid)
4801  length += strlen(callerid) + 1;
4802  else
4803  length ++; /* just the '\0' */
4804 
4805  /* Be optimistic: Build the extension structure first */
4806  if (datad == NULL)
4807  datad = null_datad;
4808  if (!(tmp = ast_calloc(1, length)))
4809  return -1;
4810 
4811  /* use p as dst in assignments, as the fields are const char * */
4812  p = tmp->stuff;
4813  if (label) {
4814  tmp->label = p;
4815  strcpy(p, label);
4816  p += strlen(label) + 1;
4817  }
4818  tmp->exten = p;
4819  p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
4820  tmp->priority = priority;
4821  tmp->cidmatch = p; /* but use p for assignments below */
4822  if (callerid) {
4823  p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
4824  tmp->matchcid = 1;
4825  } else {
4826  *p++ = '\0';
4827  tmp->matchcid = 0;
4828  }
4829  tmp->app = p;
4830  strcpy(p, application);
4831  tmp->parent = con;
4832  tmp->data = data;
4833  tmp->datad = datad;
4834  tmp->registrar = registrar;
4835 
4836  res = 0; /* some compilers will think it is uninitialized otherwise */
4837  for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */
4838  res = ext_cmp(e->exten, extension);
4839  if (res == 0) { /* extension match, now look at cidmatch */
4840  if (!e->matchcid && !tmp->matchcid)
4841  res = 0;
4842  else if (tmp->matchcid && !e->matchcid)
4843  res = 1;
4844  else if (e->matchcid && !tmp->matchcid)
4845  res = -1;
4846  else
4847  res = strcasecmp(e->cidmatch, tmp->cidmatch);
4848  }
4849  if (res >= 0)
4850  break;
4851  }
4852  if (e && res == 0) { /* exact match, insert in the pri chain */
4853  res = add_pri(con, tmp, el, e, replace);
4854  if (res < 0) {
4855  errno = EEXIST; /* XXX do we care ? */
4856  return 0; /* XXX should we return -1 maybe ? */
4857  }
4858  } else {
4859  /*
4860  * not an exact match, this is the first entry with this pattern,
4861  * so insert in the main list right before 'e' (if any)
4862  */
4863  tmp->next = e;
4864  if (el)
4865  el->next = tmp;
4866  else
4867  con->root = tmp;
4868  if (tmp->priority == PRIORITY_HINT)
4869  ast_add_hint(tmp);
4870  }
4871  if (option_debug) {
4872  if (tmp->matchcid) {
4873  ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
4874  tmp->exten, tmp->priority, tmp->cidmatch, con->name);
4875  } else {
4876  ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
4877  tmp->exten, tmp->priority, con->name);
4878  }
4879  }
4880  if (option_verbose > 2) {
4881  if (tmp->matchcid) {
4882  ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
4883  tmp->exten, tmp->priority, tmp->cidmatch, con->name);
4884  } else {
4885  ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
4886  tmp->exten, tmp->priority, con->name);
4887  }
4888  }
4889  return 0;
4890 }
4891 
4892 int localized_add_extension2(struct ast_context *con,
4893  int replace, const char *extension, int priority, const char *label, const char *callerid,
4894  const char *application, void *data, void (*datad)(void *),
4895  const char *registrar);
4896 
4898  int replace, const char *extension, int priority, const char *label, const char *callerid,
4899  const char *application, void *data, void (*datad)(void *),
4900  const char *registrar)
4901 {
4902  return ast_add_extension2(con, replace, extension, priority, label, callerid, application, data, datad, registrar);
4903 }
4904 
4905 
4906 
4907 /*! \brief The return value depends on the action:
4908  *
4909  * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
4910  * and return 0 on failure, -1 on match;
4911  * E_FINDLABEL maps the label to a priority, and returns
4912  * the priority on success, ... XXX
4913  * E_SPAWN, spawn an application,
4914  * and return 0 on success, -1 on failure.
4915  */
4916 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
4917  const char *context, const char *exten, int priority,
4918  const char *label, const char *callerid, enum ext_match_t action)
4919 {
4920  struct ast_exten *e;
4921  int res;
4922  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
4923 
4924  int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
4925 
4926  e = pbx_find_extension(NULL, con, &q, context, exten, priority, label, callerid, action);
4927  if (e) {
4928  if (matching_action) {
4929  return -1; /* success, we found it */
4930  } else if (action == E_FINDLABEL) { /* map the label to a priority */
4931  res = e->priority;
4932  return res; /* the priority we were looking for */
4933  } else { /* spawn */
4934 
4935  /* NOT!!!!! */
4936  return 0;
4937  }
4938  } else if (q.swo) { /* not found here, but in another switch */
4939  if (matching_action)
4940  return -1;
4941  else {
4942  if (!q.swo->exec) {
4943  ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
4944  res = -1;
4945  }
4946  return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
4947  }
4948  } else { /* not found anywhere, see what happened */
4949  switch (q.status) {
4950  case STATUS_NO_CONTEXT:
4951  if (!matching_action)
4952  ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
4953  break;
4954  case STATUS_NO_EXTENSION:
4955  if (!matching_action)
4956  ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
4957  break;
4958  case STATUS_NO_PRIORITY:
4959  if (!matching_action)
4960  ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
4961  break;
4962  case STATUS_NO_LABEL:
4963  if (context)
4964  ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
4965  break;
4966  default:
4967  if (option_debug)
4968  ast_log(LOG_DEBUG, "Shouldn't happen!\n");
4969  }
4970 
4971  return (matching_action) ? 0 : -1;
4972  }
4973 }
4974 
4975 static int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid);
4976 
4977 static int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
4978 {
4979  return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
4980 }
4981 
4982 static struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
4983 {
4984  return __ast_context_create(extcontexts, name, registrar, 1);
4985 }
4986 
4987 struct ast_context *localized_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar);
4988 struct ast_context *localized_context_find_or_create(struct ast_context **extcontexts, void *tab, const char *name, const char *registrar)
4989 {
4990  return __ast_context_create(extcontexts, name, registrar, 1);
4991 }
4992 
4993 
4994 /* chopped this one off at the knees */
4995 static int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
4996 {
4997  ast_log(LOG_ERROR, "Function %s not registered\n", function);
4998  return -1;
4999 }
5000 
5001 /*! \brief extract offset:length from variable name.
5002  * Returns 1 if there is a offset:length part, which is
5003  * trimmed off (values go into variables)
5004  */
5005 static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
5006 {
5007  int parens=0;
5008 
5009  *offset = 0;
5010  *length = INT_MAX;
5011  *isfunc = 0;
5012  for (; *var; var++) {
5013  if (*var == '(') {
5014  (*isfunc)++;
5015  parens++;
5016  } else if (*var == ')') {
5017  parens--;
5018  } else if (*var == ':' && parens == 0) {
5019  *var++ = '\0';
5020  sscanf(var, "%30d:%30d", offset, length);
5021  return 1; /* offset:length valid */
5022  }
5023  }
5024  return 0;
5025 }
5026 
5027 static const char *ast_var_value(const struct ast_var_t *var)
5028 {
5029  return (var ? var->value : NULL);
5030 }
5031 
5032 /*! \brief takes a substring. It is ok to call with value == workspace.
5033  *
5034  * offset < 0 means start from the end of the string and set the beginning
5035  * to be that many characters back.
5036  * length is the length of the substring. A value less than 0 means to leave
5037  * that many off the end.
5038  * Always return a copy in workspace.
5039  */
5040 static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
5041 {
5042  char *ret = workspace;
5043  int lr; /* length of the input string after the copy */
5044 
5045  ast_copy_string(workspace, value, workspace_len); /* always make a copy */
5046 
5047  lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
5048 
5049  /* Quick check if no need to do anything */
5050  if (offset == 0 && length >= lr) /* take the whole string */
5051  return ret;
5052 
5053  if (offset < 0) { /* translate negative offset into positive ones */
5054  offset = lr + offset;
5055  if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
5056  offset = 0;
5057  }
5058 
5059  /* too large offset result in empty string so we know what to return */
5060  if (offset >= lr)
5061  return ret + lr; /* the final '\0' */
5062 
5063  ret += offset; /* move to the start position */
5064  if (length >= 0 && length < lr - offset) /* truncate if necessary */
5065  ret[length] = '\0';
5066  else if (length < 0) {
5067  if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
5068  ret[lr + length - offset] = '\0';
5069  else
5070  ret[0] = '\0';
5071  }
5072 
5073  return ret;
5074 }
5075 
5076 /*! \brief Support for Asterisk built-in variables in the dialplan
5077 \note See also
5078  - \ref AstVar Channel variables
5079  - \ref AstCauses The HANGUPCAUSE variable
5080  */
5081 static void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
5082 {
5083  const char not_found = '\0';
5084  char *tmpvar;
5085  const char *s; /* the result */
5086  int offset, length;
5087  int i, need_substring;
5088  struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
5089 
5090  /*
5091  * Make a copy of var because parse_variable_name() modifies the string.
5092  * Then if called directly, we might need to run substring() on the result;
5093  * remember this for later in 'need_substring', 'offset' and 'length'
5094  */
5095  tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
5096  need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
5097 
5098  /*
5099  * Look first into predefined variables, then into variable lists.
5100  * Variable 's' points to the result, according to the following rules:
5101  * s == &not_found (set at the beginning) means that we did not find a
5102  * matching variable and need to look into more places.
5103  * If s != &not_found, s is a valid result string as follows:
5104  * s = NULL if the variable does not have a value;
5105  * you typically do this when looking for an unset predefined variable.
5106  * s = workspace if the result has been assembled there;
5107  * typically done when the result is built e.g. with an snprintf(),
5108  * so we don't need to do an additional copy.
5109  * s != workspace in case we have a string, that needs to be copied
5110  * (the ast_copy_string is done once for all at the end).
5111  * Typically done when the result is already available in some string.
5112  */
5113  s = &not_found; /* default value */
5114  if (s == &not_found) { /* look for more */
5115  if (!strcmp(var, "EPOCH")) {
5116  snprintf(workspace, workspacelen, "%u",(int)time(NULL));
5117  }
5118 
5119  s = workspace;
5120  }
5121  /* if not found, look into chanvars or global vars */
5122  for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
5123  struct ast_var_t *variables;
5124  if (!places[i])
5125  continue;
5126  if (places[i] == &globals)
5128  AST_LIST_TRAVERSE(places[i], variables, entries) {
5129  if (strcasecmp(ast_var_name(variables), var)==0) {
5130  s = ast_var_value(variables);
5131  break;
5132  }
5133  }
5134  if (places[i] == &globals)
5136  }
5137  if (s == &not_found || s ==