70 #include "asterisk/_private.h"
72 #undef sched_setscheduler
81 #include <sys/resource.h>
85 #if defined(HAVE_SYSINFO)
86 #include <sys/sysinfo.h>
87 #elif defined(HAVE_SYSCTL)
88 #include <sys/param.h>
89 #include <sys/sysctl.h>
90 #if !defined(__OpenBSD__)
91 #include <sys/vmmeter.h>
92 #if defined(__FreeBSD__)
93 #include <vm/vm_param.h>
96 #if defined(HAVE_SWAPCTL)
103 int daemon(
int,
int);
104 #include <sys/loadavg.h>
108 #include <sys/prctl.h>
110 #include <sys/capability.h>
137 #include "editline/histedit.h"
151 #include "../defaults.h"
154 #define AF_LOCAL AF_UNIX
155 #define PF_LOCAL PF_UNIX
158 #define AST_MAX_CONNECTS 128
162 #define WELCOME_MESSAGE \
163 ast_verbose("Asterisk %s, Copyright (C) 1999 - 2013 Digium, Inc. and others.\n" \
164 "Created by Mark Spencer <markster@digium.com>\n" \
165 "Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.\n" \
166 "This is free software, with components licensed under the GNU General Public\n" \
167 "License version 2 and other licenses; you are welcome to redistribute it under\n" \
168 "certain conditions. Type 'core show license' for details.\n" \
169 "=========================================================================\n", ast_get_version()) \
186 #if defined(HAVE_SYSINFO)
234 char config_dir[PATH_MAX];
235 char module_dir[PATH_MAX];
236 char spool_dir[PATH_MAX];
237 char monitor_dir[PATH_MAX];
238 char var_dir[PATH_MAX];
239 char data_dir[PATH_MAX];
240 char log_dir[PATH_MAX];
241 char agi_dir[PATH_MAX];
242 char run_dir[PATH_MAX];
243 char key_dir[PATH_MAX];
246 char db_path[PATH_MAX];
247 char pid_path[PATH_MAX];
248 char socket_path[PATH_MAX];
249 char run_user[PATH_MAX];
250 char run_group[PATH_MAX];
251 char system_name[128];
309 #if !defined(LOW_MEMORY)
322 size_t version_length;
326 version_length = strlen(work) + 1;
328 if (!(
new =
ast_calloc(1,
sizeof(*
new) + version_length)))
332 new->version = (
char *)
new +
sizeof(*
new);
333 memcpy(new->version, work, version_length);
345 if (!strcasecmp(find->file, file)) {
360 size_t len = strlen(partial);
366 if (!strncasecmp(find->file, partial, len) && ++count > n) {
382 if (!strcasecmp(iterator->file, file))
387 return iterator->version;
409 new->id = pthread_self();
422 if ((
void *) x->id ==
id) {
444 e->
command =
"core show settings";
445 e->
usage =
"Usage: core show settings\n"
446 " Show core misc settings";
461 ast_cli(a->
fd,
" Maximum calls: Not set\n");
463 ast_cli(a->
fd,
" Maximum open file handles: %d\n", option_maxfiles);
465 ast_cli(a->
fd,
" Maximum open file handles: Not set\n");
466 ast_cli(a->
fd,
" Verbosity: %d\n", option_verbose);
467 ast_cli(a->
fd,
" Debug level: %d\n", option_debug);
468 ast_cli(a->
fd,
" Maximum load average: %lf\n", option_maxload);
469 #if defined(HAVE_SYSINFO)
470 ast_cli(a->
fd,
" Minimum free memory: %ld MB\n", option_minmemfree);
474 ast_cli(a->
fd,
" Startup time: %s\n", buf);
478 ast_cli(a->
fd,
" Last reload time: %s\n", buf);
482 ast_cli(a->
fd,
" Entity ID: %s\n", eid_str);
491 if (!getrlimit(RLIMIT_NOFILE, &rlim))
492 ast_cli(a->
fd,
" Current file desc. limits: current: %i max: %i\n", rlim.rlim_cur, rlim.rlim_max);
527 e->
command =
"core show threads";
529 "Usage: core show threads\n"
530 " List threads currently active in the system.\n";
538 ast_cli(a->
fd,
"%p %s\n", (
void *)cur->id, cur->name);
542 ast_cli(a->
fd,
"%d threads listed.\n", count);
546 #if defined (HAVE_SYSCTL) && defined(HAVE_SWAPCTL)
551 static int swapmode(
int *used,
int *
total)
553 struct swapent *swdev;
554 int nswap, rnswap, i;
556 nswap = swapctl(SWAP_NSWAP, 0, 0);
564 rnswap = swapctl(SWAP_STATS, swdev, nswap);
574 for (i = 0; i < nswap; i++) {
575 if (swdev[i].se_flags & SWF_ENABLE) {
576 *used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
577 *total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
583 #elif defined(HAVE_SYSCTL) && !defined(HAVE_SYSINFO)
584 static int swapmode(
int *used,
int *total)
591 #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
595 uint64_t physmem, freeram;
596 uint64_t freeswap = 0;
600 #if defined(HAVE_SYSINFO)
601 struct sysinfo sys_info;
603 uptime = sys_info.uptime / 3600;
604 physmem = sys_info.totalram * sys_info.mem_unit;
605 freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
606 totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
607 freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
608 nprocs = sys_info.procs;
609 #elif defined(HAVE_SYSCTL)
610 static int pageshift;
611 struct vmtotal vmtotal;
612 struct timeval boottime;
614 int mib[2], pagesize, usedswap = 0;
619 mib[1] = KERN_BOOTTIME;
620 len =
sizeof(boottime);
621 if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
622 uptime = now - boottime.tv_sec;
624 uptime = uptime/3600;
627 #if defined(HW_PHYSMEM64)
628 mib[1] = HW_PHYSMEM64;
632 len =
sizeof(physmem);
633 sysctl(mib, 2, &physmem, &len, NULL, 0);
635 pagesize = getpagesize();
637 while (pagesize > 1) {
648 len =
sizeof(vmtotal);
649 sysctl(mib, 2, &vmtotal, &len, NULL, 0);
650 freeram = (vmtotal.t_free << pageshift);
652 swapmode(&usedswap, &totalswap);
653 freeswap = (totalswap - usedswap);
655 #if defined(__OpenBSD__)
657 mib[1] = KERN_NPROCS;
658 len =
sizeof(nprocs);
659 sysctl(mib, 2, &nprocs, &len, NULL, 0);
665 e->
command =
"core show sysinfo";
667 "Usage: core show sysinfo\n"
668 " List current system information.\n";
676 ast_cli(a->
fd,
" System Uptime: %ld hours\n", uptime);
677 ast_cli(a->
fd,
" Total RAM: %" PRIu64
" KiB\n", physmem / 1024);
678 ast_cli(a->
fd,
" Free RAM: %" PRIu64
" KiB\n", freeram);
679 #if defined(HAVE_SYSINFO)
680 ast_cli(a->
fd,
" Buffer RAM: %" PRIu64
" KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
682 #if defined (HAVE_SYSCTL) || defined(HAVE_SWAPCTL)
683 ast_cli(a->
fd,
" Total Swap Space: %d KiB\n", totalswap);
684 ast_cli(a->
fd,
" Free Swap Space: %" PRIu64
" KiB\n\n", freeswap);
686 ast_cli(a->
fd,
" Number of Processes: %d \n\n", nprocs);
754 #if defined ( __i686__) && (defined(__FreeBSD__) || defined(linux))
755 #if defined(__FreeBSD__)
756 #include <machine/cpufunc.h>
758 static __inline uint64_t
763 __asm __volatile(
".byte 0x0f, 0x31" :
"=A" (rv));
768 static __inline uint64_t
791 #define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
792 max = prof_data->entries;\
794 if (isdigit(a->argv[3][0])) { \
795 min = atoi(a->argv[3]); \
796 if (a->argc == 5 && strcmp(a->argv[4], "-")) \
797 max = atoi(a->argv[4]); \
799 search = a->argv[3]; \
801 if (max > prof_data->entries) \
802 max = prof_data->entries;
807 const char *search = NULL;
810 e->
command =
"core show profile";
811 e->
usage =
"Usage: core show profile\n"
812 " show profile information";
822 ast_cli(a->
fd,
"profile values (%d, allocated %d)\n-------------------\n",
824 ast_cli(a->
fd,
"%6s %8s %10s %12s %12s %s\n",
"ID",
"Scale",
"Events",
825 "Value",
"Average",
"Name");
826 for (i = min; i < max; i++) {
828 if (!search || strstr(entry->
name, search))
829 ast_cli(a->
fd,
"%6d: [%8ld] %10ld %12lld %12lld %s\n",
842 const char *search = NULL;
845 e->
command =
"core clear profile";
846 e->
usage =
"Usage: core clear profile\n"
847 " clear profile information";
857 for (i= min; i < max; i++) {
865 #undef DEFINE_PROFILE_MIN_MAX_VALUES
870 #define FORMAT "%-25.25s %-40.40s\n"
877 int matchlen, which = 0;
882 e->
command =
"core show file version [like]";
884 "Usage: core show file version [like <pattern>]\n"
885 " Lists the revision numbers of the files used to build this copy of Asterisk.\n"
886 " Optional regular expression pattern is used to filter the file list.\n";
889 matchlen = strlen(a->
word);
894 if (!strncasecmp(a->
word, find->file, matchlen) && ++which > a->
n) {
906 if (!strcasecmp(a->
argv[4],
"like")) {
907 if (regcomp(®exbuf, a->
argv[5], REG_EXTENDED | REG_NOSUB))
926 if (havename && strcasecmp(iterator->file, a->
argv[4]))
929 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0))
939 ast_cli(a->
fd,
"%d files listed.\n", count_files);
1018 return write(fd, s, strlen(s) + 1);
1024 return write(fd, s, strlen(s));
1034 .sa_flags = SA_RESTART,
1038 .sa_handler = SIG_IGN,
1081 struct rusage rusage;
1084 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
1087 #ifdef HAVE_WORKING_FORK
1095 cap_t cap = cap_from_text(
"cap_net_admin-eip");
1097 if (cap_set_proc(cap)) {
1103 #ifdef HAVE_WORKING_FORK
1109 execl(
"/bin/sh",
"/bin/sh",
"-c", s, (
char *) NULL);
1111 }
else if (pid > 0) {
1113 res = wait4(pid, &status, 0, &rusage);
1117 }
else if (
errno != EINTR)
1167 ast_cli(fd,
"Console is not muted anymore.\n");
1171 ast_cli(fd,
"Console is muted.\n");
1176 ast_cli(fd,
"Couldn't find remote console.\n");
1201 fputs(
string, stdout);
1224 fputs(
string, stdout);
1248 #if defined(SO_PEERCRED)
1249 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
1250 #define HAVE_STRUCT_UCRED_UID
1251 struct sockpeercred cred;
1255 socklen_t
len =
sizeof(cred);
1257 #if defined(HAVE_GETPEEREID)
1265 result = read(fd, buffer, size);
1270 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
1271 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
1274 #if defined(HAVE_STRUCT_UCRED_UID)
1282 #elif defined(HAVE_GETPEEREID)
1283 if (getpeereid(fd, &uid, &gid)) {
1297 struct console *con = vconsole;
1301 const char *
const end_buf = inbuf +
sizeof(
inbuf);
1302 char *start_read =
inbuf;
1304 struct pollfd fds[2];
1306 if (gethostname(hostname,
sizeof(hostname)-1))
1308 snprintf(outbuf,
sizeof(outbuf),
"%s/%ld/%s\n", hostname, (
long)ast_mainpid,
ast_get_version());
1311 fds[0].fd = con->
fd;
1312 fds[0].events = POLLIN;
1314 fds[1].fd = con->
p[0];
1315 fds[1].events = POLLIN;
1324 if (fds[0].revents) {
1325 int cmds_read, bytes_read;
1326 if ((bytes_read =
read_credentials(con->
fd, start_read, end_buf - start_read, con)) < 1) {
1330 if (strncmp(inbuf,
"cli quit after ", 15) == 0) {
1339 if (start_read + bytes_read < end_buf) {
1340 start_read += bytes_read;
1347 if (start_read[bytes_read - 1] ==
'\0') {
1355 while (cmds_read-- && (start_read = strchr(start_read,
'\0'))) {
1358 memmove(inbuf, start_read, end_buf - start_read);
1359 start_read = end_buf - start_read +
inbuf;
1361 if (fds[1].revents) {
1367 res = write(con->
fd, outbuf, res);
1373 ast_verb(3,
"Remote UNIX connection disconnected\n");
1385 struct sockaddr_un sunaddr;
1390 struct pollfd fds[1];
1395 fds[0].events = POLLIN;
1397 pthread_testcancel();
1403 len =
sizeof(sunaddr);
1404 s = accept(ast_socket, (
struct sockaddr *)&sunaddr, &len);
1409 #if !defined(SO_PASSCRED)
1414 if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt,
sizeof(sckopt)) < 0) {
1425 fdprint(s,
"Server failed to create pipe\n");
1429 flags = fcntl(
consoles[x].p[1], F_GETFL);
1430 fcntl(
consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
1442 fdprint(s,
"Server failed to spawn thread\n");
1447 if (x >= AST_MAX_CONNECTS) {
1448 fdprint(s,
"No more connections allowed\n");
1452 ast_verb(3,
"Remote UNIX connection\n");
1462 struct sockaddr_un sunaddr;
1471 ast_socket = socket(
PF_LOCAL, SOCK_STREAM, 0);
1472 if (ast_socket < 0) {
1476 memset(&sunaddr, 0,
sizeof(sunaddr));
1479 res = bind(ast_socket, (
struct sockaddr *)&sunaddr,
sizeof(sunaddr));
1486 res = listen(ast_socket, 2);
1536 struct sockaddr_un sunaddr;
1538 ast_consock = socket(
PF_LOCAL, SOCK_STREAM, 0);
1539 if (ast_consock < 0) {
1540 fprintf(stderr,
"Unable to create socket: %s\n", strerror(
errno));
1543 memset(&sunaddr, 0,
sizeof(sunaddr));
1546 res = connect(ast_consock, (
struct sockaddr *)&sunaddr,
sizeof(sunaddr));
1568 .sa_flags = SA_RESTART,
1573 int a = 0, save_errno =
errno;
1574 if (option_verbose > 1)
1575 printf(
"Received HUP signal -- Reloading configs\n");
1581 fprintf(stderr,
"hup_handler: write() failed: %s\n", strerror(
errno));
1589 .sa_flags = SA_RESTART,
1600 for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
1602 if (n == 0 && option_debug)
1603 printf(
"Huh? Child handler, but nobody there?\n");
1609 .sa_flags = SA_RESTART,
1615 struct rlimit l = {0, 0};
1625 if (setrlimit(RLIMIT_NOFILE, &l)) {
1638 if (getenv(
"TERM") && strstr(getenv(
"TERM"),
"xterm"))
1639 fprintf(stdout,
"\033]2;%s\007", text);
1644 if (getenv(
"TERM") && strstr(getenv(
"TERM"),
"xterm"))
1645 fprintf(stdout,
"\033]1;%s\007", text);
1652 struct sched_param sched;
1653 memset(&sched, 0,
sizeof(sched));
1656 sched.sched_priority = 10;
1664 sched.sched_priority = 0;
1703 ast_verbose(
"Ignoring asterisk %s request, already in progress.\n", restart ?
"restart" :
"shutdown");
1719 ast_verbose(
"Beginning asterisk %s....\n", restart ?
"restart" :
"shutdown");
1736 ast_verbose(
"Waiting for inactivity to perform %s...\n", restart ?
"restart" :
"halt");
1751 ast_verbose(
"Asterisk %s cancelled.\n", restart ?
"restart" :
"shutdown");
1765 int active_channels;
1773 char filename[80] =
"";
1774 if (getenv(
"HOME")) {
1775 snprintf(filename,
sizeof(filename),
"%s/.asterisk_history", getenv(
"HOME"));
1801 active_channels ?
"Uncleanly" :
"Cleanly",
1802 restart ?
"True" :
"False");
1805 active_channels ?
"uncleanly" :
"cleanly", num);
1812 ast_debug(1,
"Asterisk ending (%d).\n", num);
1813 if (ast_socket > -1) {
1818 pthread_kill(
lthread, SIGURG);
1821 if (ast_consock > -1)
1833 ast_verbose(
"Preparing for Asterisk restart...\n");
1835 for (i = 3; i < 32768; i++) {
1836 fcntl(i, F_SETFD, FD_CLOEXEC);
1870 fprintf(stderr,
"quit_handler: write() failed: %s\n", strerror(
errno));
1882 static const char *
fix_header(
char *outbuf,
int maxout,
const char *s,
char *cmp)
1891 if (!strncmp(s, cmp, strlen(cmp))) {
1892 c = s + strlen(cmp);
1902 const char *c = NULL;
1967 while (isspace(*s)) {
1971 if ((strncasecmp(s,
"quit", 4) == 0 || strncasecmp(s,
"exit", 4) == 0) &&
1972 (s[4] ==
'\0' || isspace(s[4]))) {
1984 e->
command =
"core show version";
1986 "Usage: core show version\n"
1987 " Shows Asterisk version information.\n";
1995 ast_cli(a->
fd,
"Asterisk %s built by %s @ %s on a %s running %s on %s\n",
2002 static int handle_quit(
int fd,
int argc,
char *argv[])
2017 "Usage: core stop now\n"
2018 " Shuts down a running Asterisk immediately, hanging up all active calls .\n";
2034 e->
command =
"core stop gracefully";
2036 "Usage: core stop gracefully\n"
2037 " Causes Asterisk to not accept new calls, and exit when all\n"
2038 " active calls have terminated normally.\n";
2054 e->
command =
"core stop when convenient";
2056 "Usage: core stop when convenient\n"
2057 " Causes Asterisk to perform a shutdown when all active calls have ended.\n";
2065 ast_cli(a->
fd,
"Waiting for inactivity to perform halt\n");
2074 e->
command =
"core restart now";
2076 "Usage: core restart now\n"
2077 " Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
2094 e->
command =
"core restart gracefully";
2096 "Usage: core restart gracefully\n"
2097 " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
2098 " restart when all active calls have ended.\n";
2114 e->
command =
"core restart when convenient";
2116 "Usage: core restart when convenient\n"
2117 " Causes Asterisk to perform a cold restart when all active calls have ended.\n";
2125 ast_cli(a->
fd,
"Waiting for inactivity to perform restart\n");
2132 int aborting_shutdown = 0;
2136 e->
command =
"core abort shutdown";
2138 "Usage: core abort shutdown\n"
2139 " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2140 " call operations.\n";
2151 aborting_shutdown = 1;
2156 if (aborting_shutdown) {
2168 "Usage: !<command>\n"
2169 " Executes a given shell command\n";
2181 "BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
2182 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"
2183 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
2184 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
2185 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
2186 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"
2187 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"
2188 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
2189 "REPAIR OR CORRECTION.\n"
2191 "IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
2192 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
2193 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
2194 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
2195 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
2196 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
2197 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
2198 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
2199 "POSSIBILITY OF SUCH DAMAGES.\n"
2206 e->
command =
"core show warranty";
2208 "Usage: core show warranty\n"
2209 " Shows the warranty (if any) for this copy of Asterisk.\n";
2222 "This program is free software; you can redistribute it and/or modify\n"
2223 "it under the terms of the GNU General Public License version 2 as\n"
2224 "published by the Free Software Foundation.\n"
2226 "This program also contains components licensed under other licenses.\n"
2229 "This program is distributed in the hope that it will be useful,\n"
2230 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2231 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
2232 "GNU General Public License for more details.\n"
2234 "You should have received a copy of the GNU General Public License\n"
2235 "along with this program; if not, write to the Free Software\n"
2236 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
2243 e->
command =
"core show license";
2245 "Usage: core show license\n"
2246 " Shows the license(s) for this copy of Asterisk.\n";
2257 #define ASTERISK_PROMPT "*CLI> "
2259 #define ASTERISK_PROMPT2 "%s*CLI> "
2284 #if !defined(LOW_MEMORY)
2287 #if defined(HAVE_SYSINFO) || defined(HAVE_SYSCTL)
2300 struct pollfd fds[2];
2303 #define EL_BUF_SIZE 512
2309 fds[0].events = POLLIN;
2311 fds[1].fd = STDIN_FILENO;
2312 fds[1].events = POLLIN;
2321 fprintf(stderr,
"poll failed: %s\n", strerror(
errno));
2326 num_read = read(STDIN_FILENO, cp, 1);
2332 if (fds[0].revents) {
2334 res = read(ast_consock, buf,
sizeof(buf) - 1);
2337 fprintf(stderr,
"\nDisconnected from Asterisk server\n");
2342 int reconnects_per_second = 20;
2343 fprintf(stderr,
"Attempting to reconnect for 30 seconds\n");
2344 for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
2346 fprintf(stderr,
"Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
2350 fdsend(ast_consock,
"logger mute silent");
2352 printf(
"log and verbose output currently muted ('logger mute' to unmute)\n");
2355 usleep(1000000 / reconnects_per_second);
2357 if (tries >= 30 * reconnects_per_second) {
2358 fprintf(stderr,
"Failed to reconnect for 30 seconds. Quitting.\n");
2368 for (tmp = buf; *tmp; tmp++) {
2370 memmove(tmp, tmp + 1, strlen(tmp));
2378 if (write(STDOUT_FILENO,
"\r[0K", 5) < 0) {
2381 if (write(STDOUT_FILENO, buf, res) < 0) {
2383 if ((res <
EL_BUF_SIZE - 1) && ((buf[res-1] ==
'\n') || (buf[res-2] ==
'\n'))) {
2402 static int cli_prompt_changes = 0;
2407 if (prompt == NULL) {
2409 }
else if (!cli_prompt_changes) {
2415 if ((pfmt = getenv(
"ASTERISK_PROMPT"))) {
2418 while (*t !=
'\0') {
2422 struct ast_tm tm = { 0, };
2429 if (sscanf(t,
"%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
2432 }
else if (sscanf(t,
"%30d%n", &fgcolor, &i) == 1) {
2444 cli_prompt_changes++;
2448 if ((gr = getgrgid(getgid()))) {
2453 if (!gethostname(hostname,
sizeof(hostname) - 1)) {
2460 if (!gethostname(hostname,
sizeof(hostname) - 1)) {
2462 if ((dotptr = strchr(hostname,
'.'))) {
2470 #ifdef HAVE_GETLOADAVG
2473 if (sscanf(t,
"%30d", &which) == 1 && which > 0 && which <= 3) {
2477 cli_prompt_changes++;
2488 cli_prompt_changes++;
2492 if ((pw = getpwuid(getuid()))) {
2529 for (idx = 0; idx < matches; ++idx) {
2539 char **match_list = NULL;
2541 size_t match_list_len = 1;
2544 while ((retstr =
strsep(&buf,
" "))) {
2548 if (matches + 1 >= match_list_len) {
2549 match_list_len <<= 1;
2550 new_list =
ast_realloc(match_list, match_list_len *
sizeof(
char *));
2555 match_list = new_list;
2563 match_list[matches++] = retstr;
2570 if (matches >= match_list_len) {
2571 new_list =
ast_realloc(match_list, (match_list_len + 1) *
sizeof(
char *));
2576 match_list = new_list;
2579 match_list[matches] = NULL;
2588 s1 = ((
char **)i1)[0];
2589 s2 = ((
char **)i2)[0];
2591 return strcasecmp(s1, s2);
2596 int i, idx, limit, count;
2597 int screenwidth = 0;
2598 int numoutput = 0, numoutputline = 0;
2603 limit = screenwidth / (max + 2);
2608 count = len / limit;
2609 if (count * limit < len)
2616 for (; count > 0; count--) {
2618 for (i = 0; i < limit && matches[idx]; i++, idx++) {
2621 if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
2624 matches[idx] = NULL;
2630 fprintf(stdout,
"%-*s ", max, matches[idx]);
2632 matches[idx] = NULL;
2634 if (numoutputline > 0)
2635 fprintf(stdout,
"\n");
2648 int retval = CC_ERROR;
2649 char buf[2048], savechr;
2652 LineInfo *lf = (LineInfo *)el_line(editline);
2654 savechr = *(
char *)lf->cursor;
2655 *(
char *)lf->cursor =
'\0';
2656 ptr = (
char *)lf->cursor;
2658 while (ptr > lf->buffer) {
2659 if (isspace(*ptr)) {
2667 len = lf->cursor - ptr;
2670 snprintf(buf,
sizeof(buf),
"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
2671 fdsend(ast_consock, buf);
2672 if ((res = read(ast_consock, buf,
sizeof(buf) - 1)) < 0) {
2673 return (
char*)(CC_ERROR);
2676 nummatches = atoi(buf);
2678 if (nummatches > 0) {
2681 int mlen = 0, maxmbuf = 2048;
2685 lf->cursor[0] = savechr;
2686 return (
char *)(CC_ERROR);
2688 snprintf(buf,
sizeof(buf),
"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
2689 fdsend(ast_consock, buf);
2693 if (mlen + 1024 > maxmbuf) {
2699 lf->cursor[0] = savechr;
2700 return (
char *)(CC_ERROR);
2705 res = read(ast_consock, mbuf + mlen, 1024);
2714 matches = (
char **) NULL;
2716 char **p, *oldbuf=NULL;
2719 for (p = matches; p && *p; p++) {
2720 if (!oldbuf || strcmp(*p,oldbuf))
2728 int matches_num, maxlen, match_len;
2730 if (matches[0][0] !=
'\0') {
2731 el_deletestr(editline, (
int) len);
2732 el_insertstr(editline, matches[0]);
2733 retval = CC_REFRESH;
2736 if (nummatches == 1) {
2738 el_insertstr(editline,
" ");
2739 retval = CC_REFRESH;
2742 for (i = 1, maxlen = 0; matches[i]; i++) {
2743 match_len = strlen(matches[i]);
2744 if (match_len > maxlen)
2747 matches_num = i - 1;
2748 if (matches_num >1) {
2749 fprintf(stdout,
"\n");
2751 retval = CC_REDISPLAY;
2753 el_insertstr(editline,
" ");
2754 retval = CC_REFRESH;
2757 for (i = 0; matches[i]; i++)
2762 lf->cursor[0] = savechr;
2764 return (
char *)(long)retval;
2770 char *editor = getenv(
"AST_EDITOR");
2777 el = el_init(
"asterisk", stdin, stdout, stderr);
2780 el_set(
el, EL_EDITMODE, 1);
2781 el_set(
el, EL_EDITOR, editor ? editor :
"emacs");
2787 history(
el_hist, &ev, H_SETSIZE, 100);
2791 el_set(
el, EL_ADDFN,
"ed-complete",
"Complete argument",
cli_complete);
2793 el_set(
el, EL_BIND,
"^I",
"ed-complete", NULL);
2795 el_set(
el, EL_BIND,
"?",
"ed-complete", NULL);
2797 el_set(
el, EL_BIND,
"^D",
"ed-redisplay", NULL);
2802 #define MAX_HISTORY_COMMAND_LENGTH 256
2822 return (history(
el_hist, &ev, H_SAVE, filename));
2834 if ((f = fopen(filename,
"r")) == NULL)
2838 if (!fgets(buf,
sizeof(buf), f))
2840 if (!strcmp(buf,
"_HiStOrY_V2_\n"))
2856 char filename[80] =
"";
2861 char *stringp = NULL;
2871 if (read(ast_consock, buf,
sizeof(buf)) < 0) {
2876 char prefix[] =
"cli quit after ";
2877 char *tmp =
ast_alloca(strlen(data) + strlen(prefix) + 1);
2878 sprintf(tmp,
"%s%s", prefix, data);
2879 if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
2887 hostname =
strsep(&stringp,
"/");
2888 cpid =
strsep(&stringp,
"/");
2889 version =
strsep(&stringp,
"\n");
2891 version =
"<Version Unknown>";
2900 snprintf(tmp,
sizeof(tmp),
"core set verbose atleast %d", option_verbose);
2901 fdsend(ast_consock, tmp);
2902 snprintf(tmp,
sizeof(tmp),
"core set debug atleast %d", option_debug);
2903 fdsend(ast_consock, tmp);
2905 fdsend(ast_consock,
"logger mute silent");
2907 printf(
"log and verbose output currently muted ('logger mute' to unmute)\n");
2913 fds.events = POLLIN;
2915 while (
ast_poll(&fds, 1, 60000) > 0) {
2916 char buffer[512] =
"", *curline = buffer, *nextline;
2917 int not_written = 1;
2923 if (read(ast_consock, buffer,
sizeof(buffer) - 1) <= 0) {
2928 if ((nextline = strchr(curline,
'\n'))) {
2931 nextline = strchr(curline,
'\0');
2935 if (*curline != 127) {
2937 if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
2952 ast_verbose(
"Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
2955 snprintf(filename,
sizeof(filename),
"%s/.asterisk_history", getenv(
"HOME"));
2965 ebuf = (
char *)el_gets(
el, &num);
2971 if (!ebuf && write(1,
"", 1) < 0)
2975 if (ebuf[strlen(ebuf)-1] ==
'\n')
2976 ebuf[strlen(ebuf)-1] =
'\0';
2980 for (temp = ebuf; *temp; temp++) {
2982 memmove(temp, temp + 1, strlen(temp));
2986 res = write(ast_consock, ebuf, strlen(ebuf) + 1);
2994 printf(
"\nDisconnected from Asterisk server\n");
3005 printf(
"Asterisk %s, Copyright (C) 1999 - 2013, Digium, Inc. and others.\n",
ast_get_version());
3006 printf(
"Usage: asterisk [OPTIONS]\n");
3007 printf(
"Valid Options:\n");
3008 printf(
" -V Display version number and exit\n");
3009 printf(
" -C <configfile> Use an alternate configuration file\n");
3010 printf(
" -G <group> Run as a group other than the caller\n");
3011 printf(
" -U <user> Run as a user other than the caller\n");
3012 printf(
" -c Provide console CLI\n");
3013 printf(
" -d Enable extra debugging\n");
3014 #if HAVE_WORKING_FORK
3015 printf(
" -f Do not fork\n");
3016 printf(
" -F Always fork\n");
3018 printf(
" -g Dump core in case of a crash\n");
3019 printf(
" -h This help screen\n");
3020 printf(
" -i Initialize crypto keys at startup\n");
3021 printf(
" -L <load> Limit the maximum load average before rejecting new calls\n");
3022 printf(
" -M <value> Limit the maximum number of calls to the specified value\n");
3023 printf(
" -m Mute debugging and console output on the console\n");
3024 printf(
" -n Disable console colorization\n");
3025 printf(
" -p Run as pseudo-realtime thread\n");
3026 printf(
" -q Quiet mode (suppress output)\n");
3027 printf(
" -r Connect to Asterisk on this machine\n");
3028 printf(
" -R Same as -r, except attempt to reconnect if disconnected\n");
3029 printf(
" -s <socket> Connect to Asterisk via socket <socket> (only valid with -r)\n");
3030 printf(
" -t Record soundfiles in /var/tmp and move them where they\n");
3031 printf(
" belong after they are done\n");
3032 printf(
" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n");
3033 printf(
" of output to the CLI\n");
3034 printf(
" -v Increase verbosity (multiple v's = more verbose)\n");
3035 printf(
" -x <cmd> Execute command <cmd> (implies -r)\n");
3036 printf(
" -X Execute includes by default (allows #exec in asterisk.conf)\n");
3037 printf(
" -W Adjust terminal colors to compensate for a light background\n");
3050 unsigned int dbdir:1;
3051 unsigned int keydir:1;
3088 if (!strcasecmp(v->
name,
"astctlpermissions"))
3090 else if (!strcasecmp(v->
name,
"astctlowner"))
3092 else if (!strcasecmp(v->
name,
"astctlgroup"))
3094 else if (!strcasecmp(v->
name,
"astctl"))
3099 if (!strcasecmp(v->
name,
"astetcdir")) {
3101 }
else if (!strcasecmp(v->
name,
"astspooldir")) {
3104 }
else if (!strcasecmp(v->
name,
"astvarlibdir")) {
3108 }
else if (!strcasecmp(v->
name,
"astdbdir")) {
3111 }
else if (!strcasecmp(v->
name,
"astdatadir")) {
3115 }
else if (!strcasecmp(v->
name,
"astkeydir")) {
3118 }
else if (!strcasecmp(v->
name,
"astlogdir")) {
3120 }
else if (!strcasecmp(v->
name,
"astagidir")) {
3122 }
else if (!strcasecmp(v->
name,
"astrundir")) {
3126 }
else if (!strcasecmp(v->
name,
"astmoddir")) {
3133 if (!strcasecmp(v->
name,
"verbose")) {
3134 option_verbose = atoi(v->
value);
3136 }
else if (!strcasecmp(v->
name,
"timestamp")) {
3139 }
else if (!strcasecmp(v->
name,
"execincludes")) {
3142 }
else if (!strcasecmp(v->
name,
"debug")) {
3144 if (sscanf(v->
value,
"%30d", &option_debug) != 1) {
3147 #if HAVE_WORKING_FORK
3149 }
else if (!strcasecmp(v->
name,
"nofork")) {
3152 }
else if (!strcasecmp(v->
name,
"alwaysfork")) {
3156 }
else if (!strcasecmp(v->
name,
"quiet")) {
3159 }
else if (!strcasecmp(v->
name,
"console")) {
3162 }
else if (!strcasecmp(v->
name,
"highpriority")) {
3165 }
else if (!strcasecmp(v->
name,
"initcrypto")) {
3168 }
else if (!strcasecmp(v->
name,
"nocolor")) {
3171 }
else if (!strcasecmp(v->
name,
"dontwarn")) {
3174 }
else if (!strcasecmp(v->
name,
"dumpcore")) {
3177 }
else if (!strcasecmp(v->
name,
"cache_record_files")) {
3180 }
else if (!strcasecmp(v->
name,
"record_cache_dir")) {
3183 }
else if (!strcasecmp(v->
name,
"transcode_via_sln")) {
3186 }
else if (!strcasecmp(v->
name,
"transmit_silence_during_record") || !strcasecmp(v->
name,
"transmit_silence")) {
3189 }
else if (!strcasecmp(v->
name,
"internal_timing")) {
3192 "NOTICE: The internal_timing option is no longer needed.\n"
3193 " It will always be enabled if you have a timing module loaded.\n");
3195 }
else if (!strcasecmp(v->
name,
"maxcalls")) {
3196 if ((sscanf(v->
value,
"%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
3197 option_maxcalls = 0;
3199 }
else if (!strcasecmp(v->
name,
"maxload")) {
3203 ast_log(
LOG_ERROR,
"Cannot obtain load average on this system. 'maxload' option disabled.\n");
3204 option_maxload = 0.0;
3205 }
else if ((sscanf(v->
value,
"%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
3206 option_maxload = 0.0;
3209 }
else if (!strcasecmp(v->
name,
"maxfiles")) {
3210 option_maxfiles = atoi(v->
value);
3213 }
else if (!strcasecmp(v->
name,
"runuser")) {
3216 }
else if (!strcasecmp(v->
name,
"rungroup")) {
3218 }
else if (!strcasecmp(v->
name,
"systemname")) {
3220 }
else if (!strcasecmp(v->
name,
"autosystemname")) {
3222 if (!gethostname(hostname,
sizeof(hostname) - 1))
3231 }
else if (!strcasecmp(v->
name,
"languageprefix")) {
3233 }
else if (!strcasecmp(v->
name,
"defaultlanguage")) {
3235 }
else if (!strcasecmp(v->
name,
"lockmode")) {
3236 if (!strcasecmp(v->
value,
"lockfile")) {
3238 }
else if (!strcasecmp(v->
value,
"flock")) {
3242 "defaulting to 'lockfile'\n", v->
value);
3245 #if defined(HAVE_SYSINFO)
3246 }
else if (!strcasecmp(v->
name,
"minmemfree")) {
3249 if ((sscanf(v->
value,
"%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
3250 option_minmemfree = 0;
3253 }
else if (!strcasecmp(v->
name,
"entityid")) {
3260 }
else if (!strcasecmp(v->
name,
"lightbackground")) {
3262 }
else if (!strcasecmp(v->
name,
"forceblackbackground")) {
3264 }
else if (!strcasecmp(v->
name,
"hideconnect")) {
3266 }
else if (!strcasecmp(v->
name,
"lockconfdir")) {
3268 }
else if (!strcasecmp(v->
name,
"live_dangerously")) {
3277 if (sscanf(v->
value,
"%30f", &version) != 1) {
3278 fprintf(stderr,
"Compatibility version for option '%s' is not a number: '%s'\n", v->
name, v->
value);
3281 if (!strcasecmp(v->
name,
"app_set")) {
3283 }
else if (!strcasecmp(v->
name,
"res_agi")) {
3285 }
else if (!strcasecmp(v->
name,
"pbx_realtime")) {
3320 struct stat canary_stat;
3328 if (stat(
canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
3330 "The canary is no more. He has ceased to be! "
3331 "He's expired and gone to meet his maker! "
3332 "He's a stiff! Bereft of life, he rests in peace. "
3333 "His metabolic processes are now history! He's off the twig! "
3334 "He's kicked the bucket. He's shuffled off his mortal coil, "
3335 "run down the curtain, and joined the bleeding choir invisible!! "
3336 "THIS is an EX-CANARY. (Reducing priority)\n");
3366 fd = open(
"/dev/null", O_RDWR);
3397 fprintf(stderr,
"Unable to register console verboser?\n");
3405 ast_verbose(
"Running under group '%s'\n", rungroup);
3418 char filename[80] =
"";
3426 int isroot = 1, rundir_exists = 0;
3428 const char *runuser = NULL, *rungroup = NULL;
3429 char *remotesock = NULL;
3435 fprintf(stderr,
"Truncating argument size to %d\n", (
int)
ARRAY_LEN(
_argv) - 1);
3438 for (x = 0; x < argc; x++)
3446 if (argv[0] && (strstr(argv[0],
"rasterisk")) != NULL) {
3449 if (gethostname(hostname,
sizeof(hostname)-1))
3451 ast_mainpid = getpid();
3454 snprintf(filename,
sizeof(filename),
"%s/.asterisk_history", getenv(
"HOME"));
3456 while ((c = getopt(argc, argv,
"BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
3479 #if defined(HAVE_SYSINFO)
3481 if ((sscanf(&optarg[1],
"%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
3482 option_minmemfree = 0;
3486 #if HAVE_WORKING_FORK
3505 "NOTICE: The -I option is no longer needed.\n"
3506 " It will always be enabled if you have a timing module loaded.\n");
3512 if ((sscanf(optarg,
"%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
3513 option_maxload = 0.0;
3517 if ((sscanf(optarg,
"%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
3518 option_maxcalls = 0;
3578 strcpy(argv[0],
"rasterisk");
3579 for (x = 1; x < argc; x++) {
3580 argv[x] = argv[0] + 10;
3591 fprintf(stderr,
"The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
3595 fprintf(stderr,
"'alwaysfork' is not compatible with console or remote console mode; ignored\n");
3600 memset(&l, 0,
sizeof(l));
3601 l.rlim_cur = RLIM_INFINITY;
3602 l.rlim_max = RLIM_INFINITY;
3603 if (setrlimit(RLIMIT_CORE, &l)) {
3604 fprintf(stderr,
"Unable to disable core size resource limit: %s\n", strerror(
errno));
3608 if (getrlimit(RLIMIT_NOFILE, &l)) {
3609 fprintf(stderr,
"Unable to check file descriptor limit: %s\n", strerror(
errno));
3612 #if !defined(CONFIGURE_RAN_AS_ROOT)
3617 struct timeval tv = { 0, };
3619 if (l.rlim_cur <= FD_SETSIZE) {
3625 if (!(fd = open(
"/dev/null", O_RDONLY))) {
3626 fprintf(stderr,
"Cannot open a file descriptor at boot? %s\n", strerror(
errno));
3630 fd2 = (l.rlim_cur >
sizeof(readers) * 8 ?
sizeof(readers) * 8 : l.rlim_cur) - 1;
3631 if (dup2(fd, fd2) < 0) {
3632 fprintf(stderr,
"Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(
errno));
3639 if (
ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
3640 fprintf(stderr,
"Maximum select()able file descriptor is %d\n", FD_SETSIZE);
3646 #elif defined(HAVE_VARIABLE_FDSET)
3658 sigaction(SIGCHLD, &child_handler, NULL);
3663 if (
errno == EEXIST) {
3666 fprintf(stderr,
"Unable to create socket file directory. Remote consoles will not be able to connect! (%s)\n", strerror(x));
3676 if (isroot && rungroup) {
3678 gr = getgrnam(rungroup);
3680 fprintf(stderr,
"No such group '%s'!\n", rungroup);
3684 fprintf(stderr,
"Unable to chgrp run directory to %d (%s)\n", (
int) gr->gr_gid, rungroup);
3686 if (setgid(gr->gr_gid)) {
3687 fprintf(stderr,
"Unable to setgid to %d (%s)\n", (
int)gr->gr_gid, rungroup);
3690 if (setgroups(0, NULL)) {
3691 fprintf(stderr,
"Unable to drop unneeded groups\n");
3701 pw = getpwnam(runuser);
3703 fprintf(stderr,
"No such user '%s'!\n", runuser);
3707 fprintf(stderr,
"Unable to chown run directory to %d (%s)\n", (
int) pw->pw_uid, runuser);
3710 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
3715 if (!isroot && pw->pw_uid != geteuid()) {
3716 fprintf(stderr,
"Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
3720 if (setgid(pw->pw_gid)) {
3721 fprintf(stderr,
"Unable to setgid to %d!\n", (
int)pw->pw_gid);
3724 if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
3725 fprintf(stderr,
"Unable to init groups for '%s'\n", runuser);
3729 if (setuid(pw->pw_uid)) {
3730 fprintf(stderr,
"Unable to setuid to %d (%s)\n", (
int)pw->pw_uid, runuser);
3737 cap = cap_from_text(
"cap_net_admin=eip");
3739 if (cap_set_proc(cap)) {
3740 fprintf(stderr,
"Unable to install capabilities.\n");
3742 if (cap_free(cap)) {
3743 fprintf(stderr,
"Unable to drop capabilities.\n");
3753 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
3754 fprintf(stderr,
"Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(
errno));
3760 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
3761 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
3762 #define eaccess euidaccess
3765 if (!getcwd(dir,
sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
3766 fprintf(stderr,
"Unable to access the running directory (%s). Changing to '/' for compatibility.\n", strerror(
errno));
3771 fprintf(stderr,
"chdir(\"/\") failed?!! %s\n", strerror(
errno));
3778 fprintf(stderr,
"Unable to chdir(\"/\") ?!! %s\n", strerror(
errno));
3798 fprintf(stderr,
"Asterisk already running on %s. Use 'asterisk -r' to connect.\n",
ast_config_AST_SOCKET);
3813 #if HAVE_WORKING_FORK
3815 #ifndef HAVE_SBIN_LAUNCHD
3816 if (daemon(1, 0) < 0) {
3817 fprintf(stderr,
"daemon() failed: %s\n", strerror(
errno));
3819 ast_mainpid = getpid();
3822 fprintf(stderr,
"Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
3832 #if defined(__AST_DEBUG_MALLOC)
3845 char canary_binary[128], *lastslash, ppid[12];
3848 signal(SIGCHLD, SIG_DFL);
3849 signal(SIGPIPE, SIG_DFL);
3853 snprintf(ppid,
sizeof(ppid),
"%d", (
int) ast_mainpid);
3855 execlp(
"astcanary",
"astcanary",
canary_filename, ppid, (
char *)NULL);
3859 if ((lastslash = strrchr(canary_binary,
'/'))) {
3860 ast_copy_string(lastslash + 1,
"astcanary",
sizeof(canary_binary) + canary_binary - (lastslash + 1));
3861 execl(canary_binary,
"astcanary",
canary_filename, ppid, (
char *)NULL);
3867 pthread_t dont_care;
3879 fprintf(f,
"%ld\n", (
long)ast_mainpid);
3895 ast_verbose(
"[ Initializing Custom Configuration Options ]\n");
3942 #ifdef TEST_FRAMEWORK
3953 sigaddset(&sigs, SIGHUP);
3954 sigaddset(&sigs, SIGTERM);
3955 sigaddset(&sigs, SIGINT);
3956 sigaddset(&sigs, SIGPIPE);
3957 sigaddset(&sigs, SIGWINCH);
3958 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
3959 sigaction(SIGURG, &urg_handler, NULL);
3962 sigaction(SIGHUP, &hup_handler, NULL);
3968 srand((
unsigned int) getpid() + (
unsigned int) time(NULL));
3969 initstate((
unsigned int) getpid() * 65536 + (
unsigned int) time(NULL),
randompool,
sizeof(
randompool));
4005 exit(moduleresult == -2 ? 2 : 1);
4085 exit(moduleresult == -2 ? 2 : 1);
4112 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
4114 #if defined(__AST_DEBUG_MALLOC)
4133 snprintf(title,
sizeof(title),
"Asterisk Console on '%s' (pid %ld)", hostname, (
long)ast_mainpid);
4143 buf = (
char *) el_gets(
el, &num);
4145 if (!buf && write(1,
"", 1) < 0)
4149 if (buf[strlen(buf)-1] ==
'\n')
4150 buf[strlen(buf)-1] =
'\0';
4153 }
else if (
ast_opt_remote && (write(STDOUT_FILENO,
"\nUse EXIT or QUIT to exit the asterisk console\n",
4154 strlen(
"\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
4157 fd = open(
"/dev/null", O_RDWR);
4159 dup2(fd, STDOUT_FILENO);
4160 dup2(fd, STDIN_FILENO);
4162 ast_log(
LOG_WARNING,
"Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
static void __ast_unregister_atexit(void(*func)(void))
static int sig_alert_pipe[2]
int ast_indications_init(void)
Load indications module.
static char * handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
A-Law to Signed linear conversion.
void ast_console_puts(const char *string)
static char * handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
const char * ast_config_AST_KEY_DIR
static int show_version(void)
void ast_register_thread(char *name)
static void * canary_thread(void *unused)
int64_t ast_mark(int, int start1_stop0)
#define AST_CLI_DEFINE(fn, txt,...)
char ** ast_cli_completion_matches(const char *, const char *)
Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter...
#define AST_LIST_LOCK(head)
Locks a list.
static struct @220 sig_flags
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static const char config_file[]
static char * handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void canary_exit(void)
const char * ast_build_user
static const char config[]
static char ast_config_AST_CTL_GROUP[PATH_MAX]
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
static char * handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int64_t ast_profile(int, int64_t)
#define DEFAULT_CONFIG_FILE
char * strsep(char **str, const char *delims)
#define AST_CLI_COMPLETE_EOF
void ast_autoservice_init(void)
static int ast_makesocket(void)
int ast_image_init(void)
Initialize image stuff Initializes all the various image stuff. Basically just registers the cli stuf...
static struct sigaction ignore_sig_handler
static const char license_lines[]
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
int main(int argc, char *argv[])
void ast_register_file_version(const char *file, const char *version)
Register the version of a source code file with the core.
void ast_builtins_init(void)
initialize the _full_cmd string in * each of the builtins.
static struct ast_cli_entry cli_asterisk[]
static char * handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
const char * ast_config_AST_DB
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define ast_pthread_create_detached(a, b, c, d)
static struct sigaction urg_handler
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Asterisk version information.
static ast_mutex_t safe_system_lock
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void ast_udptl_init(void)
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
static char * handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int ast_el_read_history(char *)
#define ast_set2_flag(p, value, flag)
#define ast_test_flag(p, flag)
static char * handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Give an overview of system statistics.
const char * ast_config_AST_MODULE_DIR
#define AST_DEFAULT_OPTIONS
const char * ast_get_version(void)
Retrieve the Asterisk version string.
static char ast_config_AST_CTL_OWNER[PATH_MAX]
static char * handle_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Convenient Signal Processing routines.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define ast_set_flag(p, flag)
static int remoteconsolehandler(char *s)
static int ast_all_zeros(char *s)
static const char * fix_header(char *outbuf, int maxout, const char *s, char *cmp)
descriptor for a cli entry.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
static void destroy_match_list(char **match_list, int matches)
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous dialplan functions to run. ...
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static char * cli_complete(EditLine *editline, int ch)
char * ast_complete_source_filename(const char *partial, int n)
static int multi_thread_safe
void ast_verbose(const char *fmt,...)
#define WELCOME_MESSAGE
Welcome message when starting a CLI interface.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
void ast_begin_shutdown(int hangup)
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
static void __remote_quit_handler(int num)
const char * ast_build_date
Structure for variables, used for configurations and for channel variables.
static struct sigaction safe_system_prev_handler
static void network_verboser(const char *s)
const char * ast_build_os
static void _hup_handler(int num)
char module_dir[PATH_MAX]
static struct profile_data * prof_data
Configuration File Parser.
int ast_features_init(void)
int ast_xmldoc_load_documentation(void)
Load XML documentation. Provided by xmldoc.c.
static char * levels[NUMLOGLEVELS]
Logging channels used in the Asterisk logging system.
static int show_cli_help(void)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static char * cli_prompt(EditLine *editline)
static void _null_sig_handler(int sig)
NULL handler so we can collect the child exit status.
void ast_set_default_eid(struct ast_eid *eid)
Fill in an ast_eid with the default eid of this machine.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
int ast_cc_init(void)
Initialize CCSS.
const char * ast_config_AST_RUN_DIR
void ast_alaw_init(void)
To init the alaw to slinear conversion stuff, this needs to be run.
void ast_module_shutdown(void)
Run the unload() callback for all loaded modules.
static int ast_cli_display_match_list(char **matches, int len, int max)
#define ast_mutex_lock(a)
const char * ast_config_AST_RUN_USER
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
void ast_console_toggle_loglevel(int fd, int level, int state)
enables or disables logging of a specified level to the console fd specifies the index of the console...
int check_manager_enabled(void)
Check if AMI is enabled.
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()
#define WIFEXITED(status)
int ast_dsp_init(void)
Load dsp settings from dsp.conf.
I/O Management (derived from Cheops-NG)
static int ast_el_write_history(char *)
void ast_cli(int fd, const char *fmt,...)
static int ast_tryconnect(void)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
An Entity ID is essentially a MAC address, brief and unique.
#define ast_pthread_create_detached_background(a, b, c, d)
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
#define ast_opt_reconnect
void ast_console_toggle_mute(int fd, int silent)
mute or unmute a console from logging
const char * ast_build_hostname
int ast_get_termcols(int fd)
int args
This gets set in ast_cli_register()
const char * ast_build_kernel
static void quit_handler(int num, shutdown_nice_t niceness, int restart)
#define WEXITSTATUS(status)
#define ast_pthread_create_background(a, b, c, d)
const char * ast_config_AST_SYSTEM_NAME
static char * handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list module versions.
#define CONFIG_STATUS_FILEMISSING
static char * handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_cel_engine_init(void)
static void _urg_handler(int num)
Urgent handler.
const char * ast_config_AST_RUN_GROUP
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static void env_init(void)
static void _child_handler(int sig)
Support for Private Asterisk HTTP Servers.
void __ast_mm_init_phase_1(void)
const char * ast_build_machine
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_RWLIST_INSERT_HEAD
const char * ast_config_AST_CONFIG_FILE
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
static void ast_readconfig(void)
#define EVENT_FLAG_SYSTEM
#define ast_debug(level,...)
Log a DEBUG message.
static pthread_t mon_sig_flags
static char * handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
General Asterisk channel definitions for image handling.
u-Law to Signed linear conversion
Generic Advice of Charge encode and decode routines.
static void * listener(void *unused)
void ast_unregister_thread(void *id)
static int ast_el_sort_compare(const void *i1, const void *i2)
void callerid_init(void)
CallerID Initialization.
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
static void __quit_handler(int num)
int ast_register_verbose(void(*verboser)(const char *string)) attribute_warn_unused_result
Asterisk file paths, configured in asterisk.conf.
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
const char * ast_config_AST_AGI_DIR
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_poll(a, b, c)
static void set_title(char *text)
Set an X-term or screen title.
const char * ast_config_AST_PID
char * term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout)
Write a color sequence to a string.
int ast_language_is_prefix
#define AST_RWLIST_TRAVERSE
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define AST_CACHE_DIR_LEN
Scheduler Routines (derived from cheops)
static struct sigaction hup_handler
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
static int ast_select(int nfds, ast_fdset *rfds, ast_fdset *wfds, ast_fdset *efds, struct timeval *tvp)
Waits for activity on a group of channels.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
#define AST_RWLIST_REMOVE_CURRENT
struct timeval ast_lastreloadtime
static const char warranty_lines[]
A set of macros to manage forward-linked lists.
ast_cli_command
calling arguments for new-style handlers.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct console consoles[AST_MAX_CONNECTS]
char monitor_dir[PATH_MAX]
int ast_aoc_cli_init(void)
enable aoc cli options
struct ast_atexit::@221 list
int register_config_cli(void)
Exposed initialization method for core process.
Core PBX routines and definitions.
int ast_set_priority(int)
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy ac...
struct ast_flags ast_compat
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
static shutdown_nice_t shuttingdown
Wrapper for network related headers, masking differences between various operating systems...
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
int ast_add_profile(const char *, uint64_t scale)
support for event profiling
const char * ast_config_AST_DATA_DIR
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
static pthread_t consolethread
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_cdr_engine_term(void)
static char canary_filename[128]
int ast_device_state_engine_init(void)
Initialize the device state engine in separate thread.
static struct _cfg_paths cfg_paths
void ast_ulaw_init(void)
Set up mu-law conversion table.
static void consolehandler(char *s)
static void run_startup_commands(void)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
void ast_stun_init(void)
Initialize the STUN system in Asterisk.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static int fdsend(int fd, const char *s)
static char randompool[256]
static char * handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Give an overview of core settings.
const char * ast_config_AST_CONFIG_DIR
TTY/TDD Generation support.
unsigned int ast_FD_SETSIZE
int setenv(const char *name, const char *value, int overwrite)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int ast_el_read_char(EditLine *editline, char *cp)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static void * netconsole(void *vconsole)
#define DEFINE_PROFILE_MIN_MAX_VALUES
const char * ast_config_AST_LOG_DIR
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_opt_override_config
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static char * remotehostname
char config_dir[PATH_MAX]
static void set_icon(char *text)
int ast_module_reload(const char *name)
Reload asterisk modules.
static void ast_remotecontrol(char *data)
const char * ast_config_AST_MONITOR_DIR
void ast_cancel_shutdown(void)
Cancel a shutdown in progress.
static int read_credentials(int fd, char *buffer, size_t size, struct console *con)
read() function supporting the reception of user credentials.
static char * handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void pbx_live_dangerously(int new_live_dangerously)
Enable/disable the execution of 'dangerous' functions from external protocols (AMI, etc.).
Call Completion Supplementary Services API.
static char ast_config_AST_CTL[PATH_MAX]
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
static char * handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Asterisk XML Documentation API.
void ast_console_puts_mutable(const char *string, int level)
log the string to the console, and all attached console clients
const char * ast_config_AST_SPOOL_DIR
#define ast_opt_always_fork
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
static struct sigaction child_handler
static void main_atexit(void)
if(yyss+yystacksize-1<=yyssp)
int check_webmanager_enabled(void)
Check if AMI/HTTP is enabled.
static unsigned int safe_system_level
Keep track of how many threads are currently trying to wait*() on a child process.
Structure used to handle boolean flags.
#define ast_clear_flag(p, flag)
char record_cache_dir[AST_CACHE_DIR_LEN]
struct ast_eid ast_eid_default
Global EID.
#define sched_setscheduler
struct timeval ast_startuptime
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define DEFAULT_SPOOL_DIR
void clean_time_zones(void)
int ast_cli_command_multiple_full(int uid, int gid, int fd, size_t size, const char *s)
Executes multiple CLI commands Interpret strings separated by NULL and execute each one...
struct ast_flags ast_options
static void ast_network_puts_mutable(const char *string, int level)
log the string to all attached console clients
void __ast_mm_init_phase_2(void)
void threadstorage_init(void)
static int fdprint(int fd, const char *s)
int load_modules(unsigned int)
Standard Command Line Interface.
static int ast_el_initialize(void)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_set_lock_type(enum AST_LOCK_TYPE type)
Set the type of locks used by ast_lock_path()
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct profile_entry e[0]
char socket_path[PATH_MAX]
int ast_cdr_engine_init(void)
Load the configuration file cdr.conf and possibly start the CDR scheduling thread.
static int register_atexit(void(*func)(void), int is_cleanup)
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define ast_realloc(a, b)
const char * ast_config_AST_SOCKET
void dnsmgr_start_refresh(void)
#define MAX_HISTORY_COMMAND_LENGTH
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static int can_safely_quit(shutdown_nice_t niceness, int restart)
int init_manager(void)
Called by Asterisk initialization.
static char * handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DEFAULT_MODULE_DIR
Handy terminal functions for vt* terms.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
static char ast_config_AST_CTL_PERMISSIONS[PATH_MAX]
struct ast_variable * next
int ast_timing_init(void)
static struct sigaction null_sig_handler
int ast_undestroyed_channels(void)
void ast_channels_init(void)
static char * show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int check_cdr_enabled(void)
Return TRUE if CDR subsystem is enabled.
#define DEFAULT_CONFIG_DIR
static struct ast_str * prompt
#define CONFIG_STATUS_FILEINVALID
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
unsigned int need_quit_handler
char config_file[PATH_MAX]
const char * ast_file_version_find(const char *file)
Find version for given module name.
static int ast_el_add_history(char *)
static void ast_network_puts(const char *string)
write the string to all attached console clients
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
#define ast_opt_hide_connect
Asterisk module definitions.
const char * ast_config_AST_VAR_DIR
static struct ast_cli_entry cli_asterisk_shutdown[]
Shutdown Asterisk CLI commands.
int ast_active_channels(void)
returns number of active/allocated channels
#define ast_opt_dump_core
static void print_intro_message(const char *runuser, const char *rungroup)
static char ** ast_el_strtoarr(char *buf)
int getloadavg(double *list, int nelem)
#define AST_RWLIST_TRAVERSE_SAFE_END
void ast_process_pending_reloads(void)
Process reload requests received during startup.
static void set_ulimit(int value)
Set maximum open files.
static void really_quit(int num, shutdown_nice_t niceness, int restart)
#define AST_MUTEX_DEFINE_STATIC(mutex)
static void * monitor_sig_flags(void *unused)
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
int ast_cli_perms_init(int reload)
static void ast_run_atexits(int run_cleanups)
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define ast_opt_high_priority
static void console_verboser(const char *s)
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
static char hostname[MAXHOSTNAMELEN]
static __inline uint64_t rdtsc(void)
void ast_unregister_file_version(const char *file)
Unregister a source code file from the core.
static char prefix[MAX_PREFIX]
int read_config_maps(void)
Exposed re-initialization method for core process.