Newer
Older
"Usage: restart when convenient\n"
" Causes Asterisk to perform a cold restart when all active calls have ended.\n";
static char bang_help[] =
"Usage: !<command>\n"
" Executes a given shell command\n";
static int handle_quit(int fd, int argc, char *argv[])
{
if (argc != 1)
return RESULT_SHOWUSAGE;
quit_handler(0, 0, 1, 0);
return RESULT_SUCCESS;
}
static int handle_shutdown_now(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
return RESULT_SUCCESS;
}
static int handle_shutdown_gracefully(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
return RESULT_SUCCESS;
}
static int handle_shutdown_when_convenient(int fd, int argc, char *argv[])
{
if (argc != 3)
return RESULT_SHOWUSAGE;
quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
return RESULT_SUCCESS;
}
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
static int handle_restart_now(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_restart_gracefully(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_restart_when_convenient(int fd, int argc, char *argv[])
{
if (argc != 3)
return RESULT_SHOWUSAGE;
quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
return RESULT_SUCCESS;
}
static int handle_abort_halt(int fd, int argc, char *argv[])
{
if (argc != 2)
return RESULT_SHOWUSAGE;
ast_cancel_shutdown();
shuttingdown = 0;
static int handle_bang(int fd, int argc, char *argv[])
{
return RESULT_SUCCESS;
}
Kevin P. Fleming
committed
static struct ast_cli_entry core_cli[] = {
{ { "abort", "halt", NULL }, handle_abort_halt,
"Cancel a running halt", abort_halt_help },
{ { "stop", "now", NULL }, handle_shutdown_now,
"Shut down Asterisk immediately", shutdown_now_help },
{ { "stop", "gracefully", NULL }, handle_shutdown_gracefully,
"Gracefully shut down Asterisk", shutdown_gracefully_help },
{ { "stop", "when","convenient", NULL }, handle_shutdown_when_convenient,
"Shut down Asterisk at empty call volume", shutdown_when_convenient_help },
{ { "restart", "now", NULL }, handle_restart_now,
"Restart Asterisk immediately", restart_now_help },
{ { "restart", "gracefully", NULL }, handle_restart_gracefully,
"Restart Asterisk gracefully", restart_gracefully_help },
{ { "restart", "when", "convenient", NULL }, handle_restart_when_convenient,
"Restart Asterisk at empty call volume", restart_when_convenient_help },
{ { "!", NULL }, handle_bang,
"Execute a shell command", bang_help },
#if !defined(LOW_MEMORY)
{ { "show", "version", "files", NULL }, handle_show_version_files,
"Show versions of files used to build Asterisk", show_version_files_help, complete_show_version_files },
#endif /* ! LOW_MEMORY */
Kevin P. Fleming
committed
};
static int ast_el_read_char(EditLine *el, char *cp)
{
struct pollfd fds[2];
int res;
int max;
char buf[512];
for (;;) {
max = 1;
fds[0].fd = ast_consock;
fds[0].events = POLLIN;
fds[1].fd = STDIN_FILENO;
fds[1].events = POLLIN;
max++;
res = poll(fds, max, -1);
if (res < 0) {
if (errno == EINTR)
continue;
ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
if (!option_exec && fds[1].revents) {
num_read = read(STDIN_FILENO, cp, 1);
if (num_read < 1) {
break;
} else
return (num_read);
}
if (fds[0].revents) {
res = read(ast_consock, buf, sizeof(buf) - 1);
/* if the remote side disappears exit */
if (res < 1) {
fprintf(stderr, "\nDisconnected from Asterisk server\n");
if (!option_reconnect) {
quit_handler(0, 0, 0, 0);
} else {
int tries;
int reconnects_per_second = 20;
fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
for (tries=0;tries<30 * reconnects_per_second;tries++) {
if (ast_tryconnect()) {
fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
printf(term_quit());
break;
} else {
usleep(1000000 / reconnects_per_second);
}
}
fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
quit_handler(0, 0, 0, 0);
}
}
write(STDOUT_FILENO, "\r", 1);
write(STDOUT_FILENO, buf, res);
if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
} else {
lastpos = 1;
}
}
}
*cp = '\0';
return (0);
}
static char *cli_prompt(EditLine *el)
static char prompt[200];
char *pfmt;
int color_used=0;
char term_code[20];
if ((pfmt = getenv("ASTERISK_PROMPT"))) {
char *t = pfmt, *p = prompt;
memset(prompt, 0, sizeof(prompt));
while (*t != '\0' && *p < sizeof(prompt)) {
if (*t == '%') {
char hostname[MAXHOSTNAMELEN]="";
int i;
struct timeval tv;
struct tm tm;
#ifdef linux
FILE *LOADAVG;
int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
t++;
switch (*t) {
case 'C': /* color */
t++;
if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
t += i - 1;
} else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
t += i - 1;
}
/* If the color has been reset correctly, then there's no need to reset it later */
if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
color_used = 0;
} else {
color_used = 1;
}
break;
case 'd': /* date */
memset(&tm, 0, sizeof(struct tm));
Kevin P. Fleming
committed
tv = ast_tvnow();
if (localtime_r(&(tv.tv_sec), &tm)) {
strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
}
break;
case 'h': /* hostname */
if (!gethostname(hostname, sizeof(hostname) - 1)) {
strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
} else {
strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
}
break;
case 'H': /* short hostname */
if (!gethostname(hostname, sizeof(hostname) - 1)) {
for (i=0;i<sizeof(hostname);i++) {
if (hostname[i] == '.') {
hostname[i] = '\0';
break;
}
}
strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
} else {
strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
}
break;
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
#ifdef linux
case 'l': /* load avg */
t++;
if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
float avg1, avg2, avg3;
int actproc, totproc, npid, which;
fscanf(LOADAVG, "%f %f %f %d/%d %d",
&avg1, &avg2, &avg3, &actproc, &totproc, &npid);
if (sscanf(t, "%d", &which) == 1) {
switch (which) {
case 1:
snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
break;
case 2:
snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
break;
case 3:
snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
break;
case 4:
snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
break;
case 5:
snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
break;
}
}
}
break;
#endif
case 't': /* time */
memset(&tm, 0, sizeof(struct tm));
Kevin P. Fleming
committed
tv = ast_tvnow();
if (localtime_r(&(tv.tv_sec), &tm)) {
strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
}
break;
case '#': /* process console or remote? */
if (! option_remote) {
strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
} else {
strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
}
break;
case '%': /* literal % */
strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
break;
case '\0': /* % is last character - prevent bug */
t--;
break;
}
while (*p != '\0') {
p++;
}
t++;
} else {
*p = *t;
p++;
t++;
}
}
if (color_used) {
/* Force colors back to normal at end */
term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
} else {
strncat(p, term_code, sizeof(term_code));
}
}
} else if (remotehostname)
snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname);
else
snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT);
}
static char **ast_el_strtoarr(char *buf)
{
char **match_list = NULL, *retstr;
while ( (retstr = strsep(&buf, " ")) != NULL) {
if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
break;
if (matches + 1 >= match_list_len) {
match_list_len <<= 1;
match_list = realloc(match_list, match_list_len * sizeof(char *));
match_list[matches++] = strdup(retstr);
if (!match_list)
return (char **) NULL;
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
if (matches>= match_list_len)
match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
match_list[matches] = (char *) NULL;
return match_list;
}
static int ast_el_sort_compare(const void *i1, const void *i2)
{
char *s1, *s2;
s1 = ((char **)i1)[0];
s2 = ((char **)i2)[0];
return strcasecmp(s1, s2);
}
static int ast_cli_display_match_list(char **matches, int len, int max)
{
int i, idx, limit, count;
int screenwidth = 0;
int numoutput = 0, numoutputline = 0;
screenwidth = ast_get_termcols(STDOUT_FILENO);
/* find out how many entries can be put on one line, with two spaces between strings */
limit = screenwidth / (max + 2);
if (limit == 0)
limit = 1;
/* how many lines of output */
count = len / limit;
if (count * limit < len)
count++;
idx = 1;
qsort(&matches[0], (size_t)(len + 1), sizeof(char *), ast_el_sort_compare);
for (; count > 0; count--) {
numoutputline = 0;
for (i=0; i < limit && matches[idx]; i++, idx++) {
/* Don't print dupes */
if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
i--;
free(matches[idx]);
matches[idx] = NULL;
free(matches[idx]);
matches[idx] = NULL;
}
if (numoutputline > 0)
fprintf(stdout, "\n");
}
return numoutput;
static char *cli_complete(EditLine *el, int ch)
int len=0;
char *ptr;
int nummatches = 0;
char **matches;
int retval = CC_ERROR;
James Golovich
committed
char buf[2048];
LineInfo *lf = (LineInfo *)el_line(el);
if (ptr) {
while (ptr > lf->buffer) {
if (isspace(*ptr)) {
ptr++;
break;
}
ptr--;
}
}
len = lf->cursor - ptr;
if (option_remote) {
snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
fdprint(ast_consock, buf);
res = read(ast_consock, buf, sizeof(buf));
buf[res] = '\0';
nummatches = atoi(buf);
if (nummatches > 0) {
char *mbuf;
int mlen = 0, maxmbuf = 2048;
/* Start with a 2048 byte buffer */
mbuf = malloc(maxmbuf);
if (!mbuf)
return (char *)(CC_ERROR);
snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
fdprint(ast_consock, buf);
res = 0;
while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
if (mlen + 1024 > maxmbuf) {
/* Every step increment buffer 1024 bytes */
maxmbuf += 1024;
mbuf = realloc(mbuf, maxmbuf);
if (!mbuf)
return (char *)(CC_ERROR);
}
/* Only read 1024 bytes at a time */
res = read(ast_consock, mbuf + mlen, 1024);
if (res > 0)
mlen += res;
}
mbuf[mlen] = '\0';
matches = ast_el_strtoarr(mbuf);
free(mbuf);
nummatches = ast_cli_generatornummatches((char *)lf->buffer,ptr);
matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
}
if (matches) {
int i;
int matches_num, maxlen, match_len;
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
el_insertstr(el, matches[0]);
retval = CC_REFRESH;
}
if (nummatches == 1) {
/* Found an exact match */
retval = CC_REFRESH;
} else {
/* Must be more than one match */
for (i=1, maxlen=0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
}
matches_num = i - 1;
if (matches_num >1) {
fprintf(stdout, "\n");
ast_cli_display_match_list(matches, nummatches, maxlen);
retval = CC_REDISPLAY;
} else {
}
static int ast_el_initialize(void)
{
HistEvent ev;
char *editor = getenv("AST_EDITOR");
if (el != NULL)
el_end(el);
if (el_hist != NULL)
history_end(el_hist);
el = el_init("asterisk", stdin, stdout, stderr);
el_set(el, EL_PROMPT, cli_prompt);
el_set(el, EL_EDITMODE, 1);
el_set(el, EL_EDITOR, editor ? editor : "emacs");
el_hist = history_init();
if (!el || !el_hist)
return -1;
/* setup history with 100 entries */
history(el_hist, &ev, H_SETSIZE, 100);
el_set(el, EL_HIST, history, el_hist);
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
/* Bind <tab> to command completion */
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
/* Bind ? to command completion */
el_set(el, EL_BIND, "?", "ed-complete", NULL);
/* Bind ^D to redisplay */
el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
return 0;
}
static int ast_el_add_history(char *buf)
{
HistEvent ev;
if (el_hist == NULL || el == NULL)
ast_el_initialize();
if (strlen(buf) > 256)
return 0;
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
return (history(el_hist, &ev, H_ENTER, buf));
}
static int ast_el_write_history(char *filename)
{
HistEvent ev;
if (el_hist == NULL || el == NULL)
ast_el_initialize();
return (history(el_hist, &ev, H_SAVE, filename));
}
static int ast_el_read_history(char *filename)
{
char buf[256];
FILE *f;
int ret = -1;
if (el_hist == NULL || el == NULL)
ast_el_initialize();
if ((f = fopen(filename, "r")) == NULL)
return ret;
while (!feof(f)) {
fgets(buf, sizeof(buf), f);
if (!strcmp(buf, "_HiStOrY_V2_\n"))
continue;
Mark Spencer
committed
if (ast_all_zeros(buf))
continue;
if ((ret = ast_el_add_history(buf)) == -1)
break;
}
fclose(f);
return ret;
}
static void ast_remotecontrol(char * data)
{
char buf[80];
int res;
char filename[80] = "";
char *hostname;
char *cpid;
char *version;
int pid;
char tmp[80];
char *stringp=NULL;
char *ebuf;
int num = 0;
if (data)
write(ast_consock, data, strlen(data) + 1);
stringp=buf;
hostname = strsep(&stringp, "/");
cpid = strsep(&stringp, "/");
if (!version)
version = "<Version Unknown>";
if (cpid)
pid = atoi(cpid);
else
pid = -1;
snprintf(tmp, sizeof(tmp), "set verbose atleast %d", option_verbose);
snprintf(tmp, sizeof(tmp), "set debug atleast %d", option_debug);
fdprint(ast_consock, tmp);
ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (el_hist == NULL || el == NULL)
ast_el_initialize();
el_set(el, EL_GETCFN, ast_el_read_char);
if (option_exec && data) { /* hack to print output then exit if asterisk -rx is used */
char tempchar;
struct pollfd fds[0];
fds[0].fd = ast_consock;
fds[0].events = POLLIN;
fds[0].revents = 0;
while(poll(fds, 1, 100) > 0) {
ast_el_read_char(el, &tempchar);
}
if (ebuf && !ast_strlen_zero(ebuf)) {
if (ebuf[strlen(ebuf)-1] == '\n')
ebuf[strlen(ebuf)-1] = '\0';
if (!remoteconsolehandler(ebuf)) {
res = write(ast_consock, ebuf, strlen(ebuf) + 1);
if (res < 1) {
ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
break;
}
}
}
}
printf("\nDisconnected from Asterisk server\n");
}
static int show_version(void)
{
printf("Asterisk " ASTERISK_VERSION "\n");
return 0;
}
printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 2000 - 2005, Digium.\n");
printf("Usage: asterisk [OPTIONS]\n");
printf("Valid Options:\n");
printf(" -C <configfile> Use an alternate configuration file\n");
printf(" -G <group> Run as a group other than the caller\n");
printf(" -U <user> Run as a user other than the caller\n");
printf(" -c Provide console CLI\n");
printf(" -d Enable extra debugging\n");
printf(" -f Do not fork\n");
printf(" -g Dump core in case of a crash\n");
printf(" -h This help screen\n");
printf(" -i Initialize crypto keys at startup\n");
printf(" -n Disable console colorization\n");
printf(" -p Run as pseudo-realtime thread\n");
printf(" -q Quiet mode (suppress output)\n");
printf(" -r Connect to Asterisk on this machine\n");
printf(" -R Connect to Asterisk, and attempt to reconnect if disconnected\n");
printf(" -t Record soundfiles in /var/tmp and move them where they belong after they are done.\n");
printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n");
printf(" -v Increase verbosity (multiple v's = more verbose)\n");
printf(" -x <cmd> Execute command <cmd> (only valid with -r)\n");
struct ast_config *cfg;
struct ast_variable *v;
Kevin P. Fleming
committed
char *config = AST_CONFIG_FILE;
cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_VAR_DIR));
snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
/* no asterisk.conf? no problem, use buildtime config! */
if (!cfg) {
v = ast_variable_browse(cfg, "files");
while (v) {
if (!strcasecmp(v->name, "astctlpermissions")) {
ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
} else if (!strcasecmp(v->name, "astctlowner")) {
ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
} else if (!strcasecmp(v->name, "astctlgroup")) {
ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
} else if (!strcasecmp(v->name, "astctl")) {
ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
}
v = v->next;
v = ast_variable_browse(cfg, "directories");
while(v) {
if (!strcasecmp(v->name, "astetcdir")) {
ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
} else if (!strcasecmp(v->name, "astspooldir")) {
ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
} else if (!strcasecmp(v->name, "astvarlibdir")) {
ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/%s", v->value, "astdb");
ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
v = ast_variable_browse(cfg, "options");
while(v) {
/* verbose level (-v at startup) */
if (!strcasecmp(v->name, "verbose")) {
option_verbose = atoi(v->value);
/* whether or not to force timestamping. (-T at startup) */
} else if (!strcasecmp(v->name, "timestamp")) {
option_timestamp = ast_true(v->value);
/* whether or not to support #exec in config files */
} else if (!strcasecmp(v->name, "execincludes")) {
option_exec_includes = ast_true(v->value);
} else if (!strcasecmp(v->name, "debug")) {
option_debug = 0;
if (sscanf(v->value, "%d", &option_debug) != 1) {
option_debug = ast_true(v->value);
}
/* Disable forking (-f at startup) */
} else if (!strcasecmp(v->name, "nofork")) {
/* Run quietly (-q at startup ) */
} else if (!strcasecmp(v->name, "quiet")) {
/* Run as console (-c at startup, implies nofork) */
} else if (!strcasecmp(v->name, "console")) {
/* Run with highg priority if the O/S permits (-p at startup) */
} else if (!strcasecmp(v->name, "highpriority")) {
/* Initialize RSA auth keys (IAX2) (-i at startup) */
} else if (!strcasecmp(v->name, "initcrypto")) {
/* Disable ANSI colors for console (-c at startup) */
} else if (!strcasecmp(v->name, "nocolor")) {
Russell Bryant
committed
/* Disable some usage warnings for picky people :p */
} else if (!strcasecmp(v->name, "dontwarn")) {
option_dontwarn = ast_true(v->value);
/* Dump core in case of crash (-g) */
} else if (!strcasecmp(v->name, "dumpcore")) {
/* Cache recorded sound files to another directory during recording */
} else if (!strcasecmp(v->name, "cache_record_files")) {
/* Specify cache directory */
} else if (!strcasecmp(v->name, "record_cache_dir")) {
ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
/* Build transcode paths via SLINEAR, instead of directly */
} else if (!strcasecmp(v->name, "transcode_via_sln")) {
option_transcode_slin = ast_true(v->value);
if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
}
v = v->next;
}
char hostname[MAXHOSTNAMELEN]="";
Kevin P. Fleming
committed
int is_child_of_nonroot=0;
char *runuser=NULL, *rungroup=NULL;
/* Remember original args for restart */
if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
}
for (x=0;x<argc;x++)
_argv[x] = argv[x];
_argv[x] = NULL;
/* if the progname is rasterisk consider it a remote console */
if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
option_remote++;
option_nofork++;
}
if (gethostname(hostname, sizeof(hostname)-1))
ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
Mark Spencer
committed
ast_mainpid = getpid();
Kevin P. Fleming
committed
/* When Asterisk restarts after it has dropped the root privileges,
* it can't issue setuid(), setgid(), setgroups() or set_priority()
* */
if (getenv("ASTERISK_ALREADY_NONROOT"))
is_child_of_nonroot=1;
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (geteuid()) {
ast_log(LOG_ERROR, "Must be run as root\n");
exit(1);
}
while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:M:")) != -1) {
switch(c) {
case 'd':
option_debug++;
option_nofork++;
case 'c':
option_console++;
option_nofork++;
case 'r':
option_remote++;
option_nofork++;
break;
case 'R':
option_remote++;
option_nofork++;
option_reconnect++;
break;
case 'M':
if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
option_maxcalls = 0;
break;
case 't':
option_cache_record_files++;
break;
case 'T':
option_timestamp++;
break;
case 'x':
option_exec++;
xarg = optarg;
break;
ast_copy_string((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE));
case 'U':
runuser = optarg;
break;
case 'G':
rungroup = optarg;
break;
Kevin P. Fleming
committed
/* For remote connections, change the name of the remote connection.
* We do this for the benefit of init scripts (which need to know if/when
* the main asterisk process has died yet). */
if (option_remote) {
strcpy(argv[0], "rasterisk");
for (x = 1; x < argc; x++) {
argv[x] = argv[0] + 10;
}
}
if (option_dumpcore) {
struct rlimit l;
memset(&l, 0, sizeof(l));
l.rlim_cur = RLIM_INFINITY;
l.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &l)) {
ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
}
}
if (option_console && !option_verbose)
ast_verbose("[ Reading Master Configuration ]");
ast_readconfig();
Kevin P. Fleming
committed
if (!is_child_of_nonroot && ast_set_priority(option_highpriority)) {
exit(1);
}
Kevin P. Fleming
committed
if (!is_child_of_nonroot && rungroup) {