lib: use printfrr for log & vty

This makes printfrr extensions available in most of our format strings.
snprintf() is the obvious exception.

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2019-05-14 16:27:30 +02:00
parent bf4d3d8021
commit 807f5b9842
3 changed files with 31 additions and 70 deletions

View File

@ -30,6 +30,7 @@
#include "command.h" #include "command.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "lib/hook.h" #include "lib/hook.h"
#include "printfrr.h"
#ifndef SUNOS_5 #ifndef SUNOS_5
#include <sys/un.h> #include <sys/un.h>
@ -191,19 +192,13 @@ static void time_print(FILE *fp, struct timestamp_control *ctl)
static void vzlog_file(struct zlog *zl, struct timestamp_control *tsctl, static void vzlog_file(struct zlog *zl, struct timestamp_control *tsctl,
const char *proto_str, int record_priority, int priority, const char *proto_str, int record_priority, int priority,
FILE *fp, const char *format, va_list args) FILE *fp, const char *msg)
{ {
va_list ac;
time_print(fp, tsctl); time_print(fp, tsctl);
if (record_priority) if (record_priority)
fprintf(fp, "%s: ", zlog_priority[priority]); fprintf(fp, "%s: ", zlog_priority[priority]);
fprintf(fp, "%s", proto_str); fprintf(fp, "%s%s\n", proto_str, msg);
va_copy(ac, args);
vfprintf(fp, format, ac);
va_end(ac);
fprintf(fp, "\n");
fflush(fp); fflush(fp);
} }
@ -217,33 +212,26 @@ void vzlog(int priority, const char *format, va_list args)
struct timestamp_control tsctl; struct timestamp_control tsctl;
tsctl.already_rendered = 0; tsctl.already_rendered = 0;
struct zlog *zl = zlog_default; struct zlog *zl = zlog_default;
char buf[256], *msg;
/* call external hook */ /* call external hook */
hook_call(zebra_ext_log, priority, format, args); hook_call(zebra_ext_log, priority, format, args);
msg = vasnprintfrr(MTYPE_TMP, buf, sizeof(buf), format, args);
/* When zlog_default is also NULL, use stderr for logging. */ /* When zlog_default is also NULL, use stderr for logging. */
if (zl == NULL) { if (zl == NULL) {
tsctl.precision = 0; tsctl.precision = 0;
time_print(stderr, &tsctl); time_print(stderr, &tsctl);
fprintf(stderr, "%s: ", "unknown"); fprintf(stderr, "%s: %s\n", "unknown", msg);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr); fflush(stderr);
goto out;
/* In this case we return at here. */
errno = original_errno;
pthread_mutex_unlock(&loglock);
return;
} }
tsctl.precision = zl->timestamp_precision; tsctl.precision = zl->timestamp_precision;
/* Syslog output */ /* Syslog output */
if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) { if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG])
va_list ac; syslog(priority | zlog_default->facility, "%s", msg);
va_copy(ac, args);
vsyslog(priority | zlog_default->facility, format, ac);
va_end(ac);
}
if (zl->instance) if (zl->instance)
sprintf(proto_str, "%s[%d]: ", zl->protoname, zl->instance); sprintf(proto_str, "%s[%d]: ", zl->protoname, zl->instance);
@ -253,7 +241,7 @@ void vzlog(int priority, const char *format, va_list args)
/* File output. */ /* File output. */
if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority,
zl->fp, format, args); zl->fp, msg);
/* fixed-config logging to stderr while we're stating up & haven't /* fixed-config logging to stderr while we're stating up & haven't
* daemonized / reached mainloop yet * daemonized / reached mainloop yet
@ -261,17 +249,19 @@ void vzlog(int priority, const char *format, va_list args)
* note the "else" on stdout output -- we don't want to print the same * note the "else" on stdout output -- we don't want to print the same
* message to both stderr and stdout. */ * message to both stderr and stdout. */
if (zlog_startup_stderr && priority <= LOG_WARNING) if (zlog_startup_stderr && priority <= LOG_WARNING)
vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, format, vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, msg);
args);
else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT])
vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority,
stdout, format, args); stdout, msg);
/* Terminal monitor. */ /* Terminal monitor. */
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
vty_log((zl->record_priority ? zlog_priority[priority] : NULL), vty_log((zl->record_priority ? zlog_priority[priority] : NULL),
proto_str, format, &tsctl, args); proto_str, msg, &tsctl);
out:
if (msg != buf)
XFREE(MTYPE_TMP, msg);
errno = original_errno; errno = original_errno;
pthread_mutex_unlock(&loglock); pthread_mutex_unlock(&loglock);
} }

View File

