From 76418674b41e4d7520e647bd833a75e64a46a7c0 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 13 Aug 2011 13:33:52 -0400 Subject: [PATCH] Split out log file word wrap code into its own file. Fixes an off-by one in the word wrap when the log line length matches loglinelen. --HG-- branch : 1.7 --- Makefile.in | 22 +++++++++------- logging.c | 62 ++++++------------------------------------- logging.h | 6 +++++ logwrap.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 64 deletions(-) create mode 100644 logwrap.c diff --git a/Makefile.in b/Makefile.in index b16338b12..e5fbda7cb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -109,14 +109,14 @@ SRCS = aix.c alias.c alloc.c audit.c boottime.c bsm_audit.c check.c \ closefrom.c def_data.c defaults.c env.c error.c exec.c exec_pty.c \ fileops.c find_path.c fnmatch.c get_pty.c getcwd.c getprogname.c \ getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y interfaces.c \ - iolog.c isblank.c lbuf.c ldap.c linux_audit.c list.c logging.c match.c \ - mksiglist.c mkstemps.c memrchr.c nanosleep.c parse.c parse_args.c \ - pwutil.c set_perms.c setsid.c sigaction.c snprintf.c strcasecmp.c \ - strerror.c strlcat.c strlcpy.c strsignal.c sudo.c sudo_noexec.c \ - sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \ - toke_util.c tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c \ - redblack.c selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \ - timestr.c $(AUTH_SRCS) + iolog.c isblank.c lbuf.c ldap.c linux_audit.c list.c logging.c \ + logwrap.c match.c mksiglist.c mkstemps.c memrchr.c nanosleep.c parse.c \ + parse_args.c pwutil.c set_perms.c setsid.c sigaction.c snprintf.c \ + strcasecmp.c strerror.c strlcat.c strlcpy.c strsignal.c sudo.c \ + sudo_noexec.c sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c \ + toke.c toke.l toke_util.c tsgetgrpw.c utimes.c vasgroups.c visudo.c \ + zero_bytes.c redblack.c selinux.c sesh.c sudoreplay.c getdate.c \ + getdate.y getline.c timestr.c $(AUTH_SRCS) AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \ auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ @@ -138,8 +138,8 @@ COMMON_OBJS = alias.o alloc.o defaults.o error.o gram.o \ SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o boottime.o check.o env.o \ exec.o gettime.o goodpath.o fileops.o find_path.o \ - interfaces.o lbuf.o logging.o parse.o parse_args.o set_perms.o \ - sudo.o sudo_edit.o sudo_nss.o tgetpass.o + interfaces.o lbuf.o logging.o logwrap.o parse.o parse_args.o \ + set_perms.o sudo.o sudo_edit.o sudo_nss.o tgetpass.o VISUDO_OBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o @@ -335,6 +335,8 @@ list.o: $(srcdir)/list.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/list.c logging.o: $(srcdir)/logging.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/logging.c +logwrap.o: $(srcdir)/logwrap.c $(SUDODEP) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/logwrap.c match.o: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/match.c memrchr.o: $(srcdir)/memrchr.c $(SUDODEP) diff --git a/logging.c b/logging.c index d0aeab990..5d349f7a7 100644 --- a/logging.c +++ b/logging.c @@ -190,13 +190,12 @@ do_logfile(msg) char *msg; { char *full_line; - char *beg, *oldend, *end; - FILE *fp; + size_t len; mode_t oldmask; - size_t maxlen; + time_t now; + FILE *fp; oldmask = umask(077); - maxlen = def_loglinelen > 0 ? def_loglinelen : 0; fp = fopen(def_logfile, "a"); (void) umask(oldmask); if (fp == NULL) { @@ -204,8 +203,6 @@ do_logfile(msg) } else if (!lock_file(fileno(fp), SUDO_LOCK)) { send_mail("Can't lock log file: %s: %s", def_logfile, strerror(errno)); } else { - time_t now; - #ifdef HAVE_SETLOCALE const char *old_locale = estrdup(setlocale(LC_ALL, NULL)); if (!setlocale(LC_ALL, def_sudoers_locale)) @@ -213,7 +210,7 @@ do_logfile(msg) #endif /* HAVE_SETLOCALE */ now = time(NULL); - if (def_loglinelen == 0) { + if (def_loglinelen < sizeof(LOG_INDENT)) { /* Don't pretty-print long log file lines (hard to grep) */ if (def_log_host) (void) fprintf(fp, "%s : %s : HOST=%s : %s\n", @@ -223,59 +220,16 @@ do_logfile(msg) get_timestr(now, def_log_year), user_name, msg); } else { if (def_log_host) - easprintf(&full_line, "%s : %s : HOST=%s : %s", + len = easprintf(&full_line, "%s : %s : HOST=%s : %s", get_timestr(now, def_log_year), user_name, user_shost, msg); else - easprintf(&full_line, "%s : %s : %s", + len = easprintf(&full_line, "%s : %s : %s", get_timestr(now, def_log_year), user_name, msg); /* - * Print out full_line with word wrap + * Print out full_line with word wrap around def_loglinelen chars. */ - beg = end = full_line; - while (beg) { - oldend = end; - end = strchr(oldend, ' '); - - if (maxlen > 0 && end) { - *end = '\0'; - if (strlen(beg) > maxlen) { - /* too far, need to back up & print the line */ - - if (beg == (char *)full_line) - maxlen -= 4; /* don't indent first line */ - - *end = ' '; - if (oldend != beg) { - /* rewind & print */ - end = oldend-1; - while (*end == ' ') - --end; - *(++end) = '\0'; - (void) fprintf(fp, "%s\n ", beg); - *end = ' '; - } else { - (void) fprintf(fp, "%s\n ", beg); - } - - /* reset beg to point to the start of the new substr */ - beg = end; - while (*beg == ' ') - ++beg; - } else { - /* we still have room */ - *end = ' '; - } - - /* remove leading whitespace */ - while (*end == ' ') - ++end; - } else { - /* final line */ - (void) fprintf(fp, "%s\n", beg); - beg = NULL; /* exit condition */ - } - } + writeln_wrap(fp, full_line, len, def_loglinelen); efree(full_line); } (void) fflush(fp); diff --git a/logging.h b/logging.h index c95423ed4..619773445 100644 --- a/logging.h +++ b/logging.h @@ -47,6 +47,11 @@ # define MAXSYSLOGLEN 960 #endif +/* + * Indentation level for file-based logs when word wrap is enabled. + */ +#define LOG_INDENT " " + void audit_success __P((char *[])); void audit_failure __P((char *[], char const * const, ...)); void log_allowed __P((int)); @@ -54,5 +59,6 @@ void log_denial __P((int, int)); void log_error __P((int flags, const char *fmt, ...)) __printflike(2, 3); RETSIGTYPE reapchild __P((int)); +void writeln_wrap __P((FILE *, char *, size_t, size_t)); #endif /* _LOGGING_H */ diff --git a/logwrap.c b/logwrap.c new file mode 100644 index 000000000..f1a552f5b --- /dev/null +++ b/logwrap.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ + +#include "sudo.h" + +void +writeln_wrap(fp, line, len, maxlen) + FILE *fp; + char *line; + size_t len; + size_t maxlen; +{ + char *indent = ""; + char *beg = line; + char *end; + + /* + * Print out line with word wrap around maxlen characters. + */ + beg = line; + while (len > maxlen) { + end = beg + maxlen; + while (end != beg && *end != ' ') + end--; + if (beg == end) { + /* Unable to find word break within maxlen, look beyond. */ + end = strchr(beg + maxlen, ' '); + if (end == NULL) + break; /* no word break */ + } + fprintf(fp, "%s%.*s\n", indent, (int)(end - beg), beg); + while (*end == ' ') + end++; + len -= (end - beg); + beg = end; + if (indent[0] == '\0') { + indent = LOG_INDENT; + maxlen -= sizeof(LOG_INDENT) - 1; + } + } + /* Print remainder, if any. */ + if (len) + fprintf(fp, "%s%s\n", indent, beg); +} -- 2.40.0