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