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