version 1.49, 2002/09/13 18:50:09 |
version 1.50, 2002/09/16 01:41:54 |
|
|
*/ |
*/ |
|
|
/* |
/* |
|
* Copyright 1988, 1989 by the Massachusetts Institute of Technology |
|
* |
|
* Permission to use, copy, modify, and distribute this software |
|
* and its documentation for any purpose and without fee is |
|
* hereby granted, provided that the above copyright notice |
|
* appear in all copies and that both that copyright notice and |
|
* this permission notice appear in supporting documentation, |
|
* and that the names of M.I.T. and the M.I.T. S.I.P.B. not be |
|
* used in advertising or publicity pertaining to distribution |
|
* of the software without specific, written prior permission. |
|
* M.I.T. and the M.I.T. S.I.P.B. make no representations about |
|
* the suitability of this software for any purpose. It is |
|
* provided "as is" without express or implied warranty. |
|
*/ |
|
|
Copyright 1988, 1989 by the Massachusetts Institute of Technology |
|
|
|
Permission to use, copy, modify, and distribute this software |
|
and its documentation for any purpose and without fee is |
|
hereby granted, provided that the above copyright notice |
|
appear in all copies and that both that copyright notice and |
|
this permission notice appear in supporting documentation, |
|
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be |
|
used in advertising or publicity pertaining to distribution |
|
of the software without specific, written prior permission. |
|
M.I.T. and the M.I.T. S.I.P.B. make no representations about |
|
the suitability of this software for any purpose. It is |
|
provided "as is" without express or implied warranty. |
|
|
|
*/ |
|
|
|
/* |
/* |
* newsyslog - roll over selected logs at the appropriate time, |
* newsyslog - roll over selected logs at the appropriate time, |
* keeping the a specified number of backup files around. |
* keeping the a specified number of backup files around. |
|
|
/* status messages */ |
/* status messages */ |
#define CE_MONITOR 0x08 /* Monitory for changes */ |
#define CE_MONITOR 0x08 /* Monitory for changes */ |
#define CE_FOLLOW 0x10 /* Follow symbolic links */ |
#define CE_FOLLOW 0x10 /* Follow symbolic links */ |
#define NONE -1 |
|
|
|
#define MIN_PID 4 /* Don't touch pids lower than this */ |
#define MIN_PID 4 /* Don't touch pids lower than this */ |
#define MIN_SIZE 512 /* Don't rotate if smaller than this */ |
#define MIN_SIZE 512 /* Don't rotate if smaller than this */ |
|
|
|
#define DPRINTF(x) do { if (verbose) printf x ; } while (0) |
|
|
struct conf_entry { |
struct conf_entry { |
char *log; /* Name of the log */ |
char *log; /* Name of the log */ |
uid_t uid; /* Owner of log */ |
uid_t uid; /* Owner of log */ |
|
|
int modtime, size; |
int modtime, size; |
struct stat sb; |
struct stat sb; |
|
|
if (!(ent->flags & CE_FOLLOW)) { |
if (lstat(ent->log, &sb) != 0) |
if (lstat(ent->log, &sb) != 0) |
return; |
return; |
if (!S_ISREG(sb.st_mode) && |
if ((sb.st_mode & S_IFLNK) != S_IFREG) { |
(!S_ISLNK(sb.st_mode) || !(ent->flags & CE_FOLLOW))) { |
if (verbose) { |
DPRINTF(("--> not a regular file, skipping\n")); |
printf("--> %s is not a regular file, skip\n", |
return; |
ent->log); |
|
return; |
|
} |
|
} |
|
} |
} |
|
|
if (verbose) |
DPRINTF(("%s <%d%s%s%s>: ", ent->log, ent->numlogs, |
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
(ent->flags & CE_COMPACT) ? "Z" : "", |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
(ent->flags & CE_BINARY) ? "B" : "", |
|
(ent->flags & CE_FOLLOW) ? "F" : "")); |
|
|
size = sizefile(ent->log); |
size = sizefile(ent->log); |
modtime = age_old_log(ent->log); |
modtime = age_old_log(ent->log); |
if (size < 0) { |
if (size < 0) { |
if (verbose) |
DPRINTF(("does not exist.\n")); |
printf("does not exist.\n"); |
|
} else { |
} else { |
if (verbose && (ent->size > 0)) |
if (ent->size > 0) |
printf("size (Kb): %d [%d] ", size, ent->size); |
DPRINTF(("size (Kb): %d [%d] ", size, ent->size)); |
if (verbose && (ent->hours > 0)) |
if (ent->hours > 0) |
printf(" age (hr): %d [%d] ", modtime, ent->hours); |
DPRINTF(("age (hr): %d [%d] ", modtime, ent->hours)); |
if (monitormode && ent->flags & CE_MONITOR) |
if (monitormode && ent->flags & CE_MONITOR) |
domonitor(ent->log, ent->whom); |
domonitor(ent->log, ent->whom); |
if (!monitormode && ((ent->size > 0 && size >= ent->size) || |
if (!monitormode && ((ent->size > 0 && size >= ent->size) || |
(ent->hours > 0 && (modtime >= ent->hours || modtime < 0) |
(ent->hours > 0 && (modtime >= ent->hours || modtime < 0) |
&& ((ent->flags & CE_BINARY) || size >= MIN_SIZE)))) { |
&& ((ent->flags & CE_BINARY) || size >= MIN_SIZE)))) { |
if (verbose) |
DPRINTF(("--> trimming log....\n")); |
printf("--> trimming log....\n"); |
|
if (noaction && !verbose) |
if (noaction && !verbose) |
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
printf("%s <%d%s%s%s>\n", ent->log, |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
ent->numlogs, |
|
(ent->flags & CE_COMPACT) ? "Z" : "", |
|
(ent->flags & CE_BINARY) ? "B" : "", |
|
(ent->flags & CE_FOLLOW) ? "F" : ""); |
dotrim(ent->log, ent->numlogs, ent->flags, |
dotrim(ent->log, ent->numlogs, ent->flags, |
ent->permissions, ent->uid, ent->gid); |
ent->permissions, ent->uid, ent->gid); |
ent->flags |= CE_ROTATED; |
ent->flags |= CE_ROTATED; |
} else if (verbose) |
} else |
printf("--> skipping\n"); |
DPRINTF(("--> skipping\n")); |
} |
} |
} |
} |
|
|
|
|
run_command(char *cmd) |
run_command(char *cmd) |
{ |
{ |
if (noaction) |
if (noaction) |
(void)printf("run %s\n", cmd); |
(void)printf("\trun %s\n", cmd); |
else |
else |
system(cmd); |
system(cmd); |
} |
} |
|
|
} else |
} else |
working->uid = atoi(q); |
working->uid = atoi(q); |
} else |
} else |
working->uid = NONE; |
working->uid = (uid_t)-1; |
|
|
q = group; |
q = group; |
if (*q) { |
if (*q) { |
|
|
} else |
} else |
working->gid = atoi(q); |
working->gid = atoi(q); |
} else |
} else |
working->gid = NONE; |
working->gid = (gid_t)-1; |
|
|
q = parse = missing_field(sob(++parse), errline); |
q = parse = missing_field(sob(++parse), errline); |
*(parse = son(parse)) = '\0'; |
*(parse = son(parse)) = '\0'; |
} else |
} else { |
working->uid = working->gid = NONE; |
working->uid = (uid_t)-1; |
|
working->gid = (gid_t)-1; |
|
} |
|
|
if (!sscanf(q, "%o", &working->permissions)) |
if (!sscanf(q, "%o", &working->permissions)) |
errx(1, "Error in config file; bad permissions: %s", q); |
errx(1, "Error in config file; bad permissions: %s", q); |
|
|
COMPRESS_POSTFIX); |
COMPRESS_POSTFIX); |
|
|
if (noaction) { |
if (noaction) { |
printf("rm -f %s %s\n", file1, zfile1); |
printf("\trm -f %s %s\n", file1, zfile1); |
} else { |
} else { |
(void)unlink(file1); |
(void)unlink(file1); |
(void)unlink(zfile1); |
(void)unlink(zfile1); |
|
|
continue; |
continue; |
} |
} |
if (noaction) { |
if (noaction) { |
printf("mv %s %s\n", zfile1, zfile2); |
printf("\tmv %s %s\n", zfile1, zfile2); |
printf("chmod %o %s\n", perm, zfile2); |
printf("\tchmod %o %s\n", perm, zfile2); |
printf("chown %u:%u %s\n", |
if (owner_uid != (uid_t)-1 || group_gid != (gid_t)-1) |
owner_uid, group_gid, zfile2); |
printf("\tchown %u:%u %s\n", |
|
owner_uid, group_gid, zfile2); |
} else { |
} else { |
if (rename(zfile1, zfile2)) |
if (rename(zfile1, zfile2)) |
warn("can't mv %s to %s", zfile1, zfile2); |
warn("can't mv %s to %s", zfile1, zfile2); |
if (chmod(zfile2, perm)) |
if (chmod(zfile2, perm)) |
warn("can't chmod %s", zfile2); |
warn("can't chmod %s", zfile2); |
if (chown(zfile2, owner_uid, group_gid)) |
if (owner_uid != (uid_t)-1 || group_gid != (gid_t)-1) |
warn("can't chown %s", zfile2); |
if (chown(zfile2, owner_uid, group_gid)) |
|
warn("can't chown %s", zfile2); |
} |
} |
} |
} |
if (!noaction && !(flags & CE_BINARY)) |
if (!noaction && !(flags & CE_BINARY)) |
|
|
|
|
(void)snprintf(file2, sizeof(file2), "%s.XXXXXXXXXX", log); |
(void)snprintf(file2, sizeof(file2), "%s.XXXXXXXXXX", log); |
if (noaction) { |
if (noaction) { |
printf("Create new log file...\n"); |
printf("\tmktemp %s\n", file2); |
} else { |
} else { |
if ((fd = mkstemp(file2)) < 0) |
if ((fd = mkstemp(file2)) < 0) |
err(1, "can't start '%s' log", file2); |
err(1, "can't start '%s' log", file2); |
if (fchown(fd, owner_uid, group_gid)) |
if (owner_uid != (uid_t)-1 || group_gid != (gid_t)-1) |
err(1, "can't chown '%s' log file", file2); |
if (fchown(fd, owner_uid, group_gid)) |
|
err(1, "can't chown '%s' log file", file2); |
if (fchmod(fd, perm)) |
if (fchmod(fd, perm)) |
err(1, "can't chmod '%s' log file", file2); |
err(1, "can't chmod '%s' log file", file2); |
(void)close(fd); |
(void)close(fd); |
|
|
|
|
if (days == 0) { |
if (days == 0) { |
if (noaction) |
if (noaction) |
printf("rm %s\n", log); |
printf("\trm %s\n", log); |
else if (unlink(log)) |
else if (unlink(log)) |
warn("can't rm %s", log); |
warn("can't rm %s", log); |
} else { |
} else { |
if (noaction) |
if (noaction) |
printf("mv %s to %s\n", log, file1); |
printf("\tmv %s to %s\n", log, file1); |
else if (rename(log, file1)) |
else if (rename(log, file1)) |
warn("can't to mv %s to %s", log, file1); |
warn("can't to mv %s to %s", log, file1); |
} |
} |
|
|
/* Now move the new log file into place */ |
/* Now move the new log file into place */ |
if (noaction) |
if (noaction) |
printf("mv %s to %s\n", file2, log); |
printf("\tmv %s to %s\n", file2, log); |
else if (rename(file2, log)) |
else if (rename(file2, log)) |
warn("can't to mv %s to %s", file2, log); |
warn("can't to mv %s to %s", file2, log); |
} |
} |
|
|
(void)snprintf(tmp, sizeof(tmp), "%s.0", log); |
(void)snprintf(tmp, sizeof(tmp), "%s.0", log); |
if (pid < 0) { |
if (pid < 0) { |
err(1, "fork"); |
err(1, "fork"); |
} else if (!pid) { |
} else if (pid == 0) { |
(void)execl(COMPRESS, base, "-f", tmp, (char *)NULL); |
(void)execl(COMPRESS, base, "-f", tmp, (char *)NULL); |
warn(COMPRESS); |
warn(COMPRESS); |
_exit(1); |
_exit(1); |