Newer
Older
if (argc != 3)
return RESULT_SHOWUSAGE;
quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
return RESULT_SUCCESS;
}
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
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;
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
#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;
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
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;
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
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;
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) {
struct group *gr;
gr = getgrnam(rungroup);
if (!gr) {
ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
exit(1);
}
ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", gr->gr_gid, rungroup);
exit(1);
}
if (option_verbose)
ast_verbose("Running as group '%s'\n", rungroup);
}
Kevin P. Fleming
committed
if (!is_child_of_nonroot && runuser) {
struct passwd *pw;
pw = getpwnam(runuser);
if (!pw) {
ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
exit(1);
}
if (setuid(pw->pw_uid)) {
ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", pw->pw_uid, runuser);
exit(1);
}
Kevin P. Fleming
committed
setenv("ASTERISK_ALREADY_NONROOT","yes",1);
if (option_verbose)
ast_verbose("Running as user '%s'\n", runuser);
}
term_init();
printf(term_end());
fflush(stdout);
Mark Spencer
committed
ast_verbose("[ Initializing Custom Configuration Options ]");
/* custom config setup */
register_config_cli();
if (el_hist == NULL || el == NULL)
ast_el_initialize();