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