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