@ -42,6 +42,7 @@
#include "frrstr.h" #include "frrstr.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "northbound_cli.h" #include "northbound_cli.h"
#include "printfrr.h"
#include <arpa/telnet.h> #include <arpa/telnet.h>
#include <termios.h> #include <termios.h>
@ -148,10 +149,9 @@ bool vty_set_include(struct vty *vty, const char *regexp)
int vty_out(struct vty *vty, const char *format, ...) int vty_out(struct vty *vty, const char *format, ...)
{ {
va_list args; va_list args;
int len = 0; ssize_t len;
int size = 1024;
char buf[1024]; char buf[1024];
char *p = NULL; char *p = buf;
char *filtered; char *filtered;
if (vty->frame_pos) { if (vty->frame_pos) {
@ -159,35 +159,11 @@ int vty_out(struct vty *vty, const char *format, ...)
vty_out(vty, "%s", vty->frame); vty_out(vty, "%s", vty->frame);
} }
/* Try to write to initial buffer. */
va_start(args, format); va_start(args, format);
len = vsnprintf(buf, sizeof(buf), format, args); p = vasnprintfrr(MTYPE_VTY_OUT_BUF, buf, sizeof(buf), format, args);
va_end(args); va_end(args);
/* Initial buffer is not enough. */ len = strlen(p);
if (len < 0 || len >= size) {
while (1) {
if (len > -1)
size = len + 1;
else
size = size * 2;
p = XREALLOC(MTYPE_VTY_OUT_BUF, p, size);
if (!p)
return -1;
va_start(args, format);
len = vsnprintf(p, size, format, args);
va_end(args);
if (len > -1 && len < size)
break;
}
}
/* When initial buffer is enough to store all output. */
if (!p)
p = buf;
/* filter buffer */ /* filter buffer */
if (vty->filter) { if (vty->filter) {
@ -274,8 +250,8 @@ done:
} }
static int vty_log_out(struct vty *vty, const char *level, static int vty_log_out(struct vty *vty, const char *level,
const char *proto_str, const char *format, const char *proto_str, const char *msg,
struct timestamp_control *ctl, va_list va) struct timestamp_control *ctl)
{ {
int ret; int ret;
int len; int len;
@ -300,7 +276,7 @@ static int vty_log_out(struct vty *vty, const char *level,
if ((ret < 0) || ((size_t)(len += ret) >= sizeof(buf))) if ((ret < 0) || ((size_t)(len += ret) >= sizeof(buf)))
return -1; return -1;
if (((ret = vsnprintf(buf + len, sizeof(buf) - len, format, va)) < 0) if (((ret = snprintf(buf + len, sizeof(buf) - len, "%s", msg)) < 0)
|| ((size_t)((len += ret) + 2) > sizeof(buf))) || ((size_t)((len += ret) + 2) > sizeof(buf)))
return -1; return -1;
@ -2552,8 +2528,8 @@ tmp_free_and_out:
} }
/* Small utility function which output log to the VTY. */ /* Small utility function which output log to the VTY. */
void vty_log(const char *level, const char *proto_str, const char *format, void vty_log(const char *level, const char *proto_str, const char *msg,
struct timestamp_control *ctl, va_list va) struct timestamp_control *ctl)
{ {
unsigned int i; unsigned int i;
struct vty *vty; struct vty *vty;
@ -2563,13 +2539,8 @@ void vty_log(const char *level, const char *proto_str, const char *format,
for (i = 0; i < vector_active(vtyvec); i++) for (i = 0; i < vector_active(vtyvec); i++)
if ((vty = vector_slot(vtyvec, i)) != NULL) if ((vty = vector_slot(vtyvec, i)) != NULL)
if (vty->monitor) { if (vty->monitor)
va_list ac; vty_log_out(vty, level, proto_str, msg, ctl);
va_copy(ac, va);
vty_log_out(vty, level, proto_str, format, ctl,
ac);
va_end(ac);
}
} }
/* Async-signal-safe version of vty_log for fixed strings. */ /* Async-signal-safe version of vty_log for fixed strings. */

View File

@ -313,8 +313,8 @@ extern void vty_time_print(struct vty *, int);
extern void vty_serv_sock(const char *, unsigned short, const char *); extern void vty_serv_sock(const char *, unsigned short, const char *);
extern void vty_close(struct vty *); extern void vty_close(struct vty *);
extern char *vty_get_cwd(void); extern char *vty_get_cwd(void);
extern void vty_log(const char *level, const char *proto, const char *fmt, extern void vty_log(const char *level, const char *proto, const char *msg,
struct timestamp_control *, va_list); struct timestamp_control *);
extern int vty_config_enter(struct vty *vty, bool private_config, extern int vty_config_enter(struct vty *vty, bool private_config,
bool exclusive); bool exclusive);
extern void vty_config_exit(struct vty *); extern void vty_config_exit(struct vty *);