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