ee91b73d53f632f2f5e4411eec1b93f73b714bdc
[asterisk/asterisk.git] / main / asterisk.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@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 /* Doxygenified Copyright Header */
21 /*!
22  * \mainpage Asterisk -- An Open Source Telephony Toolkit
23  *
24  * \par Developer Documentation for Asterisk
25  * This is the main developer documentation for Asterisk. It is 
26  * generated by running "make progdocs".
27  * \par Additional documentation
28  * \arg \ref DevDoc 
29  * \arg \ref ConfigFiles
30  *
31  * \section copyright Copyright and author
32  *
33  * Copyright (C) 1999 - 2006, Digium, Inc.
34  * Asterisk is a trade mark registered by Digium, Inc.
35  *
36  * \author Mark Spencer <markster@digium.com>
37  * Also see \ref AstCREDITS
38  *
39  * \section license License
40  * See http://www.asterisk.org for more information about
41  * the Asterisk project. Please do not directly contact
42  * any of the maintainers of this project for assistance;
43  * the project provides a web site, mailing lists and IRC
44  * channels for your use.
45  *
46  * This program is free software, distributed under the terms of
47  * the GNU General Public License Version 2. See the LICENSE file
48  * at the top of the source tree.
49  *
50  * \verbinclude LICENSE
51  *
52  */
53
54 /*! \file
55   \brief Top level source file for Asterisk  - the Open Source PBX. Implementation
56   of PBX core functions and CLI interface.
57   
58  */
59
60 #include "asterisk.h"
61
62 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
63
64 #include <unistd.h>
65 #include <stdlib.h>
66 #include <sys/time.h>
67 #include <fcntl.h>
68 #include <stdio.h>
69 #include <signal.h>
70 #include <sched.h>
71 #include <sys/socket.h>
72 #include <sys/un.h>
73 #include <sys/wait.h>
74 #include <string.h>
75 #include <errno.h>
76 #include <ctype.h>
77 #include <sys/resource.h>
78 #include <grp.h>
79 #include <pwd.h>
80 #include <sys/stat.h>
81 #ifdef linux
82 #include <sys/prctl.h>
83 #ifdef HAVE_CAP
84 #include <sys/capability.h>
85 #endif /* HAVE_CAP */
86 #endif /* linux */
87 #include <regex.h>
88
89 #if  defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS)
90 #include <netdb.h>
91 #if defined(SOLARIS)
92 int daemon(int, int);  /* defined in libresolv of all places */
93 #endif
94 #endif
95
96 #include "asterisk/logger.h"
97 #include "asterisk/options.h"
98 #include "asterisk/cli.h"
99 #include "asterisk/channel.h"
100 #include "asterisk/ulaw.h"
101 #include "asterisk/alaw.h"
102 #include "asterisk/callerid.h"
103 #include "asterisk/image.h"
104 #include "asterisk/tdd.h"
105 #include "asterisk/term.h"
106 #include "asterisk/manager.h"
107 #include "asterisk/cdr.h"
108 #include "asterisk/pbx.h"
109 #include "asterisk/enum.h"
110 #include "asterisk/rtp.h"
111 #include "asterisk/http.h"
112 #include "asterisk/udptl.h"
113 #include "asterisk/app.h"
114 #include "asterisk/lock.h"
115 #include "asterisk/utils.h"
116 #include "asterisk/file.h"
117 #include "asterisk/io.h"
118 #include "asterisk/lock.h"
119 #include "editline/histedit.h"
120 #include "asterisk/config.h"
121 #include "asterisk/version.h"
122 #include "asterisk/linkedlists.h"
123 #include "asterisk/devicestate.h"
124
125 #include "asterisk/doxyref.h"           /* Doxygen documentation */
126
127 #include "../defaults.h"
128
129 #ifndef AF_LOCAL
130 #define AF_LOCAL AF_UNIX
131 #define PF_LOCAL PF_UNIX
132 #endif
133
134 #define AST_MAX_CONNECTS 128
135 #define NUM_MSGS 64
136
137 /*! \brief Welcome message when starting a CLI interface */
138 #define WELCOME_MESSAGE \
139     ast_verbose("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2006 Digium, Inc. and others.\n" \
140                 "Created by Mark Spencer <markster@digium.com>\n" \
141                 "Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.\n" \
142                 "This is free software, with components licensed under the GNU General Public\n" \
143                 "License version 2 and other licenses; you are welcome to redistribute it under\n" \
144                 "certain conditions. Type 'core show license' for details.\n" \
145                 "=========================================================================\n" \
146                 "NOTE: This is a development version of Asterisk, and should not be used in\n" \
147                 "production installations.\n");
148
149 /*! \defgroup main_options Main Configuration Options
150  \brief Main configuration options from \ref Config_ast "asterisk.conf" or 
151   the operating system command line when starting Asterisk 
152   Some of them can be changed in the CLI 
153  */
154 /*! @{ */
155
156 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
157
158 int option_verbose;                             /*!< Verbosity level */
159 int option_debug;                               /*!< Debug level */
160
161 double option_maxload;                          /*!< Max load avg on system */
162 int option_maxcalls;                            /*!< Max number of active calls */
163 int option_maxfiles;                            /*!< Max number of open file handles (files, sockets) */
164
165 /*! @} */
166
167 char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR;
168 char debug_filename[AST_FILENAME_MAX] = "";
169
170 static int ast_socket = -1;             /*!< UNIX Socket for allowing remote control */
171 static int ast_consock = -1;            /*!< UNIX Socket for controlling another asterisk */
172 pid_t ast_mainpid;
173 struct console {
174         int fd;                         /*!< File descriptor */
175         int p[2];                       /*!< Pipe */
176         pthread_t t;                    /*!< Thread of handler */
177         int mute;                       /*!< Is the console muted for logs */
178 };
179
180 struct ast_atexit {
181         void (*func)(void);
182         AST_LIST_ENTRY(ast_atexit) list;
183 };
184
185 static AST_LIST_HEAD_STATIC(atexits, ast_atexit);
186
187 time_t ast_startuptime;
188 time_t ast_lastreloadtime;
189
190 static History *el_hist;
191 static EditLine *el;
192 static char *remotehostname;
193
194 struct console consoles[AST_MAX_CONNECTS];
195
196 char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
197
198 static int ast_el_add_history(char *);
199 static int ast_el_read_history(char *);
200 static int ast_el_write_history(char *);
201
202 char ast_config_AST_CONFIG_DIR[PATH_MAX];
203 char ast_config_AST_CONFIG_FILE[PATH_MAX];
204 char ast_config_AST_MODULE_DIR[PATH_MAX];
205 char ast_config_AST_SPOOL_DIR[PATH_MAX];
206 char ast_config_AST_MONITOR_DIR[PATH_MAX];
207 char ast_config_AST_VAR_DIR[PATH_MAX];
208 char ast_config_AST_DATA_DIR[PATH_MAX];
209 char ast_config_AST_LOG_DIR[PATH_MAX];
210 char ast_config_AST_AGI_DIR[PATH_MAX];
211 char ast_config_AST_DB[PATH_MAX];
212 char ast_config_AST_KEY_DIR[PATH_MAX];
213 char ast_config_AST_PID[PATH_MAX];
214 char ast_config_AST_SOCKET[PATH_MAX];
215 char ast_config_AST_RUN_DIR[PATH_MAX];
216 char ast_config_AST_RUN_USER[PATH_MAX];
217 char ast_config_AST_RUN_GROUP[PATH_MAX];
218 char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
219 char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0";
220 char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0";
221 char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl";
222 char ast_config_AST_SYSTEM_NAME[20] = "";
223
224 extern const char *ast_build_hostname;
225 extern const char *ast_build_kernel;
226 extern const char *ast_build_machine;
227 extern const char *ast_build_os;
228 extern const char *ast_build_date;
229 extern const char *ast_build_user;
230
231 static char *_argv[256];
232 static int shuttingdown;
233 static int restartnow;
234 static pthread_t consolethread = AST_PTHREADT_NULL;
235
236 static char randompool[256];
237
238 static unsigned int need_reload;
239
240 #if !defined(LOW_MEMORY)
241 struct file_version {
242         AST_LIST_ENTRY(file_version) list;
243         const char *file;
244         char *version;
245 };
246
247 static AST_LIST_HEAD_STATIC(file_versions, file_version);
248
249 void ast_register_file_version(const char *file, const char *version)
250 {
251         struct file_version *new;
252         char *work;
253         size_t version_length;
254
255         work = ast_strdupa(version);
256         work = ast_strip(ast_strip_quoted(work, "$", "$"));
257         version_length = strlen(work) + 1;
258         
259         if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
260                 return;
261
262         new->file = file;
263         new->version = (char *) new + sizeof(*new);
264         memcpy(new->version, work, version_length);
265         AST_LIST_LOCK(&file_versions);
266         AST_LIST_INSERT_HEAD(&file_versions, new, list);
267         AST_LIST_UNLOCK(&file_versions);
268 }
269
270 void ast_unregister_file_version(const char *file)
271 {
272         struct file_version *find;
273
274         AST_LIST_LOCK(&file_versions);
275         AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
276                 if (!strcasecmp(find->file, file)) {
277                         AST_LIST_REMOVE_CURRENT(&file_versions, list);
278                         break;
279                 }
280         }
281         AST_LIST_TRAVERSE_SAFE_END;
282         AST_LIST_UNLOCK(&file_versions);
283         if (find)
284                 free(find);
285 }
286
287 struct thread_list_t {
288         AST_LIST_ENTRY(thread_list_t) list;
289         char *name;
290         pthread_t id;
291 };
292
293 static AST_LIST_HEAD_STATIC(thread_list, thread_list_t);
294
295 static const char show_threads_help[] =
296 "Usage: core show threads\n"
297 "       List threads currently active in the system.\n";
298
299 void ast_register_thread(char *name)
300
301         struct thread_list_t *new = ast_calloc(1, sizeof(*new));
302
303         if (!new)
304                 return;
305         new->id = pthread_self();
306         new->name = name; /* steal the allocated memory for the thread name */
307         AST_LIST_LOCK(&thread_list);
308         AST_LIST_INSERT_HEAD(&thread_list, new, list);
309         AST_LIST_UNLOCK(&thread_list);
310 }
311
312 void ast_unregister_thread(void *id)
313 {
314         struct thread_list_t *x;
315
316         AST_LIST_LOCK(&thread_list);
317         AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
318                 if ((void *) x->id == id) {
319                         AST_LIST_REMOVE_CURRENT(&thread_list, list);
320                         break;
321                 }
322         }
323         AST_LIST_TRAVERSE_SAFE_END;
324         AST_LIST_UNLOCK(&thread_list);
325         if (x) {
326                 free(x->name);
327                 free(x);
328         }
329 }
330
331 #if !defined(LOW_MEMORY)
332 /*! \brief Give an overview of core settings */
333 static int handle_show_settings(int fd, int argc, char *argv[])
334 {
335         char buf[BUFSIZ];
336         struct tm tm;
337
338         ast_cli(fd, "\nPBX Core settings\n");
339         ast_cli(fd, "-----------------\n");
340         ast_cli(fd, "  Version:                     %s\n", "" ASTERISK_VERSION "" );
341         if (option_maxcalls)
342                 ast_cli(fd, "  Max. calls:                  %d (Current %d)\n", option_maxcalls, ast_active_channels());
343         else
344                 ast_cli(fd, "  Max. calls:                  Not set\n");
345         if (option_maxfiles)
346                 ast_cli(fd, "  Max. open file handles:      %d\n", option_maxfiles); 
347         else
348                 ast_cli(fd, "  Max. open file handles:      Not set\n");
349         ast_cli(fd, "  Verbosity:                   %d\n", option_verbose);
350         ast_cli(fd, "  Debug level:                 %d\n", option_debug);
351         ast_cli(fd, "  Max load avg:                %lf\n", option_maxload);
352         if (localtime_r(&ast_startuptime, &tm)) {
353                 strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
354                 ast_cli(fd, "  Startup time:                %s\n", buf);
355         }
356         if (localtime_r(&ast_lastreloadtime, &tm)) {
357                 strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
358                 ast_cli(fd, "  Last reload time:            %s\n", buf);
359         }
360         ast_cli(fd, "  System:                      %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
361         ast_cli(fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
362         ast_cli(fd, "  Default language:            %s\n", defaultlanguage);
363         ast_cli(fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
364         ast_cli(fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
365         ast_cli(fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
366         ast_cli(fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
367         ast_cli(fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
368         ast_cli(fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
369
370         ast_cli(fd, "\n* Subsystems\n");
371         ast_cli(fd, "  -------------\n");
372         ast_cli(fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
373         ast_cli(fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
374         ast_cli(fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
375         ast_cli(fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
376
377         /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
378
379         ast_cli(fd, "\n* Directories\n");
380         ast_cli(fd, "  -------------\n");
381         ast_cli(fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
382         ast_cli(fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
383         ast_cli(fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
384         ast_cli(fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
385         ast_cli(fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
386         ast_cli(fd, "\n\n");
387         return 0;
388 }
389 #endif
390
391 static int handle_show_threads(int fd, int argc, char *argv[])
392 {
393         int count = 0;
394         struct thread_list_t *cur;
395
396         AST_LIST_LOCK(&thread_list);
397         AST_LIST_TRAVERSE(&thread_list, cur, list) {
398                 ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
399                 count++;
400         }
401         AST_LIST_UNLOCK(&thread_list);
402         ast_cli(fd, "%d threads listed.\n", count);
403         return 0;
404 }
405
406 struct profile_entry {
407         const char *name;
408         uint64_t        scale;  /* if non-zero, values are scaled by this */
409         int64_t mark;
410         int64_t value;
411         int64_t events;
412 };
413
414 struct profile_data {
415         int entries;
416         int max_size;
417         struct profile_entry e[0];
418 };
419
420 static struct profile_data *prof_data;
421
422 /*! \brief allocates a counter with a given name and scale.
423  * \return Returns the identifier of the counter.
424  */
425 int ast_add_profile(const char *name, uint64_t scale)
426 {
427         int l = sizeof(struct profile_data);
428         int n = 10;     /* default entries */
429
430         if (prof_data == NULL) {
431                 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
432                 if (prof_data == NULL)
433                         return -1;
434                 prof_data->entries = 0;
435                 prof_data->max_size = n;
436         }
437         if (prof_data->entries >= prof_data->max_size) {
438                 void *p;
439                 n = prof_data->max_size + 20;
440                 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
441                 if (p == NULL)
442                         return -1;
443                 prof_data = p;
444                 prof_data->max_size = n;
445         }
446         n = prof_data->entries++;
447         prof_data->e[n].name = ast_strdup(name);
448         prof_data->e[n].value = 0;
449         prof_data->e[n].events = 0;
450         prof_data->e[n].mark = 0;
451         prof_data->e[n].scale = scale;
452         return n;
453 }
454
455 int64_t ast_profile(int i, int64_t delta)
456 {
457         if (!prof_data || i < 0 || i > prof_data->entries)      /* invalid index */
458                 return 0;
459         if (prof_data->e[i].scale > 1)
460                 delta /= prof_data->e[i].scale;
461         prof_data->e[i].value += delta;
462         prof_data->e[i].events++;
463         return prof_data->e[i].value;
464 }
465
466 #if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
467 #if defined(__FreeBSD__)
468 #include <machine/cpufunc.h>
469 #elif defined(linux)
470 static __inline uint64_t
471 rdtsc(void)
472
473         uint64_t rv;
474
475         __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
476         return (rv);
477 }
478 #endif
479 #else   /* supply a dummy function on other platforms */
480 static __inline uint64_t
481 rdtsc(void)
482 {
483         return 0;
484 }
485 #endif
486
487 int64_t ast_mark(int i, int startstop)
488 {
489         if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
490                 return 0;
491         if (startstop == 1)
492                 prof_data->e[i].mark = rdtsc();
493         else {
494                 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
495                 if (prof_data->e[i].scale > 1)
496                         prof_data->e[i].mark /= prof_data->e[i].scale;
497                 prof_data->e[i].value += prof_data->e[i].mark;
498                 prof_data->e[i].events++;
499         }
500         return prof_data->e[i].mark;
501 }
502
503 static int handle_show_profile(int fd, int argc, char *argv[])
504 {
505         int i, min, max;
506         char *search = NULL;
507
508         if (prof_data == NULL)
509                 return 0;
510
511         min = 0;
512         max = prof_data->entries;
513         if  (argc > 3) { /* specific entries */
514                 if (isdigit(argv[3][0])) {
515                         min = atoi(argv[3]);
516                         if (argc == 5 && strcmp(argv[4], "-"))
517                                 max = atoi(argv[4]);
518                 } else
519                         search = argv[3];
520         }
521         if (max > prof_data->entries)
522                 max = prof_data->entries;
523         if (!strcmp(argv[1], "clear")) {
524                 for (i= min; i < max; i++) {
525                         if (!search || strstr(prof_data->e[i].name, search)) {
526                                 prof_data->e[i].value = 0;
527                                 prof_data->e[i].events = 0;
528                         }
529                 }
530                 return 0;
531         }
532         ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
533                 prof_data->entries, prof_data->max_size);
534         ast_cli(fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
535                         "Value", "Average", "Name");
536         for (i = min; i < max; i++) {
537                 struct profile_entry *e = &prof_data->e[i];
538                 if (!search || strstr(prof_data->e[i].name, search))
539                     ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
540                         i,
541                         (long)e->scale,
542                         (long)e->events, (long long)e->value,
543                         (long long)(e->events ? e->value / e->events : e->value),
544                         e->name);
545         }
546         return 0;
547 }
548
549 static const char show_version_files_help[] = 
550 "Usage: core show file version [like <pattern>]\n"
551 "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
552 "       Optional regular expression pattern is used to filter the file list.\n";
553
554 /*! \brief CLI command to list module versions */
555 static int handle_show_version_files(int fd, int argc, char *argv[])
556 {
557 #define FORMAT "%-25.25s %-40.40s\n"
558         struct file_version *iterator;
559         regex_t regexbuf;
560         int havepattern = 0;
561         int havename = 0;
562         int count_files = 0;
563
564         switch (argc) {
565         case 5:
566                 if (!strcasecmp(argv[3], "like")) {
567                         if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
568                                 return RESULT_SHOWUSAGE;
569                         havepattern = 1;
570                 } else
571                         return RESULT_SHOWUSAGE;
572                 break;
573         case 4:
574                 havename = 1;
575                 break;
576         case 3:
577                 break;
578         default:
579                 return RESULT_SHOWUSAGE;
580         }
581
582         ast_cli(fd, FORMAT, "File", "Revision");
583         ast_cli(fd, FORMAT, "----", "--------");
584         AST_LIST_LOCK(&file_versions);
585         AST_LIST_TRAVERSE(&file_versions, iterator, list) {
586                 if (havename && strcasecmp(iterator->file, argv[3]))
587                         continue;
588
589                 if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
590                         continue;
591
592                 ast_cli(fd, FORMAT, iterator->file, iterator->version);
593                 count_files++;
594                 if (havename)
595                         break;
596         }
597         AST_LIST_UNLOCK(&file_versions);
598         if (!havename) {
599                 ast_cli(fd, "%d files listed.\n", count_files);
600         }
601
602         if (havepattern)
603                 regfree(&regexbuf);
604
605         return RESULT_SUCCESS;
606 #undef FORMAT
607 }
608
609 static char *complete_show_version_files(const char *line, const char *word, int pos, int state)
610 {
611         struct file_version *find;
612         int which = 0;
613         char *ret = NULL;
614         int matchlen = strlen(word);
615
616         if (pos != 3)
617                 return NULL;
618
619         AST_LIST_LOCK(&file_versions);
620         AST_LIST_TRAVERSE(&file_versions, find, list) {
621                 if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
622                         ret = ast_strdup(find->file);
623                         break;
624                 }
625         }
626         AST_LIST_UNLOCK(&file_versions);
627
628         return ret;
629 }
630 #endif /* ! LOW_MEMORY */
631
632 int ast_register_atexit(void (*func)(void))
633 {
634         int res = -1;
635         struct ast_atexit *ae;
636         ast_unregister_atexit(func);    
637         AST_LIST_LOCK(&atexits);
638         if ((ae = ast_calloc(1, sizeof(*ae)))) {
639                 AST_LIST_INSERT_HEAD(&atexits, ae, list);
640                 ae->func = func;
641                 res = 0;
642         }
643         AST_LIST_UNLOCK(&atexits);
644         return res;
645 }
646
647 void ast_unregister_atexit(void (*func)(void))
648 {
649         struct ast_atexit *ae;
650         AST_LIST_LOCK(&atexits);
651         AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
652                 if (ae->func == func) {
653                         AST_LIST_REMOVE_CURRENT(&atexits, list);
654                         break;
655                 }
656         }
657         AST_LIST_TRAVERSE_SAFE_END
658         AST_LIST_UNLOCK(&atexits);
659 }
660
661 static int fdprint(int fd, const char *s)
662 {
663         return write(fd, s, strlen(s) + 1);
664 }
665
666 /*! \brief NULL handler so we can collect the child exit status */
667 static void null_sig_handler(int signal)
668 {
669
670 }
671
672 AST_MUTEX_DEFINE_STATIC(safe_system_lock);
673 /*! \brief Keep track of how many threads are currently trying to wait*() on
674  *  a child process */
675 static unsigned int safe_system_level = 0;
676 static void *safe_system_prev_handler;
677
678 void ast_replace_sigchld(void)
679 {
680         unsigned int level;
681
682         ast_mutex_lock(&safe_system_lock);
683         level = safe_system_level++;
684
685         /* only replace the handler if it has not already been done */
686         if (level == 0)
687                 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
688
689         ast_mutex_unlock(&safe_system_lock);
690 }
691
692 void ast_unreplace_sigchld(void)
693 {
694         unsigned int level;
695
696         ast_mutex_lock(&safe_system_lock);
697         level = --safe_system_level;
698
699         /* only restore the handler if we are the last one */
700         if (level == 0)
701                 signal(SIGCHLD, safe_system_prev_handler);
702
703         ast_mutex_unlock(&safe_system_lock);
704 }
705
706 int ast_safe_system(const char *s)
707 {
708         pid_t pid;
709 #ifdef HAVE_WORKING_FORK
710         int x;
711 #endif
712         int res;
713         struct rusage rusage;
714         int status;
715
716 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
717         ast_replace_sigchld();
718
719 #ifdef HAVE_WORKING_FORK
720         pid = fork();
721 #else
722         pid = vfork();
723 #endif  
724
725         if (pid == 0) {
726 #ifdef HAVE_WORKING_FORK
727                 if (ast_opt_high_priority)
728                         ast_set_priority(0);
729                 /* Close file descriptors and launch system command */
730                 for (x = STDERR_FILENO + 1; x < 4096; x++)
731                         close(x);
732 #endif
733                 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
734                 _exit(1);
735         } else if (pid > 0) {
736                 for (;;) {
737                         res = wait4(pid, &status, 0, &rusage);
738                         if (res > -1) {
739                                 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
740                                 break;
741                         } else if (errno != EINTR) 
742                                 break;
743                 }
744         } else {
745                 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
746                 res = -1;
747         }
748
749         ast_unreplace_sigchld();
750 #else
751         res = -1;
752 #endif
753
754         return res;
755 }
756
757 /*!
758  * \brief mute or unmute a console from logging
759  */
760 void ast_console_toggle_mute(int fd) {
761         int x;
762         for (x = 0;x < AST_MAX_CONNECTS; x++) {
763                 if (fd == consoles[x].fd) {
764                         if (consoles[x].mute) {
765                                 consoles[x].mute = 0;
766                                 ast_cli(fd, "Console is not muted anymore.\n");
767                         } else {
768                                 consoles[x].mute = 1;
769                                 ast_cli(fd, "Console is muted.\n");
770                         }
771                         return;
772                 }
773         }
774         ast_cli(fd, "Couldn't find remote console.\n");
775 }
776
777 /*!
778  * \brief log the string to all attached console clients
779  */
780 static void ast_network_puts_mutable(const char *string)
781 {
782         int x;
783         for (x = 0;x < AST_MAX_CONNECTS; x++) {
784                 if (consoles[x].mute)
785                         continue;
786                 if (consoles[x].fd > -1) 
787                         fdprint(consoles[x].p[1], string);
788         }
789 }
790
791 /*!
792  * \brief log the string to the console, and all attached
793  * console clients
794  */
795 void ast_console_puts_mutable(const char *string)
796 {
797         fputs(string, stdout);
798         fflush(stdout);
799         ast_network_puts_mutable(string);
800 }
801
802 /*!
803  * \brief write the string to all attached console clients
804  */
805 static void ast_network_puts(const char *string)
806 {
807         int x;
808         for (x=0; x < AST_MAX_CONNECTS; x++) {
809                 if (consoles[x].fd > -1) 
810                         fdprint(consoles[x].p[1], string);
811         }
812 }
813
814 /*!
815  * write the string to the console, and all attached
816  * console clients
817  */
818 void ast_console_puts(const char *string)
819 {
820         fputs(string, stdout);
821         fflush(stdout);
822         ast_network_puts(string);
823 }
824
825 static void network_verboser(const char *s)
826 {
827         ast_network_puts_mutable(s);
828 }
829
830 static pthread_t lthread;
831
832 static void *netconsole(void *vconsole)
833 {
834         struct console *con = vconsole;
835         char hostname[MAXHOSTNAMELEN] = "";
836         char tmp[512];
837         int res;
838         struct pollfd fds[2];
839         
840         if (gethostname(hostname, sizeof(hostname)-1))
841                 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
842         snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ASTERISK_VERSION);
843         fdprint(con->fd, tmp);
844         for (;;) {
845                 fds[0].fd = con->fd;
846                 fds[0].events = POLLIN;
847                 fds[0].revents = 0;
848                 fds[1].fd = con->p[0];
849                 fds[1].events = POLLIN;
850                 fds[1].revents = 0;
851
852                 res = poll(fds, 2, -1);
853                 if (res < 0) {
854                         if (errno != EINTR)
855                                 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
856                         continue;
857                 }
858                 if (fds[0].revents) {
859                         res = read(con->fd, tmp, sizeof(tmp));
860                         if (res < 1) {
861                                 break;
862                         }
863                         tmp[res] = 0;
864                         ast_cli_command(con->fd, tmp);
865                 }
866                 if (fds[1].revents) {
867                         res = read(con->p[0], tmp, sizeof(tmp));
868                         if (res < 1) {
869                                 ast_log(LOG_ERROR, "read returned %d\n", res);
870                                 break;
871                         }
872                         res = write(con->fd, tmp, res);
873                         if (res < 1)
874                                 break;
875                 }
876         }
877         if (option_verbose > 2) 
878                 ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n");
879         close(con->fd);
880         close(con->p[0]);
881         close(con->p[1]);
882         con->fd = -1;
883         
884         return NULL;
885 }
886
887 static void *listener(void *unused)
888 {
889         struct sockaddr_un sunaddr;
890         int s;
891         socklen_t len;
892         int x;
893         int flags;
894         struct pollfd fds[1];
895         pthread_attr_t attr;
896         pthread_attr_init(&attr);
897         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
898         for (;;) {
899                 if (ast_socket < 0)
900                         return NULL;
901                 fds[0].fd = ast_socket;
902                 fds[0].events = POLLIN;
903                 s = poll(fds, 1, -1);
904                 pthread_testcancel();
905                 if (s < 0) {
906                         if (errno != EINTR)
907                                 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
908                         continue;
909                 }
910                 len = sizeof(sunaddr);
911                 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
912                 if (s < 0) {
913                         if (errno != EINTR)
914                                 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
915                 } else {
916                         for (x = 0; x < AST_MAX_CONNECTS; x++) {
917                                 if (consoles[x].fd < 0) {
918                                         if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
919                                                 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
920                                                 consoles[x].fd = -1;
921                                                 fdprint(s, "Server failed to create pipe\n");
922                                                 close(s);
923                                                 break;
924                                         }
925                                         flags = fcntl(consoles[x].p[1], F_GETFL);
926                                         fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
927                                         consoles[x].fd = s;
928                                         consoles[x].mute = ast_opt_mute;
929                                         if (ast_pthread_create_background(&consoles[x].t, &attr, netconsole, &consoles[x])) {
930                                                 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
931                                                 close(consoles[x].p[0]);
932                                                 close(consoles[x].p[1]);
933                                                 consoles[x].fd = -1;
934                                                 fdprint(s, "Server failed to spawn thread\n");
935                                                 close(s);
936                                         }
937                                         break;
938                                 }
939                         }
940                         if (x >= AST_MAX_CONNECTS) {
941                                 fdprint(s, "No more connections allowed\n");
942                                 ast_log(LOG_WARNING, "No more connections allowed\n");
943                                 close(s);
944                         } else if (consoles[x].fd > -1) {
945                                 if (option_verbose > 2) 
946                                         ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n");
947                         }
948                 }
949         }
950         return NULL;
951 }
952
953 static int ast_makesocket(void)
954 {
955         struct sockaddr_un sunaddr;
956         int res;
957         int x;
958         uid_t uid = -1;
959         gid_t gid = -1;
960
961         for (x = 0; x < AST_MAX_CONNECTS; x++)  
962                 consoles[x].fd = -1;
963         unlink(ast_config_AST_SOCKET);
964         ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
965         if (ast_socket < 0) {
966                 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
967                 return -1;
968         }               
969         memset(&sunaddr, 0, sizeof(sunaddr));
970         sunaddr.sun_family = AF_LOCAL;
971         ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
972         res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
973         if (res) {
974                 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
975                 close(ast_socket);
976                 ast_socket = -1;
977                 return -1;
978         }
979         res = listen(ast_socket, 2);
980         if (res < 0) {
981                 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
982                 close(ast_socket);
983                 ast_socket = -1;
984                 return -1;
985         }
986         ast_register_verbose(network_verboser);
987         ast_pthread_create_background(&lthread, NULL, listener, NULL);
988
989         if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
990                 struct passwd *pw;
991                 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
992                         ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
993                 else
994                         uid = pw->pw_uid;
995         }
996                 
997         if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
998                 struct group *grp;
999                 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
1000                         ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
1001                 else
1002                         gid = grp->gr_gid;
1003         }
1004
1005         if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
1006                 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1007
1008         if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
1009                 int p1;
1010                 mode_t p;
1011                 sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1);
1012                 p = p1;
1013                 if ((chmod(ast_config_AST_SOCKET, p)) < 0)
1014                         ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1015         }
1016
1017         return 0;
1018 }
1019
1020 static int ast_tryconnect(void)
1021 {
1022         struct sockaddr_un sunaddr;
1023         int res;
1024         ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
1025         if (ast_consock < 0) {
1026                 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
1027                 return 0;
1028         }
1029         memset(&sunaddr, 0, sizeof(sunaddr));
1030         sunaddr.sun_family = AF_LOCAL;
1031         ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1032         res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1033         if (res) {
1034                 close(ast_consock);
1035                 ast_consock = -1;
1036                 return 0;
1037         } else
1038                 return 1;
1039 }
1040
1041 /*! \brief Urgent handler
1042
1043  Called by soft_hangup to interrupt the poll, read, or other
1044  system call.  We don't actually need to do anything though.  
1045  Remember: Cannot EVER ast_log from within a signal handler 
1046  */
1047 static void urg_handler(int num)
1048 {
1049         signal(num, urg_handler);
1050         return;
1051 }
1052
1053 static void hup_handler(int num)
1054 {
1055         if (option_verbose > 1) 
1056                 printf("Received HUP signal -- Reloading configs\n");
1057         if (restartnow)
1058                 execvp(_argv[0], _argv);
1059         need_reload = 1;
1060         signal(num, hup_handler);
1061 }
1062
1063 static void child_handler(int sig)
1064 {
1065         /* Must not ever ast_log or ast_verbose within signal handler */
1066         int n, status;
1067
1068         /*
1069          * Reap all dead children -- not just one
1070          */
1071         for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
1072                 ;
1073         if (n == 0 && option_debug)     
1074                 printf("Huh?  Child handler, but nobody there?\n");
1075         signal(sig, child_handler);
1076 }
1077
1078 /*! \brief Set maximum open files */
1079 static void set_ulimit(int value)
1080 {
1081         struct rlimit l = {0, 0};
1082         
1083         if (value <= 0) {
1084                 ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
1085                 return;
1086         }
1087         
1088         l.rlim_cur = value;
1089         l.rlim_max = value;
1090         
1091         if (setrlimit(RLIMIT_NOFILE, &l)) {
1092                 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
1093                 return;
1094         }
1095         
1096         ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
1097         
1098         return;
1099 }
1100
1101 /*! \brief Set an X-term or screen title */
1102 static void set_title(char *text)
1103 {
1104         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1105                 fprintf(stdout, "\033]2;%s\007", text);
1106 }
1107
1108 static void set_icon(char *text)
1109 {
1110         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1111                 fprintf(stdout, "\033]1;%s\007", text);
1112 }
1113
1114 /*! \brief We set ourselves to a high priority, that we might pre-empt everything
1115    else.  If your PBX has heavy activity on it, this is a good thing.  */
1116 int ast_set_priority(int pri)
1117 {
1118         struct sched_param sched;
1119         memset(&sched, 0, sizeof(sched));
1120 #ifdef __linux__
1121         if (pri) {  
1122                 sched.sched_priority = 10;
1123                 if (sched_setscheduler(0, SCHED_RR, &sched)) {
1124                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1125                         return -1;
1126                 } else
1127                         if (option_verbose)
1128                                 ast_verbose("Set to realtime thread\n");
1129         } else {
1130                 sched.sched_priority = 0;
1131                 if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
1132                         ast_log(LOG_WARNING, "Unable to set normal priority\n");
1133                         return -1;
1134                 }
1135         }
1136 #else
1137         if (pri) {
1138                 if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
1139                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1140                         return -1;
1141                 } else
1142                         if (option_verbose)
1143                                 ast_verbose("Set to high priority\n");
1144         } else {
1145                 if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
1146                         ast_log(LOG_WARNING, "Unable to set normal priority\n");
1147                         return -1;
1148                 }
1149         }
1150 #endif
1151         return 0;
1152 }
1153
1154 static void ast_run_atexits(void)
1155 {
1156         struct ast_atexit *ae;
1157         AST_LIST_LOCK(&atexits);
1158         AST_LIST_TRAVERSE(&atexits, ae, list) {
1159                 if (ae->func) 
1160                         ae->func();
1161         }
1162         AST_LIST_UNLOCK(&atexits);
1163 }
1164
1165 static void quit_handler(int num, int nice, int safeshutdown, int restart)
1166 {
1167         char filename[80] = "";
1168         time_t s,e;
1169         int x;
1170         /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
1171         ast_cdr_engine_term();
1172         if (safeshutdown) {
1173                 shuttingdown = 1;
1174                 if (!nice) {
1175                         /* Begin shutdown routine, hanging up active channels */
1176                         ast_begin_shutdown(1);
1177                         if (option_verbose && ast_opt_console)
1178                                 ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
1179                         time(&s);
1180                         for (;;) {
1181                                 time(&e);
1182                                 /* Wait up to 15 seconds for all channels to go away */
1183                                 if ((e - s) > 15)
1184                                         break;
1185                                 if (!ast_active_channels())
1186                                         break;
1187                                 if (!shuttingdown)
1188                                         break;
1189                                 /* Sleep 1/10 of a second */
1190                                 usleep(100000);
1191                         }
1192                 } else {
1193                         if (nice < 2)
1194                                 ast_begin_shutdown(0);
1195                         if (option_verbose && ast_opt_console)
1196                                 ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
1197                         for (;;) {
1198                                 if (!ast_active_channels())
1199                                         break;
1200                                 if (!shuttingdown)
1201                                         break;
1202                                 sleep(1);
1203                         }
1204                 }
1205
1206                 if (!shuttingdown) {
1207                         if (option_verbose && ast_opt_console)
1208                                 ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
1209                         return;
1210                 }
1211         }
1212         if (ast_opt_console || ast_opt_remote) {
1213                 if (getenv("HOME")) 
1214                         snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
1215                 if (!ast_strlen_zero(filename))
1216                         ast_el_write_history(filename);
1217                 if (el != NULL)
1218                         el_end(el);
1219                 if (el_hist != NULL)
1220                         history_end(el_hist);
1221         }
1222         if (option_verbose)
1223                 ast_verbose("Executing last minute cleanups\n");
1224         ast_run_atexits();
1225         /* Called on exit */
1226         if (option_verbose && ast_opt_console)
1227                 ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
1228         if (option_debug)
1229                 ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
1230         manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
1231         if (ast_socket > -1) {
1232                 pthread_cancel(lthread);
1233                 close(ast_socket);
1234                 ast_socket = -1;
1235                 unlink(ast_config_AST_SOCKET);
1236         }
1237         if (ast_consock > -1)
1238                 close(ast_consock);
1239         if (!ast_opt_remote)
1240                 unlink(ast_config_AST_PID);
1241         printf(term_quit());
1242         if (restart) {
1243                 if (option_verbose || ast_opt_console)
1244                         ast_verbose("Preparing for Asterisk restart...\n");
1245                 /* Mark all FD's for closing on exec */
1246                 for (x=3; x < 32768; x++) {
1247                         fcntl(x, F_SETFD, FD_CLOEXEC);
1248                 }
1249                 if (option_verbose || ast_opt_console)
1250                         ast_verbose("Asterisk is now restarting...\n");
1251                 restartnow = 1;
1252
1253                 /* close logger */
1254                 close_logger();
1255
1256                 /* If there is a consolethread running send it a SIGHUP 
1257                    so it can execvp, otherwise we can do it ourselves */
1258                 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
1259                         pthread_kill(consolethread, SIGHUP);
1260                         /* Give the signal handler some time to complete */
1261                         sleep(2);
1262                 } else
1263                         execvp(_argv[0], _argv);
1264         
1265         } else {
1266                 /* close logger */
1267                 close_logger();
1268         }
1269         exit(0);
1270 }
1271
1272 static void __quit_handler(int num)
1273 {
1274         quit_handler(num, 0, 1, 0);
1275 }
1276
1277 static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp)
1278 {
1279         const char *c;
1280         if (!strncmp(s, cmp, strlen(cmp))) {
1281                 c = s + strlen(cmp);
1282                 term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
1283                 return c;
1284         }
1285         return NULL;
1286 }
1287
1288 static void console_verboser(const char *s)
1289 {
1290         char tmp[80];
1291         const char *c = NULL;
1292
1293         if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
1294             (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
1295             (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
1296             (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
1297                 fputs(tmp, stdout);
1298                 fputs(c, stdout);
1299         } else
1300                 fputs(s, stdout);
1301
1302         fflush(stdout);
1303         
1304         /* Wake up a poll()ing console */
1305         if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
1306                 pthread_kill(consolethread, SIGURG);
1307 }
1308
1309 static int ast_all_zeros(char *s)
1310 {
1311         while (*s) {
1312                 if (*s > 32)
1313                         return 0;
1314                 s++;  
1315         }
1316         return 1;
1317 }
1318
1319 static void consolehandler(char *s)
1320 {
1321         printf(term_end());
1322         fflush(stdout);
1323
1324         /* Called when readline data is available */
1325         if (!ast_all_zeros(s))
1326                 ast_el_add_history(s);
1327         /* The real handler for bang */
1328         if (s[0] == '!') {
1329                 if (s[1])
1330                         ast_safe_system(s+1);
1331                 else
1332                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
1333         } else 
1334                 ast_cli_command(STDOUT_FILENO, s);
1335 }
1336
1337 static int remoteconsolehandler(char *s)
1338 {
1339         int ret = 0;
1340
1341         /* Called when readline data is available */
1342         if (!ast_all_zeros(s))
1343                 ast_el_add_history(s);
1344         /* The real handler for bang */
1345         if (s[0] == '!') {
1346                 if (s[1])
1347                         ast_safe_system(s+1);
1348                 else
1349                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
1350                 ret = 1;
1351         }
1352         if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
1353             (s[4] == '\0' || isspace(s[4]))) {
1354                 quit_handler(0, 0, 0, 0);
1355                 ret = 1;
1356         }
1357
1358         return ret;
1359 }
1360
1361 static const char abort_halt_help[] = 
1362 "Usage: abort shutdown\n"
1363 "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
1364 "       call operations.\n";
1365
1366 static const char shutdown_now_help[] = 
1367 "Usage: stop now\n"
1368 "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
1369
1370 static const char shutdown_gracefully_help[] = 
1371 "Usage: stop gracefully\n"
1372 "       Causes Asterisk to not accept new calls, and exit when all\n"
1373 "       active calls have terminated normally.\n";
1374
1375 static const char shutdown_when_convenient_help[] = 
1376 "Usage: stop when convenient\n"
1377 "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
1378
1379 static const char restart_now_help[] = 
1380 "Usage: restart now\n"
1381 "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
1382 "       restart.\n";
1383
1384 static const char restart_gracefully_help[] = 
1385 "Usage: restart gracefully\n"
1386 "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
1387 "       restart when all active calls have ended.\n";
1388
1389 static const char restart_when_convenient_help[] = 
1390 "Usage: restart when convenient\n"
1391 "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
1392
1393 static const char bang_help[] =
1394 "Usage: !<command>\n"
1395 "       Executes a given shell command\n";
1396
1397 static const char show_warranty_help[] =
1398 "Usage: core show warranty\n"
1399 "       Shows the warranty (if any) for this copy of Asterisk.\n";
1400
1401 static const char show_license_help[] =
1402 "Usage: core show license\n"
1403 "       Shows the license(s) for this copy of Asterisk.\n";
1404
1405 static const char version_help[] =
1406 "Usage: core show version\n"
1407 "       Shows Asterisk version information.\n";
1408
1409 static int handle_version(int fd, int argc, char *argv[])
1410 {
1411         if (argc != 3)
1412                 return RESULT_SHOWUSAGE;
1413         ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
1414                 ASTERISK_VERSION, ast_build_user, ast_build_hostname,
1415                 ast_build_machine, ast_build_os, ast_build_date);
1416         return RESULT_SUCCESS;
1417 }
1418
1419 #if 0
1420 static int handle_quit(int fd, int argc, char *argv[])
1421 {
1422         if (argc != 1)
1423                 return RESULT_SHOWUSAGE;
1424         quit_handler(0, 0, 1, 0);
1425         return RESULT_SUCCESS;
1426 }
1427 #endif
1428
1429 static int handle_shutdown_now(int fd, int argc, char *argv[])
1430 {
1431         if (argc != 2)
1432                 return RESULT_SHOWUSAGE;
1433         quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
1434         return RESULT_SUCCESS;
1435 }
1436
1437 static int handle_shutdown_gracefully(int fd, int argc, char *argv[])
1438 {
1439         if (argc != 2)
1440                 return RESULT_SHOWUSAGE;
1441         quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
1442         return RESULT_SUCCESS;
1443 }
1444
1445 static int handle_shutdown_when_convenient(int fd, int argc, char *argv[])
1446 {
1447         if (argc != 3)
1448                 return RESULT_SHOWUSAGE;
1449         ast_cli(fd, "Waiting for inactivity to perform halt\n");
1450         quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
1451         return RESULT_SUCCESS;
1452 }
1453
1454 static int handle_restart_now(int fd, int argc, char *argv[])
1455 {
1456         if (argc != 2)
1457                 return RESULT_SHOWUSAGE;
1458         quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
1459         return RESULT_SUCCESS;
1460 }
1461
1462 static int handle_restart_gracefully(int fd, int argc, char *argv[])
1463 {
1464         if (argc != 2)
1465                 return RESULT_SHOWUSAGE;
1466         quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
1467         return RESULT_SUCCESS;
1468 }
1469
1470 static int handle_restart_when_convenient(int fd, int argc, char *argv[])
1471 {
1472         if (argc != 3)
1473                 return RESULT_SHOWUSAGE;
1474         ast_cli(fd, "Waiting for inactivity to perform restart\n");
1475         quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
1476         return RESULT_SUCCESS;
1477 }
1478
1479 static int handle_abort_halt(int fd, int argc, char *argv[])
1480 {
1481         if (argc != 2)
1482                 return RESULT_SHOWUSAGE;
1483         ast_cancel_shutdown();
1484         shuttingdown = 0;
1485         return RESULT_SUCCESS;
1486 }
1487
1488 static int handle_bang(int fd, int argc, char *argv[])
1489 {
1490         return RESULT_SUCCESS;
1491 }
1492 static const char warranty_lines[] = {
1493         "\n"
1494         "                           NO WARRANTY\n"
1495         "\n"
1496         "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
1497         "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n"
1498         "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
1499         "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
1500         "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
1501         "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n"
1502         "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n"
1503         "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
1504         "REPAIR OR CORRECTION.\n"
1505         "\n"
1506         "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
1507         "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
1508         "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
1509         "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
1510         "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
1511         "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
1512         "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
1513         "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
1514         "POSSIBILITY OF SUCH DAMAGES.\n"
1515 };
1516
1517 static int show_warranty(int fd, int argc, char *argv[])
1518 {
1519         ast_cli(fd, warranty_lines);
1520
1521         return RESULT_SUCCESS;
1522 }
1523
1524 static const char license_lines[] = {
1525         "\n"
1526         "This program is free software; you can redistribute it and/or modify\n"
1527         "it under the terms of the GNU General Public License version 2 as\n"
1528         "published by the Free Software Foundation.\n"
1529         "\n"
1530         "This program also contains components licensed under other licenses.\n"
1531         "They include:\n"
1532         "\n"
1533         "This program is distributed in the hope that it will be useful,\n"
1534         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1535         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
1536         "GNU General Public License for more details.\n"
1537         "\n"
1538         "You should have received a copy of the GNU General Public License\n"
1539         "along with this program; if not, write to the Free Software\n"
1540         "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
1541 };
1542
1543 static int show_license(int fd, int argc, char *argv[])
1544 {
1545         ast_cli(fd, license_lines);
1546
1547         return RESULT_SUCCESS;
1548 }
1549
1550 #define ASTERISK_PROMPT "*CLI> "
1551
1552 #define ASTERISK_PROMPT2 "%s*CLI> "
1553
1554 static struct ast_cli_entry cli_asterisk[] = {
1555         { { "abort", "halt", NULL },
1556         handle_abort_halt, "Cancel a running halt",
1557         abort_halt_help },
1558
1559         { { "stop", "now", NULL },
1560         handle_shutdown_now, "Shut down Asterisk immediately",
1561         shutdown_now_help },
1562
1563         { { "stop", "gracefully", NULL },
1564         handle_shutdown_gracefully, "Gracefully shut down Asterisk",
1565         shutdown_gracefully_help },
1566
1567         { { "stop", "when", "convenient", NULL },
1568         handle_shutdown_when_convenient, "Shut down Asterisk at empty call volume",
1569         shutdown_when_convenient_help },
1570
1571         { { "restart", "now", NULL },
1572         handle_restart_now, "Restart Asterisk immediately", restart_now_help },
1573
1574         { { "restart", "gracefully", NULL },
1575         handle_restart_gracefully, "Restart Asterisk gracefully",
1576         restart_gracefully_help },
1577
1578         { { "restart", "when", "convenient", NULL },
1579         handle_restart_when_convenient, "Restart Asterisk at empty call volume",
1580         restart_when_convenient_help },
1581
1582         { { "core", "show", "warranty", NULL },
1583         show_warranty, "Show the warranty (if any) for this copy of Asterisk",
1584         show_warranty_help },
1585
1586         { { "core", "show", "license", NULL },
1587         show_license, "Show the license(s) for this copy of Asterisk",
1588         show_license_help },
1589
1590         { { "core", "show", "version", NULL },
1591         handle_version, "Display version info",
1592         version_help },
1593
1594         { { "!", NULL },
1595         handle_bang, "Execute a shell command",
1596         bang_help },
1597
1598 #if !defined(LOW_MEMORY)
1599         { { "core", "show", "file", "version", NULL },
1600         handle_show_version_files, "List versions of files used to build Asterisk",
1601         show_version_files_help, complete_show_version_files },
1602
1603         { { "core", "show", "threads", NULL },
1604         handle_show_threads, "Show running threads",
1605         show_threads_help },
1606
1607         { { "core", "show", "profile", NULL },
1608         handle_show_profile, "Display profiling info",
1609         NULL },
1610
1611         { { "core", "show", "settings", NULL },
1612         handle_show_settings, "Show some core settings",
1613         NULL },
1614
1615         { { "core", "clear", "profile", NULL },
1616         handle_show_profile, "Clear profiling info",
1617         NULL },
1618 #endif /* ! LOW_MEMORY */
1619 };
1620
1621 static int ast_el_read_char(EditLine *el, char *cp)
1622 {
1623         int num_read = 0;
1624         int lastpos = 0;
1625         struct pollfd fds[2];
1626         int res;
1627         int max;
1628         char buf[512];
1629
1630         for (;;) {
1631                 max = 1;
1632                 fds[0].fd = ast_consock;
1633                 fds[0].events = POLLIN;
1634                 if (!ast_opt_exec) {
1635                         fds[1].fd = STDIN_FILENO;
1636                         fds[1].events = POLLIN;
1637                         max++;
1638                 }
1639                 res = poll(fds, max, -1);
1640                 if (res < 0) {
1641                         if (errno == EINTR)
1642                                 continue;
1643                         ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
1644                         break;
1645                 }
1646
1647                 if (!ast_opt_exec && fds[1].revents) {
1648                         num_read = read(STDIN_FILENO, cp, 1);
1649                         if (num_read < 1) {
1650                                 break;
1651                         } else 
1652                                 return (num_read);
1653                 }
1654                 if (fds[0].revents) {
1655                         res = read(ast_consock, buf, sizeof(buf) - 1);
1656                         /* if the remote side disappears exit */
1657                         if (res < 1) {
1658                                 fprintf(stderr, "\nDisconnected from Asterisk server\n");
1659                                 if (!ast_opt_reconnect) {
1660                                         quit_handler(0, 0, 0, 0);
1661                                 } else {
1662                                         int tries;
1663                                         int reconnects_per_second = 20;
1664                                         fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
1665                                         for (tries=0; tries < 30 * reconnects_per_second; tries++) {
1666                                                 if (ast_tryconnect()) {
1667                                                         fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
1668                                                         printf(term_quit());
1669                                                         WELCOME_MESSAGE;
1670                                                         break;
1671                                                 } else
1672                                                         usleep(1000000 / reconnects_per_second);
1673                                         }
1674                                         if (tries >= 30 * reconnects_per_second) {
1675                                                 fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
1676                                                 quit_handler(0, 0, 0, 0);
1677                                         }
1678                                 }
1679                         }
1680
1681                         buf[res] = '\0';
1682
1683                         if (!ast_opt_exec && !lastpos)
1684                                 write(STDOUT_FILENO, "\r", 1);
1685                         write(STDOUT_FILENO, buf, res);
1686                         if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
1687                                 *cp = CC_REFRESH;
1688                                 return(1);
1689                         } else
1690                                 lastpos = 1;
1691                 }
1692         }
1693
1694         *cp = '\0';
1695         return (0);
1696 }
1697
1698 static char *cli_prompt(EditLine *el)
1699 {
1700         static char prompt[200];
1701         char *pfmt;
1702         int color_used = 0;
1703         char term_code[20];
1704
1705         if ((pfmt = getenv("ASTERISK_PROMPT"))) {
1706                 char *t = pfmt, *p = prompt;
1707                 memset(prompt, 0, sizeof(prompt));
1708                 while (*t != '\0' && *p < sizeof(prompt)) {
1709                         if (*t == '%') {
1710                                 char hostname[MAXHOSTNAMELEN]="";
1711                                 int i;
1712                                 time_t ts;
1713                                 struct tm tm;
1714 #ifdef linux
1715                                 FILE *LOADAVG;
1716 #endif
1717                                 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
1718
1719                                 t++;
1720                                 switch (*t) {
1721                                 case 'C': /* color */
1722                                         t++;
1723                                         if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
1724                                                 strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
1725                                                 t += i - 1;
1726                                         } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
1727                                                 strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
1728                                                 t += i - 1;
1729                                         }
1730
1731                                         /* If the color has been reset correctly, then there's no need to reset it later */
1732                                         color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
1733                                         break;
1734                                 case 'd': /* date */
1735                                         memset(&tm, 0, sizeof(tm));
1736                                         time(&ts);
1737                                         if (localtime_r(&ts, &tm)) 
1738                                                 strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
1739                                         break;
1740                                 case 'h': /* hostname */
1741                                         if (!gethostname(hostname, sizeof(hostname) - 1))
1742                                                 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
1743                                         else
1744                                                 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
1745                                         break;
1746                                 case 'H': /* short hostname */
1747                                         if (!gethostname(hostname, sizeof(hostname) - 1)) {
1748                                                 for (i = 0; i < sizeof(hostname); i++) {
1749                                                         if (hostname[i] == '.') {
1750                                                                 hostname[i] = '\0';
1751                                                                 break;
1752                                                         }
1753                                                 }
1754                                                 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
1755                                         } else
1756                                                 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
1757                                         break;
1758 #ifdef linux
1759                                 case 'l': /* load avg */
1760                                         t++;
1761                                         if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
1762                                                 float avg1, avg2, avg3;
1763                                                 int actproc, totproc, npid, which;
1764                                                 fscanf(LOADAVG, "%f %f %f %d/%d %d",
1765                                                         &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
1766                                                 if (sscanf(t, "%d", &which) == 1) {
1767                                                         switch (which) {
1768                                                         case 1:
1769                                                                 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
1770                                                                 break;
1771                                                         case 2:
1772                                                                 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
1773                                                                 break;
1774                                                         case 3:
1775                                                                 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
1776                                                                 break;
1777                                                         case 4:
1778                                                                 snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
1779                                                                 break;
1780                                                         case 5:
1781                                                                 snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
1782                                                                 break;
1783                                                         }
1784                                                 }
1785                                         }
1786                                         break;
1787 #endif
1788                                 case 's': /* Asterisk system name (from asterisk.conf) */
1789                                         strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1);
1790                                         break;
1791                                 case 't': /* time */
1792                                         memset(&tm, 0, sizeof(tm));
1793                                         time(&ts);
1794                                         if (localtime_r(&ts, &tm))
1795                                                 strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
1796                                         break;
1797                                 case '#': /* process console or remote? */
1798                                         if (!ast_opt_remote) 
1799                                                 strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
1800                                         else
1801                                                 strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
1802                                         break;
1803                                 case '%': /* literal % */
1804                                         strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
1805                                         break;
1806                                 case '\0': /* % is last character - prevent bug */
1807                                         t--;
1808                                         break;
1809                                 }
1810                                 while (*p != '\0')
1811                                         p++;
1812                                 t++;
1813                         } else {
1814                                 *p = *t;
1815                                 p++;
1816                                 t++;
1817                         }
1818                 }
1819                 if (color_used) {
1820                         /* Force colors back to normal at end */
1821                         term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
1822                         if (strlen(term_code) > sizeof(prompt) - strlen(prompt))
1823                                 strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
1824                         else
1825                                 strncat(p, term_code, sizeof(term_code));
1826                 }
1827         } else if (remotehostname)
1828                 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname);
1829         else
1830                 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT);
1831
1832         return(prompt); 
1833 }
1834
1835 static char **ast_el_strtoarr(char *buf)
1836 {
1837         char **match_list = NULL, *retstr;
1838         size_t match_list_len;
1839         int matches = 0;
1840
1841         match_list_len = 1;
1842         while ( (retstr = strsep(&buf, " ")) != NULL) {
1843
1844                 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
1845                         break;
1846                 if (matches + 1 >= match_list_len) {
1847                         match_list_len <<= 1;
1848                         if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
1849                                 /* TODO: Handle memory allocation failure */
1850                         }
1851                 }
1852
1853                 match_list[matches++] = strdup(retstr);
1854         }
1855
1856         if (!match_list)
1857                 return (char **) NULL;
1858
1859         if (matches >= match_list_len) {
1860                 if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
1861                         /* TODO: Handle memory allocation failure */
1862                 }
1863         }
1864
1865         match_list[matches] = (char *) NULL;
1866
1867         return match_list;
1868 }
1869
1870 static int ast_el_sort_compare(const void *i1, const void *i2)
1871 {
1872         char *s1, *s2;
1873
1874         s1 = ((char **)i1)[0];
1875         s2 = ((char **)i2)[0];
1876
1877         return strcasecmp(s1, s2);
1878 }
1879
1880 static int ast_cli_display_match_list(char **matches, int len, int max)
1881 {
1882         int i, idx, limit, count;
1883         int screenwidth = 0;
1884         int numoutput = 0, numoutputline = 0;
1885
1886         screenwidth = ast_get_termcols(STDOUT_FILENO);
1887
1888         /* find out how many entries can be put on one line, with two spaces between strings */
1889         limit = screenwidth / (max + 2);
1890         if (limit == 0)
1891                 limit = 1;
1892
1893         /* how many lines of output */
1894         count = len / limit;
1895         if (count * limit < len)
1896                 count++;
1897
1898         idx = 1;
1899
1900         qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
1901
1902         for (; count > 0; count--) {
1903                 numoutputline = 0;
1904                 for (i=0; i < limit && matches[idx]; i++, idx++) {
1905
1906                         /* Don't print dupes */
1907                         if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
1908                                 i--;
1909                                 free(matches[idx]);
1910                                 matches[idx] = NULL;
1911                                 continue;
1912                         }
1913
1914                         numoutput++;
1915                         numoutputline++;
1916                         fprintf(stdout, "%-*s  ", max, matches[idx]);
1917                         free(matches[idx]);
1918                         matches[idx] = NULL;
1919                 }
1920                 if (numoutputline > 0)
1921                         fprintf(stdout, "\n");
1922         }
1923
1924         return numoutput;
1925 }
1926
1927
1928 static char *cli_complete(EditLine *el, int ch)
1929 {
1930         int len = 0;
1931         char *ptr;
1932         int nummatches = 0;
1933         char **matches;
1934         int retval = CC_ERROR;
1935         char buf[2048];
1936         int res;
1937
1938         LineInfo *lf = (LineInfo *)el_line(el);
1939
1940         *(char *)lf->cursor = '\0';
1941         ptr = (char *)lf->cursor;
1942         if (ptr) {
1943                 while (ptr > lf->buffer) {
1944                         if (isspace(*ptr)) {
1945                                 ptr++;
1946                                 break;
1947                         }
1948                         ptr--;
1949                 }
1950         }
1951
1952         len = lf->cursor - ptr;
1953
1954         if (ast_opt_remote) {
1955                 snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
1956                 fdprint(ast_consock, buf);
1957                 res = read(ast_consock, buf, sizeof(buf));
1958                 buf[res] = '\0';
1959                 nummatches = atoi(buf);
1960
1961                 if (nummatches > 0) {
1962                         char *mbuf;
1963                         int mlen = 0, maxmbuf = 2048;
1964                         /* Start with a 2048 byte buffer */                     
1965                         if (!(mbuf = ast_malloc(maxmbuf)))
1966                                 return (char *)(CC_ERROR);
1967                         snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
1968                         fdprint(ast_consock, buf);
1969                         res = 0;
1970                         mbuf[0] = '\0';
1971                         while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
1972                                 if (mlen + 1024 > maxmbuf) {
1973                                         /* Every step increment buffer 1024 bytes */
1974                                         maxmbuf += 1024;                                        
1975                                         if (!(mbuf = ast_realloc(mbuf, maxmbuf)))
1976                                                 return (char *)(CC_ERROR);
1977                                 }
1978                                 /* Only read 1024 bytes at a time */
1979                                 res = read(ast_consock, mbuf + mlen, 1024);
1980                                 if (res > 0)
1981                                         mlen += res;
1982                         }
1983                         mbuf[mlen] = '\0';
1984
1985                         matches = ast_el_strtoarr(mbuf);
1986                         free(mbuf);
1987                 } else
1988                         matches = (char **) NULL;
1989         } else {
1990                 char **p, *oldbuf=NULL;
1991                 nummatches = 0;
1992                 matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
1993                 for (p = matches; p && *p; p++) {
1994                         if (!oldbuf || strcmp(*p,oldbuf))
1995                                 nummatches++;
1996                         oldbuf = *p;
1997                 }
1998         }
1999
2000         if (matches) {
2001                 int i;
2002                 int matches_num, maxlen, match_len;
2003
2004                 if (matches[0][0] != '\0') {
2005                         el_deletestr(el, (int) len);
2006                         el_insertstr(el, matches[0]);
2007                         retval = CC_REFRESH;
2008                 }
2009
2010                 if (nummatches == 1) {
2011                         /* Found an exact match */
2012                         el_insertstr(el, " ");
2013                         retval = CC_REFRESH;
2014                 } else {
2015                         /* Must be more than one match */
2016                         for (i=1, maxlen=0; matches[i]; i++) {
2017                                 match_len = strlen(matches[i]);
2018                                 if (match_len > maxlen)
2019                                         maxlen = match_len;
2020                         }
2021                         matches_num = i - 1;
2022                         if (matches_num >1) {
2023                                 fprintf(stdout, "\n");
2024                                 ast_cli_display_match_list(matches, nummatches, maxlen);
2025                                 retval = CC_REDISPLAY;
2026                         } else { 
2027                                 el_insertstr(el," ");
2028                                 retval = CC_REFRESH;
2029                         }
2030                 }
2031                 for (i = 0; matches[i]; i++)
2032                         free(matches[i]);
2033                 free(matches);
2034         }
2035
2036         return (char *)(long)retval;
2037 }
2038
2039 static int ast_el_initialize(void)
2040 {
2041         HistEvent ev;
2042         char *editor = getenv("AST_EDITOR");
2043
2044         if (el != NULL)
2045                 el_end(el);
2046         if (el_hist != NULL)
2047                 history_end(el_hist);
2048
2049         el = el_init("asterisk", stdin, stdout, stderr);
2050         el_set(el, EL_PROMPT, cli_prompt);
2051
2052         el_set(el, EL_EDITMODE, 1);             
2053         el_set(el, EL_EDITOR, editor ? editor : "emacs");               
2054         el_hist = history_init();
2055         if (!el || !el_hist)
2056                 return -1;
2057
2058         /* setup history with 100 entries */
2059         history(el_hist, &ev, H_SETSIZE, 100);
2060
2061         el_set(el, EL_HIST, history, el_hist);
2062
2063         el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
2064         /* Bind <tab> to command completion */
2065         el_set(el, EL_BIND, "^I", "ed-complete", NULL);
2066         /* Bind ? to command completion */
2067         el_set(el, EL_BIND, "?", "ed-complete", NULL);
2068         /* Bind ^D to redisplay */
2069         el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
2070
2071         return 0;
2072 }
2073
2074 static int ast_el_add_history(char *buf)
2075 {
2076         HistEvent ev;
2077
2078         if (el_hist == NULL || el == NULL)
2079                 ast_el_initialize();
2080         if (strlen(buf) > 256)
2081                 return 0;
2082         return (history(el_hist, &ev, H_ENTER, buf));
2083 }
2084
2085 static int ast_el_write_history(char *filename)
2086 {
2087         HistEvent ev;
2088
2089         if (el_hist == NULL || el == NULL)
2090                 ast_el_initialize();
2091
2092         return (history(el_hist, &ev, H_SAVE, filename));
2093 }
2094
2095 static int ast_el_read_history(char *filename)
2096 {
2097         char buf[256];
2098         FILE *f;
2099         int ret = -1;
2100
2101         if (el_hist == NULL || el == NULL)
2102                 ast_el_initialize();
2103
2104         if ((f = fopen(filename, "r")) == NULL)
2105                 return ret;
2106
2107         while (!feof(f)) {
2108                 fgets(buf, sizeof(buf), f);
2109                 if (!strcmp(buf, "_HiStOrY_V2_\n"))
2110                         continue;
2111                 if (ast_all_zeros(buf))
2112                         continue;
2113                 if ((ret = ast_el_add_history(buf)) == -1)
2114                         break;
2115         }
2116         fclose(f);
2117
2118         return ret;
2119 }
2120
2121 static void ast_remotecontrol(char * data)
2122 {
2123         char buf[80];
2124         int res;
2125         char filename[80] = "";
2126         char *hostname;
2127         char *cpid;
2128         char *version;
2129         int pid;
2130         char tmp[80];
2131         char *stringp = NULL;
2132
2133         char *ebuf;
2134         int num = 0;
2135
2136         read(ast_consock, buf, sizeof(buf));
2137         if (data)
2138                 write(ast_consock, data, strlen(data) + 1);
2139         stringp = buf;
2140         hostname = strsep(&stringp, "/");
2141         cpid = strsep(&stringp, "/");
2142         version = strsep(&stringp, "\n");
2143         if (!version)
2144                 version = "<Version Unknown>";
2145         stringp = hostname;
2146         strsep(&stringp, ".");
2147         if (cpid)
2148                 pid = atoi(cpid);
2149         else
2150                 pid = -1;
2151         snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
2152         fdprint(ast_consock, tmp);
2153         snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
2154         fdprint(ast_consock, tmp);
2155         if (ast_opt_mute) {
2156                 snprintf(tmp, sizeof(tmp), "log and verbose output currently muted ('logger unmute' to unmute)");
2157                 fdprint(ast_consock, tmp);
2158         }
2159         ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
2160         remotehostname = hostname;
2161         if (getenv("HOME")) 
2162                 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
2163         if (el_hist == NULL || el == NULL)
2164                 ast_el_initialize();
2165
2166         el_set(el, EL_GETCFN, ast_el_read_char);
2167
2168         if (!ast_strlen_zero(filename))
2169                 ast_el_read_history(filename);
2170
2171         if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
2172                 char tempchar;
2173                 struct pollfd fds;
2174                 fds.fd = ast_consock;
2175                 fds.events = POLLIN;
2176                 fds.revents = 0;
2177                 while (poll(&fds, 1, 100) > 0)
2178                         ast_el_read_char(el, &tempchar);
2179                 return;
2180         }
2181         for (;;) {
2182                 ebuf = (char *)el_gets(el, &num);
2183
2184                 if (!ast_strlen_zero(ebuf)) {
2185                         if (ebuf[strlen(ebuf)-1] == '\n')
2186                                 ebuf[strlen(ebuf)-1] = '\0';
2187                         if (!remoteconsolehandler(ebuf)) {
2188                                 res = write(ast_consock, ebuf, strlen(ebuf) + 1);
2189                                 if (res < 1) {
2190                                         ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
2191                                         break;
2192                                 }
2193                         }
2194                 }
2195
2196                 if (need_reload) {
2197                         need_reload = 0;
2198                         ast_module_reload(NULL);
2199                 }
2200         }
2201         printf("\nDisconnected from Asterisk server\n");
2202 }
2203
2204 static int show_version(void)
2205 {
2206         printf("Asterisk " ASTERISK_VERSION "\n");
2207         return 0;
2208 }
2209
2210 static int show_cli_help(void) {
2211         printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2006, Digium, Inc. and others.\n");
2212         printf("Usage: asterisk [OPTIONS]\n");
2213         printf("Valid Options:\n");
2214         printf("   -V              Display version number and exit\n");
2215         printf("   -C <configfile> Use an alternate configuration file\n");
2216         printf("   -G <group>      Run as a group other than the caller\n");
2217         printf("   -U <user>       Run as a user other than the caller\n");
2218         printf("   -c              Provide console CLI\n");
2219         printf("   -d              Enable extra debugging\n");
2220 #if HAVE_WORKING_FORK
2221         printf("   -f              Do not fork\n");
2222         printf("   -F              Always fork\n");
2223 #endif
2224         printf("   -g              Dump core in case of a crash\n");
2225         printf("   -h              This help screen\n");
2226         printf("   -i              Initialize crypto keys at startup\n");
2227         printf("   -I              Enable internal timing if Zaptel timer is available\n");
2228         printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
2229         printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
2230         printf("   -m              Mute the console from debugging and verbose output\n");
2231         printf("   -n              Disable console colorization\n");
2232         printf("   -p              Run as pseudo-realtime thread\n");
2233         printf("   -q              Quiet mode (suppress output)\n");
2234         printf("   -r              Connect to Asterisk on this machine\n");
2235         printf("   -R              Connect to Asterisk, and attempt to reconnect if disconnected\n");
2236         printf("   -t              Record soundfiles in /var/tmp and move them where they belong after they are done.\n");
2237         printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n");
2238         printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
2239         printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
2240         printf("\n");
2241         return 0;
2242 }
2243
2244 static void ast_readconfig(void) 
2245 {
2246         struct ast_config *cfg;
2247         struct ast_variable *v;
2248         char *config = AST_CONFIG_FILE;
2249
2250         if (ast_opt_override_config) {
2251                 cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
2252                 if (!cfg)
2253                         ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
2254         } else 
2255                 cfg = ast_config_load(config);
2256
2257         /* init with buildtime config */
2258         ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
2259         ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
2260         ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
2261         snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
2262         ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
2263         ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
2264         ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
2265         ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
2266         ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
2267         ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
2268         ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
2269         ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
2270         ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
2271
2272         /* no asterisk.conf? no problem, use buildtime config! */
2273         if (!cfg) {
2274                 return;
2275         }
2276
2277         for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
2278                 if (!strcasecmp(v->name, "astctlpermissions"))
2279                         ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
2280                 else if (!strcasecmp(v->name, "astctlowner"))
2281                         ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
2282                 else if (!strcasecmp(v->name, "astctlgroup"))
2283                         ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
2284                 else if (!strcasecmp(v->name, "astctl"))
2285                         ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
2286         }
2287
2288         for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
2289                 if (!strcasecmp(v->name, "astetcdir")) {
2290                         ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
2291                 } else if (!strcasecmp(v->name, "astspooldir")) {
2292                         ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
2293                         snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
2294                 } else if (!strcasecmp(v->name, "astvarlibdir")) {
2295                         ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
2296                         snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
2297                 } else if (!strcasecmp(v->name, "astdatadir")) {
2298                         ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
2299                         snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
2300                 } else if (!strcasecmp(v->name, "astlogdir")) {
2301                         ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
2302                 } else if (!strcasecmp(v->name, "astagidir")) {
2303                         ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
2304                 } else if (!strcasecmp(v->name, "astrundir")) {
2305                         snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
2306                         snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
2307                         ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
2308                 } else if (!strcasecmp(v->name, "astmoddir")) {
2309                         ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
2310                 }
2311         }
2312
2313         for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
2314                 /* verbose level (-v at startup) */
2315                 if (!strcasecmp(v->name, "verbose")) {
2316                         option_verbose = atoi(v->value);
2317                 /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
2318                 } else if (!strcasecmp(v->name, "timestamp")) {
2319                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
2320                 /* whether or not to support #exec in config files */
2321                 } else if (!strcasecmp(v->name, "execincludes")) {
2322                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
2323                 /* debug level (-d at startup) */
2324                 } else if (!strcasecmp(v->name, "debug")) {
2325                         option_debug = 0;
2326                         if (sscanf(v->value, "%d", &option_debug) != 1) {
2327                                 option_debug = ast_true(v->value);
2328                         }
2329 #if HAVE_WORKING_FORK
2330                 /* Disable forking (-f at startup) */
2331                 } else if (!strcasecmp(v->name, "nofork")) {
2332                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
2333                 /* Always fork, even if verbose or debug are enabled (-F at startup) */
2334                 } else if (!strcasecmp(v->name, "alwaysfork")) {
2335                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
2336 #endif
2337                 /* Run quietly (-q at startup ) */
2338                 } else if (!strcasecmp(v->name, "quiet")) {
2339                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
2340                 /* Run as console (-c at startup, implies nofork) */
2341                 } else if (!strcasecmp(v->name, "console")) {
2342                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE);
2343                 /* Run with high priority if the O/S permits (-p at startup) */
2344                 } else if (!strcasecmp(v->name, "highpriority")) {
2345                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
2346                 /* Initialize RSA auth keys (IAX2) (-i at startup) */
2347                 } else if (!strcasecmp(v->name, "initcrypto")) {
2348                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
2349                 /* Disable ANSI colors for console (-c at startup) */
2350                 } else if (!strcasecmp(v->name, "nocolor")) {
2351                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
2352                 /* Disable some usage warnings for picky people :p */
2353                 } else if (!strcasecmp(v->name, "dontwarn")) {
2354                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
2355                 /* Dump core in case of crash (-g) */
2356                 } else if (!strcasecmp(v->name, "dumpcore")) {
2357                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
2358                 /* Cache recorded sound files to another directory during recording */
2359                 } else if (!strcasecmp(v->name, "cache_record_files")) {
2360                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
2361                 /* Specify cache directory */
2362                 }  else if (!strcasecmp(v->name, "record_cache_dir")) {
2363                         ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
2364                 /* Build transcode paths via SLINEAR, instead of directly */
2365                 } else if (!strcasecmp(v->name, "transcode_via_sln")) {
2366                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
2367                 /* Transmit SLINEAR silence while a channel is being recorded */
2368                 } else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
2369                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
2370                 /* Enable internal timing */
2371                 } else if (!strcasecmp(v->name, "internal_timing")) {
2372                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
2373                 } else if (!strcasecmp(v->name, "maxcalls")) {
2374                         if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
2375                                 option_maxcalls = 0;
2376                         }
2377                 } else if (!strcasecmp(v->name, "maxload")) {
2378                         double test[1];
2379
2380                         if (getloadavg(test, 1) == -1) {
2381                                 ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
2382                                 option_maxload = 0.0;
2383                         } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
2384                                 option_maxload = 0.0;
2385                         }
2386                 /* Set the maximum amount of open files */
2387                 } else if (!strcasecmp(v->name, "maxfiles")) {
2388                         option_maxfiles = atoi(v->value);
2389                         set_ulimit(option_maxfiles);
2390                 /* What user to run as */
2391                 } else if (!strcasecmp(v->name, "runuser")) {
2392                         ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
2393                 /* What group to run as */
2394                 } else if (!strcasecmp(v->name, "rungroup")) {
2395                         ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
2396                 } else if (!strcasecmp(v->name, "systemname")) {
2397                         ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
2398                 } else if (!strcasecmp(v->name, "languageprefix")) {
2399                         ast_language_is_prefix = ast_true(v->value);
2400                 }
2401         }
2402         ast_config_destroy(cfg);
2403 }
2404
2405 int main(int argc, char *argv[])
2406 {
2407         int c;
2408         char filename[80] = "";
2409         char hostname[MAXHOSTNAMELEN] = "";
2410         char tmp[80];
2411         char * xarg = NULL;
2412         int x;
2413         FILE *f;
2414         sigset_t sigs;
2415         int num;
2416         int is_child_of_nonroot = 0;
2417         char *buf;
2418         char *runuser = NULL, *rungroup = NULL;
2419
2420         /* Remember original args for restart */
2421         if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
2422                 fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
2423                 argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
2424         }
2425         for (x=0; x<argc; x++)
2426                 _argv[x] = argv[x];
2427         _argv[x] = NULL;
2428
2429         /* if the progname is rasterisk consider it a remote console */
2430         if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
2431                 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
2432         }
2433         if (gethostname(hostname, sizeof(hostname)-1))
2434                 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
2435         ast_mainpid = getpid();
2436         ast_ulaw_init();
2437         ast_alaw_init();
2438         callerid_init();
2439         ast_builtins_init();
2440         ast_utils_init();
2441         tdd_init();
2442         /* When Asterisk restarts after it has dropped the root privileges,
2443          * it can't issue setuid(), setgid(), setgroups() or set_priority() 
2444          */
2445         if (getenv("ASTERISK_ALREADY_NONROOT"))
2446                 is_child_of_nonroot=1;
2447         if (getenv("HOME")) 
2448                 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
2449         /* Check for options */
2450         while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) {
2451                 switch (c) {
2452 #if HAVE_WORKING_FORK
2453                 case 'F':
2454                         ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
2455                         break;
2456                 case 'f':
2457                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
2458                         break;
2459 #endif
2460                 case 'd':
2461                         option_debug++;
2462                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
2463                         break;
2464                 case 'c':
2465                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
2466                         break;
2467                 case 'n':
2468                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
2469                         break;
2470                 case 'r':
2471                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
2472                         break;
2473                 case 'R':
2474                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
2475                         break;
2476                 case 'p':
2477                         ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
2478                         break;
2479                 case 'v':
2480                         option_verbose++;
2481                         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
2482                         break;
2483                 case 'm':
2484                         ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
2485                         break;
2486                 case 'M':
2487                         if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
2488                                 option_maxcalls = 0;
2489                         break;
2490                 case 'L':
2491                         if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
2492                                 option_maxload = 0.0;
2493                         break;
2494                 case 'q':
2495                         ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
2496                         break;
2497                 case 't':
2498                         ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
2499                         break;
2500                 case 'T':
2501                         ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
2502                         break;
2503                 case 'x':
2504                         ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
2505                         xarg = optarg;
2506                         break;
2507                 case 'C':
2508                         ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
2509                         ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
2510                         break;
2511                 case 'I':
2512                         ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
2513                         break;
2514                 case 'i':
2515                         ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
2516                         break;
2517                 case 'g':
2518                         ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
2519                         break;
2520                 case 'h':
2521                         show_cli_help();
2522                         exit(0);
2523                 case 'V':
2524                         show_version();
2525                         exit(0);
2526                 case 'U':
2527                         runuser = optarg;
2528                         break;
2529                 case 'G':
2530                         rungroup = optarg;
2531                         break;
2532                 case '?':
2533                         exit(1);
2534                 }
2535         }
2536
2537         if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
2538                 ast_register_verbose(console_verboser);
2539                 WELCOME_MESSAGE;
2540         }
2541
2542         if (ast_opt_console && !option_verbose) 
2543                 ast_verbose("[ Booting...\n");
2544
2545         if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
2546                 ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
2547                 ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
2548         }
2549
2550         /* For remote connections, change the name of the remote connection.
2551          * We do this for the benefit of init scripts (which need to know if/when
2552          * the main asterisk process has died yet). */
2553         if (ast_opt_remote) {
2554                 strcpy(argv[0], "rasterisk");
2555                 for (x = 1; x < argc; x++) {
2556                         argv[x] = argv[0] + 10;
2557                 }
2558         }
2559
2560         if (ast_opt_console && !option_verbose) 
2561                 ast_verbose("[ Reading Master Configuration ]\n");
2562         ast_readconfig();
2563
2564         if (!ast_language_is_prefix && !ast_opt_remote)
2565                 ast_log(LOG_WARNING, "The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
2566
2567         if (ast_opt_dump_core) {
2568                 struct rlimit l;
2569                 memset(&l, 0, sizeof(l));
2570                 l.rlim_cur = RLIM_INFINITY;
2571                 l.rlim_max = RLIM_INFINITY;
2572                 if (setrlimit(RLIMIT_CORE, &l)) {
2573                         ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
2574                 }
2575         }
2576
2577         if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
2578                 rungroup = ast_config_AST_RUN_GROUP;
2579         if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
2580                 runuser = ast_config_AST_RUN_USER;
2581
2582 #ifndef __CYGWIN__
2583
2584         if (!is_child_of_nonroot) 
2585                 ast_set_priority(ast_opt_high_priority);
2586
2587         if (!is_child_of_nonroot && rungroup) {
2588                 struct group *gr;
2589                 gr = getgrnam(rungroup);
2590                 if (!gr) {
2591                         ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
2592                         exit(1);
2593                 }
2594                 if (setgid(gr->gr_gid)) {
2595                         ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
2596                         exit(1);
2597                 }
2598                 if (setgroups(0, NULL)) {
2599                         ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
2600                         exit(1);
2601                 }
2602                 if (option_verbose)
2603                         ast_verbose("Running as group '%s'\n", rungroup);
2604         }
2605
2606         if (!is_child_of_nonroot && runuser) {
2607 #ifdef HAVE_CAP
2608                 int has_cap = 1;
2609 #endif /* HAVE_CAP */
2610                 struct passwd *pw;
2611                 pw = getpwnam(runuser);
2612                 if (!pw) {
2613                         ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
2614                         exit(1);
2615                 }
2616 #ifdef HAVE_CAP
2617                 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
2618                         ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
2619                         has_cap = 0;
2620                 }
2621 #endif /* HAVE_CAP */
2622                 if (!rungroup) {
2623                         if (setgid(pw->pw_gid)) {
2624                                 ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
2625                                 exit(1);
2626                         }
2627                         if (initgroups(pw->pw_name, pw->pw_gid)) {
2628                                 ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
2629                                 exit(1);
2630                         }
2631                 }
2632                 if (setuid(pw->pw_uid)) {
2633                         ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
2634                         exit(1);
2635                 }
2636                 setenv("ASTERISK_ALREADY_NONROOT", "yes", 1);
2637                 if (option_verbose)
2638                         ast_verbose("Running as user '%s'\n", runuser);
2639 #ifdef HAVE_CAP
2640                 if (has_cap) {
2641                         cap_t cap;
2642
2643                         cap = cap_from_text("cap_net_admin=ep");
2644
2645                         if (cap_set_proc(cap))
2646                                 ast_log(LOG_WARNING, "Unable to install capabilities.\n");
2647
2648                         if (cap_free(cap))
2649                                 ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
2650                 }
2651 #endif /* HAVE_CAP */
2652         }
2653
2654 #endif /* __CYGWIN__ */
2655
2656 #ifdef linux
2657         if (geteuid() && ast_opt_dump_core) {
2658                 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
2659                         ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
2660                 }       
2661         }
2662 #endif
2663
2664         ast_term_init();
2665         printf(term_end());
2666         fflush(stdout);
2667
2668         if (ast_opt_console && !option_verbose) 
2669                 ast_verbose("[ Initializing Custom Configuration Options ]\n");
2670         /* custom config setup */
2671         register_config_cli();
2672         read_config_maps();
2673         
2674         if (ast_opt_console) {
2675                 if (el_hist == NULL || el == NULL)
2676                         ast_el_initialize();
2677
2678                 if (!ast_strlen_zero(filename))
2679                         ast_el_read_history(filename);
2680         }
2681
2682         if (ast_tryconnect()) {
2683                 /* One is already running */
2684                 if (ast_opt_remote) {
2685                         if (ast_opt_exec) {
2686                                 ast_remotecontrol(xarg);
2687                                 quit_handler(0, 0, 0, 0);
2688                                 exit(0);
2689                         }
2690                         printf(term_quit());
2691                         ast_remotecontrol(NULL);
2692                         quit_handler(0, 0, 0, 0);
2693                         exit(0);
2694                 } else {
2695                         ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
2696                         printf(term_quit());
2697                         exit(1);
2698                 }
2699         } else if (ast_opt_remote || ast_opt_exec) {
2700                 ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
2701                 printf(term_quit());
2702                 exit(1);
2703         }
2704         /* Blindly write pid file since we couldn't connect */
2705         unlink(ast_config_AST_PID);
2706         f = fopen(ast_config_AST_PID, "w");
2707         if (f) {
2708                 fprintf(f, "%ld\n", (long)getpid());
2709                 fclose(f);
2710         } else
2711                 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
2712
2713 #if HAVE_WORKING_FORK
2714         if (ast_opt_always_fork || !ast_opt_no_fork) {
2715                 daemon(0, 0);
2716                 ast_mainpid = getpid();
2717                 /* Blindly re-write pid file since we are forking */
2718                 unlink(ast_config_AST_PID);
2719                 f = fopen(ast_config_AST_PID, "w");
2720                 if (f) {
2721                         fprintf(f, "%ld\n", (long)ast_mainpid);
2722                         fclose(f);
2723                 } else
2724                         ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
2725         }
2726 #endif
2727
2728         /* Test recursive mutex locking. */
2729         if (test_for_thread_safety())
2730                 ast_verbose("Warning! Asterisk is not thread safe.\n");
2731
2732         ast_makesocket();
2733         sigemptyset(&sigs);
2734         sigaddset(&sigs, SIGHUP);
2735         sigaddset(&sigs, SIGTERM);
2736         sigaddset(&sigs, SIGINT);
2737         sigaddset(&sigs, SIGPIPE);
2738         sigaddset(&sigs, SIGWINCH);
2739         pthread_sigmask(SIG_BLOCK, &sigs, NULL);
2740         signal(SIGURG, urg_handler);
2741         signal(SIGINT, __quit_handler);
2742         signal(SIGTERM, __quit_handler);
2743         signal(SIGHUP, hup_handler);
2744         signal(SIGCHLD, child_handler);
2745         signal(SIGPIPE, SIG_IGN);
2746
2747         /* ensure that the random number generators are seeded with a different value every time
2748            Asterisk is started
2749         */
2750         srand((unsigned int) getpid() + (unsigned int) time(NULL));
2751         initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
2752
2753         if (init_logger()) {            /* Start logging subsystem */
2754                 printf(term_quit());
2755                 exit(1);
2756         }
2757
2758         threadstorage_init();
2759
2760         if (load_modules(1)) {          /* Load modules */
2761                 printf(term_quit());
2762                 exit(1);
2763         }
2764
2765         if (dnsmgr_init()) {            /* Initialize the DNS manager */
2766                 printf(term_quit());
2767                 exit(1);
2768         }
2769
2770         ast_http_init();                /* Start the HTTP server, if needed */
2771
2772         ast_channels_init();
2773
2774         if (init_manager()) {
2775                 printf(term_quit());
2776                 exit(1);
2777         }
2778
2779         if (ast_cdr_engine_init()) {
2780                 printf(term_quit());
2781                 exit(1);
2782         }
2783
2784         if (ast_device_state_engine_init()) {
2785                 printf(term_quit());
2786                 exit(1);
2787         }
2788
2789         ast_rtp_init();
2790
2791         ast_udptl_init();
2792
2793         if (ast_image_init()) {
2794                 printf(term_quit());
2795                 exit(1);
2796         }
2797
2798         if (ast_file_init()) {
2799                 printf(term_quit());
2800                 exit(1);
2801         }
2802
2803         if (load_pbx()) {
2804                 printf(term_quit());
2805                 exit(1);
2806         }
2807
2808         if (init_framer()) {
2809                 printf(term_quit());
2810                 exit(1);
2811         }
2812
2813         if (astdb_init()) {
2814                 printf(term_quit());
2815                 exit(1);
2816         }
2817
2818         if (ast_enum_init()) {
2819                 printf(term_quit());
2820                 exit(1);
2821         }
2822
2823         if (load_modules(0)) {
2824                 printf(term_quit());
2825                 exit(1);
2826         }
2827
2828         dnsmgr_start_refresh();
2829
2830         /* We might have the option of showing a console, but for now just
2831            do nothing... */
2832         if (ast_opt_console && !option_verbose)
2833                 ast_verbose(" ]\n");
2834         if (option_verbose || ast_opt_console)
2835                 ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
2836         if (ast_opt_no_fork)
2837                 consolethread = pthread_self();
2838
2839         ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
2840         pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
2841
2842 #ifdef __AST_DEBUG_MALLOC
2843         __ast_mm_init();
2844 #endif  
2845
2846         time(&ast_startuptime);
2847         ast_cli_register_multiple(cli_asterisk, sizeof(cli_asterisk) / sizeof(struct ast_cli_entry));
2848
2849         if (ast_opt_console) {
2850                 /* Console stuff now... */
2851                 /* Register our quit function */
2852                 char title[256];
2853                 set_icon("Asterisk");
2854                 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
2855                 set_title(title);
2856
2857                 for (;;) {
2858                         buf = (char *)el_gets(el, &num);
2859                         if (buf) {
2860                                 if (buf[strlen(buf)-1] == '\n')
2861                                         buf[strlen(buf)-1] = '\0';
2862
2863                                 consolehandler((char *)buf);
2864                         } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
2865                                    strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
2866                                 /* Whoa, stdout disappeared from under us... Make /dev/null's */
2867                                 int fd;
2868                                 fd = open("/dev/null", O_RDWR);
2869                                 if (fd > -1) {
2870                                         dup2(fd, STDOUT_FILENO);
2871                                         dup2(fd, STDIN_FILENO);
2872                                 } else
2873                                         ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
2874                                 break;
2875                         }
2876                         if (need_reload) {
2877                                 need_reload = 0;
2878                                 ast_module_reload(NULL);
2879                         }
2880                 }
2881         }
2882         /* Do nothing */
2883         for (;;) {      /* apparently needed for Mac OS X */
2884                 struct pollfd p = { -1 /* no descriptor */, 0, 0 };
2885                 poll(&p, 0, -1);
2886                 /* SIGHUP will cause this to break out of poll() */
2887                 if (need_reload) {
2888                         need_reload = 0;
2889                         ast_module_reload(NULL);
2890                 }
2891         }
2892
2893         return 0;
2894 }