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