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