diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 9d8411f63..fa6439536 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -176,14 +176,16 @@ do_syslog(int pri, char *msg) #endif /* HAVE_SETLOCALE */ } +#define LOG_INDENT " " + static void do_logfile(char *msg) { - char *full_line; - char *beg, *oldend, *end; - FILE *fp; + char *full_line, *beg, *end, *indent = ""; + size_t len, maxlen; mode_t oldmask; - size_t maxlen; + time_t now; + FILE *fp; oldmask = umask(077); maxlen = def_loglinelen > 0 ? def_loglinelen : 0; @@ -196,8 +198,6 @@ do_logfile(char *msg) send_mail(_("unable to 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)) @@ -205,7 +205,7 @@ do_logfile(char *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", @@ -215,59 +215,39 @@ do_logfile(char *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 maxlen characters. */ - 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 */ + beg = full_line; + while (len > maxlen) { + end = beg + maxlen + 1; + while (end != beg && *end != ' ') + end--; + if (beg == end) { + /* Unable to find word break within maxlen, look beyond. */ + end = strchr(beg + maxlen + 1, ' '); + 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); efree(full_line); } (void) fflush(fp);