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