This is better done by running tail -f on a logfile.
memcpy(cli_alloc_out(c, size), buf, size);
}
-static void
-cli_copy_message(cli *c)
-{
- byte *p, *q;
- uint cnt = 2;
-
- if (c->ring_overflow)
- {
- byte buf[64];
- int n = bsprintf(buf, "<%d messages lost>\n", c->ring_overflow);
- c->ring_overflow = 0;
- memcpy(cli_alloc_out(c, n), buf, n);
- }
- p = c->ring_read;
- while (*p)
- {
- cnt++;
- p++;
- if (p == c->ring_end)
- p = c->ring_buf;
- ASSERT(p != c->ring_write);
- }
- c->async_msg_size += cnt;
- q = cli_alloc_out(c, cnt);
- *q++ = '+';
- p = c->ring_read;
- do
- {
- *q = *p++;
- if (p == c->ring_end)
- p = c->ring_buf;
- }
- while (*q++);
- c->ring_read = p;
- q[-1] = '\n';
-}
-
static void
cli_hello(cli *c)
{
cli *c = data;
int err;
- while (c->ring_read != c->ring_write &&
- c->async_msg_size < CLI_MAX_ASYNC_QUEUE)
- cli_copy_message(c);
-
if (c->tx_pos)
;
else if (c->cont)
static list cli_log_hooks;
static int cli_log_inited;
-void
-cli_set_log_echo(cli *c, uint mask, uint size)
-{
- if (c->ring_buf)
- {
- mb_free(c->ring_buf);
- c->ring_buf = c->ring_end = c->ring_read = c->ring_write = NULL;
- rem_node(&c->n);
- }
- c->log_mask = mask;
- if (mask && size)
- {
- c->ring_buf = mb_alloc(c->pool, size);
- c->ring_end = c->ring_buf + size;
- c->ring_read = c->ring_write = c->ring_buf;
- add_tail(&cli_log_hooks, &c->n);
- c->log_threshold = size / 8;
- }
- c->ring_overflow = 0;
-}
-
-void
-cli_echo(uint class, byte *msg)
-{
- unsigned len, free, i, l;
- cli *c;
- byte *m;
-
- if (!cli_log_inited || EMPTY_LIST(cli_log_hooks))
- return;
- len = strlen(msg) + 1;
- WALK_LIST(c, cli_log_hooks)
- {
- if (!(c->log_mask & (1 << class)))
- continue;
- if (c->ring_read <= c->ring_write)
- free = (c->ring_end - c->ring_buf) - (c->ring_write - c->ring_read + 1);
- else
- free = c->ring_read - c->ring_write - 1;
- if ((len > free) ||
- (free < c->log_threshold && class < (unsigned) L_INFO[0]))
- {
- c->ring_overflow++;
- continue;
- }
- if (c->ring_read == c->ring_write)
- ev_schedule(c->event);
- m = msg;
- l = len;
- while (l)
- {
- if (c->ring_read <= c->ring_write)
- i = c->ring_end - c->ring_write;
- else
- i = c->ring_read - c->ring_write;
- if (i > l)
- i = l;
- memcpy(c->ring_write, m, i);
- m += i;
- l -= i;
- c->ring_write += i;
- if (c->ring_write == c->ring_end)
- c->ring_write = c->ring_buf;
- }
- }
-}
-
/* Hack for scheduled undo notification */
extern cli *cmd_reconfig_stored_cli;
void
cli_free(cli *c)
{
- cli_set_log_echo(c, 0, 0);
int defer = 0;
if (c->cleanup)
defer = c->cleanup(c);
int last_reply;
int restricted; /* CLI is restricted to read-only commands */
struct linpool *parser_pool; /* Pool used during parsing */
- byte *ring_buf; /* Ring buffer for asynchronous messages */
- byte *ring_end, *ring_read, *ring_write; /* Pointers to the ring buffer */
- uint ring_overflow; /* Counter of ring overflows */
uint log_mask; /* Mask of allowed message levels */
uint log_threshold; /* When free < log_threshold, store only important messages */
uint async_msg_size; /* Total size of async messages queued in tx_buf */
void cli_printf(cli *, int, char *, ...);
#define cli_msg(x...) cli_printf(this_cli, x)
-void cli_set_log_echo(cli *, uint mask, uint size);
static inline void cli_separator(cli *c)
{ if (c->last_reply) cli_printf(c, -c->last_reply, ""); };
void cli_free(cli *);
void cli_kick(cli *);
void cli_written(cli *);
-void cli_echo(uint class, byte *msg);
static inline int cli_access_restricted(void)
{
%type <s> optproto
%type <ra> r_args
%type <sd> sym_args
-%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type tos password_algorithm
+%type <i> proto_start debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type tos password_algorithm
%type <ps> proto_patt proto_patt2
%type <cc> channel_start proto_channel
%type <cl> limit_spec
CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
{ cmd_eval(f_linearize($2, 1)); } ;
-CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
-CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug|trace|info|remote|warning|error|auth [, ...] }) [<buffer-size>], [[Control echoing of log messages]]) {
- cli_set_log_echo(this_cli, $2, $3);
- cli_msg(0, "");
-} ;
-
-echo_mask:
- ALL { $$ = ~0; }
- | OFF { $$ = 0; }
- | '{' log_mask_list '}' { $$ = $2; }
- ;
-
-echo_size:
- /* empty */ { $$ = 4096; }
- | NUM {
- if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
- $$ = $1;
- }
- ;
-
CF_CLI(DISABLE, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]])
{ proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ;
CF_CLI(ENABLE, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]])
static inline void log_lock(void) { pthread_mutex_lock(&log_mutex); }
static inline void log_unlock(void) { pthread_mutex_unlock(&log_mutex); }
-static pthread_t main_thread;
-void main_thread_init(void) { main_thread = pthread_self(); }
-static int main_thread_self(void) { return pthread_equal(pthread_self(), main_thread); }
-
-
#ifdef HAVE_SYSLOG_H
#include <sys/syslog.h>
}
log_unlock();
- /* cli_echo is not thread-safe, so call it just from the main thread */
- if (main_thread_self())
- cli_echo(class, buf->start);
-
buf->pos = buf->start;
}
dup2(0, 2);
}
-
- main_thread_init();
-
write_pid_file();
signal_init();
/* log.c */
-void main_thread_init(void);
void log_init_debug(char *); /* Initialize debug dump to given file (NULL=stderr, ""=off) */
void log_switch(int initial, list *l, const char *);