123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- $Id$
- --- logrotate-3.7.1.orig/logrotate.c Tue Oct 19 23:41:24 2004
- +++ logrotate-3.7.1/logrotate.c Sat Jan 20 18:56:30 2007
- @@ -11,6 +11,7 @@
- #include <sys/wait.h>
- #include <time.h>
- #include <unistd.h>
- +#include <glob.h>
-
- #ifdef WITH_SELINUX
- #include <selinux/selinux.h>
- @@ -22,6 +23,10 @@ int selinux_enabled=0;
- #include "log.h"
- #include "logrotate.h"
-
- +#if !defined(GLOB_ABORTED) && defined(GLOB_ABEND)
- +#define GLOB_ABORTED GLOB_ABEND
- +#endif
- +
- typedef struct {
- char * fn;
- struct tm lastRotated; /* only tm.mon, tm_mday, tm_year are good! */
- @@ -42,6 +47,14 @@ int debug = 0;
- char * mailCommand = DEFAULT_MAIL_COMMAND;
- time_t nowSecs = 0;
-
- +static int globerr(const char * pathname, int theerr) {
- + message(MESS_ERROR, "error accessing %s: %s\n", pathname,
- + strerror(theerr));
- +
- + /* We want the glob operation to continue, so return 0 */
- + return 1;
- +}
- +
- static logState * findState(const char * fn, struct stateSet * sip) {
- int i;
- logState * states = sip->states;
- @@ -49,9 +62,11 @@ static logState * findState(const char *
- struct tm now = *localtime(&nowSecs);
- time_t lr_time;
-
- + /* find the filename fn in the statesPtr list */
- for (i = 0; i < numStates; i++)
- if (!strcmp(fn, states[i].fn)) break;
-
- + /* not in statesPtr list, so add new entry */
- if (i == numStates) {
- i = numStates++;
- states = realloc(states, sizeof(*states) * numStates);
- @@ -75,10 +90,7 @@ static logState * findState(const char *
- }
-
- static int runScript(char * logfn, char * script) {
- - int fd;
- - char *filespec;
- int rc;
- - char buf[256];
-
- if (debug) {
- message(MESS_DEBUG, "running script with arg %s: \"%s\"\n",
- @@ -86,39 +98,24 @@ static int runScript(char * logfn, char
- return 0;
- }
-
- - filespec = buf;
- - snprintf(buf, sizeof(buf), "%s/logrotate.XXXXXX", getenv("TMPDIR") ?: "/tmp");
- - fd = -1;
- - if (!filespec || (fd = mkstemp(filespec)) < 0 || fchmod(fd, 0700)) {
- - message(MESS_DEBUG, "error creating %s: %s\n", filespec,
- - strerror(errno));
- - if (fd >= 0) {
- - close(fd);
- - unlink(filespec);
- - }
- - return -1;
- - }
- -
- - if (write(fd, "#!/bin/sh\n\n", 11) != 11 ||
- - write(fd, script, strlen(script)) != strlen(script)) {
- - message(MESS_DEBUG, "error writing %s\n", filespec);
- - close(fd);
- - unlink(filespec);
- - return -1;
- - }
- -
- - close(fd);
- -
- if (!fork()) {
- - execlp(filespec, filespec, logfn, NULL);
- + execl("/bin/sh", "sh", "-c", script, NULL);
- exit(1);
- }
-
- wait(&rc);
- + return rc;
- +}
-
- - unlink(filespec);
- +static int removeLogFile(char * name) {
- + message(MESS_DEBUG, "removing old log %s\n", name);
-
- - return rc;
- + if (!debug && unlink(name)) {
- + message(MESS_ERROR, "Failed to remove old log %s: %s\n",
- + name, strerror(errno));
- + return 1;
- + }
- + return 0;
- }
-
- static int compressLogFile(char * name, logInfo * log, struct stat *sb) {
- @@ -265,6 +262,25 @@ static int mailLog(char * logFile, char
- return rc;
- }
-
- +static int mailLogWrapper (char * mailFilename, char * mailCommand, int logNum, logInfo * log) {
- + /* if the log is compressed (and we're not mailing a
- + * file whose compression has been delayed), we need
- + * to uncompress it */
- + if ((log->flags & LOG_FLAG_COMPRESS) &&
- + !((log->flags & LOG_FLAG_DELAYCOMPRESS) &&
- + (log->flags & LOG_FLAG_MAILFIRST))) {
- + if (mailLog(mailFilename, mailCommand,
- + log->uncompress_prog, log->logAddress,
- + log->files[logNum]))
- + return 1;
- + } else {
- + if (mailLog(mailFilename, mailCommand, NULL,
- + log->logAddress, mailFilename))
- + return 1;
- + }
- + return 0;
- +}
- +
- static int copyTruncate(char * currLog, char * saveLog, struct stat * sb, int flags) {
- char buf[BUFSIZ];
- int fdcurr = -1, fdsave = -1;
- @@ -424,12 +440,15 @@ int findNeedRotating(logInfo * log, int
- switch (log->criterium) {
- case ROT_WEEKLY:
- /* rotate if:
- - 1) the current weekday is before the weekday of the
- - last rotation
- + 1) the day of the week is the same as the day of the week of
- + the previous rotation but not the same day of the year
- + this will rotate it on the same day every week, but not
- + twice a day.
- 2) more then a week has passed since the last
- rotation */
- - state->doRotate = ((now.tm_wday < state->lastRotated.tm_wday) ||
- - ((mktime(&now) - mktime(&state->lastRotated)) >
- + state->doRotate = ((now.tm_wday == state->lastRotated.tm_wday &&
- + now.tm_yday != state->lastRotated.tm_yday) ||
- + ((mktime(&now) - mktime(&state->lastRotated)) >
- (7 * 24 * 3600)));
- break;
- case ROT_MONTHLY:
- @@ -479,6 +498,9 @@ int rotateSingleLog(logInfo * log, int l
- char * baseName;
- char * dirName;
- char * firstRotated;
- + char * glob_pattern;
- + glob_t globResult;
- + int rc;
- size_t alloc_size;
- int rotateCount = log->rotateCount ? log->rotateCount : 1;
- int logStart = (log->logStart == -1) ? 1 : log->logStart;
- @@ -509,7 +531,7 @@ int rotateSingleLog(logInfo * log, int l
-
- alloc_size = strlen(dirName) + strlen(baseName) +
- strlen(log->files[logNum]) + strlen(fileext) +
- - strlen(compext) + 10;
- + strlen(compext) + 18;
-
- oldName = alloca(alloc_size);
- newName = alloca(alloc_size);
- @@ -531,16 +553,116 @@ int rotateSingleLog(logInfo * log, int l
- /* First compress the previous log when necessary */
- if (log->flags & LOG_FLAG_COMPRESS &&
- log->flags & LOG_FLAG_DELAYCOMPRESS) {
- - struct stat sbprev;
- -
- - sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext);
- - if (stat(oldName, &sbprev)) {
- - message(MESS_DEBUG, "previous log %s does not exist\n",
- - oldName);
- - } else {
- - hasErrors = compressLogFile(oldName, log, &sbprev);
- + if (log->flags & LOG_FLAG_DATEEXT) {
- + /* glob for uncompressed files with our pattern */
- + glob_pattern = malloc(strlen(dirName) + strlen(baseName)
- + + strlen(fileext) + 44 );
- + sprintf(glob_pattern,
- + "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s",
- + dirName, baseName, fileext);
- + rc = glob(glob_pattern, 0, globerr, &globResult);
- + if (!rc && globResult.gl_pathc > 0) {
- + for (i = 0; i < globResult.gl_pathc && !hasErrors; i++) {
- + struct stat sbprev;
- + sprintf(oldName,"%s",(globResult.gl_pathv)[i]);
- + if (stat(oldName, &sbprev)) {
- + message(MESS_DEBUG, "previous log %s does not exist\n", oldName);
- + } else {
- + hasErrors = compressLogFile(oldName, log, &sbprev);
- + }
- + }
- + } else {
- + message (MESS_DEBUG, "glob finding logs to compress failed\n");
- + /* fallback to old behaviour */
- + sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext);
- + }
- + globfree(&globResult);
- + free(glob_pattern);
- + } else {
- + struct stat sbprev;
- +
- + sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext);
- + if (stat(oldName, &sbprev)) {
- + message(MESS_DEBUG, "previous log %s does not exist\n",
- + oldName);
- + } else {
- + hasErrors = compressLogFile(oldName, log, &sbprev);
- + }
- }
- }
- +
- + firstRotated = alloca(strlen(dirName) + strlen(baseName) +
- + strlen(fileext) + strlen(compext) + 30);
- +
- + if(log->flags & LOG_FLAG_DATEEXT) {
- + /* glob for compressed files with our pattern
- + * and compress ext */
- + glob_pattern = malloc(strlen(dirName)+strlen(baseName)
- + +strlen(fileext)+strlen(compext)+44);
- + sprintf(glob_pattern,
- + "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s%s",
- + dirName, baseName, fileext, compext);
- + rc = glob(glob_pattern, 0, globerr, &globResult);
- + if (!rc) {
- + /* search for files to drop, if we find one remember it,
- + * if we find another one mail and remove the first and
- + * remember the second and so on */
- + struct stat fst_buf;
- + int mail_out = -1;
- + /* remove the first (n - rotateCount) matches
- + * no real rotation needed, since the files have
- + * the date in their name */
- + for (i = 0; i < globResult.gl_pathc; i++) {
- + if( !stat((globResult.gl_pathv)[i],&fst_buf) ) {
- + if ((i <= ((int)globResult.gl_pathc - rotateCount))
- + || ((log->rotateAge > 0)
- + && (((nowSecs - fst_buf.st_mtime)/60/60/24)
- + > log->rotateAge))) {
- + if ( mail_out != -1 ) {
- + if (!hasErrors && log->logAddress) {
- + char * mailFilename = (globResult.gl_pathv)[mail_out];
- + hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log);
- + if (!hasErrors)
- + hasErrors = removeLogFile(mailFilename);
- + }
- + }
- + mail_out = i;
- + }
- + }
- + }
- + if ( mail_out != -1 ) {
- + /* oldName is oldest Backup found (for unlink later) */
- + sprintf(oldName, "%s", (globResult.gl_pathv)[mail_out]);
- + strcpy(disposeName, oldName);
- + } else
- + disposeName = NULL;
- + } else {
- + message (MESS_DEBUG, "glob finding old rotated logs failed\n");
- + disposeName = NULL;
- + }
- + /* firstRotated is most recently created/compressed rotated log */
- + sprintf(firstRotated, "%s/%s-%04d%02d%02d%s%s",
- + dirName, baseName, now.tm_year+1900,
- + now.tm_mon+1, now.tm_mday, fileext, compext);
- + globfree(&globResult);
- + free(glob_pattern);
- + } else {
- + if ( log->rotateAge ) {
- + struct stat fst_buf;
- + for (i=1; i <= rotateCount; i++) {
- + sprintf(oldName, "%s/%s.%d%s%s", dirName, baseName,
- + rotateCount + 1, fileext, compext);
- + if(!stat(oldName,&fst_buf)
- + && (((nowSecs - fst_buf.st_mtime)/60/60/24)
- + > log->rotateAge)) {
- + char * mailFilename = (globResult.gl_pathv)[i];
- + if (!hasErrors && log->logAddress)
- + hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log);
- + if (!hasErrors)
- + hasErrors = removeLogFile(mailFilename);
- + }
- + }
- + }
-
- sprintf(oldName, "%s/%s.%d%s%s", dirName, baseName,
- logStart + rotateCount, fileext, compext);
- @@ -548,8 +670,6 @@ int rotateSingleLog(logInfo * log, int l
-
- strcpy(disposeName, oldName);
-
- - firstRotated = alloca(strlen(dirName) + strlen(baseName) +
- - strlen(fileext) + strlen(compext) + 30);
- sprintf(firstRotated, "%s/%s.%d%s%s", dirName, baseName,
- logStart, fileext,
- (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext);
- @@ -600,12 +720,27 @@ int rotateSingleLog(logInfo * log, int l
- }
- }
- }
- -
- + } /* !LOG_FLAG_DATEEXT */
- +
- finalName = oldName;
- -
- - /* note: the gzip extension is *not* used here! */
- - sprintf(finalName, "%s/%s.%d%s", dirName, baseName, logStart, fileext);
- -
- +
- + if(log->flags & LOG_FLAG_DATEEXT) {
- + char * destFile = alloca(strlen(dirName) + strlen(baseName) +
- + strlen(fileext) + strlen(compext) + 30);
- + struct stat fst_buf;
- + sprintf(finalName, "%s/%s-%04d%02d%02d%s",
- + dirName, baseName, now.tm_year+1900,
- + now.tm_mon+1, now.tm_mday, fileext);
- + sprintf(destFile, "%s%s", finalName, compext);
- + if(!stat(destFile,&fst_buf)) {
- + message (MESS_DEBUG, "destination %s already exists, skipping rotation\n", firstRotated);
- + hasErrors = 1;
- + }
- + } else {
- + /* note: the gzip extension is *not* used here! */
- + sprintf(finalName, "%s/%s.%d%s", dirName, baseName, logStart, fileext);
- + }
- +
- /* if the last rotation doesn't exist, that's okay */
- if (!debug && access(disposeName, F_OK)) {
- message(MESS_DEBUG, "log %s doesn't exist -- won't try to "
- @@ -613,9 +748,6 @@ int rotateSingleLog(logInfo * log, int l
- disposeName = NULL;
- }
-
- - free(dirName);
- - free(baseName);
- -
- if (!hasErrors) {
- if (log->pre && !(log->flags & LOG_FLAG_SHAREDSCRIPTS)) {
- message(MESS_DEBUG, "running prerotate script\n");
- @@ -722,33 +854,12 @@ int rotateSingleLog(logInfo * log, int l
- else
- mailFilename = disposeName;
-
- - if (mailFilename) {
- - /* if the log is compressed (and we're not mailing a
- - file whose compression has been delayed), we need
- - to uncompress it */
- - if ((log->flags & LOG_FLAG_COMPRESS) &&
- - !((log->flags & LOG_FLAG_DELAYCOMPRESS) &&
- - (log->flags & LOG_FLAG_MAILFIRST))) {
- - if (mailLog(mailFilename, mailCommand,
- - log->uncompress_prog, log->logAddress,
- - log->files[logNum]))
- - hasErrors = 1;
- - } else {
- - if (mailLog(mailFilename, mailCommand, NULL,
- - log->logAddress, mailFilename))
- - hasErrors = 1;
- - }
- - }
- + if (mailFilename)
- + hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log);
- }
-
- if (!hasErrors && disposeName) {
- - message(MESS_DEBUG, "removing old log %s\n", disposeName);
- -
- - if (!debug && unlink(disposeName)) {
- - message(MESS_ERROR, "Failed to remove old log %s: %s\n",
- - disposeName, strerror(errno));
- - hasErrors = 1;
- - }
- + hasErrors = removeLogFile(disposeName);
- }
- }
-
- @@ -761,6 +872,8 @@ int rotateSingleLog(logInfo * log, int l
- }
- }
- #endif
- + free(dirName);
- + free(baseName);
- return hasErrors;
- }
-
- @@ -1002,7 +1115,7 @@ static int readState(char * stateFilenam
- }
-
- /* Hack to hide earlier bug */
- - if ((year != 1900) && (year < 1996 || year > 2100)) {
- + if ((year != 1900) && (year < 1970 || year > 2100)) {
- message(MESS_ERROR, "bad year %d for file %s in state file %s\n",
- year, argv[0], stateFilename);
- fclose(f);
- @@ -1047,7 +1160,9 @@ static int readState(char * stateFilenam
-
- int main(int argc, const char ** argv) {
- logInfo defConfig = { NULL, NULL, 0, NULL, ROT_SIZE,
- - /* threshHold */ 1024 * 1024, 0,
- + /* threshHold */ 1024 * 1024,
- + /* rotateCount */ 0,
- + /* rotateAge */ 0,
- /* log start */ -1,
- /* pre, post */ NULL, NULL,
- /* first, last */ NULL, NULL,
- @@ -1108,8 +1223,7 @@ int main(int argc, const char ** argv) {
-
- files = poptGetArgs((poptContext) optCon);
- if (!files) {
- - fprintf(stderr, "logrotate " VERSION
- - " - Copyright (C) 1995-2001 Red Hat, Inc.\n");
- + fprintf(stderr, "logrotate - Copyright (C) 1995-2001 Red Hat, Inc.\n");
- fprintf(stderr, "This may be freely redistributed under the terms of "
- "the GNU Public License\n\n");
- poptPrintUsage(optCon, stderr, 0);
|