Merge "res_rtp_asterisk.c: Fix rtp source address learning for broken clients"
[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         sysinfo(&sys_info);
737         uptime = sys_info.uptime / 3600;
738         physmem = sys_info.totalram * sys_info.mem_unit;
739         freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
740         totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
741         freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
742         nprocs = sys_info.procs;
743 #elif defined(HAVE_SYSCTL)
744         static int pageshift;
745         struct vmtotal vmtotal;
746         struct timeval  boottime;
747         time_t  now;
748         int mib[2], pagesize, usedswap = 0;
749         size_t len;
750         /* calculate the uptime by looking at boottime */
751         time(&now);
752         mib[0] = CTL_KERN;
753         mib[1] = KERN_BOOTTIME;
754         len = sizeof(boottime);
755         if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
756                 uptime = now - boottime.tv_sec;
757         }
758         uptime = uptime/3600;
759         /* grab total physical memory  */
760         mib[0] = CTL_HW;
761 #if defined(HW_PHYSMEM64)
762         mib[1] = HW_PHYSMEM64;
763 #else
764         mib[1] = HW_PHYSMEM;
765 #endif
766         len = sizeof(physmem);
767         sysctl(mib, 2, &physmem, &len, NULL, 0);
768
769         pagesize = getpagesize();
770         pageshift = 0;
771         while (pagesize > 1) {
772                 pageshift++;
773                 pagesize >>= 1;
774         }
775
776         /* we only need the amount of log(2)1024 for our conversion */
777         pageshift -= 10;
778
779         /* grab vm totals */
780         mib[0] = CTL_VM;
781         mib[1] = VM_METER;
782         len = sizeof(vmtotal);
783         sysctl(mib, 2, &vmtotal, &len, NULL, 0);
784         freeram = (vmtotal.t_free << pageshift);
785         /* generate swap usage and totals */
786         swapmode(&usedswap, &totalswap);
787         freeswap = (totalswap - usedswap);
788         /* grab number of processes */
789 #if defined(__OpenBSD__)
790         mib[0] = CTL_KERN;
791         mib[1] = KERN_NPROCS;
792         len = sizeof(nprocs);
793         sysctl(mib, 2, &nprocs, &len, NULL, 0);
794 #endif
795 #endif
796
797         switch (cmd) {
798         case CLI_INIT:
799                 e->command = "core show sysinfo";
800                 e->usage =
801                         "Usage: core show sysinfo\n"
802                         "       List current system information.\n";
803                 return NULL;
804         case CLI_GENERATE:
805                 return NULL;
806         }
807
808         ast_cli(a->fd, "\nSystem Statistics\n");
809         ast_cli(a->fd, "-----------------\n");
810         ast_cli(a->fd, "  System Uptime:             %ld hours\n", uptime);
811         ast_cli(a->fd, "  Total RAM:                 %" PRIu64 " KiB\n", physmem / 1024);
812         ast_cli(a->fd, "  Free RAM:                  %" PRIu64 " KiB\n", freeram);
813 #if defined(HAVE_SYSINFO)
814         ast_cli(a->fd, "  Buffer RAM:                %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
815 #endif
816 #if defined(HAVE_SWAPCTL) || defined(HAVE_SYSINFO)
817         ast_cli(a->fd, "  Total Swap Space:          %d KiB\n", totalswap);
818         ast_cli(a->fd, "  Free Swap Space:           %" PRIu64 " KiB\n\n", freeswap);
819 #endif
820         ast_cli(a->fd, "  Number of Processes:       %d \n\n", nprocs);
821         return CLI_SUCCESS;
822 }
823 #endif
824
825 struct profile_entry {
826         const char *name;
827         uint64_t        scale;  /* if non-zero, values are scaled by this */
828         int64_t mark;
829         int64_t value;
830         int64_t events;
831 };
832
833 struct profile_data {
834         int entries;
835         int max_size;
836         struct profile_entry e[0];
837 };
838
839 static struct profile_data *prof_data;
840 #endif /* ! LOW_MEMORY */
841
842 /*! \brief allocates a counter with a given name and scale.
843  * \return Returns the identifier of the counter.
844  */
845 int ast_add_profile(const char *name, uint64_t scale)
846 {
847 #if !defined(LOW_MEMORY)
848         int l = sizeof(struct profile_data);
849         int n = 10;     /* default entries */
850
851         if (prof_data == NULL) {
852                 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
853                 if (prof_data == NULL)
854                         return -1;
855                 prof_data->entries = 0;
856                 prof_data->max_size = n;
857         }
858         if (prof_data->entries >= prof_data->max_size) {
859                 void *p;
860                 n = prof_data->max_size + 20;
861                 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
862                 if (p == NULL)
863                         return -1;
864                 prof_data = p;
865                 prof_data->max_size = n;
866         }
867         n = prof_data->entries++;
868         prof_data->e[n].name = ast_strdup(name);
869         prof_data->e[n].value = 0;
870         prof_data->e[n].events = 0;
871         prof_data->e[n].mark = 0;
872         prof_data->e[n].scale = scale;
873         return n;
874 #else /* if defined(LOW_MEMORY) */
875         return 0;
876 #endif
877 }
878
879 int64_t ast_profile(int i, int64_t delta)
880 {
881 #if !defined(LOW_MEMORY)
882         if (!prof_data || i < 0 || i > prof_data->entries)      /* invalid index */
883                 return 0;
884         if (prof_data->e[i].scale > 1)
885                 delta /= prof_data->e[i].scale;
886         prof_data->e[i].value += delta;
887         prof_data->e[i].events++;
888         return prof_data->e[i].value;
889 #else /* if defined(LOW_MEMORY) */
890         return 0;
891 #endif
892 }
893
894 #if !defined(LOW_MEMORY)
895 /* The RDTSC instruction was introduced on the Pentium processor and is not
896  * implemented on certain clones, like the Cyrix 586. Hence, the previous
897  * expectation of __i386__ was in error. */
898 #if defined ( __i686__) && (defined(__FreeBSD__) || defined(linux))
899 #if defined(__FreeBSD__)
900 #include <machine/cpufunc.h>
901 #elif defined(linux)
902 static __inline uint64_t
903 rdtsc(void)
904 {
905         uint64_t rv;
906
907         __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
908         return (rv);
909 }
910 #endif
911 #else   /* supply a dummy function on other platforms */
912 static __inline uint64_t
913 rdtsc(void)
914 {
915         return 0;
916 }
917 #endif
918 #endif /* ! LOW_MEMORY */
919
920 int64_t ast_mark(int i, int startstop)
921 {
922 #if !defined(LOW_MEMORY)
923         if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
924                 return 0;
925         if (startstop == 1)
926                 prof_data->e[i].mark = rdtsc();
927         else {
928                 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
929                 if (prof_data->e[i].scale > 1)
930                         prof_data->e[i].mark /= prof_data->e[i].scale;
931                 prof_data->e[i].value += prof_data->e[i].mark;
932                 prof_data->e[i].events++;
933         }
934         return prof_data->e[i].mark;
935 #else /* if defined(LOW_MEMORY) */
936         return 0;
937 #endif
938 }
939
940 #if !defined(LOW_MEMORY)
941 #define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
942         max = prof_data->entries;\
943         if  (a->argc > 3) { /* specific entries */ \
944                 if (isdigit(a->argv[3][0])) { \
945                         min = atoi(a->argv[3]); \
946                         if (a->argc == 5 && strcmp(a->argv[4], "-")) \
947                                 max = atoi(a->argv[4]); \
948                 } else \
949                         search = a->argv[3]; \
950         } \
951         if (max > prof_data->entries) \
952                 max = prof_data->entries;
953
954 static char *handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
955 {
956         int i, min, max;
957         const char *search = NULL;
958         switch (cmd) {
959         case CLI_INIT:
960                 e->command = "core show profile";
961                 e->usage = "Usage: core show profile\n"
962                            "       show profile information";
963                 return NULL;
964         case CLI_GENERATE:
965                 return NULL;
966         }
967
968         if (prof_data == NULL)
969                 return 0;
970
971         DEFINE_PROFILE_MIN_MAX_VALUES;
972         ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
973                 prof_data->entries, prof_data->max_size);
974         ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
975                         "Value", "Average", "Name");
976         for (i = min; i < max; i++) {
977                 struct profile_entry *entry = &prof_data->e[i];
978                 if (!search || strstr(entry->name, search))
979                     ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
980                         i,
981                         (long)entry->scale,
982                         (long)entry->events, (long long)entry->value,
983                         (long long)(entry->events ? entry->value / entry->events : entry->value),
984                         entry->name);
985         }
986         return CLI_SUCCESS;
987 }
988
989 static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
990 {
991         int i, min, max;
992         const char *search = NULL;
993         switch (cmd) {
994         case CLI_INIT:
995                 e->command = "core clear profile";
996                 e->usage = "Usage: core clear profile\n"
997                            "       clear profile information";
998                 return NULL;
999         case CLI_GENERATE:
1000                 return NULL;
1001         }
1002
1003         if (prof_data == NULL)
1004                 return 0;
1005
1006         DEFINE_PROFILE_MIN_MAX_VALUES;
1007         for (i= min; i < max; i++) {
1008                 if (!search || strstr(prof_data->e[i].name, search)) {
1009                         prof_data->e[i].value = 0;
1010                         prof_data->e[i].events = 0;
1011                 }
1012         }
1013         return CLI_SUCCESS;
1014 }
1015 #undef DEFINE_PROFILE_MIN_MAX_VALUES
1016
1017 #endif /* ! LOW_MEMORY */
1018
1019 int ast_pbx_uuid_get(char *pbx_uuid, int length)
1020 {
1021         return ast_db_get("pbx", "UUID", pbx_uuid, length);
1022 }
1023
1024 static void publish_fully_booted(void)
1025 {
1026         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1027         int uptime = 0;
1028         int lastreloaded = 0;
1029         struct timeval tmp;
1030         struct timeval curtime = ast_tvnow();
1031
1032         if (ast_startuptime.tv_sec) {
1033                 tmp = ast_tvsub(curtime, ast_startuptime);
1034                 uptime = (int) tmp.tv_sec;
1035         }
1036
1037         if (ast_lastreloadtime.tv_sec) {
1038                 tmp = ast_tvsub(curtime, ast_lastreloadtime);
1039                 lastreloaded = (int) tmp.tv_sec;
1040         }
1041
1042         json_object = ast_json_pack("{s: s, s: i, s: i}",
1043                         "Status", "Fully Booted",
1044                         "Uptime", uptime,
1045                         "LastReload", lastreloaded);
1046         ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
1047 }
1048
1049 static void ast_run_atexits(int run_cleanups)
1050 {
1051         struct ast_atexit *ae;
1052
1053         AST_LIST_LOCK(&atexits);
1054         while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
1055                 if (ae->func && (!ae->is_cleanup || run_cleanups)) {
1056                         ae->func();
1057                 }
1058                 ast_free(ae);
1059         }
1060         AST_LIST_UNLOCK(&atexits);
1061 }
1062
1063 static void __ast_unregister_atexit(void (*func)(void))
1064 {
1065         struct ast_atexit *ae;
1066
1067         AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
1068                 if (ae->func == func) {
1069                         AST_LIST_REMOVE_CURRENT(list);
1070                         ast_free(ae);
1071                         break;
1072                 }
1073         }
1074         AST_LIST_TRAVERSE_SAFE_END;
1075 }
1076
1077 static int register_atexit(void (*func)(void), int is_cleanup)
1078 {
1079         struct ast_atexit *ae;
1080
1081         ae = ast_calloc(1, sizeof(*ae));
1082         if (!ae) {
1083                 return -1;
1084         }
1085         ae->func = func;
1086         ae->is_cleanup = is_cleanup;
1087
1088         AST_LIST_LOCK(&atexits);
1089         __ast_unregister_atexit(func);
1090         AST_LIST_INSERT_HEAD(&atexits, ae, list);
1091         AST_LIST_UNLOCK(&atexits);
1092
1093         return 0;
1094 }
1095
1096 int ast_register_atexit(void (*func)(void))
1097 {
1098         return register_atexit(func, 0);
1099 }
1100
1101 int ast_register_cleanup(void (*func)(void))
1102 {
1103         return register_atexit(func, 1);
1104 }
1105
1106 void ast_unregister_atexit(void (*func)(void))
1107 {
1108         AST_LIST_LOCK(&atexits);
1109         __ast_unregister_atexit(func);
1110         AST_LIST_UNLOCK(&atexits);
1111 }
1112
1113 /* Sending commands from consoles back to the daemon requires a terminating NULL */
1114 static int fdsend(int fd, const char *s)
1115 {
1116         return write(fd, s, strlen(s) + 1);
1117 }
1118
1119 /* Sending messages from the daemon back to the display requires _excluding_ the terminating NULL */
1120 static int fdprint(int fd, const char *s)
1121 {
1122         return write(fd, s, strlen(s));
1123 }
1124
1125 /*! \brief NULL handler so we can collect the child exit status */
1126 static void _null_sig_handler(int sig)
1127 {
1128 }
1129
1130 static struct sigaction null_sig_handler = {
1131         .sa_handler = _null_sig_handler,
1132         .sa_flags = SA_RESTART,
1133 };
1134
1135 static struct sigaction ignore_sig_handler = {
1136         .sa_handler = SIG_IGN,
1137 };
1138
1139 AST_MUTEX_DEFINE_STATIC(safe_system_lock);
1140 /*! \brief Keep track of how many threads are currently trying to wait*() on
1141  *  a child process
1142  */
1143 static unsigned int safe_system_level = 0;
1144 static struct sigaction safe_system_prev_handler;
1145
1146 void ast_replace_sigchld(void)
1147 {
1148         unsigned int level;
1149
1150         ast_mutex_lock(&safe_system_lock);
1151         level = safe_system_level++;
1152
1153         /* only replace the handler if it has not already been done */
1154         if (level == 0) {
1155                 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1156         }
1157
1158         ast_mutex_unlock(&safe_system_lock);
1159 }
1160
1161 void ast_unreplace_sigchld(void)
1162 {
1163         unsigned int level;
1164
1165         ast_mutex_lock(&safe_system_lock);
1166         level = --safe_system_level;
1167
1168         /* only restore the handler if we are the last one */
1169         if (level == 0) {
1170                 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1171         }
1172
1173         ast_mutex_unlock(&safe_system_lock);
1174 }
1175
1176 /*! \brief fork and perform other preparations for spawning applications */
1177 static pid_t safe_exec_prep(int dualfork)
1178 {
1179         pid_t pid;
1180
1181 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1182         ast_replace_sigchld();
1183
1184 #ifdef HAVE_WORKING_FORK
1185         pid = fork();
1186 #else
1187         pid = vfork();
1188 #endif
1189
1190         if (pid == 0) {
1191 #ifdef HAVE_CAP
1192                 cap_t cap = cap_from_text("cap_net_admin-eip");
1193
1194                 if (cap_set_proc(cap)) {
1195                         /* Careful with order! Logging cannot happen after we close FDs */
1196                         ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
1197                 }
1198                 cap_free(cap);
1199 #endif
1200 #ifdef HAVE_WORKING_FORK
1201                 if (ast_opt_high_priority) {
1202                         ast_set_priority(0);
1203                 }
1204                 /* Close file descriptors and launch system command */
1205                 ast_close_fds_above_n(STDERR_FILENO);
1206 #endif
1207                 if (dualfork) {
1208 #ifdef HAVE_WORKING_FORK
1209                         pid = fork();
1210 #else
1211                         pid = vfork();
1212 #endif
1213                         if (pid < 0) {
1214                                 /* Second fork failed. */
1215                                 /* No logger available. */
1216                                 _exit(1);
1217                         }
1218
1219                         if (pid > 0) {
1220                                 /* This is the first fork, exit so the reaper finishes right away. */
1221                                 _exit(0);
1222                         }
1223
1224                         /* This is the second fork.  The first fork will exit immediately so
1225                          * Asterisk doesn't have to wait for completion.
1226                          * ast_safe_system("cmd &") would run in the background, but the '&'
1227                          * cannot be added with ast_safe_execvp, so we have to double fork.
1228                          */
1229                 }
1230         }
1231
1232         if (pid < 0) {
1233                 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
1234         }
1235 #else
1236         ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(ENOTSUP));
1237         pid = -1;
1238 #endif
1239
1240         return pid;
1241 }
1242
1243 /*! \brief wait for spawned application to complete and unreplace sigchld */
1244 static int safe_exec_wait(pid_t pid)
1245 {
1246         int res = -1;
1247
1248 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1249         if (pid > 0) {
1250                 for (;;) {
1251                         int status;
1252
1253                         res = waitpid(pid, &status, 0);
1254                         if (res > -1) {
1255                                 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1256                                 break;
1257                         }
1258                         if (errno != EINTR) {
1259                                 break;
1260                         }
1261                 }
1262         }
1263
1264         ast_unreplace_sigchld();
1265 #endif
1266
1267         return res;
1268 }
1269
1270 int ast_safe_execvp(int dualfork, const char *file, char *const argv[])
1271 {
1272         pid_t pid = safe_exec_prep(dualfork);
1273
1274         if (pid == 0) {
1275                 execvp(file, argv);
1276                 _exit(1);
1277                 /* noreturn from _exit */
1278         }
1279
1280         return safe_exec_wait(pid);
1281 }
1282
1283 int ast_safe_system(const char *s)
1284 {
1285         pid_t pid = safe_exec_prep(0);
1286
1287         if (pid == 0) {
1288                 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1289                 _exit(1);
1290                 /* noreturn from _exit */
1291         }
1292
1293         return safe_exec_wait(pid);
1294 }
1295
1296 /*!
1297  * \brief enable or disable a logging level to a specified console
1298  */
1299 void ast_console_toggle_loglevel(int fd, int level, int state)
1300 {
1301         int x;
1302
1303         if (level >= NUMLOGLEVELS) {
1304                 level = NUMLOGLEVELS - 1;
1305         }
1306
1307         for (x = 0;x < AST_MAX_CONNECTS; x++) {
1308                 if (fd == consoles[x].fd) {
1309                         /*
1310                          * Since the logging occurs when levels are false, set to
1311                          * flipped iinput because this function accepts 0 as off and 1 as on
1312                          */
1313                         consoles[x].levels[level] = state ? 0 : 1;
1314                         return;
1315                 }
1316         }
1317 }
1318
1319 /*!
1320  * \brief mute or unmute a console from logging
1321  */
1322 void ast_console_toggle_mute(int fd, int silent)
1323 {
1324         int x;
1325         for (x = 0;x < AST_MAX_CONNECTS; x++) {
1326                 if (fd == consoles[x].fd) {
1327                         if (consoles[x].mute) {
1328                                 consoles[x].mute = 0;
1329                                 if (!silent)
1330                                         ast_cli(fd, "Console is not muted anymore.\n");
1331                         } else {
1332                                 consoles[x].mute = 1;
1333                                 if (!silent)
1334                                         ast_cli(fd, "Console is muted.\n");
1335                         }
1336                         return;
1337                 }
1338         }
1339         ast_cli(fd, "Couldn't find remote console.\n");
1340 }
1341
1342 /*!
1343  * \brief log the string to all attached network console clients
1344  */
1345 static void ast_network_puts_mutable(const char *string, int level, int sublevel)
1346 {
1347         int x;
1348
1349         for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1350                 if (consoles[x].fd < 0
1351                         || consoles[x].mute
1352                         || consoles[x].levels[level]
1353                         || (level == __LOG_VERBOSE && consoles[x].option_verbose < sublevel)) {
1354                         continue;
1355                 }
1356                 fdprint(consoles[x].p[1], string);
1357         }
1358 }
1359
1360 /*!
1361  * \brief log the string to the root console, and all attached
1362  * network console clients
1363  */
1364 void ast_console_puts_mutable(const char *string, int level)
1365 {
1366         ast_console_puts_mutable_full(string, level, 0);
1367 }
1368
1369 static int console_print(const char *s);
1370
1371 void ast_console_puts_mutable_full(const char *message, int level, int sublevel)
1372 {
1373         /* Send to the root console */
1374         console_print(message);
1375
1376         /* Wake up a poll()ing console */
1377         if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
1378                 pthread_kill(consolethread, SIGURG);
1379         }
1380
1381         /* Send to any network console clients */
1382         ast_network_puts_mutable(message, level, sublevel);
1383 }
1384
1385 /*!
1386  * \brief write the string to all attached console clients
1387  */
1388 static void ast_network_puts(const char *string)
1389 {
1390         int x;
1391
1392         for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1393                 if (consoles[x].fd < 0) {
1394                         continue;
1395                 }
1396                 fdprint(consoles[x].p[1], string);
1397         }
1398 }
1399
1400 /*!
1401  * \brief write the string to the root console, and all attached
1402  * network console clients
1403  */
1404 void ast_console_puts(const char *string)
1405 {
1406         /* Send to the root console */
1407         fputs(string, stdout);
1408         fflush(stdout);
1409
1410         /* Send to any network console clients */
1411         ast_network_puts(string);
1412 }
1413
1414 static pthread_t lthread;
1415
1416 /*!
1417  * \brief read() function supporting the reception of user credentials.
1418  *
1419  * \param fd Socket file descriptor.
1420  * \param buffer Receive buffer.
1421  * \param size 'buffer' size.
1422  * \param con Console structure to set received credentials
1423  * \retval -1 on error
1424  * \retval the number of bytes received on success.
1425  */
1426 static int read_credentials(int fd, char *buffer, size_t size, struct console *con)
1427 {
1428 #if defined(SO_PEERCRED)
1429 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
1430 #define HAVE_STRUCT_UCRED_UID
1431         struct sockpeercred cred;
1432 #else
1433         struct ucred cred;
1434 #endif
1435         socklen_t len = sizeof(cred);
1436 #endif
1437 #if defined(HAVE_GETPEEREID)
1438         uid_t uid;
1439         gid_t gid;
1440 #else
1441         int uid, gid;
1442 #endif
1443         int result;
1444
1445         result = read(fd, buffer, size);
1446         if (result < 0) {
1447                 return result;
1448         }
1449
1450 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
1451         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
1452                 return result;
1453         }
1454 #if defined(HAVE_STRUCT_UCRED_UID)
1455         uid = cred.uid;
1456         gid = cred.gid;
1457 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
1458         uid = cred.cr_uid;
1459         gid = cred.cr_gid;
1460 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
1461
1462 #elif defined(HAVE_GETPEEREID)
1463         if (getpeereid(fd, &uid, &gid)) {
1464                 return result;
1465         }
1466 #else
1467         return result;
1468 #endif
1469         con->uid = uid;
1470         con->gid = gid;
1471
1472         return result;
1473 }
1474
1475 /* This is the thread running the remote console on the main process. */
1476 static void *netconsole(void *vconsole)
1477 {
1478         struct console *con = vconsole;
1479         char hostname[MAXHOSTNAMELEN] = "";
1480         char inbuf[512];
1481         char outbuf[512];
1482         const char * const end_buf = inbuf + sizeof(inbuf);
1483         char *start_read = inbuf;
1484         int res;
1485         struct pollfd fds[2];
1486
1487         if (gethostname(hostname, sizeof(hostname)-1))
1488                 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
1489         snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
1490         fdprint(con->fd, outbuf);
1491         ast_verb_console_register(&con->option_verbose);
1492         for (;;) {
1493                 fds[0].fd = con->fd;
1494                 fds[0].events = POLLIN;
1495                 fds[0].revents = 0;
1496                 fds[1].fd = con->p[0];
1497                 fds[1].events = POLLIN;
1498                 fds[1].revents = 0;
1499
1500                 res = ast_poll(fds, 2, -1);
1501                 if (res < 0) {
1502                         if (errno != EINTR)
1503                                 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
1504                         continue;
1505                 }
1506                 if (fds[0].revents) {
1507                         int cmds_read, bytes_read;
1508                         if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
1509                                 break;
1510                         }
1511                         /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
1512                         if (strncmp(inbuf, "cli quit after ", 15) == 0) {
1513                                 ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
1514                                 break;
1515                         }
1516                         /* ast_cli_command_multiple_full will only process individual commands terminated by a
1517                          * NULL and not trailing partial commands. */
1518                         if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
1519                                 /* No commands were read. We either have a short read on the first command
1520                                  * with space left, or a command that is too long */
1521                                 if (start_read + bytes_read < end_buf) {
1522                                         start_read += bytes_read;
1523                                 } else {
1524                                         ast_log(LOG_ERROR, "Command too long! Skipping\n");
1525                                         start_read = inbuf;
1526                                 }
1527                                 continue;
1528                         }
1529                         if (start_read[bytes_read - 1] == '\0') {
1530                                 /* The read ended on a command boundary, start reading again at the head of inbuf */
1531                                 start_read = inbuf;
1532                                 continue;
1533                         }
1534                         /* If we get this far, we have left over characters that have not been processed.
1535                          * Advance to the character after the last command read by ast_cli_command_multiple_full.
1536                          * We are guaranteed to have at least cmds_read NULLs */
1537                         while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
1538                                 start_read++;
1539                         }
1540                         memmove(inbuf, start_read, end_buf - start_read);
1541                         start_read = end_buf - start_read + inbuf;
1542                 }
1543                 if (fds[1].revents) {
1544                         res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
1545                         if (res < 1) {
1546                                 ast_log(LOG_ERROR, "read returned %d\n", res);
1547                                 break;
1548                         }
1549                         res = write(con->fd, outbuf, res);
1550                         if (res < 1)
1551                                 break;
1552                 }
1553         }
1554         ast_verb_console_unregister();
1555         if (!ast_opt_hide_connect) {
1556                 ast_verb(3, "Remote UNIX connection disconnected\n");
1557         }
1558         close(con->fd);
1559         close(con->p[0]);
1560         close(con->p[1]);
1561         con->fd = -1;
1562
1563         return NULL;
1564 }
1565
1566 static void *listener(void *unused)
1567 {
1568         struct sockaddr_un sunaddr;
1569         int s;
1570         socklen_t len;
1571         int x;
1572         int flags;
1573         struct pollfd fds[1];
1574         for (;;) {
1575                 if (ast_socket < 0)
1576                         return NULL;
1577                 fds[0].fd = ast_socket;
1578                 fds[0].events = POLLIN;
1579                 s = ast_poll(fds, 1, -1);
1580                 pthread_testcancel();
1581                 if (s < 0) {
1582                         if (errno != EINTR)
1583                                 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
1584                         continue;
1585                 }
1586                 len = sizeof(sunaddr);
1587                 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
1588                 if (s < 0) {
1589                         if (errno != EINTR)
1590                                 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
1591                 } else {
1592 #if defined(SO_PASSCRED)
1593                         int sckopt = 1;
1594                         /* turn on socket credentials passing. */
1595                         if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
1596                                 ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
1597                         } else
1598 #endif
1599                         {
1600                                 for (x = 0; x < AST_MAX_CONNECTS; x++) {
1601                                         if (consoles[x].fd >= 0) {
1602                                                 continue;
1603                                         }
1604                                         if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
1605                                                 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
1606                                                 fdprint(s, "Server failed to create pipe\n");
1607                                                 close(s);
1608                                                 break;
1609                                         }
1610                                         flags = fcntl(consoles[x].p[1], F_GETFL);
1611                                         fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
1612                                         consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
1613                                         /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
1614                                            to know if the user didn't send the credentials. */
1615                                         consoles[x].uid = -2;
1616                                         consoles[x].gid = -2;
1617                                         /* Server default of remote console verbosity level is OFF. */
1618                                         consoles[x].option_verbose = 0;
1619                                         consoles[x].fd = s;
1620                                         if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
1621                                                 consoles[x].fd = -1;
1622                                                 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
1623                                                 close(consoles[x].p[0]);
1624                                                 close(consoles[x].p[1]);
1625                                                 fdprint(s, "Server failed to spawn thread\n");
1626                                                 close(s);
1627                                         }
1628                                         break;
1629                                 }
1630                                 if (x >= AST_MAX_CONNECTS) {
1631                                         fdprint(s, "No more connections allowed\n");
1632                                         ast_log(LOG_WARNING, "No more connections allowed\n");
1633                                         close(s);
1634                                 } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
1635                                         ast_verb(3, "Remote UNIX connection\n");
1636                                 }
1637                         }
1638                 }
1639         }
1640         return NULL;
1641 }
1642
1643 static int ast_makesocket(void)
1644 {
1645         struct sockaddr_un sunaddr;
1646         int res;
1647         int x;
1648         uid_t uid = -1;
1649         gid_t gid = -1;
1650
1651         for (x = 0; x < AST_MAX_CONNECTS; x++) {
1652                 consoles[x].fd = -1;
1653         }
1654
1655         if (ast_socket_is_sd) {
1656                 ast_socket = ast_sd_get_fd_un(SOCK_STREAM, ast_config_AST_SOCKET);
1657
1658                 goto start_lthread;
1659         }
1660
1661         unlink(ast_config_AST_SOCKET);
1662         ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
1663         if (ast_socket < 0) {
1664                 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
1665                 return -1;
1666         }
1667         memset(&sunaddr, 0, sizeof(sunaddr));
1668         sunaddr.sun_family = AF_LOCAL;
1669         ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1670         res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1671         if (res) {
1672                 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1673                 close(ast_socket);
1674                 ast_socket = -1;
1675                 return -1;
1676         }
1677         res = listen(ast_socket, 2);
1678         if (res < 0) {
1679                 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1680                 close(ast_socket);
1681                 ast_socket = -1;
1682                 return -1;
1683         }
1684
1685 start_lthread:
1686         if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
1687                 ast_log(LOG_WARNING, "Unable to create listener thread.\n");
1688                 close(ast_socket);
1689                 return -1;
1690         }
1691
1692         if (ast_socket_is_sd) {
1693                 /* owner/group/permissions are set by systemd, we might not even have access
1694                  * to socket file so leave it alone */
1695                 return 0;
1696         }
1697
1698         if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
1699                 struct passwd *pw;
1700                 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
1701                         ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
1702                 else
1703                         uid = pw->pw_uid;
1704         }
1705
1706         if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
1707                 struct group *grp;
1708                 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
1709                         ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
1710                 else
1711                         gid = grp->gr_gid;
1712         }
1713
1714         if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
1715                 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1716
1717         if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
1718                 unsigned int p1;
1719                 mode_t p;
1720                 sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
1721                 p = p1;
1722                 if ((chmod(ast_config_AST_SOCKET, p)) < 0)
1723                         ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1724         }
1725
1726         return 0;
1727 }
1728
1729 static int ast_tryconnect(void)
1730 {
1731         struct sockaddr_un sunaddr;
1732         int res;
1733         ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
1734         if (ast_consock < 0) {
1735                 fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
1736                 return 0;
1737         }
1738         memset(&sunaddr, 0, sizeof(sunaddr));
1739         sunaddr.sun_family = AF_LOCAL;
1740         ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1741         res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1742         if (res) {
1743                 close(ast_consock);
1744                 ast_consock = -1;
1745                 return 0;
1746         } else
1747                 return 1;
1748 }
1749
1750 /*! \brief Urgent handler
1751  *
1752  * Called by soft_hangup to interrupt the poll, read, or other
1753  * system call.  We don't actually need to do anything though.
1754  * Remember: Cannot EVER ast_log from within a signal handler
1755  */
1756 static void _urg_handler(int num)
1757 {
1758         return;
1759 }
1760
1761 static struct sigaction urg_handler = {
1762         .sa_handler = _urg_handler,
1763 };
1764
1765 static void _hup_handler(int num)
1766 {
1767         int save_errno = errno;
1768         printf("Received HUP signal -- Reloading configs\n");
1769         if (restartnow)
1770                 execvp(_argv[0], _argv);
1771         sig_flags.need_reload = 1;
1772         if (ast_alertpipe_write(sig_alert_pipe)) {
1773                 fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
1774         }
1775         errno = save_errno;
1776 }
1777
1778 static struct sigaction hup_handler = {
1779         .sa_handler = _hup_handler,
1780         .sa_flags = SA_RESTART,
1781 };
1782
1783 static void _child_handler(int sig)
1784 {
1785         /* Must not ever ast_log or ast_verbose within signal handler */
1786         int n, status, save_errno = errno;
1787
1788         /*
1789          * Reap all dead children -- not just one
1790          */
1791         for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
1792                 ;
1793         if (n == 0 && option_debug)
1794                 printf("Huh?  Child handler, but nobody there?\n");
1795         errno = save_errno;
1796 }
1797
1798 static struct sigaction child_handler = {
1799         .sa_handler = _child_handler,
1800         .sa_flags = SA_RESTART,
1801 };
1802
1803 /*! \brief Set maximum open files */
1804 static void set_ulimit(int value)
1805 {
1806         struct rlimit l = {0, 0};
1807
1808         if (value <= 0) {
1809                 ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
1810                 return;
1811         }
1812
1813         l.rlim_cur = value;
1814         l.rlim_max = value;
1815
1816         if (setrlimit(RLIMIT_NOFILE, &l)) {
1817                 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
1818                 return;
1819         }
1820
1821         ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
1822
1823         return;
1824 }
1825
1826 /*! \brief Set an X-term or screen title */
1827 static void set_title(char *text)
1828 {
1829         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1830                 fprintf(stdout, "\033]2;%s\007", text);
1831 }
1832
1833 static void set_icon(char *text)
1834 {
1835         if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
1836                 fprintf(stdout, "\033]1;%s\007", text);
1837 }
1838
1839 /*! \brief Check whether we were set to high(er) priority. */
1840 static int has_priority(void)
1841 {
1842         /* Neither of these calls should fail with these arguments. */
1843 #ifdef __linux__
1844         /* For SCHED_OTHER, SCHED_BATCH and SCHED_IDLE, this will return
1845          * 0. For the realtime priorities SCHED_RR and SCHED_FIFO, it
1846          * will return something >= 1. */
1847         return sched_getscheduler(0);
1848 #else
1849         /* getpriority() can return a value in -20..19 (or even -INF..20)
1850          * where negative numbers are high priority. We don't bother
1851          * checking errno. If the query fails and it returns -1, we'll
1852          * assume that we're running at high prio; a safe assumption
1853          * that will enable the resource starvation monitor (canary)
1854          * just in case. */
1855         return (getpriority(PRIO_PROCESS, 0) < 0);
1856 #endif
1857 }
1858
1859 /*! \brief Set priority on all known threads. */
1860 static int set_priority_all(int pri)
1861 {
1862 #if !defined(__linux__)
1863         /* The non-linux version updates the entire process prio. */
1864         return ast_set_priority(pri);
1865 #elif defined(LOW_MEMORY)
1866         ast_log(LOG_WARNING, "Unable to enumerate all threads to update priority\n");
1867         return ast_set_priority(pri);
1868 #else
1869         struct thread_list_t *cur;
1870         struct sched_param sched;
1871         char const *policy_str;
1872         int policy;
1873
1874         memset(&sched, 0, sizeof(sched));
1875         if (pri) {
1876                 policy = SCHED_RR;
1877                 policy_str = "realtime";
1878                 sched.sched_priority = 10;
1879         } else {
1880                 policy = SCHED_OTHER;
1881                 policy_str = "regular";
1882                 sched.sched_priority = 0;
1883         }
1884         if (sched_setscheduler(getpid(), policy, &sched)) {
1885                 ast_log(LOG_WARNING, "Unable to set %s thread priority on main thread\n", policy_str);
1886                 return -1;
1887         }
1888         ast_verb(1, "Setting %s thread priority on all threads\n", policy_str);
1889         AST_RWLIST_RDLOCK(&thread_list);
1890         AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
1891                 /* Don't care about the return value. It should work. */
1892                 sched_setscheduler(cur->lwp, policy, &sched);
1893         }
1894         AST_RWLIST_UNLOCK(&thread_list);
1895         return 0;
1896 #endif
1897 }
1898
1899 /*! \brief We set ourselves to a high priority, that we might pre-empt
1900  * everything else.  If your PBX has heavy activity on it, this is a
1901  * good thing.
1902  */
1903 int ast_set_priority(int pri)
1904 {
1905         struct sched_param sched;
1906         memset(&sched, 0, sizeof(sched));
1907 #ifdef __linux__
1908         if (pri) {
1909                 sched.sched_priority = 10;
1910                 if (sched_setscheduler(0, SCHED_RR, &sched)) {
1911                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1912                         return -1;
1913                 } else
1914                         ast_verb(1, "Set to realtime thread\n");
1915         } else {
1916                 sched.sched_priority = 0;
1917                 /* According to the manpage, these parameters can never fail. */
1918                 sched_setscheduler(0, SCHED_OTHER, &sched);
1919         }
1920 #else
1921         if (pri) {
1922                 if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
1923                         ast_log(LOG_WARNING, "Unable to set high priority\n");
1924                         return -1;
1925                 } else
1926                         ast_verb(1, "Set to high priority\n");
1927         } else {
1928                 /* According to the manpage, these parameters can never fail. */
1929                 setpriority(PRIO_PROCESS, 0, 0);
1930         }
1931 #endif
1932         return 0;
1933 }
1934
1935 int ast_shutdown_final(void)
1936 {
1937         return shuttingdown == SHUTTING_DOWN_FINAL;
1938 }
1939
1940 int ast_shutting_down(void)
1941 {
1942         return shutdown_pending;
1943 }
1944
1945 int ast_cancel_shutdown(void)
1946 {
1947         int shutdown_aborted = 0;
1948
1949         ast_mutex_lock(&safe_system_lock);
1950         if (shuttingdown >= SHUTDOWN_FAST) {
1951                 shuttingdown = NOT_SHUTTING_DOWN;
1952                 shutdown_pending = 0;
1953                 shutdown_aborted = 1;
1954         }
1955         ast_mutex_unlock(&safe_system_lock);
1956         return shutdown_aborted;
1957 }
1958
1959 /*!
1960  * \internal
1961  * \brief Initiate system shutdown -- prevents new channels from being allocated.
1962  */
1963 static void ast_begin_shutdown(void)
1964 {
1965         ast_mutex_lock(&safe_system_lock);
1966         if (shuttingdown != NOT_SHUTTING_DOWN) {
1967                 shutdown_pending = 1;
1968         }
1969         ast_mutex_unlock(&safe_system_lock);
1970 }
1971
1972 static int can_safely_quit(shutdown_nice_t niceness, int restart);
1973 static void really_quit(int num, shutdown_nice_t niceness, int restart);
1974
1975 static void quit_handler(int num, shutdown_nice_t niceness, int restart)
1976 {
1977         if (can_safely_quit(niceness, restart)) {
1978                 really_quit(num, niceness, restart);
1979                 /* No one gets here. */
1980         }
1981         /* It wasn't our time. */
1982 }
1983
1984 #define SHUTDOWN_TIMEOUT        15      /* Seconds */
1985
1986 /*!
1987  * \internal
1988  * \brief Wait for all channels to die, a timeout, or shutdown cancelled.
1989  * \since 13.3.0
1990  *
1991  * \param niceness Shutdown niceness in effect
1992  * \param seconds Number of seconds to wait or less than zero if indefinitely.
1993  *
1994  * \retval zero if waiting wasn't necessary.  We were idle.
1995  * \retval non-zero if we had to wait.
1996  */
1997 static int wait_for_channels_to_die(shutdown_nice_t niceness, int seconds)
1998 {
1999         time_t start;
2000         time_t now;
2001         int waited = 0;
2002
2003         time(&start);
2004         for (;;) {
2005                 if (!ast_undestroyed_channels() || shuttingdown != niceness) {
2006                         break;
2007                 }
2008                 if (seconds < 0) {
2009                         /* No timeout so just poll every second */
2010                         sleep(1);
2011                 } else {
2012                         time(&now);
2013
2014                         /* Wait up to the given seconds for all channels to go away */
2015                         if (seconds < (now - start)) {
2016                                 break;
2017                         }
2018
2019                         /* Sleep 1/10 of a second */
2020                         usleep(100000);
2021                 }
2022                 waited = 1;
2023         }
2024         return waited;
2025 }
2026
2027 static int can_safely_quit(shutdown_nice_t niceness, int restart)
2028 {
2029         int waited = 0;
2030
2031         /* Check if someone else isn't already doing this. */
2032         ast_mutex_lock(&safe_system_lock);
2033         if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
2034                 /* Already in progress and other request was less nice. */
2035                 ast_mutex_unlock(&safe_system_lock);
2036                 ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
2037                 return 0;
2038         }
2039         shuttingdown = niceness;
2040         ast_mutex_unlock(&safe_system_lock);
2041
2042         /* Try to get as many CDRs as possible submitted to the backend engines
2043          * (if in batch mode). really_quit happens to call it again when running
2044          * the atexit handlers, otherwise this would be a bit early. */
2045         ast_cdr_engine_term();
2046
2047         /*
2048          * Shutdown the message queue for the technology agnostic message channel.
2049          * This has to occur before we pause shutdown pending ast_undestroyed_channels.
2050          *
2051          * XXX This is not reversed on shutdown cancel.
2052          */
2053         ast_msg_shutdown();
2054
2055         if (niceness == SHUTDOWN_NORMAL) {
2056                 /* Begin shutdown routine, hanging up active channels */
2057                 ast_begin_shutdown();
2058                 if (ast_opt_console) {
2059                         ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
2060                 }
2061                 ast_softhangup_all();
2062                 waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
2063         } else if (niceness >= SHUTDOWN_NICE) {
2064                 if (niceness != SHUTDOWN_REALLY_NICE) {
2065                         ast_begin_shutdown();
2066                 }
2067                 if (ast_opt_console) {
2068                         ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
2069                 }
2070                 waited |= wait_for_channels_to_die(niceness, -1);
2071         }
2072
2073         /* Re-acquire lock and check if someone changed the niceness, in which
2074          * case someone else has taken over the shutdown.
2075          */
2076         ast_mutex_lock(&safe_system_lock);
2077         if (shuttingdown != niceness) {
2078                 if (shuttingdown == NOT_SHUTTING_DOWN && ast_opt_console) {
2079                         ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
2080                 }
2081                 ast_mutex_unlock(&safe_system_lock);
2082                 return 0;
2083         }
2084
2085         if (niceness >= SHUTDOWN_REALLY_NICE) {
2086                 shuttingdown = SHUTTING_DOWN;
2087                 ast_mutex_unlock(&safe_system_lock);
2088
2089                 /* No more Mr. Nice guy.  We are committed to shutting down now. */
2090                 ast_begin_shutdown();
2091                 ast_softhangup_all();
2092                 waited |= wait_for_channels_to_die(SHUTTING_DOWN, SHUTDOWN_TIMEOUT);
2093
2094                 ast_mutex_lock(&safe_system_lock);
2095         }
2096         shuttingdown = SHUTTING_DOWN_FINAL;
2097         ast_mutex_unlock(&safe_system_lock);
2098
2099         if (niceness >= SHUTDOWN_NORMAL && waited) {
2100                 /*
2101                  * We were not idle.  Give things in progress a chance to
2102                  * recognize the final shutdown phase.
2103                  */
2104                 sleep(1);
2105         }
2106         return 1;
2107 }
2108
2109 /*! Called when exiting is certain. */
2110 static void really_quit(int num, shutdown_nice_t niceness, int restart)
2111 {
2112         int active_channels;
2113         struct ast_json *json_object = NULL;
2114         int run_cleanups = niceness >= SHUTDOWN_NICE;
2115
2116         if (run_cleanups && modules_shutdown()) {
2117                 ast_verb(0, "Some modules could not be unloaded, switching to fast shutdown\n");
2118                 run_cleanups = 0;
2119         }
2120
2121         if (!restart) {
2122                 ast_sd_notify("STOPPING=1");
2123         }
2124         if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
2125                 ast_el_write_default_histfile();
2126                 if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
2127                         /* Only end if we are the consolethread, otherwise there's a race with that thread. */
2128                         if (el != NULL) {
2129                                 el_end(el);
2130                         }
2131                         if (el_hist != NULL) {
2132                                 history_end(el_hist);
2133                         }
2134                 } else if (mon_sig_flags == pthread_self()) {
2135                         if (consolethread != AST_PTHREADT_NULL) {
2136                                 pthread_kill(consolethread, SIGURG);
2137                         }
2138                 }
2139         }
2140         active_channels = ast_active_channels();
2141         /* Don't publish messages if we're a remote console - we won't have all of the Stasis
2142          * topics or message types
2143          */
2144         if (!ast_opt_remote) {
2145                 json_object = ast_json_pack("{s: s, s: s}",
2146                                 "Shutdown", active_channels ? "Uncleanly" : "Cleanly",
2147                                 "Restart", restart ? "True" : "False");
2148                 ast_manager_publish_event("Shutdown", EVENT_FLAG_SYSTEM, json_object);
2149                 ast_json_unref(json_object);
2150                 json_object = NULL;
2151         }
2152         ast_verb(0, "Asterisk %s ending (%d).\n",
2153                 active_channels ? "uncleanly" : "cleanly", num);
2154
2155         ast_verb(0, "Executing last minute cleanups\n");
2156         ast_run_atexits(run_cleanups);
2157
2158         ast_debug(1, "Asterisk ending (%d).\n", num);
2159         if (ast_socket > -1) {
2160                 pthread_cancel(lthread);
2161                 close(ast_socket);
2162                 ast_socket = -1;
2163                 if (!ast_socket_is_sd) {
2164                         unlink(ast_config_AST_SOCKET);
2165                 }
2166                 pthread_kill(lthread, SIGURG);
2167                 pthread_join(lthread, NULL);
2168         }
2169         if (ast_consock > -1)
2170                 close(ast_consock);
2171         if (!ast_opt_remote)
2172                 unlink(ast_config_AST_PID);
2173         ast_alertpipe_close(sig_alert_pipe);
2174         printf("%s", term_quit());
2175         if (restart) {
2176                 int i;
2177                 ast_verb(0, "Preparing for Asterisk restart...\n");
2178                 /* Mark all FD's for closing on exec */
2179                 for (i = 3; i < 32768; i++) {
2180                         fcntl(i, F_SETFD, FD_CLOEXEC);
2181                 }
2182                 ast_verb(0, "Asterisk is now restarting...\n");
2183                 restartnow = 1;
2184
2185                 /* close logger */
2186                 close_logger();
2187                 clean_time_zones();
2188
2189                 /* If there is a consolethread running send it a SIGHUP
2190                    so it can execvp, otherwise we can do it ourselves */
2191                 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
2192                         pthread_kill(consolethread, SIGHUP);
2193                         /* Give the signal handler some time to complete */
2194                         sleep(2);
2195                 } else
2196                         execvp(_argv[0], _argv);
2197
2198         } else {
2199                 /* close logger */
2200                 close_logger();
2201                 clean_time_zones();
2202         }
2203
2204         exit(0);
2205 }
2206
2207 static void __quit_handler(int num)
2208 {
2209         sig_flags.need_quit = 1;
2210         if (ast_alertpipe_write(sig_alert_pipe)) {
2211                 fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
2212         }
2213         /* There is no need to restore the signal handler here, since the app
2214          * is going to exit */
2215 }
2216
2217 static void __remote_quit_handler(int num)
2218 {
2219         sig_flags.need_quit = 1;
2220 }
2221
2222 static void set_header(char *outbuf, int maxout, char level)
2223 {
2224         const char *cmp;
2225         char date[40];
2226
2227         switch (level) {
2228         case 0: cmp = NULL;
2229                 break;
2230         case 1: cmp = VERBOSE_PREFIX_1;
2231                 break;
2232         case 2: cmp = VERBOSE_PREFIX_2;
2233                 break;
2234         case 3: cmp = VERBOSE_PREFIX_3;
2235                 break;
2236         default: cmp = VERBOSE_PREFIX_4;
2237                 break;
2238         }
2239
2240         if (ast_opt_timestamp) {
2241                 struct ast_tm tm;
2242                 struct timeval now = ast_tvnow();
2243                 ast_localtime(&now, &tm, NULL);
2244                 ast_strftime(date, sizeof(date), ast_logger_get_dateformat(), &tm);
2245         }
2246
2247         snprintf(outbuf, maxout, "%s%s%s%s%s%s",
2248                 ast_opt_timestamp ? "[" : "",
2249                 ast_opt_timestamp ? date : "",
2250                 ast_opt_timestamp ? "] " : "",
2251                 cmp ? ast_term_color(COLOR_GRAY, 0) : "",
2252                 cmp ? cmp : "",
2253                 cmp ? ast_term_reset() : "");
2254 }
2255
2256 struct console_state_data {
2257         char verbose_line_level;
2258 };
2259
2260 static int console_state_init(void *ptr)
2261 {
2262         struct console_state_data *state = ptr;
2263         state->verbose_line_level = 0;
2264         return 0;
2265 }
2266
2267 AST_THREADSTORAGE_CUSTOM(console_state, console_state_init, ast_free_ptr);
2268
2269 static int console_print(const char *s)
2270 {
2271         struct console_state_data *state =
2272                 ast_threadstorage_get(&console_state, sizeof(*state));
2273
2274         char prefix[80];
2275         const char *c;
2276         int num, res = 0;
2277         unsigned int newline;
2278
2279         do {
2280                 if (VERBOSE_HASMAGIC(s)) {
2281
2282                         /* always use the given line's level, otherwise
2283                            we'll use the last line's level */
2284                         state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
2285
2286                         /* move past magic */
2287                         s++;
2288
2289                         set_header(prefix, sizeof(prefix), state->verbose_line_level);
2290                 } else {
2291                         *prefix = '\0';
2292                 }
2293                 c = s;
2294
2295                 /* for a given line separate on verbose magic, newline, and eol */
2296                 if ((s = strchr(c, '\n'))) {
2297                         ++s;
2298                         newline = 1;
2299                 } else {
2300                         s = strchr(c, '\0');
2301                         newline = 0;
2302                 }
2303
2304                 /* check if we should write this line after calculating begin/end
2305                    so we process the case of a higher level line embedded within
2306                    two lower level lines */
2307                 if (state->verbose_line_level > option_verbose) {
2308                         continue;
2309                 }
2310
2311                 if (!ast_strlen_zero(prefix)) {
2312                         fputs(prefix, stdout);
2313                 }
2314
2315                 num = s - c;
2316                 if (fwrite(c, sizeof(char), num, stdout) < num) {
2317                         break;
2318                 }
2319
2320                 if (!res) {
2321                         /* if at least some info has been written
2322                            we'll want to return true */
2323                         res = 1;
2324                 }
2325         } while (*s);
2326
2327         if (newline) {
2328                 /* if ending on a newline then reset last level to zero
2329                     since what follows may be not be logging output */
2330                 state->verbose_line_level = 0;
2331         }
2332
2333         if (res) {
2334                 fflush(stdout);
2335         }
2336
2337         return res;
2338 }
2339
2340 static int ast_all_zeros(const char *s)
2341 {
2342         while (*s) {
2343                 if (*s > 32)
2344                         return 0;
2345                 s++;
2346         }
2347         return 1;
2348 }
2349
2350 /* This is the main console CLI command handler.  Run by the main() thread. */
2351 static void consolehandler(const char *s)
2352 {
2353         printf("%s", term_end());
2354         fflush(stdout);
2355
2356         /* Called when readline data is available */
2357         if (!ast_all_zeros(s))
2358                 ast_el_add_history(s);
2359         /* The real handler for bang */
2360         if (s[0] == '!') {
2361                 if (s[1])
2362                         ast_safe_system(s+1);
2363                 else
2364                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2365         } else
2366                 ast_cli_command(STDOUT_FILENO, s);
2367 }
2368
2369 static int remoteconsolehandler(const char *s)
2370 {
2371         int ret = 0;
2372
2373         /* Called when readline data is available */
2374         if (!ast_all_zeros(s))
2375                 ast_el_add_history(s);
2376
2377         while (isspace(*s)) {
2378                 s++;
2379         }
2380
2381         /* The real handler for bang */
2382         if (s[0] == '!') {
2383                 if (s[1])
2384                         ast_safe_system(s+1);
2385                 else
2386                         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2387                 ret = 1;
2388         } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
2389             (s[4] == '\0' || isspace(s[4]))) {
2390                 quit_handler(0, SHUTDOWN_FAST, 0);
2391                 ret = 1;
2392         } else if (s[0]) {
2393                 char *shrunk = ast_strdupa(s);
2394                 char *cur;
2395                 char *prev;
2396
2397                 /*
2398                  * Remove duplicate spaces from shrunk for matching purposes.
2399                  *
2400                  * shrunk has at least one character in it to start with or we
2401                  * couldn't get here.
2402                  */
2403                 for (prev = shrunk, cur = shrunk + 1; *cur; ++cur) {
2404                         if (*prev == ' ' && *cur == ' ') {
2405                                 /* Skip repeated space delimiter. */
2406                                 continue;
2407                         }
2408                         *++prev = *cur;
2409                 }
2410                 *++prev = '\0';
2411
2412                 if (strncasecmp(shrunk, "core set verbose ", 17) == 0) {
2413                         /*
2414                          * We need to still set the rasterisk option_verbose in case we are
2415                          * talking to an earlier version which doesn't prefilter verbose
2416                          * levels.  This is really a compromise as we should always take
2417                          * whatever the server sends.
2418                          */
2419
2420                         if (!strncasecmp(shrunk + 17, "off", 3)) {
2421                                 ast_verb_console_set(0);
2422                         } else {
2423                                 int verbose_new;
2424                                 int atleast;
2425
2426                                 atleast = 8;
2427                                 if (strncasecmp(shrunk + 17, "atleast ", atleast)) {
2428                                         atleast = 0;
2429                                 }
2430
2431                                 if (sscanf(shrunk + 17 + atleast, "%30d", &verbose_new) == 1) {
2432                                         if (!atleast || ast_verb_console_get() < verbose_new) {
2433                                                 ast_verb_console_set(verbose_new);
2434                                         }
2435                                 }
2436                         }
2437                 }
2438         }
2439
2440         return ret;
2441 }
2442
2443 static char *handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2444 {
2445         switch (cmd) {
2446         case CLI_INIT:
2447                 e->command = "core show version";
2448                 e->usage =
2449                         "Usage: core show version\n"
2450                         "       Shows Asterisk version information.\n";
2451                 return NULL;
2452         case CLI_GENERATE:
2453                 return NULL;
2454         }
2455
2456         if (a->argc != 3)
2457                 return CLI_SHOWUSAGE;
2458         ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
2459                 ast_get_version(), ast_build_user, ast_build_hostname,
2460                 ast_build_machine, ast_build_os, ast_build_date);
2461         return CLI_SUCCESS;
2462 }
2463
2464 static char *handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2465 {
2466         switch (cmd) {
2467         case CLI_INIT:
2468                 e->command = "core stop now";
2469                 e->usage =
2470                         "Usage: core stop now\n"
2471                         "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
2472                 ast_cli_allow_at_shutdown(e);
2473                 return NULL;
2474         case CLI_GENERATE:
2475                 return NULL;
2476         }
2477
2478         if (a->argc != e->args)
2479                 return CLI_SHOWUSAGE;
2480         quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
2481         return CLI_SUCCESS;
2482 }
2483
2484 static char *handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2485 {
2486         switch (cmd) {
2487         case CLI_INIT:
2488                 e->command = "core stop gracefully";
2489                 e->usage =
2490                         "Usage: core stop gracefully\n"
2491                         "       Causes Asterisk to not accept new calls, and exit when all\n"
2492                         "       active calls have terminated normally.\n";
2493                 ast_cli_allow_at_shutdown(e);
2494                 return NULL;
2495         case CLI_GENERATE:
2496                 return NULL;
2497         }
2498
2499         if (a->argc != e->args)
2500                 return CLI_SHOWUSAGE;
2501         quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
2502         return CLI_SUCCESS;
2503 }
2504
2505 static char *handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2506 {
2507         switch (cmd) {
2508         case CLI_INIT:
2509                 e->command = "core stop when convenient";
2510                 e->usage =
2511                         "Usage: core stop when convenient\n"
2512                         "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
2513                 ast_cli_allow_at_shutdown(e);
2514                 return NULL;
2515         case CLI_GENERATE:
2516                 return NULL;
2517         }
2518
2519         if (a->argc != e->args)
2520                 return CLI_SHOWUSAGE;
2521         ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
2522         quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
2523         return CLI_SUCCESS;
2524 }
2525
2526 static char *handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2527 {
2528         switch (cmd) {
2529         case CLI_INIT:
2530                 e->command = "core restart now";
2531                 e->usage =
2532                         "Usage: core restart now\n"
2533                         "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
2534                         "       restart.\n";
2535                 ast_cli_allow_at_shutdown(e);
2536                 return NULL;
2537         case CLI_GENERATE:
2538                 return NULL;
2539         }
2540
2541         if (a->argc != e->args)
2542                 return CLI_SHOWUSAGE;
2543         quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
2544         return CLI_SUCCESS;
2545 }
2546
2547 static char *handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2548 {
2549         switch (cmd) {
2550         case CLI_INIT:
2551                 e->command = "core restart gracefully";
2552                 e->usage =
2553                         "Usage: core restart gracefully\n"
2554                         "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
2555                         "       restart when all active calls have ended.\n";
2556                 ast_cli_allow_at_shutdown(e);
2557                 return NULL;
2558         case CLI_GENERATE:
2559                 return NULL;
2560         }
2561
2562         if (a->argc != e->args)
2563                 return CLI_SHOWUSAGE;
2564         quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
2565         return CLI_SUCCESS;
2566 }
2567
2568 static char *handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2569 {
2570         switch (cmd) {
2571         case CLI_INIT:
2572                 e->command = "core restart when convenient";
2573                 e->usage =
2574                         "Usage: core restart when convenient\n"
2575                         "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
2576                 ast_cli_allow_at_shutdown(e);
2577                 return NULL;
2578         case CLI_GENERATE:
2579                 return NULL;
2580         }
2581
2582         if (a->argc != e->args)
2583                 return CLI_SHOWUSAGE;
2584         ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
2585         quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
2586         return CLI_SUCCESS;
2587 }
2588
2589 static char *handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2590 {
2591         switch (cmd) {
2592         case CLI_INIT:
2593                 e->command = "core abort shutdown";
2594                 e->usage =
2595                         "Usage: core abort shutdown\n"
2596                         "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2597                         "       call operations.\n";
2598                 ast_cli_allow_at_shutdown(e);
2599                 return NULL;
2600         case CLI_GENERATE:
2601                 return NULL;
2602         }
2603
2604         if (a->argc != e->args)
2605                 return CLI_SHOWUSAGE;
2606
2607         ast_cancel_shutdown();
2608
2609         return CLI_SUCCESS;
2610 }
2611
2612 static char *handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2613 {
2614         switch (cmd) {
2615         case CLI_INIT:
2616                 e->command = "!";
2617                 e->usage =
2618                         "Usage: !<command>\n"
2619                         "       Executes a given shell command\n";
2620                 return NULL;
2621         case CLI_GENERATE:
2622                 return NULL;
2623         }
2624
2625         return CLI_SUCCESS;
2626 }
2627 static const char warranty_lines[] = {
2628         "\n"
2629         "                           NO WARRANTY\n"
2630         "\n"
2631         "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
2632         "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n"
2633         "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
2634         "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
2635         "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
2636         "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n"
2637         "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n"
2638         "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
2639         "REPAIR OR CORRECTION.\n"
2640         "\n"
2641         "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
2642         "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
2643         "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
2644         "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
2645         "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
2646         "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
2647         "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
2648         "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
2649         "POSSIBILITY OF SUCH DAMAGES.\n"
2650 };
2651
2652 static char *show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2653 {
2654         switch (cmd) {
2655         case CLI_INIT:
2656                 e->command = "core show warranty";
2657                 e->usage =
2658                         "Usage: core show warranty\n"
2659                         "       Shows the warranty (if any) for this copy of Asterisk.\n";
2660                 return NULL;
2661         case CLI_GENERATE:
2662                 return NULL;
2663         }
2664
2665         ast_cli(a->fd, "%s", warranty_lines);
2666
2667         return CLI_SUCCESS;
2668 }
2669
2670 static const char license_lines[] = {
2671         "\n"
2672         "This program is free software; you can redistribute it and/or modify\n"
2673         "it under the terms of the GNU General Public License version 2 as\n"
2674         "published by the Free Software Foundation.\n"
2675         "\n"
2676         "This program also contains components licensed under other licenses.\n"
2677         "They include:\n"
2678         "\n"
2679         "This program is distributed in the hope that it will be useful,\n"
2680         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2681         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
2682         "GNU General Public License for more details.\n"
2683         "\n"
2684         "You should have received a copy of the GNU General Public License\n"
2685         "along with this program; if not, write to the Free Software\n"
2686         "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
2687 };
2688
2689 static char *show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2690 {
2691         switch (cmd) {
2692         case CLI_INIT:
2693                 e->command = "core show license";
2694                 e->usage =
2695                         "Usage: core show license\n"
2696                         "       Shows the license(s) for this copy of Asterisk.\n";
2697                 return NULL;
2698         case CLI_GENERATE:
2699                 return NULL;
2700         }
2701
2702         ast_cli(a->fd, "%s", license_lines);
2703
2704         return CLI_SUCCESS;
2705 }
2706
2707 #define ASTERISK_PROMPT "*CLI> "
2708
2709 /*!
2710  * \brief Shutdown Asterisk CLI commands.
2711  *
2712  * \note These CLI commands cannot be unregistered at shutdown
2713  * because one of them is likely the reason for the shutdown.
2714  * The CLI generates a warning if a command is in-use when it is
2715  * unregistered.
2716  */
2717 static struct ast_cli_entry cli_asterisk_shutdown[] = {
2718         AST_CLI_DEFINE(handle_stop_now, "Shut down Asterisk immediately"),
2719         AST_CLI_DEFINE(handle_stop_gracefully, "Gracefully shut down Asterisk"),
2720         AST_CLI_DEFINE(handle_stop_when_convenient, "Shut down Asterisk at empty call volume"),
2721         AST_CLI_DEFINE(handle_restart_now, "Restart Asterisk immediately"),
2722         AST_CLI_DEFINE(handle_restart_gracefully, "Restart Asterisk gracefully"),
2723         AST_CLI_DEFINE(handle_restart_when_convenient, "Restart Asterisk at empty call volume"),
2724 };
2725
2726 static struct ast_cli_entry cli_asterisk[] = {
2727         AST_CLI_DEFINE(handle_abort_shutdown, "Cancel a running shutdown"),
2728         AST_CLI_DEFINE(show_warranty, "Show the warranty (if any) for this copy of Asterisk"),
2729         AST_CLI_DEFINE(show_license, "Show the license(s) for this copy of Asterisk"),
2730         AST_CLI_DEFINE(handle_version, "Display version info"),
2731         AST_CLI_DEFINE(handle_bang, "Execute a shell command"),
2732 #if !defined(LOW_MEMORY)
2733         AST_CLI_DEFINE(handle_show_threads, "Show running threads"),
2734 #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
2735         AST_CLI_DEFINE(handle_show_sysinfo, "Show System Information"),
2736 #endif
2737         AST_CLI_DEFINE(handle_show_profile, "Display profiling info"),
2738         AST_CLI_DEFINE(handle_show_settings, "Show some core settings"),
2739         AST_CLI_DEFINE(handle_clear_profile, "Clear profiling info"),
2740 #endif /* ! LOW_MEMORY */
2741 };
2742
2743 static void send_rasterisk_connect_commands(void)
2744 {
2745         char buf[80];
2746
2747         /*
2748          * Tell the server asterisk instance about the verbose level
2749          * initially desired.
2750          */
2751         if (option_verbose) {
2752                 snprintf(buf, sizeof(buf), "core set verbose atleast %d silent", option_verbose);
2753                 fdsend(ast_consock, buf);
2754         }
2755
2756         if (option_debug) {
2757                 snprintf(buf, sizeof(buf), "core set debug atleast %d", option_debug);
2758                 fdsend(ast_consock, buf);
2759         }
2760
2761         if (!ast_opt_mute) {
2762                 fdsend(ast_consock, "logger mute silent");
2763         } else {
2764                 printf("log and verbose output currently muted ('logger mute' to unmute)\n");
2765         }
2766 }
2767
2768 #ifdef HAVE_LIBEDIT_IS_UNICODE
2769 static int ast_el_read_char(EditLine *editline, wchar_t *cp)
2770 #else
2771 static int ast_el_read_char(EditLine *editline, char *cp)
2772 #endif
2773 {
2774         int num_read = 0;
2775         int lastpos = 0;
2776         struct pollfd fds[2];
2777         int res;
2778         int max;
2779 #define EL_BUF_SIZE 512
2780         char buf[EL_BUF_SIZE];
2781
2782         for (;;) {
2783                 max = 1;
2784                 fds[0].fd = ast_consock;
2785                 fds[0].events = POLLIN;
2786                 if (!ast_opt_exec) {
2787                         fds[1].fd = STDIN_FILENO;
2788                         fds[1].events = POLLIN;
2789                         max++;
2790                 }
2791                 res = ast_poll(fds, max, -1);
2792                 if (res < 0) {
2793                         if (sig_flags.need_quit || sig_flags.need_quit_handler)
2794                                 break;
2795                         if (errno == EINTR)
2796                                 continue;
2797                         fprintf(stderr, "poll failed: %s\n", strerror(errno));
2798                         break;
2799                 }
2800
2801                 if (!ast_opt_exec && fds[1].revents) {
2802                         char c = '\0';
2803                         num_read = read(STDIN_FILENO, &c, 1);
2804                         if (num_read < 1) {
2805                                 break;
2806                         } else {
2807 #ifdef  HAVE_LIBEDIT_IS_UNICODE
2808                                 *cp = btowc(c);
2809 #else
2810                                 *cp = c;
2811 #endif
2812                                 return (num_read);
2813                         }
2814                 }
2815                 if (fds[0].revents) {
2816                         res = read(ast_consock, buf, sizeof(buf) - 1);
2817                         /* if the remote side disappears exit */
2818                         if (res < 1) {
2819                                 fprintf(stderr, "\nDisconnected from Asterisk server\n");
2820                                 if (!ast_opt_reconnect) {
2821                                         quit_handler(0, SHUTDOWN_FAST, 0);
2822                                 } else {
2823                                         int tries;
2824                                         int reconnects_per_second = 20;
2825                                         fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
2826                                         for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
2827                                                 if (ast_tryconnect()) {
2828                                                         fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
2829                                                         printf("%s", term_quit());
2830                                                         WELCOME_MESSAGE;
2831                                                         send_rasterisk_connect_commands();
2832                                                         break;
2833                                                 } else
2834                                                         usleep(1000000 / reconnects_per_second);
2835                                         }
2836                                         if (tries >= 30 * reconnects_per_second) {
2837                                                 fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
2838                                                 quit_handler(0, SHUTDOWN_FAST, 0);
2839                                         }
2840                                 }
2841                                 continue;
2842                         }
2843
2844                         buf[res] = '\0';
2845
2846                         /* Write over the CLI prompt */
2847                         if (!ast_opt_exec && !lastpos) {
2848                                 if (write(STDOUT_FILENO, "\r\e[0K", 5) < 0) {
2849                                 }
2850                         }
2851
2852                         console_print(buf);
2853
2854                         if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (res >= 2 && buf[res-2] == '\n'))) {
2855 #ifdef  HAVE_LIBEDIT_IS_UNICODE
2856                                 *cp = btowc(CC_REFRESH);
2857 #else
2858                                 *cp = CC_REFRESH;
2859 #endif
2860                                 return(1);
2861                         } else {
2862                                 lastpos = 1;
2863                         }
2864                 }
2865         }
2866
2867 #ifdef  HAVE_LIBEDIT_IS_UNICODE
2868         *cp = btowc('\0');
2869 #else
2870         *cp = '\0';
2871 #endif
2872
2873         return (0);
2874 }
2875
2876 static struct ast_str *prompt = NULL;
2877
2878 static char *cli_prompt(EditLine *editline)
2879 {
2880         char tmp[100];
2881         char *pfmt;
2882         int color_used = 0;
2883         static int cli_prompt_changes = 0;
2884         struct passwd *pw;
2885         struct group *gr;
2886
2887         if (prompt == NULL) {
2888                 prompt = ast_str_create(100);
2889         } else if (!cli_prompt_changes) {
2890                 return ast_str_buffer(prompt);
2891         } else {
2892                 ast_str_reset(prompt);
2893         }
2894
2895         if ((pfmt = getenv("ASTERISK_PROMPT"))) {
2896                 char *t = pfmt;
2897                 struct timeval ts = ast_tvnow();
2898                 while (*t != '\0') {
2899                         if (*t == '%') {
2900                                 char hostname[MAXHOSTNAMELEN] = "";
2901                                 int i, which;
2902                                 struct ast_tm tm = { 0, };
2903                                 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
2904
2905                                 t++;
2906                                 switch (*t) {
2907                                 case 'C': /* color */
2908                                         t++;
2909                                         if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
2910                                                 ast_term_color_code(&prompt, fgcolor, bgcolor);
2911                                                 t += i - 1;
2912                                         } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
2913                                                 ast_term_color_code(&prompt, fgcolor, 0);
2914                                                 t += i - 1;
2915                                         }
2916
2917                                         /* If the color has been reset correctly, then there's no need to reset it later */
2918                                         color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
2919                                         break;
2920                                 case 'd': /* date */
2921                                         if (ast_localtime(&ts, &tm, NULL)) {
2922                                                 ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
2923                                                 ast_str_append(&prompt, 0, "%s", tmp);
2924                                                 cli_prompt_changes++;
2925                                         }
2926                                         break;
2927                                 case 'g': /* group */
2928                                         if ((gr = getgrgid(getgid()))) {
2929                                                 ast_str_append(&prompt, 0, "%s", gr->gr_name);
2930                                         }
2931                                         break;
2932                                 case 'h': /* hostname */
2933                                         if (!gethostname(hostname, sizeof(hostname) - 1)) {
2934                                                 ast_str_append(&prompt, 0, "%s", hostname);
2935                                         } else {
2936                                                 ast_str_append(&prompt, 0, "%s", "localhost");
2937                                         }
2938                                         break;
2939                                 case 'H': /* short hostname */
2940                                         if (!gethostname(hostname, sizeof(hostname) - 1)) {
2941                                                 char *dotptr;
2942                                                 if ((dotptr = strchr(hostname, '.'))) {
2943                                                         *dotptr = '\0';
2944                                                 }
2945                                                 ast_str_append(&prompt, 0, "%s", hostname);
2946                                         } else {
2947                                                 ast_str_append(&prompt, 0, "%s", "localhost");
2948                                         }
2949                                         break;
2950 #ifdef HAVE_GETLOADAVG
2951                                 case 'l': /* load avg */
2952                                         t++;
2953                                         if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
2954                                                 double list[3];
2955                                                 getloadavg(list, 3);
2956                                                 ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
2957                                                 cli_prompt_changes++;
2958                                         }
2959                                         break;
2960 #endif
2961                                 case 's': /* Asterisk system name (from asterisk.conf) */
2962                                         ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
2963                                         break;
2964                                 case 't': /* time */
2965                                         if (ast_localtime(&ts, &tm, NULL)) {
2966                                                 ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
2967                                                 ast_str_append(&prompt, 0, "%s", tmp);
2968                                                 cli_prompt_changes++;
2969                                         }
2970                                         break;
2971                                 case 'u': /* username */
2972                                         if ((pw = getpwuid(getuid()))) {
2973                                                 ast_str_append(&prompt, 0, "%s", pw->pw_name);
2974                                         }
2975                                         break;
2976                                 case '#': /* process console or remote? */
2977                                         ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
2978                                         break;
2979                                 case '%': /* literal % */
2980                                         ast_str_append(&prompt, 0, "%c", '%');
2981                                         break;
2982                                 case '\0': /* % is last character - prevent bug */
2983                                         t--;
2984                                         break;
2985                                 }
2986                         } else {
2987                                 ast_str_append(&prompt, 0, "%c", *t);
2988                         }
2989                         t++;
2990                 }
2991                 if (color_used) {
2992                         /* Force colors back to normal at end */
2993                         ast_term_color_code(&prompt, 0, 0);
2994                 }
2995         } else {
2996                 ast_str_set(&prompt, 0, "%s%s",
2997                         remotehostname ? remotehostname : "",
2998                         ASTERISK_PROMPT);
2999         }
3000
3001         return ast_str_buffer(prompt);
3002 }
3003
3004 static struct ast_vector_string *ast_el_strtoarr(char *buf)
3005 {
3006         char *retstr;
3007         struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
3008
3009         if (!vec) {
3010                 return NULL;
3011         }
3012
3013         while ((retstr = strsep(&buf, " "))) {
3014                 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
3015                         break;
3016                 }
3017
3018                 /* Older daemons sent duplicates. */
3019                 if (AST_VECTOR_GET_CMP(vec, retstr, strcasecmp)) {
3020                         continue;
3021                 }
3022
3023                 retstr = ast_strdup(retstr);
3024                 /* Older daemons sent unsorted. */
3025                 if (!retstr || AST_VECTOR_ADD_SORTED(vec, retstr, strcasecmp)) {
3026                         ast_free(retstr);
3027                         goto vector_cleanup;
3028                 }
3029         }
3030
3031         if (!AST_VECTOR_SIZE(vec)) {
3032                 goto vector_cleanup;
3033         }
3034
3035         return vec;
3036
3037 vector_cleanup:
3038         AST_VECTOR_CALLBACK_VOID(vec, ast_free);
3039         AST_VECTOR_PTR_FREE(vec);
3040
3041         return NULL;
3042 }
3043
3044 static void ast_cli_display_match_list(struct ast_vector_string *matches, int max)
3045 {
3046         int idx = 1;
3047         /* find out how many entries can be put on one line, with two spaces between strings */
3048         int limit = ast_get_termcols(STDOUT_FILENO) / (max + 2);
3049
3050         if (limit == 0) {
3051                 limit = 1;
3052         }
3053
3054         for (;;) {
3055                 int numoutputline;
3056
3057                 for (numoutputline = 0; numoutputline < limit && idx < AST_VECTOR_SIZE(matches); idx++) {
3058                         numoutputline++;
3059                         fprintf(stdout, "%-*s  ", max, AST_VECTOR_GET(matches, idx));
3060                 }
3061
3062                 if (!numoutputline) {
3063                         break;
3064                 }
3065
3066                 fprintf(stdout, "\n");
3067         }
3068 }
3069
3070
3071 static char *cli_complete(EditLine *editline, int ch)
3072 {
3073         int len = 0;
3074         char *ptr;
3075         struct ast_vector_string *matches;
3076         int retval = CC_ERROR;
3077         char savechr;
3078         int res;
3079
3080         LineInfo *lf = (LineInfo *)el_line(editline);
3081
3082         savechr = *(char *)lf->cursor;
3083         *(char *)lf->cursor = '\0';
3084         ptr = (char *)lf->cursor;
3085         if (ptr) {
3086                 while (ptr > lf->buffer) {
3087                         if (isspace(*ptr)) {
3088                                 ptr++;
3089                                 break;
3090                         }
3091                         ptr--;
3092                 }
3093         }
3094
3095         len = lf->cursor - ptr;
3096
3097         if (ast_opt_remote) {
3098 #define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\""
3099                 char *mbuf;
3100                 char *new_mbuf;
3101                 int mlen = 0, maxmbuf = 2048;
3102
3103                 /* Start with a 2048 byte buffer */
3104                 mbuf = ast_malloc(maxmbuf);
3105
3106                 /* This will run snprintf twice at most. */
3107                 while (mbuf && (mlen = snprintf(mbuf, maxmbuf, CMD_MATCHESARRAY, lf->buffer, ptr)) > maxmbuf) {
3108                         /* Return value does not include space for NULL terminator. */
3109                         maxmbuf = mlen + 1;
3110                         ast_free(mbuf);
3111                         mbuf = ast_malloc(maxmbuf);
3112                 }
3113
3114                 if (!mbuf) {
3115                         *((char *) lf->cursor) = savechr;
3116
3117                         return (char *)(CC_ERROR);
3118                 }
3119
3120                 fdsend(ast_consock, mbuf);
3121                 res = 0;
3122                 mlen = 0;
3123                 mbuf[0] = '\0';
3124
3125                 while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
3126                         if (mlen + 1024 > maxmbuf) {
3127                                 /* Expand buffer to the next 1024 byte increment. */
3128                                 maxmbuf = mlen + 1024;
3129                                 new_mbuf = ast_realloc(mbuf, maxmbuf);
3130                                 if (!new_mbuf) {
3131                                         ast_free(mbuf);
3132                                         *((char *) lf->cursor) = savechr;
3133
3134                                         return (char *)(CC_ERROR);
3135                                 }
3136                                 mbuf = new_mbuf;
3137                         }
3138                         /* Only read 1024 bytes at a time */
3139                         res = read(ast_consock, mbuf + mlen, 1024);
3140                         if (res > 0) {
3141                                 mlen += res;
3142                         }
3143                 }
3144                 mbuf[mlen] = '\0';
3145
3146                 matches = ast_el_strtoarr(mbuf);
3147                 ast_free(mbuf);
3148         } else {
3149                 matches = ast_cli_completion_vector((char *)lf->buffer, ptr);
3150         }
3151
3152         if (matches) {
3153                 int i;
3154                 int maxlen, match_len;
3155                 const char *best_match = AST_VECTOR_GET(matches, 0);
3156
3157                 if (!ast_strlen_zero(best_match)) {
3158                         el_deletestr(editline, (int) len);
3159                         el_insertstr(editline, best_match);
3160                         retval = CC_REFRESH;
3161                 }
3162
3163                 if (AST_VECTOR_SIZE(matches) == 2) {
3164                         /* Found an exact match */
3165                         el_insertstr(editline, " ");
3166                         retval = CC_REFRESH;
3167                 } else {
3168                         /* Must be more than one match */
3169                         for (i = 1, maxlen = 0; i < AST_VECTOR_SIZE(matches); i++) {
3170                                 match_len = strlen(AST_VECTOR_GET(matches, i));
3171                                 if (match_len > maxlen) {
3172                                         maxlen = match_len;
3173                                 }
3174                         }
3175
3176                         fprintf(stdout, "\n");
3177                         ast_cli_display_match_list(matches, maxlen);
3178                         retval = CC_REDISPLAY;
3179                 }
3180                 AST_VECTOR_CALLBACK_VOID(matches, ast_free);
3181                 AST_VECTOR_PTR_FREE(matches);
3182         }
3183
3184         *((char *) lf->cursor) = savechr;
3185
3186         return (char *)(long)retval;
3187 }
3188
3189 static int ast_el_initialize(void)
3190 {
3191         HistEvent ev;
3192         char *editor, *editrc = getenv("EDITRC");
3193
3194         if (!(editor = getenv("AST_EDITMODE"))) {
3195                 if (!(editor = getenv("AST_EDITOR"))) {
3196                         editor = "emacs";
3197                 }
3198         }
3199
3200         if (el != NULL)
3201                 el_end(el);
3202         if (el_hist != NULL)
3203                 history_end(el_hist);
3204
3205         el = el_init("asterisk", stdin, stdout, stderr);
3206         el_set(el, EL_PROMPT, cli_prompt);
3207
3208         el_set(el, EL_EDITMODE, 1);
3209         el_set(el, EL_EDITOR, editor);
3210         el_hist = history_init();
3211         if (!el || !el_hist)
3212                 return -1;
3213
3214         /* setup history with 100 entries */
3215         history(el_hist, &ev, H_SETSIZE, 100);
3216
3217         el_set(el, EL_HIST, history, el_hist);
3218
3219         el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
3220         /* Bind <tab> to command completion */
3221         el_set(el, EL_BIND, "^I", "ed-complete", NULL);
3222         /* Bind ? to command completion */
3223         el_set(el, EL_BIND, "?", "ed-complete", NULL);
3224         /* Bind ^D to redisplay */
3225         el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
3226         /* Bind Delete to delete char left */
3227         el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
3228         /* Bind Home and End to move to line start and end */
3229         el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
3230         el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
3231         /* Bind C-left and C-right to move by word (not all terminals) */
3232         el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
3233         el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
3234
3235         if (editrc) {