1817eefd8d13a5aa68ee4ea27b7a21b50013251b
[asterisk/asterisk.git] / main / asterisk.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2014, 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 -- The Open Source Telephony Project
23  *
24  * \par Welcome
25  *
26  * This documentation created by the Doxygen project clearly explains the
27  * internals of the Asterisk software. This documentation contains basic
28  * examples, developer documentation, support information, and information
29  * for upgrading.
30  *
31  * \section community Community
32  * Asterisk is a big project and has a busy community. Look at the
33  * resources for questions and stick around to help answer questions.
34  * \li \ref asterisk_community_resources
35  *
36  * \par Developer Documentation for Asterisk
37  *
38  * This is the main developer documentation for Asterisk. It is
39  * generated by running "make progdocs" from the Asterisk source tree.
40  *
41  * In addition to the information available on the Asterisk source code,
42  * please see the appendices for information on coding guidelines,
43  * release management, commit policies, and more.
44  *
45  * \arg \ref AsteriskArchitecture
46  *
47  * \par Additional documentation
48  * \arg \ref Licensing
49  * \arg \ref DevDoc
50  * \arg \ref configuration_file
51  * \arg \ref channel_drivers
52  * \arg \ref applications
53  *
54  * \section copyright Copyright and Author
55  *
56  * Copyright (C) 1999 - 2014, Digium, Inc.
57  * Asterisk is a <a href="http://www.digium.com/en/company/view-policy.php?id=Trademark-Policy">registered trademark</a>
58  * of <a rel="nofollow" href="http://www.digium.com">Digium, Inc</a>.
59  *
60  * \author Mark Spencer <markster@digium.com>
61  *
62  * See http://www.asterisk.org for more information about
63  * the Asterisk project. Please do not directly contact
64  * any of the maintainers of this project for assistance;
65  * the project provides a web site, mailing lists, and IRC
66  * channels for your use.
67  *
68  */
69
70 /*!
71  * \page asterisk_community_resources Asterisk Community Resources
72  * \par Websites
73  * \li http://www.asterisk.org Asterisk Homepage
74  * \li http://wiki.asterisk.org Asterisk Wiki
75  *
76  * \par Mailing Lists
77  * \par
78  * All lists: http://lists.digium.com/mailman/listinfo
79  * \li aadk-commits     SVN commits to the AADK repository
80  * \li asterisk-addons-commits  SVN commits to the Asterisk addons project
81  * \li asterisk-announce        [no description available]
82  * \li asterisk-biz     Commercial and Business-Oriented Asterisk Discussion
83  * \li Asterisk-BSD     Asterisk on BSD discussion
84  * \li asterisk-bugs    [no description available]
85  * \li asterisk-commits SVN commits to the Asterisk project
86  * \li asterisk-dev     Asterisk Developers Mailing List
87  * \li asterisk-doc     Discussions regarding The Asterisk Documentation Project
88  * \li asterisk-embedded        Asterisk Embedded Development
89  * \li asterisk-gui     Asterisk GUI project discussion
90  * \li asterisk-gui-commits     SVN commits to the Asterisk-GUI project
91  * \li asterisk-ha-clustering   Asterisk High Availability and Clustering List - Non-Commercial Discussion
92  * \li Asterisk-i18n    Discussion of Asterisk internationalization
93  * \li asterisk-r2      [no description available]
94  * \li asterisk-scf-commits     Commits to the Asterisk SCF project code repositories
95  * \li asterisk-scf-committee   Asterisk SCF Steering Committee discussions
96  * \li asterisk-scf-dev Asterisk SCF Developers Mailing List
97  * \li asterisk-scf-wiki-changes        Changes to the Asterisk SCF space on wiki.asterisk.org
98  * \li asterisk-security        Asterisk Security Discussion
99  * \li asterisk-speech-rec      Use of speech recognition in Asterisk
100  * \li asterisk-ss7     [no description available]
101  * \li asterisk-users   Asterisk Users Mailing List - Non-Commercial Discussion
102  * \li asterisk-video   Development discussion of video media support in Asterisk
103  * \li asterisk-wiki-changes    Changes to the Asterisk space on wiki.asterisk.org
104  * \li asterisknow      AsteriskNOW Discussion
105  * \li dahdi-commits    SVN commits to the DAHDI project
106  * \li digium-announce  Digium Product Announcements
107  * \li Dundi    Distributed Universal Number Discovery
108  * \li libiax2-commits  SVN commits to the libiax2 project
109  * \li libpri-commits   SVN commits to the libpri project
110  * \li libss7-commits   SVN commits to the libss7 project
111  * \li svn-commits      SVN commits to the Digium repositories
112  * \li Test-results     Results from automated testing
113  * \li thirdparty-commits       SVN commits to the Digium third-party software repository
114  * \li zaptel-commits   SVN commits to the Zaptel project
115  *
116  * \par Forums
117  * \li Forums are located at http://forums.asterisk.org/
118  *
119  * \par IRC
120  * \par
121  * Use http://www.freenode.net IRC server to connect with Asterisk
122  * developers and users in realtime.
123  *
124  * \li \verbatim #asterisk \endverbatim Asterisk Users Room
125  * \li \verbatim #asterisk-dev \endverbatim Asterisk Developers Room
126  *
127  * \par More
128  * \par
129  * If you would like to add a resource to this list please create an issue
130  * on the issue tracker with a patch.
131  */
132
133 /*! \file
134  * \brief Top level source file for Asterisk - the Open Source PBX.
135  *      Implementation of PBX core functions and CLI interface.
136  */
137
138 /*! \li \ref asterisk.c uses the configuration file \ref asterisk.conf
139  * \addtogroup configuration_file
140  */
141
142 /*! \page asterisk.conf asterisk.conf
143  * \verbinclude asterisk.conf.sample
144  */
145
146 /*** MODULEINFO
147         <support_level>core</support_level>
148  ***/
149
150 #include "asterisk.h"
151
152 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
153
154 #include "asterisk/_private.h"
155
156 #undef sched_setscheduler
157 #undef setpriority
158 #include <sys/time.h>
159 #include <fcntl.h>
160 #include <signal.h>
161 #include <sched.h>
162 #include <sys/un.h>
163 #include <sys/wait.h>
164 #include <ctype.h>
165 #include <sys/resource.h>
166 #include <grp.h>
167 #include <pwd.h>
168 #include <sys/stat.h>
169 #if defined(HAVE_SYSINFO)
170 #include <sys/sysinfo.h>
171 #elif defined(HAVE_SYSCTL)
172 #include <sys/param.h>
173 #include <sys/sysctl.h>
174 #if !defined(__OpenBSD__)
175 #include <sys/vmmeter.h>
176 #if defined(__FreeBSD__)
177 #include <vm/vm_param.h>
178 #endif
179 #endif
180 #if defined(HAVE_SWAPCTL)
181 #include <sys/swap.h>
182 #endif
183 #endif
184 #include <regex.h>
185 #include <histedit.h>
186
187 #if defined(SOLARIS)
188 int daemon(int, int);  /* defined in libresolv of all places */
189 #include <sys/loadavg.h>
190 #endif
191
192 #ifdef linux
193 #include <sys/prctl.h>
194 #ifdef HAVE_CAP
195 #include <sys/capability.h>
196 #endif /* HAVE_CAP */
197 #endif /* linux */
198
199 /* we define here the variables so to better agree on the prototype */
200 #include "asterisk/paths.h"
201 #include "asterisk/network.h"
202 #include "asterisk/cli.h"
203 #include "asterisk/channel.h"
204 #include "asterisk/translate.h"
205 #include "asterisk/pickup.h"
206 #include "asterisk/features.h"
207 #include "asterisk/acl.h"
208 #include "asterisk/ulaw.h"
209 #include "asterisk/alaw.h"
210 #include "asterisk/callerid.h"
211 #include "asterisk/image.h"
212 #include "asterisk/tdd.h"
213 #include "asterisk/term.h"
214 #include "asterisk/manager.h"
215 #include "asterisk/cdr.h"
216 #include "asterisk/cel.h"
217 #include "asterisk/pbx.h"
218 #include "asterisk/enum.h"
219 #include "asterisk/http.h"
220 #include "asterisk/udptl.h"
221 #include "asterisk/app.h"
222 #include "asterisk/lock.h"
223 #include "asterisk/utils.h"
224 #include "asterisk/file.h"
225 #include "asterisk/io.h"
226 #include "editline/histedit.h"
227 #include "asterisk/config.h"
228 #include "asterisk/ast_version.h"
229 #include "asterisk/linkedlists.h"
230 #include "asterisk/devicestate.h"
231 #include "asterisk/presencestate.h"
232 #include "asterisk/module.h"
233 #include "asterisk/dsp.h"
234 #include "asterisk/buildinfo.h"
235 #include "asterisk/xmldoc.h"
236 #include "asterisk/poll-compat.h"
237 #include "asterisk/ccss.h"
238 #include "asterisk/test.h"
239 #include "asterisk/rtp_engine.h"
240 #include "asterisk/format.h"
241 #include "asterisk/aoc.h"
242 #include "asterisk/uuid.h"
243 #include "asterisk/sorcery.h"
244 #include "asterisk/bucket.h"
245 #include "asterisk/stasis.h"
246 #include "asterisk/json.h"
247 #include "asterisk/stasis_endpoints.h"
248 #include "asterisk/stasis_system.h"
249 #include "asterisk/security_events.h"
250 #include "asterisk/endpoints.h"
251 #include "asterisk/codec.h"
252 #include "asterisk/format_cache.h"
253
254 #include "../defaults.h"
255
256 /*** DOCUMENTATION
257         <managerEvent language="en_US" name="FullyBooted">
258                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
259                         <synopsis>Raised when all Asterisk initialization procedures have finished.</synopsis>
260                         <syntax>
261                                 <parameter name="Status">
262                                         <para>Informational message</para>
263                                 </parameter>
264                         </syntax>
265                 </managerEventInstance>
266         </managerEvent>
267         <managerEvent language="en_US" name="Shutdown">
268                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
269                         <synopsis>Raised when Asterisk is shutdown or restarted.</synopsis>
270                         <syntax>
271                                 <parameter name="Shutdown">
272                                         <para>Whether the shutdown is proceeding cleanly (all channels
273                                         were hungup successfully) or uncleanly (channels will be
274                                         terminated)</para>
275                                         <enumlist>
276                                                 <enum name="Uncleanly"/>
277                                                 <enum name="Cleanly"/>
278                                         </enumlist>
279                                 </parameter>
280                                 <parameter name="Restart">
281                                         <para>Whether or not a restart will occur.</para>
282                                         <enumlist>
283                                                 <enum name="True"/>
284                                                 <enum name="False"/>
285                                         </enumlist>
286                                 </parameter>
287                         </syntax>
288                 </managerEventInstance>
289         </managerEvent>
290  ***/
291
292 #ifndef AF_LOCAL
293 #define AF_LOCAL AF_UNIX
294 #define PF_LOCAL PF_UNIX
295 #endif
296
297 #define AST_MAX_CONNECTS 128
298 #define NUM_MSGS 64
299
300 /*! Default minimum DTMF digit length - 80ms */
301 #define AST_MIN_DTMF_DURATION 80
302
303
304 /*! \brief Welcome message when starting a CLI interface */
305 #define WELCOME_MESSAGE \
306     ast_verbose("Asterisk %s, Copyright (C) 1999 - 2014, Digium, Inc. and others.\n" \
307                 "Created by Mark Spencer <markster@digium.com>\n" \
308                 "Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.\n" \
309                 "This is free software, with components licensed under the GNU General Public\n" \
310                 "License version 2 and other licenses; you are welcome to redistribute it under\n" \
311                 "certain conditions. Type 'core show license' for details.\n" \
312                 "=========================================================================\n", ast_get_version()) \
313
314 /*! \defgroup main_options Main Configuration Options
315  * \brief Main configuration options from asterisk.conf or OS command line on starting Asterisk.
316  * \arg \ref Config_ast "asterisk.conf"
317  * \note Some of them can be changed in the CLI
318  */
319 /*! @{ */
320
321 struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
322
323 /*! Maximum active system verbosity level. */
324 int ast_verb_sys_level;
325
326 int option_verbose;                             /*!< Verbosity level */
327 int option_debug;                               /*!< Debug level */
328 double ast_option_maxload;                      /*!< Max load avg on system */
329 int ast_option_maxcalls;                        /*!< Max number of active calls */
330 int ast_option_maxfiles;                        /*!< Max number of open file handles (files, sockets) */
331 unsigned int option_dtmfminduration;            /*!< Minimum duration of DTMF. */
332 #if defined(HAVE_SYSINFO)
333 long option_minmemfree;                         /*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
334 #endif
335
336 /*! @} */
337
338 struct ast_eid ast_eid_default;
339
340 /* XXX tmpdir is a subdir of the spool directory, and no way to remap it */
341 char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR;
342
343 static int ast_socket = -1;             /*!< UNIX Socket for allowing remote control */
344 static int ast_consock = -1;            /*!< UNIX Socket for controlling another asterisk */
345 pid_t ast_mainpid;
346 struct console {
347         int fd;                         /*!< File descriptor */
348         int p[2];                       /*!< Pipe */
349         pthread_t t;                    /*!< Thread of handler */
350         int mute;                       /*!< Is the console muted for logs */
351         int uid;                        /*!< Remote user ID. */
352         int gid;                        /*!< Remote group ID. */
353         int levels[NUMLOGLEVELS];       /*!< Which log levels are enabled for the console */
354         /*! Verbosity level of this console. */
355         int option_verbose;
356 };
357
358 struct ast_atexit {
359         void (*func)(void);
360         int is_cleanup;
361         AST_LIST_ENTRY(ast_atexit) list;
362 };
363
364 static AST_LIST_HEAD_STATIC(atexits, ast_atexit);
365
366 struct timeval ast_startuptime;
367 struct timeval ast_lastreloadtime;
368
369 static History *el_hist;
370 static EditLine *el;
371 static char *remotehostname;
372
373 struct console consoles[AST_MAX_CONNECTS];
374
375 char ast_defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
376
377 static int ast_el_add_history(char *);
378 static int ast_el_read_history(char *);
379 static int ast_el_write_history(char *);
380
381 struct _cfg_paths {
382         char config_dir[PATH_MAX];
383         char module_dir[PATH_MAX];
384         char spool_dir[PATH_MAX];
385         char monitor_dir[PATH_MAX];
386         char recording_dir[PATH_MAX];
387         char var_dir[PATH_MAX];
388         char data_dir[PATH_MAX];
389         char log_dir[PATH_MAX];
390         char agi_dir[PATH_MAX];
391         char run_dir[PATH_MAX];
392         char key_dir[PATH_MAX];
393
394         char config_file[PATH_MAX];
395         char db_path[PATH_MAX];
396         char sbin_dir[PATH_MAX];
397         char pid_path[PATH_MAX];
398         char socket_path[PATH_MAX];
399         char run_user[PATH_MAX];
400         char run_group[PATH_MAX];
401         char system_name[128];
402 };
403
404 static struct _cfg_paths cfg_paths;
405
406 const char *ast_config_AST_CONFIG_DIR   = cfg_paths.config_dir;
407 const char *ast_config_AST_CONFIG_FILE  = cfg_paths.config_file;
408 const char *ast_config_AST_MODULE_DIR   = cfg_paths.module_dir;
409 const char *ast_config_AST_SPOOL_DIR    = cfg_paths.spool_dir;
410 const char *ast_config_AST_MONITOR_DIR  = cfg_paths.monitor_dir;
411 const char *ast_config_AST_RECORDING_DIR        = cfg_paths.recording_dir;
412 const char *ast_config_AST_VAR_DIR      = cfg_paths.var_dir;
413 const char *ast_config_AST_DATA_DIR     = cfg_paths.data_dir;
414 const char *ast_config_AST_LOG_DIR      = cfg_paths.log_dir;
415 const char *ast_config_AST_AGI_DIR      = cfg_paths.agi_dir;
416 const char *ast_config_AST_KEY_DIR      = cfg_paths.key_dir;
417 const char *ast_config_AST_RUN_DIR      = cfg_paths.run_dir;
418 const char *ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir;
419
420 const char *ast_config_AST_DB           = cfg_paths.db_path;
421 const char *ast_config_AST_PID          = cfg_paths.pid_path;
422 const char *ast_config_AST_SOCKET       = cfg_paths.socket_path;
423 const char *ast_config_AST_RUN_USER     = cfg_paths.run_user;
424 const char *ast_config_AST_RUN_GROUP    = cfg_paths.run_group;
425 const char *ast_config_AST_SYSTEM_NAME  = cfg_paths.system_name;
426
427 static char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
428 static char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0";
429 static char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0";
430 static char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl";
431
432 extern unsigned int ast_FD_SETSIZE;
433
434 static char *_argv[256];
435
436 typedef enum {
437         /*! Normal operation */
438         NOT_SHUTTING_DOWN,
439         /*! Committed to shutting down.  Final phase */
440         SHUTTING_DOWN_FINAL,
441         /*! Committed to shutting down.  Initial phase */
442         SHUTTING_DOWN,
443         /*!
444          * Valid values for quit_handler() niceness below.
445          * These shutdown/restart levels can be cancelled.
446          *
447          * Remote console exit right now
448          */
449         SHUTDOWN_FAST,
450         /*! core stop/restart now */
451         SHUTDOWN_NORMAL,
452         /*! core stop/restart gracefully */
453         SHUTDOWN_NICE,
454         /*! core stop/restart when convenient */
455         SHUTDOWN_REALLY_NICE
456 } shutdown_nice_t;
457
458 static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN;
459
460 /*! Prevent new channel allocation for shutdown. */
461 static int shutdown_pending;
462
463 static int restartnow;
464 static pthread_t consolethread = AST_PTHREADT_NULL;
465 static pthread_t mon_sig_flags;
466 static int canary_pid = 0;
467 static char canary_filename[128];
468 static int multi_thread_safe;
469
470 static char randompool[256];
471
472 static int sig_alert_pipe[2] = { -1, -1 };
473 static struct {
474          unsigned int need_reload:1;
475          unsigned int need_quit:1;
476          unsigned int need_quit_handler:1;
477 } sig_flags;
478
479 #if !defined(LOW_MEMORY)
480 struct file_version {
481         AST_RWLIST_ENTRY(file_version) list;
482         const char *file;
483         char *version;
484 };
485
486 static AST_RWLIST_HEAD_STATIC(file_versions, file_version);
487
488 void ast_register_file_version(const char *file, const char *version)
489 {
490         struct file_version *new;
491         char *work;
492         size_t version_length;
493
494         work = ast_strdupa(version);
495         work = ast_strip(ast_strip_quoted(work, "$", "$"));
496         version_length = strlen(work) + 1;
497
498         if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
499                 return;
500
501         new->file = file;
502         new->version = (char *) new + sizeof(*new);
503         memcpy(new->version, work, version_length);
504         AST_RWLIST_WRLOCK(&file_versions);
505         AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
506         AST_RWLIST_UNLOCK(&file_versions);
507 }
508
509 void ast_unregister_file_version(const char *file)
510 {
511         struct file_version *find;
512
513         AST_RWLIST_WRLOCK(&file_versions);
514         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
515                 if (!strcasecmp(find->file, file)) {
516                         AST_RWLIST_REMOVE_CURRENT(list);
517                         break;
518                 }
519         }
520         AST_RWLIST_TRAVERSE_SAFE_END;
521         AST_RWLIST_UNLOCK(&file_versions);
522
523         if (find)
524                 ast_free(find);
525 }
526
527 char *ast_complete_source_filename(const char *partial, int n)
528 {
529         struct file_version *find;
530         size_t len = strlen(partial);
531         int count = 0;
532         char *res = NULL;
533
534         AST_RWLIST_RDLOCK(&file_versions);
535         AST_RWLIST_TRAVERSE(&file_versions, find, list) {
536                 if (!strncasecmp(find->file, partial, len) && ++count > n) {
537                         res = ast_strdup(find->file);
538                         break;
539                 }
540         }
541         AST_RWLIST_UNLOCK(&file_versions);
542         return res;
543 }
544
545 /*! \brief Find version for given module name */
546 const char *ast_file_version_find(const char *file)
547 {
548         struct file_version *iterator;
549
550         AST_RWLIST_WRLOCK(&file_versions);
551         AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
552                 if (!strcasecmp(iterator->file, file))
553                         break;
554         }
555         AST_RWLIST_UNLOCK(&file_versions);
556         if (iterator)
557                 return iterator->version;
558         return NULL;
559 }
560
561 struct thread_list_t {
562         AST_RWLIST_ENTRY(thread_list_t) list;
563         char *name;
564         pthread_t id;
565         int lwp;
566 };
567
568 static AST_RWLIST_HEAD_STATIC(thread_list, thread_list_t);
569
570 void ast_register_thread(char *name)
571 {
572         struct thread_list_t *new = ast_calloc(1, sizeof(*new));
573
574         if (!new)
575                 return;
576
577         ast_assert(multi_thread_safe);
578         new->id = pthread_self();
579         new->lwp = ast_get_tid();
580         new->name = name; /* steal the allocated memory for the thread name */
581         AST_RWLIST_WRLOCK(&thread_list);
582         AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
583         AST_RWLIST_UNLOCK(&thread_list);
584 }
585
586 void ast_unregister_thread(void *id)
587 {
588         struct thread_list_t *x;
589
590         AST_RWLIST_WRLOCK(&thread_list);
591         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
592                 if ((void *) x->id == id) {
593                         AST_RWLIST_REMOVE_CURRENT(list);
594                         break;
595                 }
596         }
597         AST_RWLIST_TRAVERSE_SAFE_END;
598         AST_RWLIST_UNLOCK(&thread_list);
599         if (x) {
600                 ast_free(x->name);
601                 ast_free(x);
602         }
603 }
604
605 /*! \brief Give an overview of core settings */
606 static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
607 {
608         char buf[BUFSIZ];
609         struct ast_tm tm;
610         char eid_str[128];
611
612         switch (cmd) {
613         case CLI_INIT:
614                 e->command = "core show settings";
615                 e->usage = "Usage: core show settings\n"
616                            "       Show core misc settings";
617                 return NULL;
618         case CLI_GENERATE:
619                 return NULL;
620         }
621
622         ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
623
624         ast_cli(a->fd, "\nPBX Core settings\n");
625         ast_cli(a->fd, "-----------------\n");
626         ast_cli(a->fd, "  Version:                     %s\n", ast_get_version());
627         ast_cli(a->fd, "  Build Options:               %s\n", S_OR(AST_BUILDOPTS, "(none)"));
628         if (ast_option_maxcalls)
629                 ast_cli(a->fd, "  Maximum calls:               %d (Current %d)\n", ast_option_maxcalls, ast_active_channels());
630         else
631                 ast_cli(a->fd, "  Maximum calls:               Not set\n");
632         if (ast_option_maxfiles)
633                 ast_cli(a->fd, "  Maximum open file handles:   %d\n", ast_option_maxfiles);
634         else
635                 ast_cli(a->fd, "  Maximum open file handles:   Not set\n");
636         ast_cli(a->fd, "  Root console verbosity:      %d\n", option_verbose);
637         ast_cli(a->fd, "  Current console verbosity:   %d\n", ast_verb_console_get());
638         ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
639         ast_cli(a->fd, "  Maximum load average:        %lf\n", ast_option_maxload);
640 #if defined(HAVE_SYSINFO)
641         ast_cli(a->fd, "  Minimum free memory:         %ld MB\n", option_minmemfree);
642 #endif
643         if (ast_localtime(&ast_startuptime, &tm, NULL)) {
644                 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
645                 ast_cli(a->fd, "  Startup time:                %s\n", buf);
646         }
647         if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
648                 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
649                 ast_cli(a->fd, "  Last reload time:            %s\n", buf);
650         }
651         ast_cli(a->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);
652         ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
653         ast_cli(a->fd, "  Entity ID:                   %s\n", eid_str);
654         ast_cli(a->fd, "  Default language:            %s\n", ast_defaultlanguage);
655         ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
656         ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
657         ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
658         ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
659         ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
660         ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
661         ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
662
663         ast_cli(a->fd, "\n* Subsystems\n");
664         ast_cli(a->fd, "  -------------\n");
665         ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
666         ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
667         ast_cli(a->fd, "  Call data records:           %s\n", ast_cdr_is_enabled() ? "Enabled" : "Disabled");
668         ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
669
670         /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
671
672         ast_cli(a->fd, "\n* Directories\n");
673         ast_cli(a->fd, "  -------------\n");
674         ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
675         ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
676         ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
677         ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
678         ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
679         ast_cli(a->fd, "  Run/Sockets directory:       %s\n", ast_config_AST_RUN_DIR);
680         ast_cli(a->fd, "  PID file:                    %s\n", ast_config_AST_PID);
681         ast_cli(a->fd, "  VarLib directory:            %s\n", ast_config_AST_VAR_DIR);
682         ast_cli(a->fd, "  Data directory:              %s\n", ast_config_AST_DATA_DIR);
683         ast_cli(a->fd, "  ASTDB:                       %s\n", ast_config_AST_DB);
684         ast_cli(a->fd, "  IAX2 Keys directory:         %s\n", ast_config_AST_KEY_DIR);
685         ast_cli(a->fd, "  AGI Scripts directory:       %s\n", ast_config_AST_AGI_DIR);
686         ast_cli(a->fd, "\n\n");
687         return CLI_SUCCESS;
688 }
689
690 static char *handle_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
691 {
692         int count = 0;
693         struct thread_list_t *cur;
694         switch (cmd) {
695         case CLI_INIT:
696                 e->command = "core show threads";
697                 e->usage =
698                         "Usage: core show threads\n"
699                         "       List threads currently active in the system.\n";
700                 return NULL;
701         case CLI_GENERATE:
702                 return NULL;
703         }
704
705         AST_RWLIST_RDLOCK(&thread_list);
706         AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
707                 ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
708                 count++;
709         }
710         AST_RWLIST_UNLOCK(&thread_list);
711         ast_cli(a->fd, "%d threads listed.\n", count);
712         return CLI_SUCCESS;
713 }
714
715 #if defined (HAVE_SYSCTL) && defined(HAVE_SWAPCTL)
716 /*
717  * swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
718  * to be based on the new swapctl(2) system call.
719  */
720 static int swapmode(int *used, int *total)
721 {
722         struct swapent *swdev;
723         int nswap, rnswap, i;
724
725         nswap = swapctl(SWAP_NSWAP, 0, 0);
726         if (nswap == 0)
727                 return 0;
728
729         swdev = ast_calloc(nswap, sizeof(*swdev));
730         if (swdev == NULL)
731                 return 0;
732
733         rnswap = swapctl(SWAP_STATS, swdev, nswap);
734         if (rnswap == -1) {
735                 ast_free(swdev);
736                 return 0;
737         }
738
739         /* if rnswap != nswap, then what? */
740
741         /* Total things up */
742         *total = *used = 0;
743         for (i = 0; i < nswap; i++) {
744                 if (swdev[i].se_flags & SWF_ENABLE) {
745                         *used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
746                         *total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
747                 }
748         }
749         ast_free(swdev);
750         return 1;
751 }
752 #elif defined(HAVE_SYSCTL) && !defined(HAVE_SYSINFO)
753 static int swapmode(int *used, int *total)
754 {
755         *used = *total = 0;
756         return 1;
757 }
758 #endif
759
760 #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
761 /*! \brief Give an overview of system statistics */
762 static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
763 {
764         uint64_t physmem, freeram;
765         uint64_t freeswap = 0;
766         int nprocs = 0;
767         long uptime = 0;
768         int totalswap = 0;
769 #if defined(HAVE_SYSINFO)
770         struct sysinfo sys_info;
771         sysinfo(&sys_info);
772         uptime = sys_info.uptime / 3600;
773         physmem = sys_info.totalram * sys_info.mem_unit;
774         freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
775         totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
776         freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
777         nprocs = sys_info.procs;
778 #elif defined(HAVE_SYSCTL)
779         static int pageshift;
780         struct vmtotal vmtotal;
781         struct timeval  boottime;
782         time_t  now;
783         int mib[2], pagesize, usedswap = 0;
784         size_t len;
785         /* calculate the uptime by looking at boottime */
786         time(&now);
787         mib[0] = CTL_KERN;
788         mib[1] = KERN_BOOTTIME;
789         len = sizeof(boottime);
790         if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
791                 uptime = now - boottime.tv_sec;
792         }
793         uptime = uptime/3600;
794         /* grab total physical memory  */
795         mib[0] = CTL_HW;
796 #if defined(HW_PHYSMEM64)
797         mib[1] = HW_PHYSMEM64;
798 #else
799         mib[1] = HW_PHYSMEM;
800 #endif
801         len = sizeof(physmem);
802         sysctl(mib, 2, &physmem, &len, NULL, 0);
803
804         pagesize = getpagesize();
805         pageshift = 0;
806         while (pagesize > 1) {
807                 pageshift++;
808                 pagesize >>= 1;
809         }
810
811         /* we only need the amount of log(2)1024 for our conversion */
812         pageshift -= 10;
813
814         /* grab vm totals */
815         mib[0] = CTL_VM;
816         mib[1] = VM_METER;
817         len = sizeof(vmtotal);
818         sysctl(mib, 2, &vmtotal, &len, NULL, 0);
819         freeram = (vmtotal.t_free << pageshift);
820         /* generate swap usage and totals */
821         swapmode(&usedswap, &totalswap);
822         freeswap = (totalswap - usedswap);
823         /* grab number of processes */
824 #if defined(__OpenBSD__)
825         mib[0] = CTL_KERN;
826         mib[1] = KERN_NPROCS;
827         len = sizeof(nprocs);
828         sysctl(mib, 2, &nprocs, &len, NULL, 0);
829 #endif
830 #endif
831
832         switch (cmd) {
833         case CLI_INIT:
834                 e->command = "core show sysinfo";
835                 e->usage =
836                         "Usage: core show sysinfo\n"
837                         "       List current system information.\n";
838                 return NULL;
839         case CLI_GENERATE:
840                 return NULL;
841         }
842
843         ast_cli(a->fd, "\nSystem Statistics\n");
844         ast_cli(a->fd, "-----------------\n");
845         ast_cli(a->fd, "  System Uptime:             %ld hours\n", uptime);
846         ast_cli(a->fd, "  Total RAM:                 %" PRIu64 " KiB\n", physmem / 1024);
847         ast_cli(a->fd, "  Free RAM:                  %" PRIu64 " KiB\n", freeram);
848 #if defined(HAVE_SYSINFO)
849         ast_cli(a->fd, "  Buffer RAM:                %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
850 #endif
851 #if defined (HAVE_SYSCTL) || defined(HAVE_SWAPCTL)
852         ast_cli(a->fd, "  Total Swap Space:          %d KiB\n", totalswap);
853         ast_cli(a->fd, "  Free Swap Space:           %" PRIu64 " KiB\n\n", freeswap);
854 #endif
855         ast_cli(a->fd, "  Number of Processes:       %d \n\n", nprocs);
856         return CLI_SUCCESS;
857 }
858 #endif
859
860 struct profile_entry {
861         const char *name;
862         uint64_t        scale;  /* if non-zero, values are scaled by this */
863         int64_t mark;
864         int64_t value;
865         int64_t events;
866 };
867
868 struct profile_data {
869         int entries;
870         int max_size;
871         struct profile_entry e[0];
872 };
873
874 static struct profile_data *prof_data;
875
876 /*! \brief allocates a counter with a given name and scale.
877  * \return Returns the identifier of the counter.
878  */
879 int ast_add_profile(const char *name, uint64_t scale)
880 {
881         int l = sizeof(struct profile_data);
882         int n = 10;     /* default entries */
883
884         if (prof_data == NULL) {
885                 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
886                 if (prof_data == NULL)
887                         return -1;
888                 prof_data->entries = 0;
889                 prof_data->max_size = n;
890         }
891         if (prof_data->entries >= prof_data->max_size) {
892                 void *p;
893                 n = prof_data->max_size + 20;
894                 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
895                 if (p == NULL)
896                         return -1;
897                 prof_data = p;
898                 prof_data->max_size = n;
899         }
900         n = prof_data->entries++;
901         prof_data->e[n].name = ast_strdup(name);
902         prof_data->e[n].value = 0;
903         prof_data->e[n].events = 0;
904         prof_data->e[n].mark = 0;
905         prof_data->e[n].scale = scale;
906         return n;
907 }
908
909 int64_t ast_profile(int i, int64_t delta)
910 {
911         if (!prof_data || i < 0 || i > prof_data->entries)      /* invalid index */
912                 return 0;
913         if (prof_data->e[i].scale > 1)
914                 delta /= prof_data->e[i].scale;
915         prof_data->e[i].value += delta;
916         prof_data->e[i].events++;
917         return prof_data->e[i].value;
918 }
919
920 /* The RDTSC instruction was introduced on the Pentium processor and is not
921  * implemented on certain clones, like the Cyrix 586. Hence, the previous
922  * expectation of __i386__ was in error. */
923 #if defined ( __i686__) && (defined(__FreeBSD__) || defined(linux))
924 #if defined(__FreeBSD__)
925 #include <machine/cpufunc.h>
926 #elif defined(linux)
927 static __inline uint64_t
928 rdtsc(void)
929 {
930         uint64_t rv;
931
932         __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
933         return (rv);
934 }
935 #endif
936 #else   /* supply a dummy function on other platforms */
937 static __inline uint64_t
938 rdtsc(void)
939 {
940         return 0;
941 }
942 #endif
943
944 int64_t ast_mark(int i, int startstop)
945 {
946         if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
947                 return 0;
948         if (startstop == 1)
949                 prof_data->e[i].mark = rdtsc();
950         else {
951                 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
952                 if (prof_data->e[i].scale > 1)
953                         prof_data->e[i].mark /= prof_data->e[i].scale;
954                 prof_data->e[i].value += prof_data->e[i].mark;
955                 prof_data->e[i].events++;
956         }
957         return prof_data->e[i].mark;
958 }
959
960 #define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
961         max = prof_data->entries;\
962         if  (a->argc > 3) { /* specific entries */ \
963                 if (isdigit(a->argv[3][0])) { \
964                         min = atoi(a->argv[3]); \
965                         if (a->argc == 5 && strcmp(a->argv[4], "-")) \
966                                 max = atoi(a->argv[4]); \
967                 } else \
968                         search = a->argv[3]; \
969         } \
970         if (max > prof_data->entries) \
971                 max = prof_data->entries;
972
973 static char *handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
974 {
975         int i, min, max;
976         const char *search = NULL;
977         switch (cmd) {
978         case CLI_INIT:
979                 e->command = "core show profile";
980                 e->usage = "Usage: core show profile\n"
981                            "       show profile information";
982                 return NULL;
983         case CLI_GENERATE:
984                 return NULL;
985         }
986
987         if (prof_data == NULL)
988                 return 0;
989
990         DEFINE_PROFILE_MIN_MAX_VALUES;
991         ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
992                 prof_data->entries, prof_data->max_size);
993         ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
994                         "Value", "Average", "Name");
995         for (i = min; i < max; i++) {
996                 struct profile_entry *entry = &prof_data->e[i];
997                 if (!search || strstr(entry->name, search))
998                     ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
999                         i,
1000                         (long)entry->scale,
1001                         (long)entry->events, (long long)entry->value,
1002                         (long long)(entry->events ? entry->value / entry->events : entry->value),
1003                         entry->name);
1004         }
1005         return CLI_SUCCESS;
1006 }
1007
1008 static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1009 {
1010         int i, min, max;
1011         const char *search = NULL;
1012         switch (cmd) {
1013         case CLI_INIT:
1014                 e->command = "core clear profile";
1015                 e->usage = "Usage: core clear profile\n"
1016                            "       clear profile information";
1017                 return NULL;
1018         case CLI_GENERATE:
1019                 return NULL;
1020         }
1021
1022         if (prof_data == NULL)
1023                 return 0;
1024
1025         DEFINE_PROFILE_MIN_MAX_VALUES;
1026         for (i= min; i < max; i++) {
1027                 if (!search || strstr(prof_data->e[i].name, search)) {
1028                         prof_data->e[i].value = 0;
1029                         prof_data->e[i].events = 0;
1030                 }
1031         }
1032         return CLI_SUCCESS;
1033 }
1034 #undef DEFINE_PROFILE_MIN_MAX_VALUES
1035
1036 /*! \brief CLI command to list module versions */
1037 static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1038 {
1039 #define FORMAT "%-25.25s %-40.40s\n"
1040         struct file_version *iterator;
1041         regex_t regexbuf;
1042         int havepattern = 0;
1043         int havename = 0;
1044         int count_files = 0;
1045         char *ret = NULL;
1046         int matchlen, which = 0;
1047         struct file_version *find;
1048
1049         switch (cmd) {
1050         case CLI_INIT:
1051                 e->command = "core show file version [like]";
1052                 e->usage =
1053                         "Usage: core show file version [like <pattern>]\n"
1054                         "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
1055                         "       Optional regular expression pattern is used to filter the file list.\n";
1056                 return NULL;
1057         case CLI_GENERATE:
1058                 matchlen = strlen(a->word);
1059                 if (a->pos != 3)
1060                         return NULL;
1061                 AST_RWLIST_RDLOCK(&file_versions);
1062                 AST_RWLIST_TRAVERSE(&file_versions, find, list) {
1063                         if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
1064                                 ret = ast_strdup(find->file);
1065                                 break;
1066                         }
1067                 }
1068                 AST_RWLIST_UNLOCK(&file_versions);
1069                 return ret;
1070         }
1071
1072
1073         switch (a->argc) {
1074         case 6:
1075                 if (!strcasecmp(a->argv[4], "like")) {
1076                         if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
1077                                 return CLI_SHOWUSAGE;
1078                         havepattern = 1;
1079                 } else
1080                         return CLI_SHOWUSAGE;
1081                 break;
1082         case 5:
1083                 havename = 1;
1084                 break;
1085         case 4:
1086                 break;
1087         default:
1088                 return CLI_SHOWUSAGE;
1089         }
1090
1091         ast_cli(a->fd, FORMAT, "File", "Revision");
1092         ast_cli(a->fd, FORMAT, "----", "--------");
1093         AST_RWLIST_RDLOCK(&file_versions);
1094         AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
1095                 if (havename && strcasecmp(iterator->file, a->argv[4]))
1096                         continue;
1097
1098                 if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
1099                         continue;
1100
1101                 ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
1102                 count_files++;
1103                 if (havename)
1104                         break;
1105         }
1106         AST_RWLIST_UNLOCK(&file_versions);
1107         if (!havename) {
1108                 ast_cli(a->fd, "%d files listed.\n", count_files);
1109         }
1110
1111         if (havepattern)
1112                 regfree(&regexbuf);
1113
1114         return CLI_SUCCESS;
1115 #undef FORMAT
1116 }
1117
1118 #endif /* ! LOW_MEMORY */
1119
1120 static void publish_fully_booted(void)
1121 {
1122         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1123
1124         json_object = ast_json_pack("{s: s}",
1125                         "Status", "Fully Booted");
1126         ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
1127 }
1128
1129 static void ast_run_atexits(int run_cleanups)
1130 {
1131         struct ast_atexit *ae;
1132
1133         AST_LIST_LOCK(&atexits);
1134         while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
1135                 if (ae->func && (!ae->is_cleanup || run_cleanups)) {
1136                         ae->func();
1137                 }
1138                 ast_free(ae);
1139         }
1140         AST_LIST_UNLOCK(&atexits);
1141 }
1142
1143 static void __ast_unregister_atexit(void (*func)(void))
1144 {
1145         struct ast_atexit *ae;
1146
1147         AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
1148                 if (ae->func == func) {
1149                         AST_LIST_REMOVE_CURRENT(list);
1150                         ast_free(ae);
1151                         break;
1152                 }
1153         }
1154         AST_LIST_TRAVERSE_SAFE_END;
1155 }
1156
1157 static int register_atexit(void (*func)(void), int is_cleanup)
1158 {
1159         struct ast_atexit *ae;
1160
1161         ae = ast_calloc(1, sizeof(*ae));
1162         if (!ae) {
1163                 return -1;
1164         }
1165         ae->func = func;
1166         ae->is_cleanup = is_cleanup;
1167
1168         AST_LIST_LOCK(&atexits);
1169         __ast_unregister_atexit(func);
1170         AST_LIST_INSERT_HEAD(&atexits, ae, list);
1171         AST_LIST_UNLOCK(&atexits);
1172
1173         return 0;
1174 }
1175
1176 int ast_register_atexit(void (*func)(void))
1177 {
1178         return register_atexit(func, 0);
1179 }
1180
1181 int ast_register_cleanup(void (*func)(void))
1182 {
1183         return register_atexit(func, 1);
1184 }
1185
1186 void ast_unregister_atexit(void (*func)(void))
1187 {
1188         AST_LIST_LOCK(&atexits);
1189         __ast_unregister_atexit(func);
1190         AST_LIST_UNLOCK(&atexits);
1191 }
1192
1193 /* Sending commands from consoles back to the daemon requires a terminating NULL */
1194 static int fdsend(int fd, const char *s)
1195 {
1196         return write(fd, s, strlen(s) + 1);
1197 }
1198
1199 /* Sending messages from the daemon back to the display requires _excluding_ the terminating NULL */
1200 static int fdprint(int fd, const char *s)
1201 {
1202         return write(fd, s, strlen(s));
1203 }
1204
1205 /*! \brief NULL handler so we can collect the child exit status */
1206 static void _null_sig_handler(int sig)
1207 {
1208 }
1209
1210 static struct sigaction null_sig_handler = {
1211         .sa_handler = _null_sig_handler,
1212         .sa_flags = SA_RESTART,
1213 };
1214
1215 static struct sigaction ignore_sig_handler = {
1216         .sa_handler = SIG_IGN,
1217 };
1218
1219 AST_MUTEX_DEFINE_STATIC(safe_system_lock);
1220 /*! \brief Keep track of how many threads are currently trying to wait*() on
1221  *  a child process
1222  */
1223 static unsigned int safe_system_level = 0;
1224 static struct sigaction safe_system_prev_handler;
1225
1226 void ast_replace_sigchld(void)
1227 {
1228         unsigned int level;
1229
1230         ast_mutex_lock(&safe_system_lock);
1231         level = safe_system_level++;
1232
1233         /* only replace the handler if it has not already been done */
1234         if (level == 0) {
1235                 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1236         }
1237
1238         ast_mutex_unlock(&safe_system_lock);
1239 }
1240
1241 void ast_unreplace_sigchld(void)
1242 {
1243         unsigned int level;
1244
1245         ast_mutex_lock(&safe_system_lock);
1246         level = --safe_system_level;
1247
1248         /* only restore the handler if we are the last one */
1249         if (level == 0) {
1250                 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1251         }
1252
1253         ast_mutex_unlock(&safe_system_lock);
1254 }
1255
1256 int ast_safe_system(const char *s)
1257 {
1258         pid_t pid;
1259         int res;
1260         int status;
1261
1262 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1263         ast_replace_sigchld();
1264
1265 #ifdef HAVE_WORKING_FORK
1266         pid = fork();
1267 #else
1268         pid = vfork();
1269 #endif
1270
1271         if (pid == 0) {
1272 #ifdef HAVE_CAP
1273                 cap_t cap = cap_from_text("cap_net_admin-eip");
1274
1275                 if (cap_set_proc(cap)) {
1276                         /* Careful with order! Logging cannot happen after we close FDs */
1277                         ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
1278                 }
1279                 cap_free(cap);
1280 #endif
1281 #ifdef HAVE_WORKING_FORK
1282                 if (ast_opt_high_priority)
1283                         ast_set_priority(0);
1284                 /* Close file descriptors and launch system command */
1285                 ast_close_fds_above_n(STDERR_FILENO);
1286 #endif
1287                 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1288                 _exit(1);
1289         } else if (pid > 0) {
1290                 for (;;) {
1291                         res = waitpid(pid, &status, 0);
1292                         if (res > -1) {
1293                                 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1294                                 break;
1295                         } else if (errno != EINTR)
1296                                 break;
1297                 }
1298         } else {
1299                 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
1300                 res = -1;
1301         }
1302
1303         ast_unreplace_sigchld();
1304 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
1305         res = -1;
1306 #endif
1307
1308         return res;
1309 }
1310
1311 /*!
1312  * \brief enable or disable a logging level to a specified console
1313  */
1314 void ast_console_toggle_loglevel(int fd, int level, int state)
1315 {
1316         int x;
1317
1318         if (level >= NUMLOGLEVELS) {
1319                 level = NUMLOGLEVELS - 1;
1320         }
1321
1322         for (x = 0;x < AST_MAX_CONNECTS; x++) {
1323                 if (fd == consoles[x].fd) {
1324                         /*
1325                          * Since the logging occurs when levels are false, set to
1326                          * flipped iinput because this function accepts 0 as off and 1 as on
1327                          */
1328                         consoles[x].levels[level] = state ? 0 : 1;
1329                         return;
1330                 }
1331         }
1332 }
1333
1334 /*!
1335  * \brief mute or unmute a console from logging
1336  */
1337 void ast_console_toggle_mute(int fd, int silent)
1338 {
1339         int x;
1340         for (x = 0;x < AST_MAX_CONNECTS; x++) {
1341                 if (fd == consoles[x].fd) {
1342                         if (consoles[x].mute) {
1343                                 consoles[x].mute = 0;
1344                                 if (!silent)
1345                                         ast_cli(fd, "Console is not muted anymore.\n");
1346                         } else {
1347                                 consoles[x].mute = 1;
1348                                 if (!silent)
1349                                         ast_cli(fd, "Console is muted.\n");
1350                         }
1351                         return;
1352                 }
1353         }
1354         ast_cli(fd, "Couldn't find remote console.\n");
1355 }
1356
1357 /*!
1358  * \brief log the string to all attached network console clients
1359  */
1360 static void ast_network_puts_mutable(const char *string, int level)
1361 {
1362         int x;
1363
1364         for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1365                 if (consoles[x].fd < 0
1366                         || consoles[x].mute
1367                         || consoles[x].levels[level]) {
1368                         continue;
1369                 }
1370                 fdprint(consoles[x].p[1], string);
1371         }
1372 }
1373
1374 /*!
1375  * \brief log the string to the root console, and all attached
1376  * network console clients
1377  */
1378 void ast_console_puts_mutable(const char *string, int level)
1379 {
1380         /* Send to the root console */
1381         fputs(string, stdout);
1382         fflush(stdout);
1383
1384         /* Send to any network console clients */
1385         ast_network_puts_mutable(string, level);
1386 }
1387
1388 /*!
1389  * \brief write the string to all attached console clients
1390  */
1391 static void ast_network_puts(const char *string)
1392 {
1393         int x;
1394
1395         for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1396                 if (consoles[x].fd < 0) {
1397                         continue;
1398                 }
1399                 fdprint(consoles[x].p[1], string);
1400         }
1401 }
1402
1403 /*!
1404  * \brief write the string to the root console, and all attached
1405  * network console clients
1406  */
1407 void ast_console_puts(const char *string)
1408 {
1409         /* Send to the root console */
1410         fputs(string, stdout);
1411         fflush(stdout);
1412
1413         /* Send to any network console clients */
1414         ast_network_puts(string);
1415 }
1416
1417 static void network_verboser(const char *string)
1418 {
1419         int x;
1420         int verb_level;
1421
1422         /* Send to any network console clients if client verbocity allows. */
1423         verb_level = VERBOSE_MAGIC2LEVEL(string);
1424         for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1425                 if (consoles[x].fd < 0
1426                         || consoles[x].mute
1427                         || consoles[x].levels[__LOG_VERBOSE]
1428                         || consoles[x].option_verbose < verb_level) {
1429                         continue;
1430                 }
1431                 fdprint(consoles[x].p[1], string);
1432         }
1433 }
1434
1435 static pthread_t lthread;
1436
1437 /*!
1438  * \brief read() function supporting the reception of user credentials.
1439  *
1440  * \param fd Socket file descriptor.
1441  * \param buffer Receive buffer.
1442  * \param size 'buffer' size.
1443  * \param con Console structure to set received credentials
1444  * \retval -1 on error
1445  * \retval the number of bytes received on success.
1446  */
1447 static int read_credentials(int fd, char *buffer, size_t size, struct console *con)
1448 {
1449 #if defined(SO_PEERCRED)
1450 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
1451 #define HAVE_STRUCT_UCRED_UID
1452         struct sockpeercred cred;
1453 #else
1454         struct ucred cred;
1455 #endif
1456         socklen_t len = sizeof(cred);
1457 #endif
1458 #if defined(HAVE_GETPEEREID)
1459         uid_t uid;
1460         gid_t gid;
1461 #else
1462         int uid, gid;
1463 #endif
1464         int result;
1465
1466         result = read(fd, buffer, size);
1467         if (result < 0) {
1468                 return result;
1469         }
1470
1471 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
1472         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
1473                 return result;
1474         }
1475 #if defined(HAVE_STRUCT_UCRED_UID)
1476         uid = cred.uid;
1477         gid = cred.gid;
1478 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
1479         uid = cred.cr_uid;
1480         gid = cred.cr_gid;
1481 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
1482
1483 #elif defined(HAVE_GETPEEREID)
1484         if (getpeereid(fd, &uid, &gid)) {
1485                 return result;
1486         }
1487 #else
1488         return result;
1489 #endif
1490         con->uid = uid;
1491         con->gid = gid;
1492
1493         return result;
1494 }
1495
1496 /* This is the thread running the remote console on the main process. */
1497 static void *netconsole(void *vconsole)
1498 {
1499         struct console *con = vconsole;
1500         char hostname[MAXHOSTNAMELEN] = "";
1501         char inbuf[512];
1502         char outbuf[512];
1503         const char * const end_buf = inbuf + sizeof(inbuf);
1504         char *start_read = inbuf;
1505         int res;
1506         struct pollfd fds[2];
1507
1508         if (gethostname(hostname, sizeof(hostname)-1))
1509                 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
1510         snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
1511         fdprint(con->fd, outbuf);
1512         ast_verb_console_register(&con->option_verbose);
1513         for (;;) {
1514                 fds[0].fd = con->fd;
1515                 fds[0].events = POLLIN;
1516                 fds[0].revents = 0;
1517                 fds[1].fd = con->p[0];
1518                 fds[1].events = POLLIN;
1519                 fds[1].revents = 0;
1520
1521                 res = ast_poll(fds, 2, -1);
1522                 if (res < 0) {
1523                         if (errno != EINTR)
1524                                 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
1525                         continue;
1526                 }
1527                 if (fds[0].revents) {
1528                         int cmds_read, bytes_read;
1529                         if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
1530                                 break;
1531                         }
1532                         /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
1533                         if (strncmp(inbuf, "cli quit after ", 15) == 0) {
1534                                 ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
1535                                 break;
1536                         }
1537                         /* ast_cli_command_multiple_full will only process individual commands terminated by a
1538                          * NULL and not trailing partial commands. */
1539                         if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
1540                                 /* No commands were read. We either have a short read on the first command
1541                                  * with space left, or a command that is too long */
1542                                 if (start_read + bytes_read < end_buf) {
1543                                         start_read += bytes_read;
1544                                 } else {
1545                                         ast_log(LOG_ERROR, "Command too long! Skipping\n");
1546                                         start_read = inbuf;
1547                                 }
1548                                 continue;
1549                         }
1550                         if (start_read[bytes_read - 1] == '\0') {
1551                                 /* The read ended on a command boundary, start reading again at the head of inbuf */
1552                                 start_read = inbuf;
1553                                 continue;
1554                         }
1555                         /* If we get this far, we have left over characters that have not been processed.
1556                          * Advance to the character after the last command read by ast_cli_command_multiple_full.
1557                          * We are guaranteed to have at least cmds_read NULLs */
1558                         while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
1559                                 start_read++;
1560                         }
1561                         memmove(inbuf, start_read, end_buf - start_read);
1562                         start_read = end_buf - start_read + inbuf;
1563                 }
1564                 if (fds[1].revents) {
1565                         res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
1566                         if (res < 1) {
1567                                 ast_log(LOG_ERROR, "read returned %d\n", res);
1568                                 break;
1569                         }
1570                         res = write(con->fd, outbuf, res);
1571                         if (res < 1)
1572                                 break;
1573                 }
1574         }
1575         ast_verb_console_unregister();
1576         if (!ast_opt_hide_connect) {
1577                 ast_verb(3, "Remote UNIX connection disconnected\n");
1578         }
1579         close(con->fd);
1580         close(con->p[0]);
1581         close(con->p[1]);
1582         con->fd = -1;
1583
1584         return NULL;
1585 }
1586
1587 static void *listener(void *unused)
1588 {
1589         struct sockaddr_un sunaddr;
1590         int s;
1591         socklen_t len;
1592         int x;
1593         int flags;
1594         struct pollfd fds[1];
1595         for (;;) {
1596                 if (ast_socket < 0)
1597                         return NULL;
1598                 fds[0].fd = ast_socket;
1599                 fds[0].events = POLLIN;
1600                 s = ast_poll(fds, 1, -1);
1601                 pthread_testcancel();
1602                 if (s < 0) {
1603                         if (errno != EINTR)
1604                                 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
1605                         continue;
1606                 }
1607                 len = sizeof(sunaddr);
1608                 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
1609                 if (s < 0) {
1610                         if (errno != EINTR)
1611                                 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
1612                 } else {
1613 #if !defined(SO_PASSCRED)
1614                         {
1615 #else
1616                         int sckopt = 1;
1617                         /* turn on socket credentials passing. */
1618                         if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
1619                                 ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
1620                         } else {
1621 #endif
1622                                 for (x = 0; x < AST_MAX_CONNECTS; x++) {
1623                                         if (consoles[x].fd >= 0) {
1624                                                 continue;
1625                                         }
1626                                         if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
1627                                                 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
1628                                                 fdprint(s, "Server failed to create pipe\n");
1629                                                 close(s);
1630                                                 break;
1631                                         }
1632                                         flags = fcntl(consoles[x].p[1], F_GETFL);
1633                                         fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
1634                                         consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
1635                                         /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
1636                                            to know if the user didn't send the credentials. */
1637                                         consoles[x].uid = -2;
1638                                         consoles[x].gid = -2;
1639                                         /* Server default of remote console verbosity level is OFF. */
1640                                         consoles[x].option_verbose = 0;
1641                                         consoles[x].fd = s;
1642                                         if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
1643                                                 consoles[x].fd = -1;
1644                                                 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
1645                                                 close(consoles[x].p[0]);
1646                                                 close(consoles[x].p[1]);
1647                                                 fdprint(s, "Server failed to spawn thread\n");
1648                                                 close(s);
1649                                         }
1650                                         break;
1651                                 }
1652                                 if (x >= AST_MAX_CONNECTS) {
1653                                         fdprint(s, "No more connections allowed\n");
1654                                         ast_log(LOG_WARNING, "No more connections allowed\n");
1655                                         close(s);
1656                                 } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
1657                                         ast_verb(3, "Remote UNIX connection\n");
1658                                 }
1659                         }
1660                 }
1661         }
1662         return NULL;
1663 }
1664
1665 static int ast_makesocket(void)
1666 {
1667         struct sockaddr_un sunaddr;
1668         int res;
1669         int x;
1670         uid_t uid = -1;
1671         gid_t gid = -1;
1672
1673         for (x = 0; x < AST_MAX_CONNECTS; x++)
1674                 consoles[x].fd = -1;
1675         unlink(ast_config_AST_SOCKET);
1676         ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
1677         if (ast_socket < 0) {
1678                 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
1679                 return -1;
1680         }
1681         memset(&sunaddr, 0, sizeof(sunaddr));
1682         sunaddr.sun_family = AF_LOCAL;
1683         ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1684         res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1685         if (res) {
1686                 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1687                 close(ast_socket);
1688                 ast_socket = -1;
1689                 return -1;
1690         }
1691         res = listen(ast_socket, 2);
1692         if (res < 0) {
1693                 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1694                 close(ast_socket);
1695                 ast_socket = -1;
1696                 return -1;
1697         }
1698         if (ast_register_verbose(network_verboser)) {
1699                 ast_log(LOG_WARNING, "Unable to register network verboser?\n");
1700         }
1701
1702         if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
1703                 ast_log(LOG_WARNING, "Unable to create listener thread.\n");
1704                 close(ast_socket);
1705                 return -1;
1706         }
1707
1708         if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
1709                 struct passwd *pw;
1710                 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
1711                         ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
1712                 else
1713                         uid = pw->pw_uid;
1714         }
1715
1716         if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
1717                 struct group *grp;
1718                 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
1719                         ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
1720                 else
1721                         gid = grp->gr_gid;
1722         }
1723
1724         if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
1725                 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1726
1727         if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
1728                 unsigned int p1;
1729                 mode_t p;
1730                 sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
1731                 p = p1;
1732                 if ((chmod(ast_config_AST_SOCKET, p)) < 0)
1733                         ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1734         }
1735
1736         return 0;
1737 }
1738
1739 static int ast_tryconnect(void)
1740 {
1741         struct sockaddr_un sunaddr;
1742         int res;
1743         ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
1744         if (ast_consock < 0) {
1745                 fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
1746                 return 0;
1747         }
1748         memset(&sunaddr, 0, sizeof(sunaddr));
1749         sunaddr.sun_family = AF_LOCAL;
1750         ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1751         res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1752         if (res) {
1753                 close(ast_consock);
1754                 ast_consock = -1;
1755                 return 0;
1756         } else
1757                 return 1;
1758 }
1759
1760 /*! \brief Urgent handler
1761  *
1762  * Called by soft_hangup to interrupt the poll, read, or other
1763  * system call.  We don't actually need to do anything though.
1764  * Remember: Cannot EVER ast_log from within a signal handler
1765  */
1766 static void _urg_handler(int num)
1767 {
1768         return;
1769 }
1770
1771 static struct sigaction urg_handler = {
1772         .sa_handler = _urg_handler,
1773         .sa_flags = SA_RESTART,
1774 };
1775
1776 static void _hup_handler(int num)
1777 {
1778         int a = 0, save_errno = errno;
1779         printf("Received HUP signal -- Reloading configs\n");
1780         if (restartnow)
1781                 execvp(_argv[0], _argv);
1782         sig_flags.need_reload = 1;
1783         if (sig_alert_pipe[1] != -1) {
1784                 if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
1785                         fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
1786                 }
1787         }
1788         errno = save_errno;
1789 }
1790
1791 static struct sigaction hup_handler = {
1792         .sa_handler = _hup_handler,
1793         .sa_flags = SA_RESTART,
1794 };
1795
1796 static void _child_handler(int sig)
1797 {
1798         /* Must not ever ast_log or ast_verbose within signal handler */
1799         int n, status, save_errno = errno;
1800
1801         /*
1802          * Reap all dead children -- not just one
1803          */
1804         for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
1805                 ;
1806         if (n == 0 && option_debug)
1807                 printf("Huh?  Child handler, but nobody there?\n");
1808         errno = save_errno;
1809 }
1810
1811 static struct sigaction child_handler = {
1812         .sa_handler = _child_handler,
1813         .sa_flags = SA_RESTART,
1814 };
1815
1816 /*! \brief Set maximum open files */
1817 static void set_ulimit(int value)
1818 {
1819         struct rlimit l = {0, 0};
1820
1821         if (value <= 0) {
1822                 ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
1823                 return;
1824         }
1825
1826         l.rlim_cur = value;
1827         l.rlim_max = value;
1828
1829         if (setrlimit(RLIMIT_NOFILE, &l)) {
1830                 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
1831                 return;
1832         }
1833
1834         ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
1835
1836         return;
1837 }
1838
1839 /*! \brief Set an X-term or screen title */
1840 static void set_title(char *text)
1841 {
1842         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1843                 fprintf(stdout, "\033]2;%s\007", text);
1844 }
1845
1846 static void set_icon(char *text)
1847 {
1848         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1849                 fprintf(stdout, "\033]1;%s\007", text);
1850 }
1851
1852 /*! \brief We set ourselves to a high priority, that we might pre-empt
1853  * everything else.  If your PBX has heavy activity on it, this is a
1854  * good thing.
1855  */
1856 int ast_set_priority(int pri)
1857 {
1858         struct sched_param sched;
1859         memset(&sched, 0, sizeof(sched));
1860 #ifdef __linux__
1861         if (pri) {
1862                 sched.sched_priority = 10;
1863                 if (sched_setscheduler(0, SCHED_RR, &sched)) {
1864                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1865                         return -1;
1866                 } else
1867                         ast_verb(1, "Set to realtime thread\n");
1868         } else {
1869                 sched.sched_priority = 0;
1870                 /* According to the manpage, these parameters can never fail. */
1871                 sched_setscheduler(0, SCHED_OTHER, &sched);
1872         }
1873 #else
1874         if (pri) {
1875                 if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
1876                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1877                         return -1;
1878                 } else
1879                         ast_verb(1, "Set to high priority\n");
1880         } else {
1881                 /* According to the manpage, these parameters can never fail. */
1882                 setpriority(PRIO_PROCESS, 0, 0);
1883         }
1884 #endif
1885         return 0;
1886 }
1887
1888 int ast_shutdown_final(void)
1889 {
1890         return shuttingdown == SHUTTING_DOWN_FINAL;
1891 }
1892
1893 int ast_shutting_down(void)
1894 {
1895         return shutdown_pending;
1896 }
1897
1898 int ast_cancel_shutdown(void)
1899 {
1900         int shutdown_aborted = 0;
1901
1902         ast_mutex_lock(&safe_system_lock);
1903         if (shuttingdown >= SHUTDOWN_FAST) {
1904                 shuttingdown = NOT_SHUTTING_DOWN;
1905                 shutdown_pending = 0;
1906                 shutdown_aborted = 1;
1907         }
1908         ast_mutex_unlock(&safe_system_lock);
1909         return shutdown_aborted;
1910 }
1911
1912 /*!
1913  * \internal
1914  * \brief Initiate system shutdown -- prevents new channels from being allocated.
1915  */
1916 static void ast_begin_shutdown(void)
1917 {
1918         ast_mutex_lock(&safe_system_lock);
1919         if (shuttingdown != NOT_SHUTTING_DOWN) {
1920                 shutdown_pending = 1;
1921         }
1922         ast_mutex_unlock(&safe_system_lock);
1923 }
1924
1925 static int can_safely_quit(shutdown_nice_t niceness, int restart);
1926 static void really_quit(int num, shutdown_nice_t niceness, int restart);
1927
1928 static void quit_handler(int num, shutdown_nice_t niceness, int restart)
1929 {
1930         if (can_safely_quit(niceness, restart)) {
1931                 really_quit(num, niceness, restart);
1932                 /* No one gets here. */
1933         }
1934         /* It wasn't our time. */
1935 }
1936
1937 #define SHUTDOWN_TIMEOUT        15      /* Seconds */
1938
1939 /*!
1940  * \internal
1941  * \brief Wait for all channels to die, a timeout, or shutdown cancelled.
1942  * \since 13.3.0
1943  *
1944  * \param niceness Shutdown niceness in effect
1945  * \param seconds Number of seconds to wait or less than zero if indefinitely.
1946  *
1947  * \retval zero if waiting wasn't necessary.  We were idle.
1948  * \retval non-zero if we had to wait.
1949  */
1950 static int wait_for_channels_to_die(shutdown_nice_t niceness, int seconds)
1951 {
1952         time_t start;
1953         time_t now;
1954         int waited = 0;
1955
1956         time(&start);
1957         for (;;) {
1958                 if (!ast_undestroyed_channels() || shuttingdown != niceness) {
1959                         break;
1960                 }
1961                 if (seconds < 0) {
1962                         /* No timeout so just poll every second */
1963                         sleep(1);
1964                 } else {
1965                         time(&now);
1966
1967                         /* Wait up to the given seconds for all channels to go away */
1968                         if (seconds < (now - start)) {
1969                                 break;
1970                         }
1971
1972                         /* Sleep 1/10 of a second */
1973                         usleep(100000);
1974                 }
1975                 waited = 1;
1976         }
1977         return waited;
1978 }
1979
1980 static int can_safely_quit(shutdown_nice_t niceness, int restart)
1981 {
1982         int waited = 0;
1983
1984         /* Check if someone else isn't already doing this. */
1985         ast_mutex_lock(&safe_system_lock);
1986         if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
1987                 /* Already in progress and other request was less nice. */
1988                 ast_mutex_unlock(&safe_system_lock);
1989                 ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
1990                 return 0;
1991         }
1992         shuttingdown = niceness;
1993         ast_mutex_unlock(&safe_system_lock);
1994
1995         /* Try to get as many CDRs as possible submitted to the backend engines
1996          * (if in batch mode). really_quit happens to call it again when running
1997          * the atexit handlers, otherwise this would be a bit early. */
1998         ast_cdr_engine_term();
1999
2000         /*
2001          * Shutdown the message queue for the technology agnostic message channel.
2002          * This has to occur before we pause shutdown pending ast_undestroyed_channels.
2003          *
2004          * XXX This is not reversed on shutdown cancel.
2005          */
2006         ast_msg_shutdown();
2007
2008         if (niceness == SHUTDOWN_NORMAL) {
2009                 /* Begin shutdown routine, hanging up active channels */
2010                 ast_begin_shutdown();
2011                 if (ast_opt_console) {
2012                         ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
2013                 }
2014                 ast_softhangup_all();
2015                 waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
2016         } else if (niceness >= SHUTDOWN_NICE) {
2017                 if (niceness != SHUTDOWN_REALLY_NICE) {
2018                         ast_begin_shutdown();
2019                 }
2020                 if (ast_opt_console) {
2021                         ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
2022                 }
2023                 waited |= wait_for_channels_to_die(niceness, -1);
2024         }
2025
2026         /* Re-acquire lock and check if someone changed the niceness, in which
2027          * case someone else has taken over the shutdown.
2028          */
2029         ast_mutex_lock(&safe_system_lock);
2030         if (shuttingdown != niceness) {
2031                 if (shuttingdown == NOT_SHUTTING_DOWN && ast_opt_console) {
2032                         ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
2033                 }
2034                 ast_mutex_unlock(&safe_system_lock);
2035                 return 0;
2036         }
2037
2038         if (niceness >= SHUTDOWN_REALLY_NICE) {
2039                 shuttingdown = SHUTTING_DOWN;
2040                 ast_mutex_unlock(&safe_system_lock);
2041
2042                 /* No more Mr. Nice guy.  We are committed to shutting down now. */
2043                 ast_begin_shutdown();
2044                 ast_softhangup_all();
2045                 waited |= wait_for_channels_to_die(SHUTTING_DOWN, SHUTDOWN_TIMEOUT);
2046
2047                 ast_mutex_lock(&safe_system_lock);
2048         }
2049         shuttingdown = SHUTTING_DOWN_FINAL;
2050         ast_mutex_unlock(&safe_system_lock);
2051
2052         if (niceness >= SHUTDOWN_NORMAL && waited) {
2053                 /*
2054                  * We were not idle.  Give things in progress a chance to
2055                  * recognize the final shutdown phase.
2056                  */
2057                 sleep(1);
2058         }
2059         return 1;
2060 }
2061
2062 /*! Called when exiting is certain. */
2063 static void really_quit(int num, shutdown_nice_t niceness, int restart)
2064 {
2065         int active_channels;
2066         struct ast_json *json_object = NULL;
2067         int run_cleanups = niceness >= SHUTDOWN_NICE;
2068
2069         if (run_cleanups) {
2070                 ast_module_shutdown();
2071         }
2072
2073         if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
2074                 char filename[80] = "";
2075                 if (getenv("HOME")) {
2076                         snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
2077                 }
2078                 if (!ast_strlen_zero(filename)) {
2079                         ast_el_write_history(filename);
2080                 }
2081                 if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
2082                         /* Only end if we are the consolethread, otherwise there's a race with that thread. */
2083                         if (el != NULL) {
2084                                 el_end(el);
2085                         }
2086                         if (el_hist != NULL) {
2087                                 history_end(el_hist);
2088                         }
2089                 } else if (mon_sig_flags == pthread_self()) {
2090                         if (consolethread != AST_PTHREADT_NULL) {
2091                                 pthread_kill(consolethread, SIGURG);
2092                         }
2093                 }
2094         }
2095         active_channels = ast_active_channels();
2096         /* Don't publish messages if we're a remote console - we won't have all of the Stasis
2097          * topics or message types
2098          */
2099         if (!ast_opt_remote) {
2100                 json_object = ast_json_pack("{s: s, s: s}",
2101                                 "Shutdown", active_channels ? "Uncleanly" : "Cleanly",
2102                                 "Restart", restart ? "True" : "False");
2103                 ast_manager_publish_event("Shutdown", EVENT_FLAG_SYSTEM, json_object);
2104                 ast_json_unref(json_object);
2105                 json_object = NULL;
2106         }
2107         ast_verb(0, "Asterisk %s ending (%d).\n",
2108                 active_channels ? "uncleanly" : "cleanly", num);
2109
2110         ast_verb(0, "Executing last minute cleanups\n");
2111         ast_run_atexits(run_cleanups);
2112
2113         ast_debug(1, "Asterisk ending (%d).\n", num);
2114         if (ast_socket > -1) {
2115                 pthread_cancel(lthread);
2116                 close(ast_socket);
2117                 ast_socket = -1;
2118                 unlink(ast_config_AST_SOCKET);
2119                 pthread_kill(lthread, SIGURG);
2120                 pthread_join(lthread, NULL);
2121         }
2122         if (ast_consock > -1)
2123                 close(ast_consock);
2124         if (!ast_opt_remote)
2125                 unlink(ast_config_AST_PID);
2126         if (sig_alert_pipe[0])
2127                 close(sig_alert_pipe[0]);
2128         if (sig_alert_pipe[1])
2129                 close(sig_alert_pipe[1]);
2130         printf("%s", term_quit());
2131         if (restart) {
2132                 int i;
2133                 ast_verb(0, "Preparing for Asterisk restart...\n");
2134                 /* Mark all FD's for closing on exec */
2135                 for (i = 3; i < 32768; i++) {
2136                         fcntl(i, F_SETFD, FD_CLOEXEC);
2137                 }
2138                 ast_verb(0, "Asterisk is now restarting...\n");
2139                 restartnow = 1;
2140
2141                 /* close logger */
2142                 close_logger();
2143                 clean_time_zones();
2144
2145                 /* If there is a consolethread running send it a SIGHUP
2146                    so it can execvp, otherwise we can do it ourselves */
2147                 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
2148                         pthread_kill(consolethread, SIGHUP);
2149                         /* Give the signal handler some time to complete */
2150                         sleep(2);
2151                 } else
2152                         execvp(_argv[0], _argv);
2153
2154         } else {
2155                 /* close logger */
2156                 close_logger();
2157                 clean_time_zones();
2158         }
2159
2160         exit(0);
2161 }
2162
2163 static void __quit_handler(int num)
2164 {
2165         int a = 0;
2166         sig_flags.need_quit = 1;
2167         if (sig_alert_pipe[1] != -1) {
2168                 if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
2169                         fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
2170                 }
2171         }
2172         /* There is no need to restore the signal handler here, since the app
2173          * is going to exit */
2174 }
2175
2176 static void __remote_quit_handler(int num)
2177 {
2178         sig_flags.need_quit = 1;
2179 }
2180
2181 static void set_header(char *outbuf, int maxout, char level)
2182 {
2183         const char *cmp;
2184         char date[40];
2185
2186         switch (level) {
2187         case 0: cmp = NULL;
2188                 break;
2189         case 1: cmp = VERBOSE_PREFIX_1;
2190                 break;
2191         case 2: cmp = VERBOSE_PREFIX_2;
2192                 break;
2193         case 3: cmp = VERBOSE_PREFIX_3;
2194                 break;
2195         default: cmp = VERBOSE_PREFIX_4;
2196                 break;
2197         }
2198
2199         if (ast_opt_timestamp) {
2200                 struct ast_tm tm;
2201                 struct timeval now = ast_tvnow();
2202                 ast_localtime(&now, &tm, NULL);
2203                 ast_strftime(date, sizeof(date), ast_logger_get_dateformat(), &tm);
2204         }
2205
2206         snprintf(outbuf, maxout, "%s%s%s%s%s%s",
2207                 ast_opt_timestamp ? "[" : "",
2208                 ast_opt_timestamp ? date : "",
2209                 ast_opt_timestamp ? "] " : "",
2210                 cmp ? ast_term_color(COLOR_GRAY, 0) : "",
2211                 cmp ? cmp : "",
2212                 cmp ? ast_term_reset() : "");
2213 }
2214
2215 struct console_state_data {
2216         char verbose_line_level;
2217 };
2218
2219 static int console_state_init(void *ptr)
2220 {
2221         struct console_state_data *state = ptr;
2222         state->verbose_line_level = 0;
2223         return 0;
2224 }
2225
2226 AST_THREADSTORAGE_CUSTOM(console_state, console_state_init, ast_free_ptr);
2227
2228 static int console_print(const char *s, int local)
2229 {
2230         struct console_state_data *state =
2231                 ast_threadstorage_get(&console_state, sizeof(*state));
2232
2233         char prefix[80];
2234         const char *c;
2235         int num, res = 0;
2236         unsigned int newline;
2237
2238         do {
2239                 if (VERBOSE_HASMAGIC(s)) {
2240
2241                         /* always use the given line's level, otherwise
2242                            we'll use the last line's level */
2243                         state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
2244
2245                         /* move past magic */
2246                         s++;
2247
2248                         set_header(prefix, sizeof(prefix), state->verbose_line_level);
2249                 } else {
2250                         *prefix = '\0';
2251                 }
2252                 c = s;
2253
2254                 /* for a given line separate on verbose magic, newline, and eol */
2255                 if ((s = strchr(c, '\n'))) {
2256                         ++s;
2257                         newline = 1;
2258                 } else {
2259                         s = strchr(c, '\0');
2260                         newline = 0;
2261                 }
2262
2263                 /* check if we should write this line after calculating begin/end
2264                    so we process the case of a higher level line embedded within
2265                    two lower level lines */
2266                 if (state->verbose_line_level > option_verbose) {
2267                         continue;
2268                 }
2269
2270                 if (!ast_strlen_zero(prefix)) {
2271                         fputs(prefix, stdout);
2272                 }
2273
2274                 num = s - c;
2275                 if (fwrite(c, sizeof(char), num, stdout) < num) {
2276                         break;
2277                 }
2278
2279                 if (!res) {
2280                         /* if at least some info has been written
2281                            we'll want to return true */
2282                         res = 1;
2283                 }
2284         } while (*s);
2285
2286         if (newline) {
2287                 /* if ending on a newline then reset last level to zero
2288                     since what follows may be not be logging output */
2289                 state->verbose_line_level = 0;
2290         }
2291
2292         if (res) {
2293                 fflush(stdout);
2294         }
2295
2296         return res;
2297 }
2298
2299 static void console_verboser(const char *s)
2300 {
2301         if (!console_print(s, 1)) {
2302                 return;
2303         }
2304
2305         /* Wake up a poll()ing console */
2306         if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
2307                 pthread_kill(consolethread, SIGURG);
2308         }
2309 }
2310
2311 static int ast_all_zeros(char *s)
2312 {
2313         while (*s) {
2314                 if (*s > 32)
2315                         return 0;
2316                 s++;
2317         }
2318         return 1;
2319 }
2320
2321 /* This is the main console CLI command handler.  Run by the main() thread. */
2322 static void consolehandler(char *s)
2323 {
2324         printf("%s", term_end());
2325         fflush(stdout);
2326
2327         /* Called when readline data is available */
2328         if (!ast_all_zeros(s))
2329                 ast_el_add_history(s);
2330         /* The real handler for bang */
2331         if (s[0] == '!') {
2332                 if (s[1])
2333                         ast_safe_system(s+1);
2334                 else
2335                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2336         } else
2337                 ast_cli_command(STDOUT_FILENO, s);
2338 }
2339
2340 static int remoteconsolehandler(char *s)
2341 {
2342         int ret = 0;
2343
2344         /* Called when readline data is available */
2345         if (!ast_all_zeros(s))
2346                 ast_el_add_history(s);
2347
2348         while (isspace(*s)) {
2349                 s++;
2350         }
2351
2352         /* The real handler for bang */
2353         if (s[0] == '!') {
2354                 if (s[1])
2355                         ast_safe_system(s+1);
2356                 else
2357                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2358                 ret = 1;
2359         } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
2360             (s[4] == '\0' || isspace(s[4]))) {
2361                 quit_handler(0, SHUTDOWN_FAST, 0);
2362                 ret = 1;
2363         } else if (s[0]) {
2364                 char *shrunk = ast_strdupa(s);
2365                 char *cur;
2366                 char *prev;
2367
2368                 /*
2369                  * Remove duplicate spaces from shrunk for matching purposes.
2370                  *
2371                  * shrunk has at least one character in it to start with or we
2372                  * couldn't get here.
2373                  */
2374                 for (prev = shrunk, cur = shrunk + 1; *cur; ++cur) {
2375                         if (*prev == ' ' && *cur == ' ') {
2376                                 /* Skip repeated space delimiter. */
2377                                 continue;
2378                         }
2379                         *++prev = *cur;
2380                 }
2381                 *++prev = '\0';
2382
2383                 if (strncasecmp(shrunk, "core set verbose ", 17) == 0) {
2384                         /*
2385                          * We need to still set the rasterisk option_verbose in case we are
2386                          * talking to an earlier version which doesn't prefilter verbose
2387                          * levels.  This is really a compromise as we should always take
2388                          * whatever the server sends.
2389                          */
2390
2391                         if (!strncasecmp(shrunk + 17, "off", 3)) {
2392                                 ast_verb_console_set(0);
2393                         } else {
2394                                 int verbose_new;
2395                                 int atleast;
2396
2397                                 atleast = 8;
2398                                 if (strncasecmp(shrunk + 17, "atleast ", atleast)) {
2399                                         atleast = 0;
2400                                 }
2401
2402                                 if (sscanf(shrunk + 17 + atleast, "%30d", &verbose_new) == 1) {
2403                                         if (!atleast || ast_verb_console_get() < verbose_new) {
2404                                                 ast_verb_console_set(verbose_new);
2405                                         }
2406                                 }
2407                         }
2408                 }
2409         }
2410
2411         return ret;
2412 }
2413
2414 static char *handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2415 {
2416         switch (cmd) {
2417         case CLI_INIT:
2418                 e->command = "core show version";
2419                 e->usage =
2420                         "Usage: core show version\n"
2421                         "       Shows Asterisk version information.\n";
2422                 return NULL;
2423         case CLI_GENERATE:
2424                 return NULL;
2425         }
2426
2427         if (a->argc != 3)
2428                 return CLI_SHOWUSAGE;
2429         ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
2430                 ast_get_version(), ast_build_user, ast_build_hostname,
2431                 ast_build_machine, ast_build_os, ast_build_date);
2432         return CLI_SUCCESS;
2433 }
2434
2435 #if 0
2436 static int handle_quit(int fd, int argc, char *argv[])
2437 {
2438         if (argc != 1)
2439                 return RESULT_SHOWUSAGE;
2440         quit_handler(0, SHUTDOWN_NORMAL, 0);
2441         return RESULT_SUCCESS;
2442 }
2443 #endif
2444
2445 static char *handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2446 {
2447         switch (cmd) {
2448         case CLI_INIT:
2449                 e->command = "core stop now";
2450                 e->usage =
2451                         "Usage: core stop now\n"
2452                         "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
2453                 return NULL;
2454         case CLI_GENERATE:
2455                 return NULL;
2456         }
2457
2458         if (a->argc != e->args)
2459                 return CLI_SHOWUSAGE;
2460         quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
2461         return CLI_SUCCESS;
2462 }
2463
2464 static char *handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2465 {
2466         switch (cmd) {
2467         case CLI_INIT:
2468                 e->command = "core stop gracefully";
2469                 e->usage =
2470                         "Usage: core stop gracefully\n"
2471                         "       Causes Asterisk to not accept new calls, and exit when all\n"
2472                         "       active calls have terminated normally.\n";
2473                 return NULL;
2474         case CLI_GENERATE:
2475                 return NULL;
2476         }
2477
2478         if (a->argc != e->args)
2479                 return CLI_SHOWUSAGE;
2480         quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
2481         return CLI_SUCCESS;
2482 }
2483
2484 static char *handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2485 {
2486         switch (cmd) {
2487         case CLI_INIT:
2488                 e->command = "core stop when convenient";
2489                 e->usage =
2490                         "Usage: core stop when convenient\n"
2491                         "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
2492                 return NULL;
2493         case CLI_GENERATE:
2494                 return NULL;
2495         }
2496
2497         if (a->argc != e->args)
2498                 return CLI_SHOWUSAGE;
2499         ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
2500         quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
2501         return CLI_SUCCESS;
2502 }
2503
2504 static char *handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2505 {
2506         switch (cmd) {
2507         case CLI_INIT:
2508                 e->command = "core restart now";
2509                 e->usage =
2510                         "Usage: core restart now\n"
2511                         "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
2512                         "       restart.\n";
2513                 return NULL;
2514         case CLI_GENERATE:
2515                 return NULL;
2516         }
2517
2518         if (a->argc != e->args)
2519                 return CLI_SHOWUSAGE;
2520         quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
2521         return CLI_SUCCESS;
2522 }
2523
2524 static char *handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2525 {
2526         switch (cmd) {
2527         case CLI_INIT:
2528                 e->command = "core restart gracefully";
2529                 e->usage =
2530                         "Usage: core restart gracefully\n"
2531                         "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
2532                         "       restart when all active calls have ended.\n";
2533                 return NULL;
2534         case CLI_GENERATE:
2535                 return NULL;
2536         }
2537
2538         if (a->argc != e->args)
2539                 return CLI_SHOWUSAGE;
2540         quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
2541         return CLI_SUCCESS;
2542 }
2543
2544 static char *handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2545 {
2546         switch (cmd) {
2547         case CLI_INIT:
2548                 e->command = "core restart when convenient";
2549                 e->usage =
2550                         "Usage: core restart when convenient\n"
2551                         "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
2552                 return NULL;
2553         case CLI_GENERATE:
2554                 return NULL;
2555         }
2556
2557         if (a->argc != e->args)
2558                 return CLI_SHOWUSAGE;
2559         ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
2560         quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
2561         return CLI_SUCCESS;
2562 }
2563
2564 static char *handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2565 {
2566         switch (cmd) {
2567         case CLI_INIT:
2568                 e->command = "core abort shutdown";
2569                 e->usage =
2570                         "Usage: core abort shutdown\n"
2571                         "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2572                         "       call operations.\n";
2573                 return NULL;
2574         case CLI_GENERATE:
2575                 return NULL;
2576         }
2577
2578         if (a->argc != e->args)
2579                 return CLI_SHOWUSAGE;
2580
2581         ast_cancel_shutdown();
2582
2583         return CLI_SUCCESS;
2584 }
2585
2586 static char *handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2587 {
2588         switch (cmd) {
2589         case CLI_INIT:
2590                 e->command = "!";
2591                 e->usage =
2592                         "Usage: !<command>\n"
2593                         "       Executes a given shell command\n";
2594                 return NULL;
2595         case CLI_GENERATE:
2596                 return NULL;
2597         }
2598
2599         return CLI_SUCCESS;
2600 }
2601 static const char warranty_lines[] = {
2602         "\n"
2603         "                           NO WARRANTY\n"
2604         "\n"
2605         "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
2606         "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n"
2607         "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
2608         "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
2609         "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
2610         "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n"
2611         "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n"
2612         "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
2613         "REPAIR OR CORRECTION.\n"
2614         "\n"
2615         "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
2616         "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
2617         "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
2618         "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
2619         "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
2620         "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
2621         "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
2622         "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
2623         "POSSIBILITY OF SUCH DAMAGES.\n"
2624 };
2625
2626 static char *show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2627 {
2628         switch (cmd) {
2629         case CLI_INIT:
2630                 e->command = "core show warranty";
2631                 e->usage =
2632                         "Usage: core show warranty\n"
2633                         "       Shows the warranty (if any) for this copy of Asterisk.\n";
2634                 return NULL;
2635         case CLI_GENERATE:
2636                 return NULL;
2637         }
2638
2639         ast_cli(a->fd, "%s", warranty_lines);
2640
2641         return CLI_SUCCESS;
2642 }
2643
2644 static const char license_lines[] = {
2645         "\n"
2646         "This program is free software; you can redistribute it and/or modify\n"
2647         "it under the terms of the GNU General Public License version 2 as\n"
2648         "published by the Free Software Foundation.\n"
2649         "\n"
2650         "This program also contains components licensed under other licenses.\n"
2651         "They include:\n"
2652         "\n"
2653         "This program is distributed in the hope that it will be useful,\n"
2654         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2655         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
2656         "GNU General Public License for more details.\n"
2657         "\n"
2658         "You should have received a copy of the GNU General Public License\n"
2659         "along with this program; if not, write to the Free Software\n"
2660         "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
2661 };
2662
2663 static char *show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2664 {
2665         switch (cmd) {
2666         case CLI_INIT:
2667                 e->command = "core show license";
2668                 e->usage =
2669                         "Usage: core show license\n"
2670                         "       Shows the license(s) for this copy of Asterisk.\n";
2671                 return NULL;
2672         case CLI_GENERATE:
2673                 return NULL;
2674         }
2675
2676         ast_cli(a->fd, "%s", license_lines);
2677
2678         return CLI_SUCCESS;
2679 }
2680
2681 #define ASTERISK_PROMPT "*CLI> "
2682
2683 /*!
2684  * \brief Shutdown Asterisk CLI commands.
2685  *
2686  * \note These CLI commands cannot be unregistered at shutdown
2687  * because one of them is likely the reason for the shutdown.
2688  * The CLI generates a warning if a command is in-use when it is
2689  * unregistered.
2690  */
2691 static struct ast_cli_entry cli_asterisk_shutdown[] = {
2692         AST_CLI_DEFINE(handle_stop_now, "Shut down Asterisk immediately"),
2693         AST_CLI_DEFINE(handle_stop_gracefully, "Gracefully shut down Asterisk"),
2694         AST_CLI_DEFINE(handle_stop_when_convenient, "Shut down Asterisk at empty call volume"),
2695         AST_CLI_DEFINE(handle_restart_now, "Restart Asterisk immediately"),
2696         AST_CLI_DEFINE(handle_restart_gracefully, "Restart Asterisk gracefully"),
2697         AST_CLI_DEFINE(handle_restart_when_convenient, "Restart Asterisk at empty call volume"),
2698 };
2699
2700 static struct ast_cli_entry cli_asterisk[] = {
2701         AST_CLI_DEFINE(handle_abort_shutdown, "Cancel a running shutdown"),
2702         AST_CLI_DEFINE(show_warranty, "Show the warranty (if any) for this copy of Asterisk"),
2703         AST_CLI_DEFINE(show_license, "Show the license(s) for this copy of Asterisk"),
2704         AST_CLI_DEFINE(handle_version, "Display version info"),
2705         AST_CLI_DEFINE(handle_bang, "Execute a shell command"),
2706 #if !defined(LOW_MEMORY)
2707         AST_CLI_DEFINE(handle_show_version_files, "List versions of files used to build Asterisk"),
2708         AST_CLI_DEFINE(handle_show_threads, "Show running threads"),
2709 #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
2710         AST_CLI_DEFINE(handle_show_sysinfo, "Show System Information"),
2711 #endif
2712         AST_CLI_DEFINE(handle_show_profile, "Display profiling info"),
2713         AST_CLI_DEFINE(handle_show_settings, "Show some core settings"),
2714         AST_CLI_DEFINE(handle_clear_profile, "Clear profiling info"),
2715 #endif /* ! LOW_MEMORY */
2716 };
2717
2718 static void send_rasterisk_connect_commands(void)
2719 {
2720         char buf[80];
2721
2722         /*
2723          * Tell the server asterisk instance about the verbose level
2724          * initially desired.
2725          */
2726         if (option_verbose) {
2727                 snprintf(buf, sizeof(buf), "core set verbose atleast %d silent", option_verbose);
2728                 fdsend(ast_consock, buf);
2729         }
2730
2731         if (option_debug) {
2732                 snprintf(buf, sizeof(buf), "core set debug atleast %d", option_debug);
2733                 fdsend(ast_consock, buf);
2734         }
2735
2736         if (!ast_opt_mute) {
2737                 fdsend(ast_consock, "logger mute silent");
2738         } else {
2739                 printf("log and verbose output currently muted ('logger mute' to unmute)\n");
2740         }
2741 }
2742
2743 static int ast_el_read_char(EditLine *editline, char *cp)
2744 {
2745         int num_read = 0;
2746         int lastpos = 0;
2747         struct pollfd fds[2];
2748         int res;
2749         int max;
2750 #define EL_BUF_SIZE 512
2751         char buf[EL_BUF_SIZE];
2752
2753         for (;;) {
2754                 max = 1;
2755                 fds[0].fd = ast_consock;
2756                 fds[0].events = POLLIN;
2757                 if (!ast_opt_exec) {
2758                         fds[1].fd = STDIN_FILENO;
2759                         fds[1].events = POLLIN;
2760                         max++;
2761                 }
2762                 res = ast_poll(fds, max, -1);
2763                 if (res < 0) {
2764                         if (sig_flags.need_quit || sig_flags.need_quit_handler)
2765                                 break;
2766                         if (errno == EINTR)
2767                                 continue;
2768                         fprintf(stderr, "poll failed: %s\n", strerror(errno));
2769                         break;
2770                 }
2771
2772                 if (!ast_opt_exec && fds[1].revents) {
2773                         num_read = read(STDIN_FILENO, cp, 1);
2774                         if (num_read < 1) {
2775                                 break;
2776                         } else {
2777                                 return (num_read);
2778                         }
2779                 }
2780                 if (fds[0].revents) {
2781                         res = read(ast_consock, buf, sizeof(buf) - 1);
2782                         /* if the remote side disappears exit */
2783                         if (res < 1) {
2784                                 fprintf(stderr, "\nDisconnected from Asterisk server\n");
2785                                 if (!ast_opt_reconnect) {
2786                                         quit_handler(0, SHUTDOWN_FAST, 0);
2787                                 } else {
2788                                         int tries;
2789                                         int reconnects_per_second = 20;
2790                                         fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
2791                                         for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
2792                                                 if (ast_tryconnect()) {
2793                                                         fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
2794                                                         printf("%s", term_quit());
2795                                                         WELCOME_MESSAGE;
2796                                                         send_rasterisk_connect_commands();
2797                                                         break;
2798                                                 } else
2799                                                         usleep(1000000 / reconnects_per_second);
2800                                         }
2801                                         if (tries >= 30 * reconnects_per_second) {
2802                                                 fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
2803                                                 quit_handler(0, SHUTDOWN_FAST, 0);
2804                                         }
2805                                 }
2806                                 continue;
2807                         }
2808
2809                         buf[res] = '\0';
2810
2811                         /* Write over the CLI prompt */
2812                         if (!ast_opt_exec && !lastpos) {
2813                                 if (write(STDOUT_FILENO, "\r\e[0K", 5) < 0) {
2814                                 }
2815                         }
2816
2817                         console_print(buf, 0);
2818
2819                         if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
2820                                 *cp = CC_REFRESH;
2821                                 return(1);
2822                         } else
2823                                 lastpos = 1;
2824                 }
2825         }
2826
2827         *cp = '\0';
2828         return (0);
2829 }
2830
2831 static struct ast_str *prompt = NULL;
2832
2833 static char *cli_prompt(EditLine *editline)
2834 {
2835         char tmp[100];
2836         char *pfmt;
2837         int color_used = 0;
2838         static int cli_prompt_changes = 0;
2839         struct passwd *pw;
2840         struct group *gr;
2841
2842         if (prompt == NULL) {
2843                 prompt = ast_str_create(100);
2844         } else if (!cli_prompt_changes) {
2845                 return ast_str_buffer(prompt);
2846         } else {
2847                 ast_str_reset(prompt);
2848         }
2849
2850         if ((pfmt = getenv("ASTERISK_PROMPT"))) {
2851                 char *t = pfmt;
2852                 struct timeval ts = ast_tvnow();
2853                 while (*t != '\0') {
2854                         if (*t == '%') {
2855                                 char hostname[MAXHOSTNAMELEN] = "";
2856                                 int i, which;
2857                                 struct ast_tm tm = { 0, };
2858                                 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
2859
2860                                 t++;
2861                                 switch (*t) {
2862                                 case 'C': /* color */
2863                                         t++;
2864                                         if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
2865                                                 ast_term_color_code(&prompt, fgcolor, bgcolor);
2866                                                 t += i - 1;
2867                                         } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
2868                                                 ast_term_color_code(&prompt, fgcolor, 0);
2869                                                 t += i - 1;
2870                                         }
2871
2872                                         /* If the color has been reset correctly, then there's no need to reset it later */
2873                                         color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
2874                                         break;
2875                                 case 'd': /* date */
2876                                         if (ast_localtime(&ts, &tm, NULL)) {
2877                                                 ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
2878                                                 ast_str_append(&prompt, 0, "%s", tmp);
2879                                                 cli_prompt_changes++;
2880                                         }
2881                                         break;
2882                                 case 'g': /* group */
2883                                         if ((gr = getgrgid(getgid()))) {
2884                                                 ast_str_append(&prompt, 0, "%s", gr->gr_name);
2885                                         }
2886                                         break;
2887                                 case 'h': /* hostname */
2888                                         if (!gethostname(hostname, sizeof(hostname) - 1)) {
2889                                                 ast_str_append(&prompt, 0, "%s", hostname);
2890                                         } else {
2891                                                 ast_str_append(&prompt, 0, "%s", "localhost");
2892                                         }
2893                                         break;
2894                                 case 'H': /* short hostname */
2895                                         if (!gethostname(hostname, sizeof(hostname) - 1)) {
2896                                                 char *dotptr;
2897                                                 if ((dotptr = strchr(hostname, '.'))) {
2898                                                         *dotptr = '\0';
2899                                                 }
2900                                                 ast_str_append(&prompt, 0, "%s", hostname);
2901                                         } else {
2902                                                 ast_str_append(&prompt, 0, "%s", "localhost");
2903                                         }
2904                                         break;
2905 #ifdef HAVE_GETLOADAVG
2906                                 case 'l': /* load avg */
2907                                         t++;
2908                                         if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
2909                                                 double list[3];
2910                                                 getloadavg(list, 3);
2911                                                 ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
2912                                                 cli_prompt_changes++;
2913                                         }
2914                                         break;
2915 #endif
2916                                 case 's': /* Asterisk system name (from asterisk.conf) */
2917                                         ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
2918                                         break;
2919                                 case 't': /* time */
2920                                         if (ast_localtime(&ts, &tm, NULL)) {
2921                                                 ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
2922                                                 ast_str_append(&prompt, 0, "%s", tmp);
2923                                                 cli_prompt_changes++;
2924                                         }
2925                                         break;
2926                                 case 'u': /* username */
2927                                         if ((pw = getpwuid(getuid()))) {
2928                                                 ast_str_append(&prompt, 0, "%s", pw->pw_name);
2929                                         }
2930                                         break;
2931                                 case '#': /* process console or remote? */
2932                                         ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
2933                                         break;
2934                                 case '%': /* literal % */
2935                                         ast_str_append(&prompt, 0, "%c", '%');
2936                                         break;
2937                                 case '\0': /* % is last character - prevent bug */
2938                                         t--;
2939                                         break;
2940                                 }
2941                         } else {
2942                                 ast_str_append(&prompt, 0, "%c", *t);
2943                         }
2944                         t++;
2945                 }
2946                 if (color_used) {
2947                         /* Force colors back to normal at end */
2948                         ast_term_color_code(&prompt, 0, 0);
2949                 }
2950         } else {
2951                 ast_str_set(&prompt, 0, "%s%s",
2952                         remotehostname ? remotehostname : "",
2953                         ASTERISK_PROMPT);
2954         }
2955
2956         return ast_str_buffer(prompt);
2957 }
2958
2959 static void destroy_match_list(char **match_list, int matches)
2960 {
2961         if (match_list) {
2962                 int idx;
2963
2964                 for (idx = 0; idx < matches; ++idx) {
2965                         ast_free(match_list[idx]);
2966                 }
2967                 ast_free(match_list);
2968         }
2969 }
2970
2971 static char **ast_el_strtoarr(char *buf)
2972 {
2973         char *retstr;
2974         char **match_list = NULL;
2975         char **new_list;
2976         size_t match_list_len = 1;
2977         int matches = 0;
2978
2979         while ((retstr = strsep(&buf, " "))) {
2980                 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
2981                         break;
2982                 }
2983                 if (matches + 1 >= match_list_len) {
2984                         match_list_len <<= 1;
2985                         new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
2986                         if (!new_list) {
2987                                 destroy_match_list(match_list, matches);
2988                                 return NULL;
2989                         }
2990                         match_list = new_list;
2991                 }
2992
2993                 retstr = ast_strdup(retstr);
2994                 if (!retstr) {
2995                         destroy_match_list(match_list, matches);
2996                         return NULL;
2997                 }
2998                 match_list[matches++] = retstr;
2999         }
3000
3001         if (!match_list) {
3002                 return NULL;
3003         }
3004
3005         if (matches >= match_list_len) {
3006                 new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
3007                 if (!new_list) {
3008                         destroy_match_list(match_list, matches);
3009                         return NULL;
3010                 }
3011                 match_list = new_list;
3012         }
3013
3014         match_list[matches] = NULL;
3015
3016         return match_list;
3017 }
3018
3019 static int ast_el_sort_compare(const void *i1, const void *i2)
3020 {
3021         char *s1, *s2;
3022
3023         s1 = ((char **)i1)[0];
3024         s2 = ((char **)i2)[0];
3025
3026         return strcasecmp(s1, s2);
3027 }
3028
3029 static int ast_cli_display_match_list(char **matches, int len, int max)
3030 {
3031         int i, idx, limit, count;
3032         int screenwidth = 0;
3033         int numoutput = 0, numoutputline = 0;
3034
3035         screenwidth = ast_get_termcols(STDOUT_FILENO);
3036
3037         /* find out how many entries can be put on one line, with two spaces between strings */
3038         limit = screenwidth / (max + 2);
3039         if (limit == 0)
3040                 limit = 1;
3041
3042         /* how many lines of output */
3043         count = len / limit;
3044         if (count * limit < len)
3045                 count++;
3046
3047         idx = 1;
3048
3049         qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
3050
3051         for (; count > 0; count--) {
3052                 numoutputline = 0;
3053                 for (i = 0; i < limit && matches[idx]; i++, idx++) {
3054
3055                         /* Don't print dupes */
3056                         if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
3057                                 i--;
3058                                 ast_free(matches[idx]);
3059                                 matches[idx] = NULL;
3060                                 continue;
3061                         }
3062
3063                         numoutput++;
3064                         numoutputline++;
3065                         fprintf(stdout, "%-*s  ", max, matches[idx]);
3066                         ast_free(matches[idx]);
3067                         matches[idx] = NULL;
3068                 }
3069                 if (numoutputline > 0)
3070                         fprintf(stdout, "\n");
3071         }
3072
3073         return numoutput;
3074 }
3075
3076
3077 static char *cli_complete(EditLine *editline, int ch)
3078 {
3079         int len = 0;
3080         char *ptr;
3081         int nummatches = 0;
3082         char **matches;
3083         int retval = CC_ERROR;
3084         char buf[2048], savechr;
3085         int res;
3086
3087         LineInfo *lf = (LineInfo *)el_line(editline);
3088
3089         savechr = *(char *)lf->cursor;
3090         *(char *)lf->cursor = '\0';
3091         ptr = (char *)lf->cursor;
3092         if (ptr) {
3093                 while (ptr > lf->buffer) {
3094                         if (isspace(*ptr)) {
3095                                 ptr++;
3096                                 break;
3097                         }
3098                         ptr--;
3099                 }
3100         }
3101
3102         len = lf->cursor - ptr;
3103
3104         if (ast_opt_remote) {
3105                 snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
3106                 fdsend(ast_consock, buf);
3107                 if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
3108                         return (char*)(CC_ERROR);
3109                 }
3110                 buf[res] = '\0';
3111                 nummatches = atoi(buf);
3112
3113                 if (nummatches > 0) {
3114                         char *mbuf;
3115                         char *new_mbuf;
3116                         int mlen = 0, maxmbuf = 2048;
3117
3118                         /* Start with a 2048 byte buffer */
3119                         if (!(mbuf = ast_malloc(maxmbuf))) {
3120                                 *((char *) lf->cursor) = savechr;
3121                                 return (char *)(CC_ERROR);
3122                         }
3123                         snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
3124                         fdsend(ast_consock, buf);
3125                         res = 0;
3126                         mbuf[0] = '\0';
3127                         while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
3128                                 if (mlen + 1024 > maxmbuf) {
3129                                         /* Every step increment buffer 1024 bytes */
3130                                         maxmbuf += 1024;
3131                                         new_mbuf = ast_realloc(mbuf, maxmbuf);
3132                                         if (!new_mbuf) {
3133                                                 ast_free(mbuf);
3134                                                 *((char *) lf->cursor) = savechr;
3135                                                 return (char *)(CC_ERROR);
3136                                         }
3137                                         mbuf = new_mbuf;
3138                                 }
3139                                 /* Only read 1024 bytes at a time */
3140                                 res = read(ast_consock, mbuf + mlen, 1024);
3141                                 if (res > 0)
3142                                         mlen += res;
3143                         }
3144                         mbuf[mlen] = '\0';
3145
3146                         matches = ast_el_strtoarr(mbuf);
3147                         ast_free(mbuf);
3148                 } else
3149                         matches = (char **) NULL;
3150         } else {
3151                 char **p, *oldbuf=NULL;
3152                 nummatches = 0;
3153                 matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
3154                 for (p = matches; p && *p; p++) {
3155                         if (!oldbuf || strcmp(*p,oldbuf))
3156                                 nummatches++;
3157                         oldbuf = *p;
3158                 }
3159         }
3160
3161         if (matches) {
3162                 int i;
3163                 int matches_num, maxlen, match_len;
3164
3165                 if (matches[0][0] != '\0') {
3166                         el_deletestr(editline, (int) len);
3167                         el_insertstr(editline, matches[0]);
3168                         retval = CC_REFRESH;
3169                 }
3170
3171                 if (nummatches == 1) {
3172                         /* Found an exact match */
3173                         el_insertstr(editline, " ");
3174                         retval = CC_REFRESH;
3175                 } else {
3176                         /* Must be more than one match */
3177                         for (i = 1, maxlen = 0; matches[i]; i++) {
3178                                 match_len = strlen(matches[i]);
3179                                 if (match_len > maxlen)
3180                                         maxlen = match_len;
3181                         }
3182                         matches_num = i - 1;
3183                         if (matches_num >1) {
3184                                 fprintf(stdout, "\n");
3185                                 ast_cli_display_match_list(matches, nummatches, maxlen);
3186                                 retval = CC_REDISPLAY;
3187                         } else {
3188                                 el_insertstr(editline," ");
3189                                 retval = CC_REFRESH;
3190                         }
3191                 }
3192                 for (i = 0; matches[i]; i++)
3193                         ast_free(matches[i]);
3194                 ast_free(matches);
3195         }
3196
3197         *((char *) lf->cursor) = savechr;
3198
3199         return (char *)(long)retval;
3200 }
3201
3202 static int ast_el_initialize(void)
3203 {
3204         HistEvent ev;
3205         char *editor, *editrc = getenv("EDITRC");
3206
3207         if (!(editor = getenv("AST_EDITMODE"))) {
3208                 if (!(editor = getenv("AST_EDITOR"))) {
3209                         editor = "emacs";
3210                 }
3211         }
3212
3213         if (el != NULL)
3214                 el_end(el);
3215         if (el_hist != NULL)
3216                 history_end(el_hist);
3217
3218         el = el_init("asterisk", stdin, stdout, stderr);
3219         el_set(el, EL_PROMPT, cli_prompt);
3220
3221         el_set(el, EL_EDITMODE, 1);
3222         el_set(el, EL_EDITOR, editor);
3223         el_hist = history_init();
3224         if (!el || !el_hist)
3225                 return -1;
3226
3227         /* setup history with 100 entries */
3228         history(el_hist, &ev, H_SETSIZE, 100);
3229
3230         el_set(el, EL_HIST, history, el_hist);
3231
3232         el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
3233         /* Bind <tab> to command completion */
3234         el_set(el, EL_BIND, "^I", "ed-complete", NULL);
3235         /* Bind ? to command completion */
3236         el_set(el, EL_BIND, "?", "ed-complete", NULL);
3237         /* Bind ^D to redisplay */
3238         el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
3239         /* Bind Delete to delete char left */
3240         el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
3241         /* Bind Home and End to move to line start and end */
3242         el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
3243         el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
3244         /* Bind C-left and C-right to move by word (not all terminals) */
3245         el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
3246         el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
3247
3248         if (editrc) {
3249                 el_source(el, editrc);
3250         }
3251
3252         return 0;
3253 }
3254
3255 #define MAX_HISTORY_COMMAND_LENGTH 256
3256
3257 static int ast_el_add_history(char *buf)
3258 {
3259         HistEvent ev;
3260         char *stripped_buf;
3261
3262         if (el_hist == NULL || el == NULL) {
3263                 ast_el_initialize();
3264         }
3265         if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
3266                 return 0;
3267         }
3268
3269         stripped_buf = ast_strip(ast_strdupa(buf));
3270
3271         /* HISTCONTROL=ignoredups */
3272         if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
3273                 return 0;
3274         }
3275
3276         return history(el_hist, &ev, H_ENTER, stripped_buf);
3277 }
3278
3279 static int ast_el_write_history(char *filename)
3280 {
3281         HistEvent ev;
3282
3283         if (el_hist == NULL || el == NULL)
3284                 ast_el_initialize();
3285
3286         return (history(el_hist, &ev, H_SAVE, filename));
3287 }
3288
3289 static int ast_el_read_history(char *filename)
3290 {
3291         HistEvent ev;
3292
3293         if (el_hist == NULL || el == NULL) {
3294                 ast_el_initialize();
3295         }
3296
3297         return history(el_hist, &ev, H_LOAD, filename);
3298 }
3299
3300 static void ast_remotecontrol(char *data)
3301 {
3302         char buf[256] = "";
3303         int res;
3304         char filename[80] = "";
3305         char *hostname;
3306         char *cpid;
3307         char *version;
3308         int pid;
3309         char *stringp = NULL;
3310
3311         char *ebuf;
3312         int num = 0;
3313
3314         memset(&sig_flags, 0, sizeof(sig_flags));
3315         signal(SIGINT, __remote_quit_handler);
3316         signal(SIGTERM, __remote_quit_handler);
3317         signal(SIGHUP, __remote_quit_handler);
3318
3319         if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
3320                 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
3321                 return;
3322         }
3323         if (data) {
3324                 char prefix[] = "cli quit after ";
3325                 char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
3326                 sprintf(tmp, "%s%s", prefix, data);
3327                 if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
3328                         ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
3329                         if (sig_flags.need_quit || sig_flags.need_quit_handler) {
3330                                 return;
3331                         }
3332                 }
3333         }
3334         stringp = buf;
3335         hostname = strsep(&stringp, "/");
3336         cpid = strsep(&stringp, "/");
3337         version = strsep(&stringp, "\n");
3338         if (!version)
3339                 version = "<Version Unknown>";
3340         stringp = hostname;
3341         strsep(&stringp, ".");
3342         if (cpid)
3343                 pid = atoi(cpid);
3344         else
3345                 pid = -1;
3346         if (!data) {
3347                 send_rasterisk_connect_commands();
3348         }
3349
3350         if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
3351                 int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
3352                 struct pollfd fds;
3353                 fds.fd = ast_consock;
3354                 fds.events = POLLIN;
3355                 fds.revents = 0;
3356
3357                 while (ast_poll(&fds, 1, 60000) > 0) {
3358                         char buffer[512] = "", *curline = buffer, *nextline;
3359                         int not_written = 1;
3360
3361                         if (sig_flags.need_quit || sig_flags.need_quit_handler) {
3362                                 break;
3363                         }
3364
3365                         if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
3366                                 break;
3367                         }
3368
3369                         do {
3370                                 prev_linefull = linefull;
3371                                 if ((nextline = strchr(curline, '\n'))) {
3372                                         linefull = 1;
3373                                         nextline++;
3374                                 } else {
3375                                         linefull = 0;
3376                                         nextline = strchr(curline, '\0');
3377                                 }
3378
3379                                 /* Skip verbose lines */
3380                                 /* Prev line full? | Line is verbose | Last line verbose? | Print
3381                                  * TRUE            | TRUE*           | TRUE               | FALSE
3382                                  * TRUE            | TRUE*           | FALSE              | FALSE
3383                                  * TRUE            | FALSE*          | TRUE               | TRUE
3384                                  * TRUE            | FALSE*          | FALSE              | TRUE
3385                                  * FALSE           | TRUE            | TRUE*              | FALSE
3386                                  * FALSE           | TRUE            | FALSE*             | TRUE
3387                                  * FALSE           | FALSE           | TRUE*              | FALSE
3388                                  * FALSE           | FALSE           | FALSE*             | TRUE
3389                                  */
3390                                 if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
3391                                         prev_line_verbose = 0;
3392                                         not_written = 0;
3393                                         if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
3394                                                 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
3395                                         }
3396                                 } else {
3397                                         prev_line_verbose = 1;
3398                                 }
3399                                 curline = nextline;
3400                         } while (!ast_strlen_zero(curline));
3401
3402                         /* No non-verbose output in 60 seconds. */
3403                         if (not_written) {
3404                                 break;
3405                         }
3406                 }
3407                 return;
3408         }
3409
3410         ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
3411         remotehostname = hostname;
3412         if (getenv("HOME"))
3413                 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
3414         if (el_hist == NULL || el == NULL)
3415                 ast_el_initialize();
3416
3417         el_set(el, EL_GETCFN, ast_el_read_char);
3418
3419         if (!ast_strlen_zero(filename))
3420                 ast_el_read_history(filename);
3421
3422         for (;;) {
3423                 ebuf = (char *)el_gets(el, &num);
3424
3425                 if (sig_flags.need_quit || sig_flags.need_quit_handler) {
3426                         break;
3427                 }
3428
3429                 if (!ebuf && write(1, "", 1) < 0)
3430                         break;
3431
3432                 if (!ast_strlen_zero(ebuf)) {
3433                         if (ebuf[strlen(ebuf)-1] == '\n')
3434                                 ebuf[strlen(ebuf)-1] = '\0';
3435                         if (!remoteconsolehandler(ebuf)) {
3436                                 res = write(ast_consock, ebuf, strlen(ebuf) + 1);
3437                                 if (res < 1) {
3438                                         ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
3439                                         break;
3440                                 }
3441                         }
3442                 }
3443         }
3444         printf("\nDisconnected from Asterisk server\n");
3445 }
3446
3447 static int show_version(void)
3448 {
3449         printf("Asterisk %s\n", ast_get_version());
3450         return 0;
3451 }
3452
3453 static int show_cli_help(void)
3454 {
3455         printf("Asterisk %s, Copyright (C) 1999 - 2014, Digium, Inc. and others.\n", ast_get_version());
3456         printf("Usage: asterisk [OPTIONS]\n");
3457         printf("Valid Options:\n");
3458         printf("   -V              Display version number and exit\n");
3459         printf("   -C <configfile> Use an alternate configuration file\n");
3460         printf("   -G <group>      Run as a group other than the caller\n");
3461         printf("   -U <user>       Run as a user other than the caller\n");
3462         printf("   -c              Provide console CLI\n");
3463         printf("   -d              Enable extra debugging\n");
3464 #if HAVE_WORKING_FORK
3465         printf("   -f              Do not fork\n");
3466         printf("   -F              Always fork\n");
3467 #endif
3468         printf("   -g              Dump core in case of a crash\n");
3469         printf("   -h              This help screen\n");
3470         printf("   -i              Initialize crypto keys at startup\n");
3471         printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
3472         printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
3473         printf("   -m              Mute debugging and console output on the console\n");
3474         printf("   -n              Disable console colorization\n");
3475         printf("   -p              Run as pseudo-realtime thread\n");
3476         printf("   -q              Quiet mode (suppress output)\n");
3477         printf("   -r              Connect to Asterisk on this machine\n");
3478         printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
3479         printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
3480         printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
3481         printf("                   belong after they are done\n");
3482         printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
3483         printf("                   of output to the CLI\n");
3484         printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
3485         printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
3486         printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
3487         printf("   -W              Adjust terminal colors to compensate for a light background\n");
3488         printf("\n");
3489         return 0;
3490 }
3491
3492 static void ast_readconfig(void)
3493 {
3494         struct ast_config *cfg;
3495         struct ast_variable *v;
3496         char *config = DEFAULT_CONFIG_FILE;
3497         char hostname[MAXHOSTNAMELEN] = "";
3498         struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
3499         struct {
3500                 unsigned int dbdir:1;
3501                 unsigned int keydir:1;
3502         } found = { 0, 0 };
3503         /* Default to false for security */
3504         int live_dangerously = 0;
3505
3506         /* Set default value */
3507         option_dtmfminduration = AST_MIN_DTMF_DURATION;
3508
3509         if (ast_opt_override_config) {
3510                 cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
3511                 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
3512                         fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
3513                 }
3514         } else {
3515                 cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
3516         }
3517
3518         /* init with buildtime config */
3519         ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
3520         ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
3521         ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
3522         snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
3523         snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", cfg_paths.spool_dir);
3524         ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
3525         ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
3526         ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
3527         ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
3528         ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
3529         ast_copy_string(cfg_paths.sbin_dir, DEFAULT_SBIN_DIR, sizeof(cfg_paths.sbin_dir));
3530         ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
3531         ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
3532         ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
3533         ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
3534
3535         ast_set_default_eid(&ast_eid_default);
3536
3537         /* no asterisk.conf? no problem, use buildtime config! */
3538         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
3539                 return;
3540         }
3541
3542         for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
3543                 if (!strcasecmp(v->name, "astctlpermissions"))
3544                         ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
3545                 else if (!strcasecmp(v->name, "astctlowner"))
3546                         ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
3547                 else if (!strcasecmp(v->name, "astctlgroup"))
3548                         ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
3549                 else if (!strcasecmp(v->name, "astctl"))
3550                         ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
3551         }
3552
3553         for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
3554                 if (!strcasecmp(v->name, "astetcdir")) {
3555                         ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
3556                 } else if (!strcasecmp(v->name, "astspooldir")) {
3557                         ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
3558                         snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
3559                         snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", v->value);
3560                 } else if (!strcasecmp(v->name, "astvarlibdir")) {
3561                         ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
3562                         if (!found.dbdir)
3563                                 snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
3564                 } else if (!strcasecmp(v->name, "astdbdir")) {
3565                         snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
3566                         found.dbdir = 1;
3567                 } else if (!strcasecmp(v->name, "astdatadir")) {
3568                         ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
3569                         if (!found.keydir)
3570                                 snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
3571                 } else if (!strcasecmp(v->name, "astkeydir")) {
3572                         snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
3573                         found.keydir = 1;
3574                 } else if (!strcasecmp(v->name, "astlogdir")) {
3575                         ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
3576                 } else if (!strcasecmp(v->name, "astagidir")) {
3577                         ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
3578                 } else if (!strcasecmp(v->name, "astrundir")) {
3579                         snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
3580                         snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
3581                         ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
3582                 } else if (!strcasecmp(v->name, "astmoddir")) {
3583                         ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
3584                 } else if (!strcasecmp(v->name, "astsbindir")) {
3585                         ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir));
3586                 }
3587         }
3588
3589         for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
3590                 /* verbose level (-v at startup) */
3591                 if (!strcasecmp(v->name, "verbose")) {
3592                         option_verbose = atoi(v->value);
3593                 /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
3594                 } else if (!strcasecmp(v->name, "timestamp")) {
3595                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
3596                 /* whether or not to support #exec in config files */
3597                 } else if (!strcasecmp(v->name, "execincludes")) {
3598                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
3599                 /* debug level (-d at startup) */
3600                 } else if (!strcasecmp(v->name, "debug")) {
3601                         option_debug = 0;
3602                         if (sscanf(v->value, "%30d", &option_debug) != 1) {
3603                                 option_debug = ast_true(v->value);
3604                         }
3605 #if HAVE_WORKING_FORK
3606                 /* Disable forking (-f at startup) */
3607                 } else if (!strcasecmp(v->name, "nofork")) {
3608                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
3609                 /* Always fork, even if verbose or debug are enabled (-F at startup) */
3610                 } else if (!strcasecmp(v->name, "alwaysfork")) {
3611                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
3612 #endif
3613                 /* Run quietly (-q at startup ) */
3614                 } else if (!strcasecmp(v->name, "quiet")) {
3615                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
3616                 /* Run as console (-c at startup, implies nofork) */
3617                 } else if (!strcasecmp(v->name, "console")) {
3618                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
3619                 /* Run with high priority if the O/S permits (-p at startup) */
3620                 } else if (!strcasecmp(v->name, "highpriority")) {
3621                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
3622                 /* Initialize RSA auth keys (IAX2) (-i at startup) */
3623                 } else if (!strcasecmp(v->name, "initcrypto")) {
3624                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
3625                 /* Disable ANSI colors for console (-c at startup) */
3626                 } else if (!strcasecmp(v->name, "nocolor")) {
3627                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
3628                 /* Disable some usage warnings for picky people :p */
3629                 } else if (!strcasecmp(v->name, "dontwarn")) {
3630                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
3631                 /* Dump core in case of crash (-g) */
3632                 } else if (!strcasecmp(v->name, "dumpcore")) {
3633                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
3634                 /* Cache recorded sound files to another directory during recording */
3635                 } else if (!strcasecmp(v->name, "cache_record_files")) {
3636                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
3637                 /* Specify cache directory */
3638                 }  else if (!strcasecmp(v->name, "record_cache_dir")) {
3639                         ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
3640                 /* Build transcode paths via SLINEAR, instead of directly */
3641                 } else if (!strcasecmp(v->name, "transcode_via_sln")) {
3642                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
3643                 /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
3644                 } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
3645                         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
3646                 /* Enable internal timing */
3647                 } else if (!strcasecmp(v->name, "internal_timing")) {
3648                         if (!ast_opt_remote) {
3649                                 fprintf(stderr,
3650                                         "NOTICE: The internal_timing option is no longer needed.\n"
3651                                         "  It will always be enabled if you have a timing module loaded.\n");
3652                         }
3653                 } else if (!strcasecmp(v->name, "mindtmfduration")) {
3654                         if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
3655                                 option_dtmfminduration = AST_MIN_DTMF_DURATION;
3656                         }
3657                 } else if (!strcasecmp(v->name, "maxcalls")) {
3658                         if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
3659                                 ast_option_maxcalls = 0;
3660                         }
3661                 } else if (!strcasecmp(v->name, "maxload")) {
3662                         double test[1];
3663
3664                         if (getloadavg(test, 1) == -1) {
3665                                 ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
3666                                 ast_option_maxload = 0.0;
3667                         } else if ((sscanf(v->value, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
3668                     &nb