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