diff -up cups-2.0.2/conf/cups-files.conf.in.rMbEsH cups-2.0.2/conf/cups-files.conf.in --- cups-2.0.2/conf/cups-files.conf.in.rMbEsH 2014-12-05 18:25:55.000000000 +0100 +++ cups-2.0.2/conf/cups-files.conf.in 2015-02-10 13:51:24.912193296 +0100 @@ -29,9 +29,10 @@ SystemGroup @CUPS_SYSTEM_GROUPS@ #ConfigFilePerm 0@CUPS_CONFIG_FILE_PERM@ #LogFilePerm 0@CUPS_LOG_FILE_PERM@ -# Location of the file logging all access to the scheduler; may be the name -# "syslog". If not an absolute path, the value of ServerRoot is used as the -# root directory. Also see the "AccessLogLevel" directive in cupsd.conf. +# Location of the file logging all access to the scheduler; may be the +# name "syslog" or "journal". If not an absolute path, the value of +# ServerRoot is used as the root directory. Also see the +# "AccessLogLevel" directive in cupsd.conf. AccessLog @CUPS_LOGDIR@/access_log # Location of cache files used by the scheduler... @@ -43,11 +44,11 @@ AccessLog @CUPS_LOGDIR@/access_log # Location of the static web content served by the scheduler... #DocumentRoot @CUPS_DOCROOT@ -# Location of the file logging all messages produced by the scheduler and any -# helper programs; may be the name "syslog". If not an absolute path, the value -# of ServerRoot is used as the root directory. Also see the "LogLevel" -# directive in cupsd.conf. -ErrorLog @CUPS_LOGDIR@/error_log +# Location of the file logging all messages produced by the scheduler +# and any helper programs; may be the name "syslog" or "journal". If +# not an absolute path, the value of ServerRoot is used as the root +# directory. Also see the "LogLevel" # directive in cupsd.conf. +ErrorLog journal # Location of fonts used by older print filters... #FontPath @CUPS_FONTPATH@ @@ -55,10 +56,10 @@ ErrorLog @CUPS_LOGDIR@/error_log # Location of LPD configuration #LPDConfigFile @CUPS_DEFAULT_LPD_CONFIG_FILE@ -# Location of the file logging all pages printed by the scheduler and any -# helper programs; may be the name "syslog". If not an absolute path, the value -# of ServerRoot is used as the root directory. Also see the "PageLogFormat" -# directive in cupsd.conf. +# Location of the file logging all pages printed by the scheduler and +# any helper programs; may be the name "syslog" or "journal". If not +# an absolute path, the value of ServerRoot is used as the root +# directory. Also see the "PageLogFormat" directive in cupsd.conf. PageLog @CUPS_LOGDIR@/page_log # Location of the file listing all of the local printers... diff -up cups-2.0.2/config-scripts/cups-startup.m4.rMbEsH cups-2.0.2/config-scripts/cups-startup.m4 --- cups-2.0.2/config-scripts/cups-startup.m4.rMbEsH 2014-12-09 23:18:45.000000000 +0100 +++ cups-2.0.2/config-scripts/cups-startup.m4 2015-02-10 13:51:24.912193296 +0100 @@ -56,11 +56,11 @@ if test x$enable_systemd != xno; then AC_MSG_ERROR(Need pkg-config to enable systemd support.) fi else - AC_MSG_CHECKING(for libsystemd-daemon) - if $PKGCONFIG --exists libsystemd-daemon; then + AC_MSG_CHECKING(for libsystemd) + if $PKGCONFIG --exists libsystemd; then AC_MSG_RESULT(yes) - ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd-daemon` - ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd-daemon` + ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd` + ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd` AC_DEFINE(HAVE_SYSTEMD) if test "x$SYSTEMD_DIR" = x; then SYSTEMD_DIR="`$PKGCONFIG --variable=systemdsystemunitdir systemd`" diff -up cups-2.0.2/doc/help/man-cups-files.conf.html.rMbEsH cups-2.0.2/doc/help/man-cups-files.conf.html --- cups-2.0.2/doc/help/man-cups-files.conf.html.rMbEsH 2015-02-10 13:51:24.977192375 +0100 +++ cups-2.0.2/doc/help/man-cups-files.conf.html 2015-02-10 13:52:36.839175089 +0100 @@ -24,6 +24,7 @@ The following directives are understood
AccessLog
AccessLog filename
AccessLog syslog +
AccessLog journal
Defines the access log filename. Specifying a blank filename disables access log generation. The value "syslog" causes log entries to be sent to the system log daemon. @@ -51,6 +52,7 @@ The default is usually "/usr/share/doc/c
ErrorLog
ErrorLog filename
ErrorLog syslog +
ErrorLog journal
Defines the error log filename. Specifying a blank filename disables error log generation. The value "syslog" causes log entries to be sent to the system log daemon. @@ -96,6 +98,7 @@ The default group is operating system sp The default is "0644".
PageLog [ filename ]
PageLog syslog +
PageLog journal
Defines the page log filename. The value "syslog" causes log entries to be sent to the system log daemon. Specifying a blank filename disables page log generation. diff -up cups-2.0.2/man/cups-files.conf.man.in.rMbEsH cups-2.0.2/man/cups-files.conf.man.in --- cups-2.0.2/man/cups-files.conf.man.in.rMbEsH 2015-02-02 19:38:25.000000000 +0100 +++ cups-2.0.2/man/cups-files.conf.man.in 2015-02-10 13:51:24.980192333 +0100 @@ -34,9 +34,13 @@ The following directives are understood \fBAccessLog \fIfilename\fR .TP 5 \fBAccessLog syslog\fR +.TP 5 +\fBAccessLog journal\fR Defines the access log filename. Specifying a blank filename disables access log generation. -The value "syslog" causes log entries to be sent to the system log daemon. +The value "syslog" causes log entries to be sent to the system log +daemon. The value "journal" causes log entries to be sent to the +systemd journal. The server name may be included in filenames using the string "%s", for example: .nf @@ -70,9 +74,13 @@ The default is usually "/usr/share/doc/c \fBErrorLog \fIfilename\fR .TP 5 \fBErrorLog syslog\fR +.TP 5 +\fBErrorLog journal\fR Defines the error log filename. Specifying a blank filename disables error log generation. -The value "syslog" causes log entries to be sent to the system log daemon. +The value "syslog" causes log entries to be sent to the system log +daemon. The value "journal" causes log entries to be sent to the +systemd journal. The server name may be included in filenames using the string "%s", for example: .nf @@ -135,8 +143,12 @@ The default is "0644". \fBPageLog \fR[ \fIfilename\fR ] .TP 5 \fBPageLog syslog\fR +.TP 5 +\fBPageLog journal\fR Defines the page log filename. -The value "syslog" causes log entries to be sent to the system log daemon. +The value "syslog" causes log entries to be sent to the system log +daemon. The value "journal" causes log entries to be sent to the +systemd journal. Specifying a blank filename disables page log generation. The server name may be included in filenames using the string "%s", for example: .nf diff -up cups-2.0.2/scheduler/conf.c.rMbEsH cups-2.0.2/scheduler/conf.c --- cups-2.0.2/scheduler/conf.c.rMbEsH 2015-02-10 13:40:24.057548432 +0100 +++ cups-2.0.2/scheduler/conf.c 2015-02-10 13:51:24.991192177 +0100 @@ -952,9 +952,9 @@ cupsdReadConfiguration(void) */ #ifdef HAVE_VSYSLOG - if (!strcmp(AccessLog, "syslog") || - !strcmp(ErrorLog, "syslog") || - !strcmp(PageLog, "syslog")) + if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal") || + !strcmp(ErrorLog, "syslog") || !strcmp(ErrorLog, "journal") || + !strcmp(PageLog, "syslog") || !strcmp(PageLog, "journal")) openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR); #endif /* HAVE_VSYSLOG */ @@ -962,13 +962,13 @@ cupsdReadConfiguration(void) * Make sure each of the log files exists and gets rotated as necessary... */ - if (strcmp(AccessLog, "syslog")) + if (strcmp(AccessLog, "syslog") && strcmp(AccessLog, "journal")) cupsdCheckLogFile(&AccessFile, AccessLog); - if (strcmp(ErrorLog, "syslog")) + if (strcmp(ErrorLog, "syslog") && strcmp(ErrorLog, "journal")) cupsdCheckLogFile(&ErrorFile, ErrorLog); - if (strcmp(PageLog, "syslog")) + if (strcmp(PageLog, "syslog") && strcmp(PageLog, "journal")) cupsdCheckLogFile(&PageFile, PageLog); /* diff -up cups-2.0.2/scheduler/conf.h.rMbEsH cups-2.0.2/scheduler/conf.h --- cups-2.0.2/scheduler/conf.h.rMbEsH 2015-02-10 13:40:24.057548432 +0100 +++ cups-2.0.2/scheduler/conf.h 2015-02-10 13:51:24.999192064 +0100 @@ -291,16 +291,69 @@ extern int cupsdLogGSSMessage(int level, OM_uint32 minor_status, const char *message, ...); #endif /* HAVE_GSSAPI */ -extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message, - ...) __attribute__((__format__(__printf__, 3, 4))); -extern int cupsdLogMessage(int level, const char *message, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); +extern int _cupsdLogJobWithLocation(const char *file, + const char *line, + const char *func, + cupsd_job_t *job, + int level, + const char *message, + ...) + __attribute__((__format__(__printf__, 6, 7))); +extern int _cupsdLogMessageWithLocation(const char *file, + const char *line, + const char *func, + int level, + const char *message, + ...) + __attribute__ ((__format__ (__printf__, 5, 6))); extern int cupsdLogPage(cupsd_job_t *job, const char *page); extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code); extern int cupsdReadConfiguration(void); -extern int cupsdWriteErrorLog(int level, const char *message); +extern int _cupsdWriteErrorLogJobWithLocation(const char *file, + const char *line, + const char *func, + cupsd_job_t *job, + int level, + const char *message); +extern int _cupsdWriteErrorLogWithLocation(const char *file, + const char *line, + const char *func, + int level, const char *message); +#ifndef _CUPSD_STRINGIFY +#define _CUPSD_XSTRINGIFY(x) #x +#define _CUPSD_STRINGIFY(x) _CUPSD_XSTRINGIFY(x) +#endif /* !defined(_CUPSD_STRINGIFY) */ + +#define cupsdLogJob(...) \ + _cupsdLogJobWithLocation("CODE_FILE=" __FILE__, \ + "CODE_LINE=" \ + _CUPSD_STRINGIFY(__LINE__), \ + __func__, \ + __VA_ARGS__) + +#define cupsdLogMessage(...) \ + _cupsdLogMessageWithLocation("CODE_FILE=" __FILE__, \ + "CODE_LINE=" \ + _CUPSD_STRINGIFY(__LINE__), \ + __func__, \ + __VA_ARGS__) + +#define cupsdWriteErrorLogJob(...) \ + _cupsdWriteErrorLogJobWithLocation("CODE_FILE=" __FILE__, \ + "CODE_LINE=" \ + _CUPSD_STRINGIFY(__LINE__), \ + __func__, \ + __VA_ARGS__) + +#define cupsdWriteErrorLog(...) \ + _cupsdWriteErrorLogWithLocation("CODE_FILE=" __FILE__, \ + "CODE_LINE=" \ + _CUPSD_STRINGIFY(__LINE__), \ + __func__, \ + __VA_ARGS__) + /* * End of "$Id: conf.h 11789 2014-04-02 16:52:53Z msweet $". */ diff -up cups-2.0.2/scheduler/log.c.rMbEsH cups-2.0.2/scheduler/log.c --- cups-2.0.2/scheduler/log.c.rMbEsH 2015-02-10 13:40:24.173546790 +0100 +++ cups-2.0.2/scheduler/log.c 2015-02-10 13:51:25.008191937 +0100 @@ -23,6 +23,12 @@ #include #include #include +#include +#ifdef HAVE_SYSTEMD +/* We handle location fields ourselves */ +# define SD_JOURNAL_SUPPRESS_LOCATION +# include +#endif /* HAVE_SYSTEMD */ /* @@ -509,15 +515,135 @@ cupsdLogClient(cupsd_client_t *con, /* I } +#ifdef HAVE_SYSTEMD +static int +dup_iovec_string(struct iovec *vec, + const char *str) +{ + vec->iov_base = strdup (str); + vec->iov_len = strlen (str); + return (vec->iov_base ? 1 : 0); +} + + +/* + * '_cupsdLogToJournal()' - Log to journal with fields + */ +static int /* O - 1 on success, 0 on error */ +_cupsdLogToJournal(const char *file, /* I - Code file */ + const char *line, /* I - Code line */ + const char *func, /* I - Code func */ + cupsd_job_t *job, /* I - Job or NULL */ + int level, /* I - Log level */ + const char *message)/* I - Formatted message */ +{ + size_t n_journal_fields; + struct iovec *journal_fields = NULL; + char buffer[256]; + int result = 1; + + /* + * There will be at least 5 fields: + * CODE_FILE, CODE_LINE, CODE_FUNC, MESSAGE, PRIORITY + */ + + n_journal_fields = 5; + + if (job) + { + n_journal_fields++; /* CUPS_JOB_ID */ + + if (job->dest) + n_journal_fields++; /* CUPS_DEST */ + + if (job->printer) + n_journal_fields++; /* CUPS_PRINTER */ + } + + journal_fields = calloc (n_journal_fields, sizeof (struct iovec)); + if (!journal_fields) + return (0); + + n_journal_fields = 0; + + result = dup_iovec_string (&journal_fields[n_journal_fields], file); + + if (result) + { + n_journal_fields++; + result = dup_iovec_string (&journal_fields[n_journal_fields], line); + } + + if (result) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "CODE_FUNC=%s", func); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + } + + if (result) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "MESSAGE=%s", log_line); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + } + + if (result) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "PRIORITY=%i", syslevels[level]); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + } + + if (result && job) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "CUPS_JOB_ID=%d", job->id); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + + if (result && job->dest) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "CUPS_DEST=%s", job->dest); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + } + + if (result && job->printer) + { + n_journal_fields++; + snprintf (buffer, sizeof (buffer), "CUPS_PRINTER=%s", + job->printer->name); + result = dup_iovec_string (&journal_fields[n_journal_fields], buffer); + } + } + + if (result) + { + n_journal_fields++; + result = sd_journal_sendv (journal_fields, n_journal_fields); + } + + while (n_journal_fields > 0) + free (journal_fields[--n_journal_fields].iov_base); + + free (journal_fields); + return (result); +} +#endif /* HAVE_SYSTEMD */ + + /* * 'cupsdLogJob()' - Log a job message. */ -int /* O - 1 on success, 0 on error */ -cupsdLogJob(cupsd_job_t *job, /* I - Job */ - int level, /* I - Log level */ - const char *message, /* I - Printf-style message string */ - ...) /* I - Additional arguments as needed */ +int /* O - 1 on success, 0 on error */ +_cupsdLogJobWithLocation(const char *file, /* I - Code file */ + const char *line, /* I - Code line */ + const char *func, /* I - Code func */ + cupsd_job_t *job, /* I - Job */ + int level, /* I - Log level */ + const char *message, /* I - Printf-style message string */ + ...) /* I - Additional arguments as needed */ { va_list ap, ap2; /* Argument pointers */ char jobmsg[1024]; /* Format string for job message */ @@ -603,8 +729,14 @@ cupsdLogJob(cupsd_job_t *job, /* I - Jo } else if (level <= LogLevel && (level != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG)) - return (cupsdWriteErrorLog(level, log_line)); - else + { +#ifdef HAVE_SYSTEMD + if (!strcmp (ErrorLog, "journal")) + return (_cupsdLogToJournal (file, line, func, job, level, log_line)); + else +#endif /* HAVE_SYSTEMD */ + return (cupsdWriteErrorLog(level, log_line)); + } else return (1); } else @@ -617,10 +749,13 @@ cupsdLogJob(cupsd_job_t *job, /* I - Jo * 'cupsdLogMessage()' - Log a message to the error log file. */ -int /* O - 1 on success, 0 on error */ -cupsdLogMessage(int level, /* I - Log level */ - const char *message, /* I - printf-style message string */ - ...) /* I - Additional args as needed */ +int /* O - 1 on success, 0 on error */ +_cupsdLogMessageWithLocation(const char *file, /* I - Code file */ + const char *line, /* I - Code line */ + const char *func, /* I - Code func */ + int level, /* I - Log level */ + const char *message, /* I - printf-style message string */ + ...) /* I - Additional args as needed */ { va_list ap, ap2; /* Argument pointers */ int status; /* Formatting status */ @@ -664,10 +799,10 @@ cupsdLogMessage(int level, /* I - va_end(ap); if (status > 0) - return (cupsdWriteErrorLog(level, log_line)); + return (_cupsdWriteErrorLogWithLocation(file, line, func, level, log_line)); else - return (cupsdWriteErrorLog(CUPSD_LOG_ERROR, - "Unable to allocate memory for log line!")); + return (_cupsdWriteErrorLogWithLocation(file, line, func, CUPSD_LOG_ERROR, + "Unable to allocate memory for log line!")); } @@ -860,6 +995,17 @@ cupsdLogPage(cupsd_job_t *job, /* I - J *bufptr = '\0'; +#ifdef HAVE_SYSTEMD + if (!strcmp(PageLog, "journal")) + return (sd_journal_send ("MESSAGE=%s", buffer, + "PRIORITY=%d", LOG_INFO, + "CUPS_JOB_ID=%d", job->id, + "CUPS_DEST=%s", job->dest, + "CUPS_PRINTER=%s", job->printer->name, + "CUPS_PAGE_NUMBER=%s", number, + NULL) ? 0 : 1); +#endif /* HAVE_SYSTEMD */ + #ifdef HAVE_VSYSLOG /* * See if we are logging pages via syslog... @@ -1037,7 +1183,7 @@ cupsdLogRequest(cupsd_client_t *con, /* * See if we are logging accesses via syslog... */ - if (!strcmp(AccessLog, "syslog")) + if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal")) { syslog(LOG_INFO, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n", @@ -1091,8 +1237,12 @@ cupsdLogRequest(cupsd_client_t *con, /* */ int /* O - 1 on success, 0 on failure */ -cupsdWriteErrorLog(int level, /* I - Log level */ - const char *message) /* I - Message string */ +_cupsdWriteErrorLogJobWithLocation(const char *file, /* I - Code file */ + const char *line, /* I - Code line */ + const char *func, /* I - Code func */ + cupsd_job_t *job, /* I - Job or NULL */ + int level, /* I - Log level */ + const char *message) /* I - Message string */ { int ret = 1; /* Return value */ static const char levels[] = /* Log levels... */ @@ -1110,6 +1260,10 @@ cupsdWriteErrorLog(int level, /* }; +#ifdef HAVE_SYSTEMD + if (!strcmp(ErrorLog, "journal")) + return (_cupsdLogToJournal (file, line, func, job, level, message)); +#endif /* HAVE_SYSTEMD */ #ifdef HAVE_VSYSLOG /* * See if we are logging errors via syslog... @@ -1149,6 +1303,22 @@ cupsdWriteErrorLog(int level, /* } +/* + * 'cupsdWriteErrorLog()' - Write a line to the ErrorLog. + */ + +int /* O - 1 on success, 0 on failure */ +_cupsdWriteErrorLogWithLocation(const char *file, /* I - Code file */ + const char *line, /* I - Code line */ + const char *func, /* I - Code func */ + int level, /* I - Log level */ + const char *message) /* I - Message string */ +{ + return (_cupsdWriteErrorLogJobWithLocation(file, line, func, + NULL, level, message)); +} + + /* * 'format_log_line()' - Format a line for a log file. *