diff --git a/lib/log.c b/lib/log.c index 5e3064a8d8..b799f7ea99 100644 --- a/lib/log.c +++ b/lib/log.c @@ -30,6 +30,7 @@ #include "command.h" #include "lib_errors.h" #include "lib/hook.h" +#include "printfrr.h" #ifndef SUNOS_5 #include @@ -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, 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); if (record_priority) fprintf(fp, "%s: ", zlog_priority[priority]); - fprintf(fp, "%s", proto_str); - va_copy(ac, args); - vfprintf(fp, format, ac); - va_end(ac); - fprintf(fp, "\n"); + fprintf(fp, "%s%s\n", proto_str, msg); fflush(fp); } @@ -217,33 +212,26 @@ void vzlog(int priority, const char *format, va_list args) struct timestamp_control tsctl; tsctl.already_rendered = 0; struct zlog *zl = zlog_default; + char buf[256], *msg; /* call external hook */ 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. */ if (zl == NULL) { tsctl.precision = 0; time_print(stderr, &tsctl); - fprintf(stderr, "%s: ", "unknown"); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + fprintf(stderr, "%s: %s\n", "unknown", msg); fflush(stderr); - - /* In this case we return at here. */ - errno = original_errno; - pthread_mutex_unlock(&loglock); - return; + goto out; } tsctl.precision = zl->timestamp_precision; /* Syslog output */ - if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) { - va_list ac; - va_copy(ac, args); - vsyslog(priority | zlog_default->facility, format, ac); - va_end(ac); - } + if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) + syslog(priority | zlog_default->facility, "%s", msg); if (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. */ if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) 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 * 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 * message to both stderr and stdout. */ if (zlog_startup_stderr && priority <= LOG_WARNING) - vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, format, - args); + vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, msg); else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, - stdout, format, args); + stdout, msg); /* Terminal monitor. */ if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) 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; pthread_mutex_unlock(&loglock); } diff --git a/lib/vty.c b/lib/vty.c index 8273d0e0c0..639307b507 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -42,6 +42,7 @@ #include "frrstr.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "printfrr.h" #include #include @@ -148,10 +149,9 @@ bool vty_set_include(struct vty *vty, const char *regexp) int vty_out(struct vty *vty, const char *format, ...) { va_list args; - int len = 0; - int size = 1024; + ssize_t len; char buf[1024]; - char *p = NULL; + char *p = buf; char *filtered; if (vty->frame_pos) { @@ -159,35 +159,11 @@ int vty_out(struct vty *vty, const char *format, ...) vty_out(vty, "%s", vty->frame); } - /* Try to write to initial buffer. */ 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); - /* Initial buffer is not enough. */ - 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; + len = strlen(p); /* filter buffer */ if (vty->filter) { @@ -274,8 +250,8 @@ done: } static int vty_log_out(struct vty *vty, const char *level, - const char *proto_str, const char *format, - struct timestamp_control *ctl, va_list va) + const char *proto_str, const char *msg, + struct timestamp_control *ctl) { int ret; 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))) 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))) return -1; @@ -2552,8 +2528,8 @@ tmp_free_and_out: } /* Small utility function which output log to the VTY. */ -void vty_log(const char *level, const char *proto_str, const char *format, - struct timestamp_control *ctl, va_list va) +void vty_log(const char *level, const char *proto_str, const char *msg, + struct timestamp_control *ctl) { unsigned int i; 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++) if ((vty = vector_slot(vtyvec, i)) != NULL) - if (vty->monitor) { - va_list ac; - va_copy(ac, va); - vty_log_out(vty, level, proto_str, format, ctl, - ac); - va_end(ac); - } + if (vty->monitor) + vty_log_out(vty, level, proto_str, msg, ctl); } /* Async-signal-safe version of vty_log for fixed strings. */ diff --git a/lib/vty.h b/lib/vty.h index 4847c9f189..035e758024 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -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_close(struct vty *); extern char *vty_get_cwd(void); -extern void vty_log(const char *level, const char *proto, const char *fmt, - struct timestamp_control *, va_list); +extern void vty_log(const char *level, const char *proto, const char *msg, + struct timestamp_control *); extern int vty_config_enter(struct vty *vty, bool private_config, bool exclusive); extern void vty_config_exit(struct vty *);