summaryrefslogtreecommitdiff
path: root/main/asterisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/asterisk.c')
-rw-r--r--main/asterisk.c197
1 files changed, 131 insertions, 66 deletions
diff --git a/main/asterisk.c b/main/asterisk.c
index ebc9a8a3f..fd81462fb 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -1502,8 +1502,7 @@ static struct sigaction urg_handler = {
static void _hup_handler(int num)
{
int a = 0, save_errno = errno;
- if (option_verbose > 1)
- printf("Received HUP signal -- Reloading configs\n");
+ printf("Received HUP signal -- Reloading configs\n");
if (restartnow)
execvp(_argv[0], _argv);
sig_flags.need_reload = 1;
@@ -1589,8 +1588,7 @@ int ast_set_priority(int pri)
ast_log(LOG_WARNING, "Unable to set high priority\n");
return -1;
} else
- if (option_verbose)
- ast_verbose("Set to realtime thread\n");
+ ast_verb(1, "Set to realtime thread\n");
} else {
sched.sched_priority = 0;
/* According to the manpage, these parameters can never fail. */
@@ -1602,8 +1600,7 @@ int ast_set_priority(int pri)
ast_log(LOG_WARNING, "Unable to set high priority\n");
return -1;
} else
- if (option_verbose)
- ast_verbose("Set to high priority\n");
+ ast_verb(1, "Set to high priority\n");
} else {
/* According to the manpage, these parameters can never fail. */
setpriority(PRIO_PROCESS, 0, 0);
@@ -1675,7 +1672,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
ast_begin_shutdown(0);
}
if (option_verbose && ast_opt_console) {
- ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
+ ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
}
for (;;) {
if (!ast_active_channels() || shuttingdown != niceness) {
@@ -1690,7 +1687,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
ast_mutex_lock(&safe_system_lock);
if (shuttingdown != niceness) {
if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
- ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
+ ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
}
ast_mutex_unlock(&safe_system_lock);
return 0;
@@ -1729,12 +1726,10 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
}
}
}
- if (option_verbose)
- ast_verbose("Executing last minute cleanups\n");
+ ast_verb(0, "Executing last minute cleanups\n");
ast_run_atexits();
/* Called on exit */
- if (option_verbose && ast_opt_console)
- ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
+ ast_verb(0, "Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
ast_debug(1, "Asterisk ending (%d).\n", num);
manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
if (ast_socket > -1) {
@@ -1750,14 +1745,12 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
printf("%s", term_quit());
if (restart) {
int i;
- if (option_verbose || ast_opt_console)
- ast_verbose("Preparing for Asterisk restart...\n");
+ ast_verb(0, "Preparing for Asterisk restart...\n");
/* Mark all FD's for closing on exec */
for (i = 3; i < 32768; i++) {
fcntl(i, F_SETFD, FD_CLOEXEC);
}
- if (option_verbose || ast_opt_console)
- ast_verbose("Asterisk is now restarting...\n");
+ ast_verb(0, "Asterisk is now restarting...\n");
restartnow = 1;
/* close logger */
@@ -1802,11 +1795,6 @@ static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp
{
const char *c;
- /* Check for verboser preamble */
- if (*s == 127) {
- s++;
- }
-
if (!strncmp(s, cmp, strlen(cmp))) {
c = s + strlen(cmp);
term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
@@ -1815,10 +1803,25 @@ static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp
return NULL;
}
+/* These gymnastics are due to platforms which designate char as unsigned by
+ * default. Level is the negative character -- offset by 1, because \0 is the
+ * EOS delimiter. */
+#define VERBOSE_MAGIC2LEVEL(x) (((char) -*(signed char *) (x)) - 1)
+#define VERBOSE_HASMAGIC(x) (*(signed char *) (x) < 0)
+
static void console_verboser(const char *s)
{
char tmp[80];
const char *c = NULL;
+ char level = 0;
+
+ if (VERBOSE_HASMAGIC(s)) {
+ level = VERBOSE_MAGIC2LEVEL(s);
+ s++;
+ if (level > option_verbose) {
+ return;
+ }
+ }
if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
(c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
@@ -1827,14 +1830,11 @@ static void console_verboser(const char *s)
fputs(tmp, stdout);
fputs(c, stdout);
} else {
- if (*s == 127) {
- s++;
- }
fputs(s, stdout);
}
fflush(stdout);
-
+
/* Wake up a poll()ing console */
if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
pthread_kill(consolethread, SIGURG);
@@ -1883,8 +1883,35 @@ static int remoteconsolehandler(char *s)
else
ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
ret = 1;
- }
- if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
+ } else if (strncasecmp(s, "core set verbose ", 17) == 0) {
+ int old_verbose = option_verbose;
+ if (strncasecmp(s + 17, "atleast ", 8) == 0) {
+ int tmp;
+ if (sscanf(s + 25, "%d", &tmp) != 1) {
+ fprintf(stderr, "Usage: core set verbose [atleast] <level>\n");
+ } else {
+ if (tmp > option_verbose) {
+ option_verbose = tmp;
+ }
+ if (old_verbose != option_verbose) {
+ fprintf(stdout, "Set remote console verbosity from %d to %d\n", old_verbose, option_verbose);
+ } else {
+ fprintf(stdout, "Verbosity level unchanged.\n");
+ }
+ }
+ } else {
+ if (sscanf(s + 17, "%d", &option_verbose) != 1) {
+ fprintf(stderr, "Usage: core set verbose [atleast] <level>\n");
+ } else {
+ if (old_verbose != option_verbose) {
+ fprintf(stdout, "Set remote console verbosity to %d\n", option_verbose);
+ } else {
+ fprintf(stdout, "Verbosity level unchanged.\n");
+ }
+ }
+ }
+ ret = 1;
+ } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
(s[4] == '\0' || isspace(s[4]))) {
quit_handler(0, SHUTDOWN_FAST, 0);
ret = 1;
@@ -2198,6 +2225,23 @@ static struct ast_cli_entry cli_asterisk[] = {
#endif /* ! LOW_MEMORY */
};
+struct el_read_char_state_struct {
+ unsigned int line_full:1;
+ unsigned int prev_line_full:1;
+ char prev_line_verbosity;
+};
+
+static int el_read_char_state_init(void *ptr)
+{
+ struct el_read_char_state_struct *state = ptr;
+ state->line_full = 1;
+ state->prev_line_full = 1;
+ state->prev_line_verbosity = 0;
+ return 0;
+}
+
+AST_THREADSTORAGE_CUSTOM(el_read_char_state, el_read_char_state_init, ast_free_ptr);
+
static int ast_el_read_char(EditLine *editline, char *cp)
{
int num_read = 0;
@@ -2207,6 +2251,7 @@ static int ast_el_read_char(EditLine *editline, char *cp)
int max;
#define EL_BUF_SIZE 512
char buf[EL_BUF_SIZE];
+ struct el_read_char_state_struct *state = ast_threadstorage_get(&el_read_char_state, sizeof(*state));
for (;;) {
max = 1;
@@ -2236,7 +2281,8 @@ static int ast_el_read_char(EditLine *editline, char *cp)
}
}
if (fds[0].revents) {
- char *tmp;
+ char level = 0;
+ char *curline = buf, *nextline;
res = read(ast_consock, buf, sizeof(buf) - 1);
/* if the remote side disappears exit */
if (res < 1) {
@@ -2269,22 +2315,37 @@ static int ast_el_read_char(EditLine *editline, char *cp)
buf[res] = '\0';
- /* Strip preamble from asynchronous events, too */
- for (tmp = buf; *tmp; tmp++) {
- if (*tmp == 127) {
- memmove(tmp, tmp + 1, strlen(tmp));
- tmp--;
- res--;
- }
- }
-
/* Write over the CLI prompt */
if (!ast_opt_exec && !lastpos) {
if (write(STDOUT_FILENO, "\r", 5) < 0) {
}
}
- if (write(STDOUT_FILENO, buf, res) < 0) {
- }
+
+ do {
+ state->prev_line_full = state->line_full;
+ if ((nextline = strchr(curline, '\n'))) {
+ state->line_full = 1;
+ nextline++;
+ } else {
+ state->line_full = 0;
+ nextline = strchr(curline, '\0');
+ }
+
+ if (state->prev_line_full && VERBOSE_HASMAGIC(curline)) {
+ level = VERBOSE_MAGIC2LEVEL(curline);
+ curline++;
+ } else {
+ level = state->prev_line_verbosity;
+ }
+ if ((!state->prev_line_full && state->prev_line_verbosity <= option_verbose) || (state->prev_line_full && level <= option_verbose)) {
+ if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
+ }
+ }
+
+ state->prev_line_verbosity = level;
+ curline = nextline;
+ } while (!ast_strlen_zero(curline));
+
if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
*cp = CC_REFRESH;
return(1);
@@ -2795,22 +2856,20 @@ static void ast_remotecontrol(char *data)
else
pid = -1;
if (!data) {
- char tmp[80];
- snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
- fdsend(ast_consock, tmp);
- snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
- fdsend(ast_consock, tmp);
- if (!ast_opt_mute)
+ if (!ast_opt_mute) {
fdsend(ast_consock, "logger mute silent");
- else
+ } else {
printf("log and verbose output currently muted ('logger mute' to unmute)\n");
+ }
}
if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
+ int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
struct pollfd fds;
fds.fd = ast_consock;
fds.events = POLLIN;
fds.revents = 0;
+
while (ast_poll(&fds, 1, 60000) > 0) {
char buffer[512] = "", *curline = buffer, *nextline;
int not_written = 1;
@@ -2824,18 +2883,34 @@ static void ast_remotecontrol(char *data)
}
do {
+ prev_linefull = linefull;
if ((nextline = strchr(curline, '\n'))) {
+ linefull = 1;
nextline++;
} else {
+ linefull = 0;
nextline = strchr(curline, '\0');
}
/* Skip verbose lines */
- if (*curline != 127) {
+ /* Prev line full? | Line is verbose | Last line verbose? | Print
+ * TRUE | TRUE* | TRUE | FALSE
+ * TRUE | TRUE* | FALSE | FALSE
+ * TRUE | FALSE* | TRUE | TRUE
+ * TRUE | FALSE* | FALSE | TRUE
+ * FALSE | TRUE | TRUE* | FALSE
+ * FALSE | TRUE | FALSE* | TRUE
+ * FALSE | FALSE | TRUE* | FALSE
+ * FALSE | FALSE | FALSE* | TRUE
+ */
+ if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
+ prev_line_verbose = 0;
not_written = 0;
if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
}
+ } else {
+ prev_line_verbose = 1;
}
curline = nextline;
} while (!ast_strlen_zero(curline));
@@ -2874,14 +2949,6 @@ static void ast_remotecontrol(char *data)
if (ebuf[strlen(ebuf)-1] == '\n')
ebuf[strlen(ebuf)-1] = '\0';
if (!remoteconsolehandler(ebuf)) {
- /* Strip preamble from output */
- char *temp;
- for (temp = ebuf; *temp; temp++) {
- if (*temp == 127) {
- memmove(temp, temp + 1, strlen(temp));
- temp--;
- }
- }
res = write(ast_consock, ebuf, strlen(ebuf) + 1);
if (res < 1) {
ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
@@ -3580,8 +3647,7 @@ int main(int argc, char *argv[])
ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
exit(1);
}
- if (option_verbose)
- ast_verbose("Running as group '%s'\n", rungroup);
+ ast_verb(1, "Running as group '%s'\n", rungroup);
}
if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
@@ -3621,8 +3687,7 @@ int main(int argc, char *argv[])
ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
exit(1);
}
- if (option_verbose)
- ast_verbose("Running as user '%s'\n", runuser);
+ ast_verb(1, "Running as user '%s'\n", runuser);
#ifdef HAVE_CAP
if (has_cap) {
cap_t cap;
@@ -3676,8 +3741,9 @@ int main(int argc, char *argv[])
printf("%s", term_end());
fflush(stdout);
- if (ast_opt_console && !option_verbose)
+ if (ast_opt_console && !option_verbose) {
ast_verbose("[ Initializing Custom Configuration Options ]\n");
+ }
/* custom config setup */
register_config_cli();
read_config_maps();
@@ -3952,15 +4018,14 @@ int main(int argc, char *argv[])
/* We might have the option of showing a console, but for now just
do nothing... */
- if (ast_opt_console && !option_verbose)
- ast_verbose(" ]\n");
- if (option_verbose || ast_opt_console)
- ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
- if (ast_opt_no_fork)
+ ast_verb(0, "%s\n", term_color(tmp, "Asterisk Ready.", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
+ if (ast_opt_no_fork) {
consolethread = pthread_self();
+ }
- if (pipe(sig_alert_pipe))
+ if (pipe(sig_alert_pipe)) {
sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
+ }
ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");