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 \
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
$(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)
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) {
} 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))
#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",
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);
# 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));
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 */
--- /dev/null
+/*
+ * 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);
+}