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