--------------------- PatchSet 11672 Date: 2007/09/18 15:03:03 Author: adrian Branch: HEAD Tag: (none) Log: Logging daemons Members: src/logfile-daemon.c:1.8->1.9 src/logfile_mod_daemon.c:INITIAL->1.1 src/logfile_mod_daemon.h:INITIAL->1.1 src/logfile_mod_stdio.c:INITIAL->1.1 src/logfile_mod_stdio.h:INITIAL->1.1 src/logfile_mod_syslog.c:INITIAL->1.1 src/logfile_mod_syslog.h:INITIAL->1.1 --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile-daemon.c Tue Sep 18 15:52:18 2007 @@ -0,0 +1,159 @@ +#include "config.h" + +#if HAVE_STDIO_H +#include +#endif +#if HAVE_STDLIB_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_FCNTL_H +#include +#endif +#if HAVE_ASSERT_H +#include +#endif +#if HAVE_SYS_PARAM_H +#include +#endif +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_STRING_H +#include +#endif +#if HAVE_PATHS_H +#include +#endif + +#include "defines.h" + +#define SQUID_MAXPATHLEN 256 +#ifndef MAXPATHLEN +#define MAXPATHLEN SQUID_MAXPATHLEN +#endif + +/* parse buffer - ie, length of longest expected line */ +#define LOGFILE_BUF_LEN 65536 + +static void +rotate(const char *path, int rotate_count) +{ +#ifdef S_ISREG + struct stat sb; +#endif + int i; + char from[MAXPATHLEN]; + char to[MAXPATHLEN]; + assert(path); +#ifdef S_ISREG + if (stat(path, &sb) == 0) + if (S_ISREG(sb.st_mode) == 0) + return; +#endif + /* Rotate numbers 0 through N up one */ + for (i = rotate_count; i > 1;) { + i--; + snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", path, i); +#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_) + remove(to); +#endif + rename(from, to); + } + if (rotate_count > 0) { + snprintf(to, MAXPATHLEN, "%s.%d", path, 0); +#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_) + remove(to); +#endif + rename(path, to); + } +} + +/* + * The commands: + * + * L\n - logfile data + * R\n - rotate file + * T\n - truncate file + * O\n - repoen file + * F\n - flush file + * r\n - set rotate count to + * b\n - 1 = buffer output, 0 = don't buffer output + */ +int +main(int argc, char *argv[]) +{ + int t; + FILE *fp; + char buf[LOGFILE_BUF_LEN]; + int rotate_count = 10; + int do_buffer = 1; + + if (argc < 2) { + printf("Error: usage: %s \n", argv[0]); + exit(1); + } + fp = fopen(argv[1], "a"); + if (fp == NULL) { + perror("fopen"); + exit(1); + } + setbuf(stdout, NULL); + close(2); + t = open(_PATH_DEVNULL, O_RDWR); + assert(t > -1); + dup2(t, 2); + + while (fgets(buf, LOGFILE_BUF_LEN, stdin)) { + /* First byte indicates what we're logging! */ + switch (buf[0]) { + case 'L': + if (buf[1] != '\0') { + fprintf(fp, "%s", buf + 1); + } + if (!do_buffer) + fflush(fp); + break; + case 'R': + fclose(fp); + rotate(argv[1], rotate_count); + fp = fopen(argv[1], "a"); + if (fp == NULL) { + perror("fopen"); + exit(1); + } + break; + case 'T': + break; + case 'O': + break; + case 'r': + //fprintf(fp, "SET ROTATE: %s\n", buf + 1); + rotate_count = atoi(buf + 1); + break; + case 'b': + //fprintf(fp, "SET BUFFERED: %s\n", buf + 1); + do_buffer = (buf[1] == '1'); + break; + case 'F': + fflush(fp); + break; + default: + /* Just in case .. */ + fprintf(fp, "%s", buf); + break; + } + } + fclose(fp); + fp = NULL; + exit(0); +} --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_daemon.c Tue Sep 18 15:52:18 2007 @@ -0,0 +1,354 @@ +/* + * $Id: logfile_mod_daemon.c,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#include "logfile_mod_daemon.h" + +/* How many buffers to keep before we say we've buffered too much */ +#define LOGFILE_MAXBUFS 128 + +/* Size of the logfile buffer */ +/* + * For optimal performance this should match LOGFILE_BUFSIZ in logfile-daemon.c + */ +#define LOGFILE_BUFSZ 32768 + +/* How many seconds between warnings */ +#define LOGFILE_WARN_TIME 30 + +static LOGWRITE logfile_mod_daemon_writeline; +static LOGLINESTART logfile_mod_daemon_linestart; +static LOGLINEEND logfile_mod_daemon_lineend; +static LOGROTATE logfile_mod_daemon_rotate; +static LOGFLUSH logfile_mod_daemon_flush; +static LOGCLOSE logfile_mod_daemon_close; + +static void logfile_mod_daemon_append(Logfile * lf, const char *buf, int len); + +struct _l_daemon { + int rfd, wfd; + char eol; + pid_t pid; + int flush_pending; + dlink_list bufs; + int nbufs; + int last_warned; +}; + +typedef struct _l_daemon l_daemon_t; + +/* Internal code */ +static void +logfileNewBuffer(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + logfile_buffer_t *b; + + debug(50, 5) ("logfileNewBuffer: %s: new buffer\n", lf->path); + + b = xcalloc(1, sizeof(logfile_buffer_t)); + assert(b != NULL); + b->buf = xcalloc(1, LOGFILE_BUFSZ); + assert(b->buf != NULL); + b->size = LOGFILE_BUFSZ; + b->written_len = 0; + b->len = 0; + dlinkAddTail(b, &b->node, &ll->bufs); + ll->nbufs++; +} + +static void +logfileFreeBuffer(Logfile * lf, logfile_buffer_t * b) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + assert(b != NULL); + dlinkDelete(&b->node, &ll->bufs); + ll->nbufs--; + xfree(b->buf); + xfree(b); +} + +static void +logfileHandleWrite(int fd, void *data) +{ + Logfile *lf = (Logfile *) data; + l_daemon_t *ll = (l_daemon_t *) lf->data; + int ret; + logfile_buffer_t *b; + + /* + * We'll try writing the first entry until its done - if we + * get a partial write then we'll re-schedule until its completed. + * Its naive but it'll do for now. + */ + b = ll->bufs.head->data; + assert(b != NULL); + ll->flush_pending = 0; + + ret = FD_WRITE_METHOD(ll->wfd, b->buf + b->written_len, b->len - b->written_len); + debug(50, 3) ("logfileHandleWrite: %s: write returned %d\n", lf->path, ret); + if (ret < 0) { + if (ignoreErrno(errno)) { + /* something temporary */ + goto reschedule; + } + debug(50, 1) ("logfileHandleWrite: %s: error writing (%s)\n", lf->path, xstrerror()); + /* XXX should handle this better */ + fatal("I don't handle this error well!"); + } + if (ret == 0) { + /* error? */ + debug(50, 1) ("logfileHandleWrite: %s: wrote 0 bytes?\n", lf->path); + /* XXX should handle this better */ + fatal("I don't handle this error well!"); + } + /* ret > 0, so something was written */ + b->written_len += ret; + assert(b->written_len <= b->len); + if (b->written_len == b->len) { + /* written the whole buffer! */ + logfileFreeBuffer(lf, b); + b = NULL; + } + /* Is there more to write? */ + if (ll->bufs.head == NULL) { + goto finish; + } + /* there is, so schedule more */ + + reschedule: + commSetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0); + ll->flush_pending = 1; + finish: + return; +} + +static void +logfileQueueWrite(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + if (ll->flush_pending || ll->bufs.head == NULL) { + return; + } + ll->flush_pending = 1; + if (ll->bufs.head) { + logfile_buffer_t *b = ll->bufs.head->data; + if (b->len + 2 <= b->size) + logfile_mod_daemon_append(lf, "F\n", 2); + } + /* Ok, schedule a write-event */ + commSetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0); +} + +static void +logfile_mod_daemon_append(Logfile * lf, const char *buf, int len) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + logfile_buffer_t *b; + int s; + + /* Is there a buffer? If not, create one */ + if (ll->bufs.head == NULL) { + logfileNewBuffer(lf); + } + debug(50, 3) ("logfile_mod_daemon_append: %s: appending %d bytes\n", lf->path, len); + /* Copy what can be copied */ + while (len > 0) { + b = ll->bufs.tail->data; + debug(50, 3) ("logfile_mod_daemon_append: current buffer has %d of %d bytes before append\n", b->len, b->size); + s = XMIN(len, (b->size - b->len)); + xmemcpy(b->buf + b->len, buf, s); + len = len - s; + buf = buf + s; + b->len = b->len + s; + assert(b->len <= LOGFILE_BUFSZ); + assert(len >= 0); + if (len > 0) { + logfileNewBuffer(lf); + } + } +} + +/* + * only schedule a flush (write) if one isn't scheduled. + */ +static void +logfileFlushEvent(void *data) +{ + Logfile *lf = (Logfile *) data; + + /* + * This might work better if we keep track of when we wrote last and only + * schedule a write if we haven't done so in the last second or two. + */ + logfileQueueWrite(lf); + eventAdd("logfileFlush", logfileFlushEvent, lf, 1.0, 1); +} + + +/* External code */ + +int +logfile_mod_daemon_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag) +{ + const char *args[5]; + char *tmpbuf; + l_daemon_t *ll; + + cbdataLock(lf); + debug(50, 1) ("Logfile Daemon: opening log %s\n", path); + ll = xcalloc(1, sizeof(*ll)); + lf->data = ll; + ll->eol = 1; + { + args[0] = "(logfile-daemon)"; + args[1] = path; + args[2] = NULL; + ll->pid = ipcCreate(IPC_STREAM, Config.Program.logfile_daemon, args, "logfile-daemon", &ll->rfd, &ll->wfd, NULL); + if (ll->pid < 0) + fatal("Couldn't start logfile helper"); + } + ll->nbufs = 0; + + /* Queue the initial control data */ + tmpbuf = (char *) xmalloc(BUFSIZ); + snprintf(tmpbuf, BUFSIZ, "r%d\nb%d\n", Config.Log.rotateNumber, Config.onoff.buffered_logs); + logfile_mod_daemon_append(lf, tmpbuf, strlen(tmpbuf)); + xfree(tmpbuf); + + /* Start the flush event */ + eventAdd("logfileFlush", logfileFlushEvent, lf, 1.0, 1); + + lf->f_close = logfile_mod_daemon_close; + lf->f_linewrite = logfile_mod_daemon_writeline; + lf->f_linestart = logfile_mod_daemon_linestart; + lf->f_lineend = logfile_mod_daemon_lineend; + lf->f_flush = logfile_mod_daemon_flush; + lf->f_rotate = logfile_mod_daemon_rotate; + + return 1; +} + +static void +logfile_mod_daemon_close(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + debug(50, 1) ("Logfile Daemon: closing log %s\n", lf->path); + logfileFlush(lf); + fd_close(ll->rfd); + fd_close(ll->wfd); + kill(ll->pid, SIGTERM); + eventDelete(logfileFlushEvent, lf); + xfree(ll); + lf->data = NULL; + cbdataUnlock(lf); +} + +static void +logfile_mod_daemon_rotate(Logfile * lf) +{ + char tb[3]; + debug(50, 1) ("logfileRotate: %s\n", lf->path); + tb[0] = 'R'; + tb[1] = '\n'; + tb[2] = '\0'; + logfile_mod_daemon_append(lf, tb, 2); +} + +/* + * This routine assumes that up to one line is written. Don't try to + * call this routine with more than one line or subsequent lines + * won't be prefixed with the command type and confuse the logging + * daemon somewhat. + */ +static void +logfile_mod_daemon_writeline(Logfile * lf, const char *buf, size_t len) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + /* Make sure the logfile buffer isn't too large */ + if (ll->nbufs > LOGFILE_MAXBUFS) { + if (ll->last_warned < squid_curtime - LOGFILE_WARN_TIME) { + ll->last_warned = squid_curtime; + debug(50, 1) ("Logfile: %s: queue is too large; some log messages have been lost.\n", lf->path); + } + return; + } + /* Append this data to the end buffer; create a new one if needed */ + /* Are we eol? If so, prefix with our logfile command byte */ + logfile_mod_daemon_append(lf, buf, len); +} + +static void +logfile_mod_daemon_linestart(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + char tb[2]; + assert(ll->eol == 1); + ll->eol = 0; + tb[0] = 'L'; + tb[1] = '\0'; + logfile_mod_daemon_append(lf, tb, 1); +} + +static void +logfile_mod_daemon_lineend(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + logfile_buffer_t *b; + assert(ll->eol == 0); + ll->eol = 1; + /* Kick a write off if the head buffer is -full- */ + if (ll->bufs.head != NULL) { + b = ll->bufs.head->data; + if (b->node.next != NULL || !Config.onoff.buffered_logs) + logfileQueueWrite(lf); + } +} + +static void +logfile_mod_daemon_flush(Logfile * lf) +{ + l_daemon_t *ll = (l_daemon_t *) lf->data; + if (commUnsetNonBlocking(ll->wfd)) { + debug(50, 1) ("Logfile Daemon: Couldn't set the pipe blocking for flush! You're now missing some log entries.\n"); + return; + } + while (ll->bufs.head != NULL) { + logfileHandleWrite(ll->wfd, lf); + } + if (commSetNonBlocking(ll->wfd)) { + fatalf("Logfile Daemon: %s: Couldn't set the pipe non-blocking for flush!\n", lf->path); + return; + } +} --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_daemon.h Tue Sep 18 15:52:18 2007 @@ -0,0 +1,35 @@ +/* + * $Id: logfile_mod_daemon.h,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +extern int logfile_mod_daemon_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag); --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_stdio.c Tue Sep 18 15:52:18 2007 @@ -0,0 +1,223 @@ +/* + * $Id: logfile_mod_stdio.c,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#include "logfile_mod_stdio.h" + +typedef struct { + int fd; + char *buf; + int bufsz; + int offset; +} l_stdio_t; + +/* + * Aborts with fatal message if write() returns something other + * than its length argument. + */ +static void +logfileWriteWrapper(Logfile * lf, const void *buf, size_t len) +{ + l_stdio_t *ll = (l_stdio_t *) lf->data; + size_t s; + s = FD_WRITE_METHOD(ll->fd, (char const *) buf, len); + fd_bytes(ll->fd, s, FD_WRITE); + + if (s == len) + return; + + if (!lf->flags.fatal) + return; + + fatalf("logfileWrite (stdio): %s: %s\n", lf->path, xstrerror()); +} + +static void +logfile_mod_stdio_writeline(Logfile * lf, const char *buf, size_t len) +{ + l_stdio_t *ll = (l_stdio_t *) lf->data; + + if (0 == ll->bufsz) { + /* buffering disabled */ + logfileWriteWrapper(lf, buf, len); + return; + } + if (ll->offset > 0 && ll->offset + len > ll->bufsz) + logfileFlush(lf); + + if (len > ll->bufsz) { + /* too big to fit in buffer */ + logfileWriteWrapper(lf, buf, len); + return; + } + /* buffer it */ + xmemcpy(ll->buf + ll->offset, buf, len); + + ll->offset += len; + + assert(ll->offset >= 0); + + assert((size_t) ll->offset <= ll->bufsz); +} + +static void +logfile_mod_stdio_linestart(Logfile * lf) +{ +} + +static void +logfile_mod_stdio_lineend(Logfile * lf) +{ + lf->f_flush(lf); +} + +static void +logfile_mod_stdio_flush(Logfile * lf) +{ + l_stdio_t *ll = (l_stdio_t *) lf->data; + if (0 == ll->offset) + return; + logfileWriteWrapper(lf, ll->buf, (size_t) ll->offset); + ll->offset = 0; +} + +static void +logfile_mod_stdio_rotate(Logfile * lf) +{ +#ifdef S_ISREG + + struct stat sb; +#endif + + int i; + char from[MAXPATHLEN]; + char to[MAXPATHLEN]; + l_stdio_t *ll = (l_stdio_t *) lf->data; + assert(lf->path); + +#ifdef S_ISREG + + if (stat(lf->path, &sb) == 0) + if (S_ISREG(sb.st_mode) == 0) + return; + +#endif + + debug(0, 1) ("logfileRotate (stdio): %s\n", lf->path); + + /* Rotate numbers 0 through N up one */ + for (i = Config.Log.rotateNumber; i > 1;) { + i--; + snprintf(from, MAXPATHLEN, "%s.%d", lf->path, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", lf->path, i); + xrename(from, to); + } + + /* Rotate the current log to .0 */ + logfileFlush(lf); + + file_close(ll->fd); /* always close */ + + if (Config.Log.rotateNumber > 0) { + snprintf(to, MAXPATHLEN, "%s.%d", lf->path, 0); + xrename(lf->path, to); + } + /* Reopen the log. It may have been renamed "manually" */ + ll->fd = file_open(lf->path, O_WRONLY | O_CREAT | O_TEXT); + + if (DISK_ERROR == ll->fd && lf->flags.fatal) { + debug(50, 1) ("logfileRotate (stdio): %s: %s\n", lf->path, xstrerror()); + fatalf("Cannot open %s: %s", lf->path, xstrerror()); + } +} + +static void +logfile_mod_stdio_close(Logfile * lf) +{ + l_stdio_t *ll = (l_stdio_t *) lf->data; + lf->f_flush(lf); + + if (ll->fd >= 0) + file_close(ll->fd); + + if (ll->buf) + xfree(ll->buf); + + xfree(lf->data); + lf->data = NULL; +} + + + +/* + * This code expects the path to be syslog: + */ +int +logfile_mod_stdio_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag) +{ + l_stdio_t *ll; + + ll = xcalloc(1, sizeof(*ll)); + lf->data = ll; + + ll->fd = file_open(path, O_WRONLY | O_CREAT | O_TEXT); + + if (DISK_ERROR == ll->fd) { + if (ENOENT == errno && fatal_flag) { + fatalf("Cannot open '%s' because\n" + "\tthe parent directory does not exist.\n" + "\tPlease create the directory.\n", path); + } else if (EACCES == errno && fatal_flag) { + fatalf("Cannot open '%s' for writing.\n" + "\tThe parent directory must be writeable by the\n" + "\tuser '%s', which is the cache_effective_user\n" + "\tset in squid.conf.", path, Config.effectiveUser); + } else { + debug(50, 1) ("logfileOpen (stdio): %s: %s\n", path, xstrerror()); + return 0; + } + } + if (bufsz > 0) { + ll->buf = (char *) xmalloc(bufsz); + ll->bufsz = bufsz; + } + lf->f_close = logfile_mod_stdio_close; + lf->f_linewrite = logfile_mod_stdio_writeline; + lf->f_linestart = logfile_mod_stdio_linestart; + lf->f_lineend = logfile_mod_stdio_lineend; + lf->f_flush = logfile_mod_stdio_flush; + lf->f_rotate = logfile_mod_stdio_rotate; + + return 1; +} --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_stdio.h Tue Sep 18 15:52:18 2007 @@ -0,0 +1,35 @@ +/* + * $Id: logfile_mod_stdio.h,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +extern int logfile_mod_stdio_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag); --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_syslog.c Tue Sep 18 15:52:18 2007 @@ -0,0 +1,187 @@ +/* + * $Id: logfile_mod_syslog.c,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#if HAVE_SYSLOG +#include "logfile_mod_syslog.h" + +/* Define LOG_AUTHPRIV as LOG_AUTH on systems still using the old deprecated LOG_AUTH */ +#if !defined(LOG_AUTHPRIV) && defined(LOG_AUTH) +#define LOG_AUTHPRIV LOG_AUTH +#endif + +typedef struct { + const char *name; + int value; +} syslog_symbol_t; + +static int +syslog_ntoa(const char *s) +{ +#define syslog_symbol(a) #a, a + static syslog_symbol_t symbols[] = + { +#ifdef LOG_AUTHPRIV + {syslog_symbol(LOG_AUTHPRIV)}, +#endif +#ifdef LOG_DAEMON + {syslog_symbol(LOG_DAEMON)}, +#endif +#ifdef LOG_LOCAL0 + {syslog_symbol(LOG_LOCAL0)}, +#endif +#ifdef LOG_LOCAL1 + {syslog_symbol(LOG_LOCAL1)}, +#endif +#ifdef LOG_LOCAL2 + {syslog_symbol(LOG_LOCAL2)}, +#endif +#ifdef LOG_LOCAL3 + {syslog_symbol(LOG_LOCAL3)}, +#endif +#ifdef LOG_LOCAL4 + {syslog_symbol(LOG_LOCAL4)}, +#endif +#ifdef LOG_LOCAL5 + {syslog_symbol(LOG_LOCAL5)}, +#endif +#ifdef LOG_LOCAL6 + {syslog_symbol(LOG_LOCAL6)}, +#endif +#ifdef LOG_LOCAL7 + {syslog_symbol(LOG_LOCAL7)}, +#endif +#ifdef LOG_USER + {syslog_symbol(LOG_USER)}, +#endif +#ifdef LOG_ERR + {syslog_symbol(LOG_ERR)}, +#endif +#ifdef LOG_WARNING + {syslog_symbol(LOG_WARNING)}, +#endif +#ifdef LOG_NOTICE + {syslog_symbol(LOG_NOTICE)}, +#endif +#ifdef LOG_INFO + {syslog_symbol(LOG_INFO)}, +#endif +#ifdef LOG_DEBUG + {syslog_symbol(LOG_DEBUG)}, +#endif + {NULL, 0} + }; + syslog_symbol_t *p; + + for (p = symbols; p->name != NULL; ++p) + if (!strcmp(s, p->name) || !strcmp(s, p->name + 4)) + return p->value; + return 0; +} + +typedef struct { + int syslog_priority; +} l_syslog_t; + +#define PRIORITY_MASK (LOG_ERR | LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG) + +static void +logfile_mod_syslog_writeline(Logfile * lf, const char *buf, size_t len) +{ + l_syslog_t *ll = (l_syslog_t *) lf->data; + syslog(ll->syslog_priority, "%s", (char *) buf); +} + +static void +logfile_mod_syslog_linestart(Logfile * lf) +{ +} + +static void +logfile_mod_syslog_lineend(Logfile * lf) +{ +} + +static void +logfile_mod_syslog_flush(Logfile * lf) +{ +} + +static void +logfile_mod_syslog_rotate(Logfile * lf) +{ +} + +static void +logfile_mod_syslog_close(Logfile * lf) +{ + xfree(lf->data); + lf->data = NULL; +} + + + +/* + * This code expects the path to be syslog: + */ +int +logfile_mod_syslog_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag) +{ + l_syslog_t *ll; + + ll = xcalloc(1, sizeof(*ll)); + lf->data = ll; + + if (path[6] != '\0') { + const char *priority = path + 7; + char *facility = (char *) strchr(priority, '|'); + if (facility) { + *facility++ = '\0'; + ll->syslog_priority |= syslog_ntoa(facility); + } + ll->syslog_priority |= syslog_ntoa(priority); + } + if ((ll->syslog_priority & PRIORITY_MASK) == 0) + ll->syslog_priority |= LOG_INFO; + + lf->f_close = logfile_mod_syslog_close; + lf->f_linewrite = logfile_mod_syslog_writeline; + lf->f_linestart = logfile_mod_syslog_linestart; + lf->f_lineend = logfile_mod_syslog_lineend; + lf->f_flush = logfile_mod_syslog_flush; + lf->f_rotate = logfile_mod_syslog_rotate; + + return 1; +} +#endif --- /dev/null Tue Sep 18 15:52:18 2007 +++ squid/src/logfile_mod_syslog.h Tue Sep 18 15:52:18 2007 @@ -0,0 +1,35 @@ +/* + * $Id: logfile_mod_syslog.h,v 1.1 2007/09/18 15:03:03 adrian Exp $ + * + * DEBUG: section 50 Log file handling + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +extern int logfile_mod_syslog_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag);