version 1.10, 1997/07/07 22:50:56 |
version 1.11, 1997/07/08 04:26:00 |
|
|
#include <pwd.h> |
#include <pwd.h> |
#include <grp.h> |
#include <grp.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <err.h> |
|
|
#define kbytes(size) (((size) + 1023) >> 10) |
#define kbytes(size) (((size) + 1023) >> 10) |
|
|
|
|
struct conf_entry *next; /* Linked list pointer */ |
struct conf_entry *next; /* Linked list pointer */ |
}; |
}; |
|
|
char *progname; /* contains argv[0] */ |
extern const char *__progname; |
|
|
int verbose = 0; /* Print out what's going on */ |
int verbose = 0; /* Print out what's going on */ |
int needroot = 1; /* Root privs are necessary */ |
int needroot = 1; /* Root privs are necessary */ |
int noaction = 0; /* Don't do anything, just show it */ |
int noaction = 0; /* Don't do anything, just show it */ |
|
|
struct conf_entry *p, *q; |
struct conf_entry *p, *q; |
|
|
PRS(argc,argv); |
PRS(argc,argv); |
if (needroot && getuid() && geteuid()) { |
if (needroot && getuid() && geteuid()) |
fprintf(stderr,"%s: must have root privs\n",progname); |
errx(1, "You must be root."); |
exit(1); |
|
} |
|
p = q = parse_file(); |
p = q = parse_file(); |
while (p) { |
while (p) { |
do_entry(p); |
do_entry(p); |
p=p->next; |
p=p->next; |
free((char *) q); |
free(q); |
q=p; |
q=p; |
} |
} |
exit(0); |
exit(0); |
|
|
char line[BUFSIZ]; |
char line[BUFSIZ]; |
char *p; |
char *p; |
|
|
progname = argv[0]; |
|
timenow = time((time_t *) 0); |
timenow = time((time_t *) 0); |
daytime = ctime(&timenow) + 4; |
daytime = ctime(&timenow) + 4; |
daytime[15] = '\0'; |
daytime[15] = '\0'; |
|
|
|
|
void usage() |
void usage() |
{ |
{ |
fprintf(stderr, |
errx(1, "usage: %s <-nrvm> <-f config-file>", __progname); |
"Usage: %s <-nrv> <-f config-file>\n", progname); |
|
exit(1); |
|
} |
} |
|
|
/* Parse a configuration file and return a linked list of all the logs |
/* Parse a configuration file and return a linked list of all the logs |
|
|
f = fopen(conf,"r"); |
f = fopen(conf,"r"); |
else |
else |
f = stdin; |
f = stdin; |
if (!f) { |
if (!f) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, conf); |
perror(conf); |
|
exit(1); |
|
} |
|
while (fgets(line,BUFSIZ,f)) { |
while (fgets(line,BUFSIZ,f)) { |
if ((line[0]== '\n') || (line[0] == '#')) |
if ((line[0]== '\n') || (line[0] == '#')) |
continue; |
continue; |
errline = strdup(line); |
errline = strdup(line); |
if (errline == NULL) { |
if (errline == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "strdup"); |
perror("strdup()"); |
|
exit(1); |
|
} |
|
if (!first) { |
if (!first) { |
working = (struct conf_entry *) malloc(sizeof(struct conf_entry)); |
working = (struct conf_entry *) malloc(sizeof(struct conf_entry)); |
if (working == NULL) { |
if (working == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "malloc"); |
perror("malloc()"); |
|
exit(1); |
|
} |
|
first = working; |
first = working; |
} else { |
} else { |
working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry)); |
working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry)); |
if (working->next == NULL) { |
if (working->next == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "malloc"); |
perror("malloc()"); |
|
exit(1); |
|
} |
|
working = working->next; |
working = working->next; |
} |
} |
|
|
q = parse = missing_field(sob(line),errline); |
q = parse = missing_field(sob(line),errline); |
*(parse = son(line)) = '\0'; |
*(parse = son(line)) = '\0'; |
working->log = strdup(q); |
working->log = strdup(q); |
if (working->log == NULL) { |
if (working->log == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "strdup"); |
perror("strdup()"); |
|
exit(1); |
|
} |
|
|
|
q = parse = missing_field(sob(++parse),errline); |
q = parse = missing_field(sob(++parse),errline); |
*(parse = son(parse)) = '\0'; |
*(parse = son(parse)) = '\0'; |
|
|
*group++ = '\0'; |
*group++ = '\0'; |
if (*q) { |
if (*q) { |
if (!(isnumberstr(q))) { |
if (!(isnumberstr(q))) { |
if ((pass = getpwnam(q)) == NULL) { |
if ((pass = getpwnam(q)) == NULL) |
fprintf(stderr, |
errx(1, "Error in config file; unknown user: %s", q); |
"Error in config file; unknown user:\n"); |
|
fputs(errline,stderr); |
|
exit(1); |
|
} |
|
working->uid = pass->pw_uid; |
working->uid = pass->pw_uid; |
} else |
} else |
working->uid = atoi(q); |
working->uid = atoi(q); |
|
|
q = group; |
q = group; |
if (*q) { |
if (*q) { |
if (!(isnumberstr(q))) { |
if (!(isnumberstr(q))) { |
if ((grp = getgrnam(q)) == NULL) { |
if ((grp = getgrnam(q)) == NULL) |
fprintf(stderr, |
errx(1, "Error in config file; unknown group: %s", q); |
"Error in config file; unknown group:\n"); |
|
fputs(errline,stderr); |
|
exit(1); |
|
} |
|
working->gid = grp->gr_gid; |
working->gid = grp->gr_gid; |
} else |
} else |
working->gid = atoi(q); |
working->gid = atoi(q); |
|
|
|
|
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 = working->gid = NONE; |
|
|
if (!sscanf(q,"%o",&working->permissions)) { |
if (!sscanf(q,"%o",&working->permissions)) |
fprintf(stderr, |
errx(1, "Error in config file; bad permissions: %s", q); |
"Error in config file; bad permissions:\n"); |
|
fputs(errline,stderr); |
|
exit(1); |
|
} |
|
|
|
q = parse = missing_field(sob(++parse),errline); |
q = parse = missing_field(sob(++parse),errline); |
*(parse = son(parse)) = '\0'; |
*(parse = son(parse)) = '\0'; |
if (!sscanf(q,"%d",&working->numlogs)) { |
if (!sscanf(q,"%d",&working->numlogs)) |
fprintf(stderr, |
errx(1, "Error in config file; bad number: %s", q); |
"Error in config file; bad number:\n"); |
|
fputs(errline,stderr); |
|
exit(1); |
|
} |
|
|
|
q = parse = missing_field(sob(++parse),errline); |
q = parse = missing_field(sob(++parse),errline); |
*(parse = son(parse)) = '\0'; |
*(parse = son(parse)) = '\0'; |
|
|
working->flags |= CE_BINARY; |
working->flags |= CE_BINARY; |
else if ((*q == 'M') || (*q == 'm')) |
else if ((*q == 'M') || (*q == 'm')) |
working->flags |= CE_MONITOR; |
working->flags |= CE_MONITOR; |
else { |
else |
fprintf(stderr, |
errx(1, "Illegal flag in config file: %c", *q); |
"Illegal flag in config file -- %c\n", |
|
*q); |
|
exit(1); |
|
} |
|
q++; |
q++; |
} |
} |
|
|
|
|
*(parse = son(parse)) = '\0'; |
*(parse = son(parse)) = '\0'; |
|
|
working->whom = strdup(q); |
working->whom = strdup(q); |
if (working->log == NULL) { |
if (working->log == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "strdup"); |
perror("strdup()"); |
|
exit(1); |
|
} |
|
} |
} |
|
|
free(errline); |
free(errline); |
|
|
char *p,*errline; |
char *p,*errline; |
{ |
{ |
if (!p || !*p) { |
if (!p || !*p) { |
fprintf(stderr,"Missing field in config file:\n"); |
fprintf(stderr, "%s: Missing field in config file line:\n", |
fputs(errline,stderr); |
__progname); |
|
fputs(errline, stderr); |
exit(1); |
exit(1); |
} |
} |
return(p); |
return(p); |
|
|
printf("Start new log..."); |
printf("Start new log..."); |
else { |
else { |
fd = creat(log,perm); |
fd = creat(log,perm); |
if (fd < 0) { |
if (fd < 0) |
perror("can't start new log"); |
err(1, "can't start new log"); |
exit(1); |
if (fchown(fd, owner_uid, group_gid)) |
} |
err(1, "can't chmod new log file"); |
if (fchown(fd, owner_uid, group_gid)) { |
|
perror("can't chmod new log file"); |
|
exit(1); |
|
} |
|
(void) close(fd); |
(void) close(fd); |
if (!(flags & CE_BINARY)) |
if (!(flags & CE_BINARY)) |
if (log_trim(log)) { /* Add status message */ |
if (log_trim(log)) /* Add status message */ |
perror("can't add status message to log"); |
err(1, "can't add status message to log"); |
exit(1); |
|
} |
|
} |
} |
if (noaction) |
if (noaction) |
printf("chmod %o %s...",perm,log); |
printf("chmod %o %s...",perm,log); |
|
|
(void) chmod(log,perm); |
(void) chmod(log,perm); |
if (noaction) |
if (noaction) |
printf("kill -HUP %d (syslogd)\n",syslog_pid); |
printf("kill -HUP %d (syslogd)\n",syslog_pid); |
else |
else if (syslog_pid < MIN_PID || syslog_pid > MAX_PID) |
if (syslog_pid < MIN_PID || syslog_pid > MAX_PID) { |
warnx("preposterous process number: %d", syslog_pid); |
fprintf(stderr,"%s: preposterous process number: %d\n", |
else if (kill(syslog_pid,SIGHUP)) |
progname, syslog_pid); |
warnx("warning - could not restart syslogd"); |
} else if (kill(syslog_pid,SIGHUP)) { |
|
fprintf(stderr,"%s: ",progname); |
|
perror("warning - could not restart syslogd"); |
|
} |
|
if (flags & CE_COMPACT) { |
if (flags & CE_COMPACT) { |
if (noaction) |
if (noaction) |
printf("Compress %s.0\n",log); |
printf("Compress %s.0\n",log); |
|
|
fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n", |
fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n", |
daytime, hostname, getpid()); |
daytime, hostname, getpid()); |
if (fclose(f) == EOF) { |
if (fclose(f) == EOF) { |
perror("log_trim: fclose:"); |
err(1, "log_trim: fclose"); |
exit(1); |
|
} |
} |
return(0); |
return(0); |
} |
} |
|
|
pid = fork(); |
pid = fork(); |
(void) sprintf(tmp,"%s.0",log); |
(void) sprintf(tmp,"%s.0",log); |
if (pid < 0) { |
if (pid < 0) { |
fprintf(stderr,"%s: ",progname); |
err(1, "fork"); |
perror("fork"); |
|
exit(1); |
|
} else if (!pid) { |
} else if (!pid) { |
(void) execl(COMPRESS,"compress","-f",tmp,0); |
(void) execl(COMPRESS,"compress","-f",tmp,0); |
fprintf(stderr,"%s: ",progname); |
err(1, COMPRESS); |
perror(COMPRESS); |
|
exit(1); |
|
} |
} |
} |
} |
|
|
|
|
return; |
return; |
|
|
flog = strdup(log); |
flog = strdup(log); |
if (flog == NULL) { |
if (flog == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "strdup"); |
perror("strdup()"); |
|
exit(1); |
|
} |
|
for (p = flog; *p != '\0'; p++) { |
for (p = flog; *p != '\0'; p++) { |
if (*p == '/') |
if (*p == '/') |
*p = '_'; |
*p = '_'; |
} |
} |
fname = (char *) malloc(strlen(STATS_DIR) + strlen(flog) + 17); |
fname = (char *) malloc(strlen(STATS_DIR) + strlen(flog) + 17); |
if (fname == NULL) { |
if (fname == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "malloc"); |
perror("malloc()"); |
|
exit(1); |
|
} |
|
sprintf(fname, "%s/newsyslog.%s.size", STATS_DIR, flog); |
sprintf(fname, "%s/newsyslog.%s.size", STATS_DIR, flog); |
|
|
/* ..if it doesn't exist, simply record the current size. */ |
/* ..if it doesn't exist, simply record the current size. */ |
|
|
|
|
fp = fopen(fname, "r"); |
fp = fopen(fname, "r"); |
if (fp == NULL) { |
if (fp == NULL) { |
(void) fprintf(stderr,"%s: ",progname); |
warn(fname); |
perror(fname); |
|
goto cleanup; |
goto cleanup; |
} |
} |
#ifdef QUAD_OFF_T |
#ifdef QUAD_OFF_T |
|
|
/* Now see if current size is larger. */ |
/* Now see if current size is larger. */ |
if (sb.st_size > osize) { |
if (sb.st_size > osize) { |
rb = (char *) malloc(sb.st_size - osize); |
rb = (char *) malloc(sb.st_size - osize); |
if (rb == NULL) { |
if (rb == NULL) |
(void) fprintf(stderr,"%s: ",progname); |
err(1, "malloc"); |
perror("malloc()"); |
|
exit(1); |
|
} |
|
|
|
/* Open logfile, seek. */ |
/* Open logfile, seek. */ |
fp = fopen(log, "r"); |
fp = fopen(log, "r"); |
if (fp == NULL) { |
if (fp == NULL) { |
(void) fprintf(stderr,"%s: ",progname); |
warn(log); |
perror(log); |
|
goto cleanup; |
goto cleanup; |
} |
} |
fseek(fp, osize, SEEK_SET); |
fseek(fp, osize, SEEK_SET); |
rd = fread(rb, 1, sb.st_size - osize, fp); |
rd = fread(rb, 1, sb.st_size - osize, fp); |
if (rd < 1) { |
if (rd < 1) { |
(void) fprintf(stderr,"%s: ",progname); |
warn("fread"); |
perror("fread()"); |
|
fclose(fp); |
fclose(fp); |
goto cleanup; |
goto cleanup; |
} |
} |
|
|
|
|
fp = openmail(); |
fp = openmail(); |
if (fp == NULL) { |
if (fp == NULL) { |
(void) fprintf(stderr,"%s: ",progname); |
warn("openmail"); |
perror("openmail()"); |
|
goto cleanup; |
goto cleanup; |
} |
} |
fprintf(fp, "To: %s\nSubject: LOGFILE NOTIFICATION: %s\n\n\n", |
fprintf(fp, "To: %s\nSubject: LOGFILE NOTIFICATION: %s\n\n\n", |
|
|
/* Reopen for writing and update file. */ |
/* Reopen for writing and update file. */ |
fp = fopen(fname, "w"); |
fp = fopen(fname, "w"); |
if (fp == NULL) { |
if (fp == NULL) { |
(void) fprintf(stderr,"%s: ",progname); |
warn(fname); |
perror(fname); |
|
goto cleanup; |
goto cleanup; |
} |
} |
#ifdef QUAD_OFF_T |
#ifdef QUAD_OFF_T |