]> granicus.if.org Git - sudo/commitdiff
Split out log file word wrap code into its own file. Fixes an
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2011 17:33:52 +0000 (13:33 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2011 17:33:52 +0000 (13:33 -0400)
off-by one in the word wrap when the log line length matches
loglinelen.

--HG--
branch : 1.7

Makefile.in
logging.c
logging.h
logwrap.c [new file with mode: 0644]

index b16338b12a3a2ae6a6b4260506067a9c5e7e0441..e5fbda7cb44aedb0f8be8aa56819f7e37299a7c8 100644 (file)
@@ -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)
index d0aeab9906f3836f972a55b23a1e2608171e0e06..5d349f7a79c0e86fcc8c24ecf391c8158815c032 100644 (file)
--- 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);
index c95423ed4ccdcc89d253af435ebd3aa22711de53..619773445a6cc07f312d5456d03356de22ff6d44 100644 (file)
--- a/logging.h
+++ b/logging.h
 # 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 (file)
index 0000000..f1a552f
--- /dev/null
+++ b/logwrap.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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 <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#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);
+}