newsyslog.c revision 13244
113244Sgraichen/* 213244Sgraichen * This file contains changes from the Open Software Foundation. 313244Sgraichen */ 413244Sgraichen 513244Sgraichen/* 613244Sgraichen 713244SgraichenCopyright 1988, 1989 by the Massachusetts Institute of Technology 813244Sgraichen 913244SgraichenPermission to use, copy, modify, and distribute this software 1013244Sgraichenand its documentation for any purpose and without fee is 1113244Sgraichenhereby granted, provided that the above copyright notice 1213244Sgraichenappear in all copies and that both that copyright notice and 1313244Sgraichenthis permission notice appear in supporting documentation, 1413244Sgraichenand that the names of M.I.T. and the M.I.T. S.I.P.B. not be 1513244Sgraichenused in advertising or publicity pertaining to distribution 1613244Sgraichenof the software without specific, written prior permission. 1713244SgraichenM.I.T. and the M.I.T. S.I.P.B. make no representations about 1813244Sgraichenthe suitability of this software for any purpose. It is 1913244Sgraichenprovided "as is" without express or implied warranty. 2013244Sgraichen 2113244Sgraichen*/ 2213244Sgraichen 2313244Sgraichen/* 2413244Sgraichen * newsyslog - roll over selected logs at the appropriate time, 2513244Sgraichen * keeping the a specified number of backup files around. 2613244Sgraichen * 2713244Sgraichen * $Source: /a/cvsroot/src/usr.bin/newsyslog/newsyslog.c,v $ 2813244Sgraichen * $Author: jtc $ 2913244Sgraichen */ 3013244Sgraichen 3113244Sgraichen#ifndef lint 3213244Sgraichenstatic char rcsid[] = "$Id: newsyslog.c,v 1.9 1995/01/21 21:53:46 jtc Exp $"; 3313244Sgraichen#endif /* not lint */ 3413244Sgraichen 3513244Sgraichen#ifndef CONF 3613244Sgraichen#define CONF "/etc/athena/newsyslog.conf" /* Configuration file */ 3713244Sgraichen#endif 3813244Sgraichen#ifndef PIDFILE 3913244Sgraichen#define PIDFILE "/etc/syslog.pid" 4013244Sgraichen#endif 4113244Sgraichen#ifndef COMPRESS 4213244Sgraichen#define COMPRESS "/usr/ucb/compress" /* File compression program */ 4313244Sgraichen#endif 4413244Sgraichen#ifndef COMPRESS_POSTFIX 4513244Sgraichen#define COMPRESS_POSTFIX ".Z" 4613244Sgraichen#endif 4713244Sgraichen 4813244Sgraichen#include <stdio.h> 4913244Sgraichen#include <stdlib.h> 5013244Sgraichen#include <string.h> 5113244Sgraichen#include <ctype.h> 5213244Sgraichen#include <signal.h> 5313244Sgraichen#include <pwd.h> 5413244Sgraichen#include <grp.h> 5513244Sgraichen#include <sys/types.h> 5613244Sgraichen#include <sys/time.h> 5713244Sgraichen#include <sys/stat.h> 5813244Sgraichen#include <sys/param.h> 5913244Sgraichen#include <sys/wait.h> 6013244Sgraichen 6113244Sgraichen#define kbytes(size) (((size) + 1023) >> 10) 6213244Sgraichen#ifdef _IBMR2 6313244Sgraichen/* Calculates (db * DEV_BSIZE) */ 6413244Sgraichen#define dbtob(db) ((unsigned)(db) << UBSHIFT) 6513244Sgraichen#endif 6613244Sgraichen 6713244Sgraichen#define CE_COMPACT 1 /* Compact the achived log files */ 6813244Sgraichen#define CE_BINARY 2 /* Logfile is in binary, don't add */ 6913244Sgraichen /* status messages */ 7013244Sgraichen#define NONE -1 7113244Sgraichen 7213244Sgraichenstruct conf_entry { 7313244Sgraichen char *log; /* Name of the log */ 7413244Sgraichen int uid; /* Owner of log */ 7513244Sgraichen int gid; /* Group of log */ 7613244Sgraichen int numlogs; /* Number of logs to keep */ 7713244Sgraichen int size; /* Size cutoff to trigger trimming the log */ 7813244Sgraichen int hours; /* Hours between log trimming */ 7913244Sgraichen int permissions; /* File permissions on the log */ 8013244Sgraichen int flags; /* Flags (CE_COMPACT & CE_BINARY) */ 8113244Sgraichen struct conf_entry *next; /* Linked list pointer */ 8213244Sgraichen}; 8313244Sgraichen 8413244Sgraichenextern int optind; 8513244Sgraichenextern char *optarg; 8613244Sgraichenextern char *malloc(); 8713244Sgraichenextern uid_t getuid(),geteuid(); 8813244Sgraichenextern time_t time(); 8913244Sgraichen 9013244Sgraichenchar *progname; /* contains argv[0] */ 9113244Sgraichenint verbose = 0; /* Print out what's going on */ 9213244Sgraichenint needroot = 1; /* Root privs are necessary */ 9313244Sgraichenint noaction = 0; /* Don't do anything, just show it */ 9413244Sgraichenchar *conf = CONF; /* Configuration file to use */ 9513244Sgraichentime_t timenow; 9613244Sgraichenint syslog_pid; /* read in from /etc/syslog.pid */ 9713244Sgraichen#define MIN_PID 3 9813244Sgraichen#define MAX_PID 65534 9913244Sgraichenchar hostname[64]; /* hostname */ 10013244Sgraichenchar *daytime; /* timenow in human readable form */ 10113244Sgraichen 10213244Sgraichen 10313244Sgraichenstruct conf_entry *parse_file(); 10413244Sgraichenchar *sob(), *son(), *strdup(), *missing_field(); 10513244Sgraichen 10613244Sgraichenmain(argc,argv) 10713244Sgraichen int argc; 10813244Sgraichen char **argv; 10913244Sgraichen{ 11013244Sgraichen struct conf_entry *p, *q; 11113244Sgraichen 11213244Sgraichen PRS(argc,argv); 11313244Sgraichen if (needroot && getuid() && geteuid()) { 11413244Sgraichen fprintf(stderr,"%s: must have root privs\n",progname); 11513244Sgraichen exit(1); 11613244Sgraichen } 11713244Sgraichen p = q = parse_file(); 11813244Sgraichen while (p) { 11913244Sgraichen do_entry(p); 12013244Sgraichen p=p->next; 12113244Sgraichen free((char *) q); 12213244Sgraichen q=p; 12313244Sgraichen } 12413244Sgraichen exit(0); 12513244Sgraichen} 12613244Sgraichen 12713244Sgraichendo_entry(ent) 12813244Sgraichen struct conf_entry *ent; 12913244Sgraichen 13013244Sgraichen{ 13113244Sgraichen int size, modtime; 13213244Sgraichen 13313244Sgraichen if (verbose) { 13413244Sgraichen if (ent->flags & CE_COMPACT) 13513244Sgraichen printf("%s <%dZ>: ",ent->log,ent->numlogs); 13613244Sgraichen else 13713244Sgraichen printf("%s <%d>: ",ent->log,ent->numlogs); 13813244Sgraichen } 13913244Sgraichen size = sizefile(ent->log); 14013244Sgraichen modtime = age_old_log(ent->log); 14113244Sgraichen if (size < 0) { 14213244Sgraichen if (verbose) 14313244Sgraichen printf("does not exist.\n"); 14413244Sgraichen } else { 14513244Sgraichen if (verbose && (ent->size > 0)) 14613244Sgraichen printf("size (Kb): %d [%d] ", size, ent->size); 14713244Sgraichen if (verbose && (ent->hours > 0)) 14813244Sgraichen printf(" age (hr): %d [%d] ", modtime, ent->hours); 14913244Sgraichen if (((ent->size > 0) && (size >= ent->size)) || 15013244Sgraichen ((ent->hours > 0) && ((modtime >= ent->hours) 15113244Sgraichen || (modtime < 0)))) { 15213244Sgraichen if (verbose) 15313244Sgraichen printf("--> trimming log....\n"); 15413244Sgraichen if (noaction && !verbose) { 15513244Sgraichen if (ent->flags & CE_COMPACT) 15613244Sgraichen printf("%s <%dZ>: trimming", 15713244Sgraichen ent->log,ent->numlogs); 15813244Sgraichen else 15913244Sgraichen printf("%s <%d>: trimming", 16013244Sgraichen ent->log,ent->numlogs); 16113244Sgraichen } 16213244Sgraichen dotrim(ent->log, ent->numlogs, ent->flags, 16313244Sgraichen ent->permissions, ent->uid, ent->gid); 16413244Sgraichen } else { 16513244Sgraichen if (verbose) 16613244Sgraichen printf("--> skipping\n"); 16713244Sgraichen } 16813244Sgraichen } 16913244Sgraichen} 17013244Sgraichen 17113244SgraichenPRS(argc,argv) 17213244Sgraichen int argc; 17313244Sgraichen char **argv; 17413244Sgraichen{ 17513244Sgraichen int c; 17613244Sgraichen FILE *f; 17713244Sgraichen char line[BUFSIZ]; 17813244Sgraichen char *p; 17913244Sgraichen 18013244Sgraichen progname = argv[0]; 18113244Sgraichen timenow = time((time_t *) 0); 18213244Sgraichen daytime = ctime(&timenow) + 4; 18313244Sgraichen daytime[16] = '\0'; 18413244Sgraichen 18513244Sgraichen /* Let's find the pid of syslogd */ 18613244Sgraichen syslog_pid = 0; 18713244Sgraichen f = fopen(PIDFILE,"r"); 18813244Sgraichen if (f && fgets(line,BUFSIZ,f)) 18913244Sgraichen syslog_pid = atoi(line); 19013244Sgraichen if (f) 19113244Sgraichen (void)fclose(f); 19213244Sgraichen 19313244Sgraichen /* Let's get our hostname */ 19413244Sgraichen (void) gethostname(hostname, sizeof(hostname)); 19513244Sgraichen 19613244Sgraichen /* Truncate domain */ 19713244Sgraichen if (p = strchr(hostname, '.')) { 19813244Sgraichen *p = '\0'; 19913244Sgraichen } 20013244Sgraichen 20113244Sgraichen optind = 1; /* Start options parsing */ 20213244Sgraichen while ((c=getopt(argc,argv,"nrvf:t:")) != EOF) 20313244Sgraichen switch (c) { 20413244Sgraichen case 'n': 20513244Sgraichen noaction++; /* This implies needroot as off */ 20613244Sgraichen /* fall through */ 20713244Sgraichen case 'r': 20813244Sgraichen needroot = 0; 20913244Sgraichen break; 21013244Sgraichen case 'v': 21113244Sgraichen verbose++; 21213244Sgraichen break; 21313244Sgraichen case 'f': 21413244Sgraichen conf = optarg; 21513244Sgraichen break; 21613244Sgraichen default: 21713244Sgraichen usage(); 21813244Sgraichen } 21913244Sgraichen } 22013244Sgraichen 22113244Sgraichenusage() 22213244Sgraichen{ 22313244Sgraichen fprintf(stderr, 22413244Sgraichen "Usage: %s <-nrv> <-f config-file>\n", progname); 22513244Sgraichen exit(1); 22613244Sgraichen} 22713244Sgraichen 22813244Sgraichen/* Parse a configuration file and return a linked list of all the logs 22913244Sgraichen * to process 23013244Sgraichen */ 23113244Sgraichenstruct conf_entry *parse_file() 23213244Sgraichen{ 23313244Sgraichen FILE *f; 23413244Sgraichen char line[BUFSIZ], *parse, *q; 23513244Sgraichen char *errline, *group; 23613244Sgraichen struct conf_entry *first = NULL; 23713244Sgraichen struct conf_entry *working; 23813244Sgraichen struct passwd *pass; 23913244Sgraichen struct group *grp; 24013244Sgraichen 24113244Sgraichen if (strcmp(conf,"-")) 24213244Sgraichen f = fopen(conf,"r"); 24313244Sgraichen else 24413244Sgraichen f = stdin; 24513244Sgraichen if (!f) { 24613244Sgraichen (void) fprintf(stderr,"%s: ",progname); 24713244Sgraichen perror(conf); 24813244Sgraichen exit(1); 24913244Sgraichen } 25013244Sgraichen while (fgets(line,BUFSIZ,f)) { 25113244Sgraichen if ((line[0]== '\n') || (line[0] == '#')) 25213244Sgraichen continue; 25313244Sgraichen errline = strdup(line); 25413244Sgraichen if (!first) { 25513244Sgraichen working = (struct conf_entry *) malloc(sizeof(struct conf_entry)); 25613244Sgraichen first = working; 25713244Sgraichen } else { 25813244Sgraichen working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry)); 25913244Sgraichen working = working->next; 26013244Sgraichen } 26113244Sgraichen 26213244Sgraichen q = parse = missing_field(sob(line),errline); 26313244Sgraichen *(parse = son(line)) = '\0'; 26413244Sgraichen working->log = strdup(q); 26513244Sgraichen 26613244Sgraichen q = parse = missing_field(sob(++parse),errline); 26713244Sgraichen *(parse = son(parse)) = '\0'; 26813244Sgraichen if ((group = strchr(q, '.')) != NULL) { 26913244Sgraichen *group++ = '\0'; 27013244Sgraichen if (*q) { 27113244Sgraichen if (!(isnumber(*q))) { 27213244Sgraichen if ((pass = getpwnam(q)) == NULL) { 27313244Sgraichen fprintf(stderr, 27413244Sgraichen "Error in config file; unknown user:\n"); 27513244Sgraichen fputs(errline,stderr); 27613244Sgraichen exit(1); 27713244Sgraichen } 27813244Sgraichen working->uid = pass->pw_uid; 27913244Sgraichen } else 28013244Sgraichen working->uid = atoi(q); 28113244Sgraichen } else 28213244Sgraichen working->uid = NONE; 28313244Sgraichen 28413244Sgraichen q = group; 28513244Sgraichen if (*q) { 28613244Sgraichen if (!(isnumber(*q))) { 28713244Sgraichen if ((grp = getgrnam(q)) == NULL) { 28813244Sgraichen fprintf(stderr, 28913244Sgraichen "Error in config file; unknown group:\n"); 29013244Sgraichen fputs(errline,stderr); 29113244Sgraichen exit(1); 29213244Sgraichen } 29313244Sgraichen working->gid = grp->gr_gid; 29413244Sgraichen } else 29513244Sgraichen working->gid = atoi(q); 29613244Sgraichen } else 29713244Sgraichen working->gid = NONE; 29813244Sgraichen 29913244Sgraichen q = parse = missing_field(sob(++parse),errline); 30013244Sgraichen *(parse = son(parse)) = '\0'; 30113244Sgraichen } 30213244Sgraichen else 30313244Sgraichen working->uid = working->gid = NONE; 30413244Sgraichen 30513244Sgraichen if (!sscanf(q,"%o",&working->permissions)) { 30613244Sgraichen fprintf(stderr, 30713244Sgraichen "Error in config file; bad permissions:\n"); 30813244Sgraichen fputs(errline,stderr); 30913244Sgraichen exit(1); 31013244Sgraichen } 31113244Sgraichen 31213244Sgraichen q = parse = missing_field(sob(++parse),errline); 31313244Sgraichen *(parse = son(parse)) = '\0'; 31413244Sgraichen if (!sscanf(q,"%d",&working->numlogs)) { 31513244Sgraichen fprintf(stderr, 31613244Sgraichen "Error in config file; bad number:\n"); 31713244Sgraichen fputs(errline,stderr); 31813244Sgraichen exit(1); 31913244Sgraichen } 32013244Sgraichen 32113244Sgraichen q = parse = missing_field(sob(++parse),errline); 32213244Sgraichen *(parse = son(parse)) = '\0'; 32313244Sgraichen if (isdigit(*q)) 32413244Sgraichen working->size = atoi(q); 32513244Sgraichen else 32613244Sgraichen working->size = -1; 32713244Sgraichen 32813244Sgraichen q = parse = missing_field(sob(++parse),errline); 32913244Sgraichen *(parse = son(parse)) = '\0'; 33013244Sgraichen if (isdigit(*q)) 33113244Sgraichen working->hours = atoi(q); 33213244Sgraichen else 33313244Sgraichen working->hours = -1; 33413244Sgraichen 33513244Sgraichen q = parse = sob(++parse); /* Optional field */ 33613244Sgraichen *(parse = son(parse)) = '\0'; 33713244Sgraichen working->flags = 0; 33813244Sgraichen while (q && *q && !isspace(*q)) { 33913244Sgraichen if ((*q == 'Z') || (*q == 'z')) 34013244Sgraichen working->flags |= CE_COMPACT; 34113244Sgraichen else if ((*q == 'B') || (*q == 'b')) 34213244Sgraichen working->flags |= CE_BINARY; 34313244Sgraichen else { 34413244Sgraichen fprintf(stderr, 34513244Sgraichen "Illegal flag in config file -- %c\n", 34613244Sgraichen *q); 34713244Sgraichen exit(1); 34813244Sgraichen } 34913244Sgraichen q++; 35013244Sgraichen } 35113244Sgraichen 35213244Sgraichen free(errline); 35313244Sgraichen } 35413244Sgraichen if (working) 35513244Sgraichen working->next = (struct conf_entry *) NULL; 35613244Sgraichen (void) fclose(f); 35713244Sgraichen return(first); 35813244Sgraichen} 35913244Sgraichen 36013244Sgraichenchar *missing_field(p,errline) 36113244Sgraichen char *p,*errline; 36213244Sgraichen{ 36313244Sgraichen if (!p || !*p) { 36413244Sgraichen fprintf(stderr,"Missing field in config file:\n"); 36513244Sgraichen fputs(errline,stderr); 36613244Sgraichen exit(1); 36713244Sgraichen } 36813244Sgraichen return(p); 36913244Sgraichen} 37013244Sgraichen 37113244Sgraichendotrim(log,numdays,flags,perm,owner_uid,group_gid) 37213244Sgraichen char *log; 37313244Sgraichen int numdays; 37413244Sgraichen int flags; 37513244Sgraichen int perm; 37613244Sgraichen int owner_uid; 37713244Sgraichen int group_gid; 37813244Sgraichen{ 37913244Sgraichen char file1[128], file2[128]; 38013244Sgraichen char zfile1[128], zfile2[128]; 38113244Sgraichen int fd; 38213244Sgraichen struct stat st; 38313244Sgraichen 38413244Sgraichen#ifdef _IBMR2 38513244Sgraichen/* AIX 3.1 has a broken fchown- if the owner_uid is -1, it will actually */ 38613244Sgraichen/* change it to be owned by uid -1, instead of leaving it as is, as it is */ 38713244Sgraichen/* supposed to. */ 38813244Sgraichen if (owner_uid == -1) 38913244Sgraichen owner_uid = geteuid(); 39013244Sgraichen#endif 39113244Sgraichen 39213244Sgraichen /* Remove oldest log */ 39313244Sgraichen (void) sprintf(file1,"%s.%d",log,numdays); 39413244Sgraichen (void) strcpy(zfile1, file1); 39513244Sgraichen (void) strcat(zfile1, COMPRESS_POSTFIX); 39613244Sgraichen 39713244Sgraichen if (noaction) { 39813244Sgraichen printf("rm -f %s\n", file1); 39913244Sgraichen printf("rm -f %s\n", zfile1); 40013244Sgraichen } else { 40113244Sgraichen (void) unlink(file1); 40213244Sgraichen (void) unlink(zfile1); 40313244Sgraichen } 40413244Sgraichen 40513244Sgraichen /* Move down log files */ 40613244Sgraichen while (numdays--) { 40713244Sgraichen (void) strcpy(file2,file1); 40813244Sgraichen (void) sprintf(file1,"%s.%d",log,numdays); 40913244Sgraichen (void) strcpy(zfile1, file1); 41013244Sgraichen (void) strcpy(zfile2, file2); 41113244Sgraichen if (lstat(file1, &st)) { 41213244Sgraichen (void) strcat(zfile1, COMPRESS_POSTFIX); 41313244Sgraichen (void) strcat(zfile2, COMPRESS_POSTFIX); 41413244Sgraichen if (lstat(zfile1, &st)) continue; 41513244Sgraichen } 41613244Sgraichen if (noaction) { 41713244Sgraichen printf("mv %s %s\n",zfile1,zfile2); 41813244Sgraichen printf("chmod %o %s\n", perm, zfile2); 41913244Sgraichen printf("chown %d.%d %s\n", 42013244Sgraichen owner_uid, group_gid, zfile2); 42113244Sgraichen } else { 42213244Sgraichen (void) rename(zfile1, zfile2); 42313244Sgraichen (void) chmod(zfile2, perm); 42413244Sgraichen (void) chown(zfile2, owner_uid, group_gid); 42513244Sgraichen } 42613244Sgraichen } 42713244Sgraichen if (!noaction && !(flags & CE_BINARY)) 42813244Sgraichen (void) log_trim(log); /* Report the trimming to the old log */ 42913244Sgraichen 43013244Sgraichen if (noaction) 43113244Sgraichen printf("mv %s to %s\n",log,file1); 43213244Sgraichen else 43313244Sgraichen (void) rename(log,file1); 43413244Sgraichen if (noaction) 43513244Sgraichen printf("Start new log..."); 43613244Sgraichen else { 43713244Sgraichen fd = creat(log,perm); 43813244Sgraichen if (fd < 0) { 43913244Sgraichen perror("can't start new log"); 44013244Sgraichen exit(1); 44113244Sgraichen } 44213244Sgraichen if (fchown(fd, owner_uid, group_gid)) { 44313244Sgraichen perror("can't chmod new log file"); 44413244Sgraichen exit(1); 44513244Sgraichen } 44613244Sgraichen (void) close(fd); 44713244Sgraichen if (!(flags & CE_BINARY)) 44813244Sgraichen if (log_trim(log)) { /* Add status message */ 44913244Sgraichen perror("can't add status message to log"); 45013244Sgraichen exit(1); 45113244Sgraichen } 45213244Sgraichen } 45313244Sgraichen if (noaction) 45413244Sgraichen printf("chmod %o %s...",perm,log); 45513244Sgraichen else 45613244Sgraichen (void) chmod(log,perm); 45713244Sgraichen if (noaction) 45813244Sgraichen printf("kill -HUP %d (syslogd)\n",syslog_pid); 45913244Sgraichen else 46013244Sgraichen if (syslog_pid < MIN_PID || syslog_pid > MAX_PID) { 46113244Sgraichen fprintf(stderr,"%s: preposterous process number: %d\n", 46213244Sgraichen progname, syslog_pid); 46313244Sgraichen } else if (kill(syslog_pid,SIGHUP)) { 46413244Sgraichen fprintf(stderr,"%s: ",progname); 46513244Sgraichen perror("warning - could not restart syslogd"); 46613244Sgraichen } 46713244Sgraichen if (flags & CE_COMPACT) { 46813244Sgraichen if (noaction) 46913244Sgraichen printf("Compress %s.0\n",log); 47013244Sgraichen else 47113244Sgraichen compress_log(log); 47213244Sgraichen } 47313244Sgraichen} 47413244Sgraichen 47513244Sgraichen/* Log the fact that the logs were turned over */ 47613244Sgraichenlog_trim(log) 47713244Sgraichen char *log; 47813244Sgraichen{ 47913244Sgraichen FILE *f; 48013244Sgraichen if ((f = fopen(log,"a")) == NULL) 48113244Sgraichen return(-1); 48213244Sgraichen fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n", 48313244Sgraichen daytime, hostname, getpid()); 48413244Sgraichen if (fclose(f) == EOF) { 48513244Sgraichen perror("log_trim: fclose:"); 48613244Sgraichen exit(1); 48713244Sgraichen } 48813244Sgraichen return(0); 48913244Sgraichen} 49013244Sgraichen 49113244Sgraichen/* Fork of /usr/ucb/compress to compress the old log file */ 49213244Sgraichencompress_log(log) 49313244Sgraichen char *log; 49413244Sgraichen{ 49513244Sgraichen int pid; 49613244Sgraichen char tmp[128]; 49713244Sgraichen 49813244Sgraichen pid = fork(); 49913244Sgraichen (void) sprintf(tmp,"%s.0",log); 50013244Sgraichen if (pid < 0) { 50113244Sgraichen fprintf(stderr,"%s: ",progname); 50213244Sgraichen perror("fork"); 50313244Sgraichen exit(1); 50413244Sgraichen } else if (!pid) { 50513244Sgraichen (void) execl(COMPRESS,"compress","-f",tmp,0); 50613244Sgraichen fprintf(stderr,"%s: ",progname); 50713244Sgraichen perror(COMPRESS); 50813244Sgraichen exit(1); 50913244Sgraichen } 51013244Sgraichen} 51113244Sgraichen 51213244Sgraichen/* Return size in kilobytes of a file */ 51313244Sgraichenint sizefile(file) 51413244Sgraichen char *file; 51513244Sgraichen{ 51613244Sgraichen struct stat sb; 51713244Sgraichen 51813244Sgraichen if (stat(file,&sb) < 0) 51913244Sgraichen return(-1); 52013244Sgraichen return(kbytes(dbtob(sb.st_blocks))); 52113244Sgraichen} 52213244Sgraichen 52313244Sgraichen/* Return the age of old log file (file.0) */ 52413244Sgraichenint age_old_log(file) 52513244Sgraichen char *file; 52613244Sgraichen{ 52713244Sgraichen struct stat sb; 52813244Sgraichen char tmp[MAXPATHLEN+3]; 52913244Sgraichen 53013244Sgraichen (void) strcpy(tmp,file); 53113244Sgraichen if (stat(strcat(tmp,".0"),&sb) < 0) 53213244Sgraichen if (stat(strcat(tmp,COMPRESS_POSTFIX), &sb) < 0) 53313244Sgraichen return(-1); 53413244Sgraichen return( (int) (timenow - sb.st_mtime + 1800) / 3600); 53513244Sgraichen} 53613244Sgraichen 53713244Sgraichen 53813244Sgraichen#ifndef OSF 53913244Sgraichen/* Duplicate a string using malloc */ 54013244Sgraichen 54113244Sgraichenchar *strdup(strp) 54213244Sgraichenregister char *strp; 54313244Sgraichen{ 54413244Sgraichen register char *cp; 54513244Sgraichen 54613244Sgraichen if ((cp = malloc((unsigned) strlen(strp) + 1)) == NULL) 54713244Sgraichen abort(); 54813244Sgraichen return(strcpy (cp, strp)); 54913244Sgraichen} 55013244Sgraichen#endif 55113244Sgraichen 55213244Sgraichen/* Skip Over Blanks */ 55313244Sgraichenchar *sob(p) 55413244Sgraichen register char *p; 55513244Sgraichen{ 55613244Sgraichen while (p && *p && isspace(*p)) 55713244Sgraichen p++; 55813244Sgraichen return(p); 55913244Sgraichen} 56013244Sgraichen 56113244Sgraichen/* Skip Over Non-Blanks */ 56213244Sgraichenchar *son(p) 56313244Sgraichen register char *p; 56413244Sgraichen{ 56513244Sgraichen while (p && *p && !isspace(*p)) 56613244Sgraichen p++; 56713244Sgraichen return(p); 56813244Sgraichen} 569