version 1.25, 1999/11/07 03:59:12 |
version 1.26, 1999/11/07 05:16:28 |
|
|
#include <unistd.h> |
#include <unistd.h> |
#include <err.h> |
#include <err.h> |
|
|
#define CE_COMPACT 0x01 /* Compact the achived log files */ |
#define CE_ROTATED 0x01 /* Log file has been rotated */ |
#define CE_BINARY 0x02 /* Logfile is in binary, don't add */ |
#define CE_COMPACT 0x02 /* Compact the achived log files */ |
|
#define CE_BINARY 0x04 /* Logfile is in binary, don't add */ |
/* status messages */ |
/* status messages */ |
#define CE_MONITOR 0x04 /* Monitory for changes */ |
#define CE_MONITOR 0x08 /* Monitory for changes */ |
#define NONE -1 |
#define NONE -1 |
|
|
struct conf_entry { |
struct conf_entry { |
|
|
void usage __P((void)); |
void usage __P((void)); |
struct conf_entry *parse_file __P((void)); |
struct conf_entry *parse_file __P((void)); |
char *missing_field __P((char *, char *)); |
char *missing_field __P((char *, char *)); |
void dotrim __P((char *, int, int, int, uid_t, gid_t, pid_t)); |
void dotrim __P((char *, int, int, int, uid_t, gid_t)); |
int log_trim __P((char *)); |
int log_trim __P((char *)); |
void compress_log __P((char *)); |
void compress_log __P((char *)); |
int sizefile __P((char *)); |
int sizefile __P((char *)); |
|
|
FILE *openmail __P((void)); |
FILE *openmail __P((void)); |
void closemail __P((FILE *)); |
void closemail __P((FILE *)); |
void child_killer __P((int)); |
void child_killer __P((int)); |
|
void send_hup __P((char *)); |
|
|
int |
int |
main(argc, argv) |
main(argc, argv) |
|
|
errx(1, "You must be root."); |
errx(1, "You must be root."); |
p = q = parse_file(); |
p = q = parse_file(); |
signal(SIGCHLD, child_killer); |
signal(SIGCHLD, child_killer); |
|
|
|
/* Step 1, rotate all log files */ |
|
while (q) { |
|
do_entry(q); |
|
q = q->next; |
|
} |
|
|
|
/* Step 2, send a HUP to relevant processes */ |
|
/* XXX - should avoid HUP'ing the same process multiple times */ |
|
q = p; |
|
while (q) { |
|
if (q->flags & CE_ROTATED) |
|
send_hup(q->pidfile); |
|
q = q->next; |
|
} |
|
|
|
/* Step 3, compress the log.0 file if configured to do so and free */ |
while (p) { |
while (p) { |
do_entry(p); |
if ((p->flags & CE_COMPACT) && (p->flags & CE_ROTATED)) |
|
compress_log(p->log); |
|
q = p; |
p = p->next; |
p = p->next; |
free(q); |
free(q); |
q = p; |
|
} |
} |
|
|
/* Wait for children to finish, then exit */ |
/* Wait for children to finish, then exit */ |
|
|
|
|
{ |
{ |
int modtime, size; |
int modtime, size; |
pid_t pid; |
|
char line[BUFSIZ]; |
|
FILE *f; |
|
|
|
/* First find the pid to HUP */ |
|
pid = (pid_t)-1; |
|
if ((f = fopen(ent->pidfile, "r")) != NULL) { |
|
if (fgets(line, sizeof(line), f)) |
|
pid = atoi(line); |
|
(void)fclose(f); |
|
} else |
|
warn("can't open %s", ent->pidfile); |
|
|
|
if (verbose) |
if (verbose) |
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
|
|
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
printf("%s <%d%s>: ", ent->log, ent->numlogs, |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
(ent->flags & CE_COMPACT) ? "Z" : ""); |
dotrim(ent->log, ent->numlogs, ent->flags, |
dotrim(ent->log, ent->numlogs, ent->flags, |
ent->permissions, ent->uid, ent->gid, pid); |
ent->permissions, ent->uid, ent->gid); |
|
ent->flags |= CE_ROTATED; |
} else if (verbose) |
} else if (verbose) |
printf("--> skipping\n"); |
printf("--> skipping\n"); |
} |
} |
} |
} |
|
|
|
/* Send a HUP to the pid specified by pidfile */ |
void |
void |
|
send_hup(pidfile) |
|
char *pidfile; |
|
{ |
|
FILE *f; |
|
char line[BUFSIZ]; |
|
pid_t pid = 0; |
|
|
|
if ((f = fopen(pidfile, "r")) == NULL) { |
|
warn("can't open %s", pidfile); |
|
return; |
|
} |
|
|
|
if (fgets(line, sizeof(line), f)) |
|
pid = atoi(line); |
|
(void)fclose(f); |
|
|
|
if (noaction) |
|
(void)printf("kill -HUP %d\n", pid); |
|
else if (pid == 0) |
|
warnx("empty pid file: %s", pidfile); |
|
else if (pid < MIN_PID) |
|
warnx("preposterous process number: %d", pid); |
|
else if (kill(pid, SIGHUP)) |
|
warnx("warning - could not HUP daemon"); |
|
} |
|
|
|
void |
PRS(argc, argv) |
PRS(argc, argv) |
int argc; |
int argc; |
char **argv; |
char **argv; |
|
|
} |
} |
|
|
void |
void |
dotrim(log, numdays, flags, perm, owner_uid, group_gid, daemon_pid) |
dotrim(log, numdays, flags, perm, owner_uid, group_gid) |
char *log; |
char *log; |
int numdays; |
int numdays; |
int flags; |
int flags; |
int perm; |
int perm; |
uid_t owner_uid; |
uid_t owner_uid; |
gid_t group_gid; |
gid_t group_gid; |
pid_t daemon_pid; |
|
{ |
{ |
char file1[MAXPATHLEN], file2[MAXPATHLEN]; |
char file1[MAXPATHLEN], file2[MAXPATHLEN]; |
char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN]; |
char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN]; |
|
|
(void)strcpy(zfile1, file1); |
(void)strcpy(zfile1, file1); |
(void)strcat(zfile1, COMPRESS_POSTFIX); |
(void)strcat(zfile1, COMPRESS_POSTFIX); |
if (noaction) { |
if (noaction) { |
printf("rm -f %s\n", file1); |
printf("rm -f %s %s\n", file1, zfile1); |
printf("rm -f %s\n", zfile1); |
|
} else { |
} else { |
(void)unlink(file1); |
(void)unlink(file1); |
(void)unlink(zfile1); |
(void)unlink(zfile1); |
|
|
if (!noaction && !(flags & CE_BINARY)) |
if (!noaction && !(flags & CE_BINARY)) |
(void)log_trim(log); /* Report the trimming to the old log */ |
(void)log_trim(log); /* Report the trimming to the old log */ |
|
|
|
(void)snprintf(file2, sizeof(file2), "%s.XXXXXXXXXX", log); |
|
if (noaction) { |
|
printf("Create new log file...\n"); |
|
} else { |
|
if ((fd = mkstemp(file2)) < 0) |
|
err(1, "can't start '%s' log", file2); |
|
if (fchown(fd, owner_uid, group_gid)) |
|
err(1, "can't chown '%s' log file", file2); |
|
if (fchmod(fd, perm)) |
|
err(1, "can't chmod '%s' log file", file2); |
|
(void)close(fd); |
|
/* Add status message */ |
|
if (!(flags & CE_BINARY) && log_trim(file2)) |
|
err(1, "can't add status message to log '%s'", file2); |
|
} |
|
|
if (days == 0) { |
if (days == 0) { |
if (noaction) |
if (noaction) |
printf("rm %s\n", log); |
printf("rm %s\n", log); |
|
|
warn("can't to mv %s to %s", log, file1); |
warn("can't to mv %s to %s", log, file1); |
} |
} |
|
|
if (noaction) { |
/* Now move the new log file into place */ |
printf("Start new log..."); |
if (noaction) |
} else { |
printf("mv %s to %s\n", file2, log); |
fd = open(log, O_WRONLY|O_TRUNC|O_CREAT, perm); |
else if (rename(file2, log)) |
if (fd < 0) |
warn("can't to mv %s to %s", file2, log); |
err(1, "can't start '%s' log", log); |
|
if (fchown(fd, owner_uid, group_gid)) |
|
err(1, "can't chown '%s' log file", log); |
|
if (fchmod(fd, perm)) |
|
err(1, "can't chmod '%s' log file", log); |
|
(void)close(fd); |
|
/* Add status message */ |
|
if (!(flags & CE_BINARY) && log_trim(log)) |
|
err(1, "can't add status message to log '%s'", log); |
|
} |
|
if (noaction) |
|
(void)printf("kill -HUP %d\n", daemon_pid); |
|
else if (daemon_pid != (pid_t)-1) { |
|
if (daemon_pid < MIN_PID) |
|
warnx("preposterous process number: %d", daemon_pid); |
|
else if (kill(daemon_pid, SIGHUP)) |
|
warnx("warning - could not HUP daemon"); |
|
} |
|
if (flags & CE_COMPACT) { |
|
if (noaction) |
|
(void)printf("Compress %s.0\n", log); |
|
else |
|
compress_log(log); |
|
} |
|
} |
} |
|
|
/* Log the fact that the logs were turned over */ |
/* Log the fact that the logs were turned over */ |