newsyslog.c revision 1.3 1 1.1 cgd /*
2 1.1 cgd * This file contains changes from the Open Software Foundation.
3 1.1 cgd * The RCS history log will appear at the end of this file.
4 1.3 cgd * @(#)newsyslog.c $Revision: 1.3 $ $Date: 1993/05/22 03:52:20 $ $Locker: $
5 1.1 cgd */
6 1.1 cgd
7 1.1 cgd /*
8 1.1 cgd
9 1.2 cgd Copyright 1988, 1989 by the Massachusetts Institute of Technology
10 1.1 cgd
11 1.2 cgd Permission to use, copy, modify, and distribute this software
12 1.2 cgd and its documentation for any purpose and without fee is
13 1.2 cgd hereby granted, provided that the above copyright notice
14 1.2 cgd appear in all copies and that both that copyright notice and
15 1.2 cgd this permission notice appear in supporting documentation,
16 1.2 cgd and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
17 1.2 cgd used in advertising or publicity pertaining to distribution
18 1.2 cgd of the software without specific, written prior permission.
19 1.2 cgd M.I.T. and the M.I.T. S.I.P.B. make no representations about
20 1.2 cgd the suitability of this software for any purpose. It is
21 1.2 cgd provided "as is" without express or implied warranty.
22 1.1 cgd
23 1.1 cgd */
24 1.1 cgd
25 1.1 cgd /*
26 1.1 cgd * newsyslog - roll over selected logs at the appropriate time,
27 1.1 cgd * keeping the a specified number of backup files around.
28 1.1 cgd *
29 1.2 cgd * $Source: /tank/opengrok/rsync2/NetBSD/src/usr.bin/newsyslog/newsyslog.c,v $
30 1.2 cgd * $Author: cgd $
31 1.1 cgd */
32 1.1 cgd
33 1.1 cgd #if !defined(lint) && !defined(_NOIDENT)
34 1.3 cgd static char rcsid[] = "@(#)$RCSfile: newsyslog.c,v $ $Revision: 1.3 $ (OSF) $Date: 1993/05/22 03:52:20 $";
35 1.1 cgd #endif
36 1.1 cgd
37 1.1 cgd #ifndef CONF
38 1.1 cgd #define CONF "/etc/athena/newsyslog.conf" /* Configuration file */
39 1.1 cgd #endif
40 1.1 cgd #ifndef PIDFILE
41 1.1 cgd #define PIDFILE "/etc/syslog.pid"
42 1.1 cgd #endif
43 1.1 cgd #ifndef COMPRESS
44 1.1 cgd #define COMPRESS "/usr/ucb/compress" /* File compression program */
45 1.1 cgd #endif
46 1.3 cgd #ifndef COMPRESS_POSTFIX
47 1.3 cgd #define COMPRESS_POSTFIX ".Z"
48 1.3 cgd #endif
49 1.1 cgd
50 1.1 cgd #include <stdio.h>
51 1.1 cgd #include <strings.h>
52 1.1 cgd #include <ctype.h>
53 1.1 cgd #include <signal.h>
54 1.1 cgd #include <pwd.h>
55 1.1 cgd #include <grp.h>
56 1.1 cgd #include <sys/types.h>
57 1.1 cgd #include <sys/time.h>
58 1.1 cgd #include <sys/stat.h>
59 1.1 cgd #include <sys/param.h>
60 1.1 cgd #include <sys/wait.h>
61 1.1 cgd
62 1.1 cgd #define kbytes(size) (((size) + 1023) >> 10)
63 1.1 cgd #ifdef _IBMR2
64 1.1 cgd /* Calculates (db * DEV_BSIZE) */
65 1.1 cgd #define dbtob(db) ((unsigned)(db) << UBSHIFT)
66 1.1 cgd #endif
67 1.1 cgd
68 1.1 cgd #define CE_COMPACT 1 /* Compact the achived log files */
69 1.1 cgd #define CE_BINARY 2 /* Logfile is in binary, don't add */
70 1.1 cgd /* status messages */
71 1.1 cgd #define NONE -1
72 1.1 cgd
73 1.1 cgd struct conf_entry {
74 1.1 cgd char *log; /* Name of the log */
75 1.1 cgd int uid; /* Owner of log */
76 1.1 cgd int gid; /* Group of log */
77 1.1 cgd int numlogs; /* Number of logs to keep */
78 1.1 cgd int size; /* Size cutoff to trigger trimming the log */
79 1.1 cgd int hours; /* Hours between log trimming */
80 1.1 cgd int permissions; /* File permissions on the log */
81 1.1 cgd int flags; /* Flags (CE_COMPACT & CE_BINARY) */
82 1.1 cgd struct conf_entry *next; /* Linked list pointer */
83 1.1 cgd };
84 1.1 cgd
85 1.1 cgd extern int optind;
86 1.1 cgd extern char *optarg;
87 1.1 cgd extern char *malloc();
88 1.1 cgd extern uid_t getuid(),geteuid();
89 1.1 cgd extern time_t time();
90 1.1 cgd
91 1.1 cgd char *progname; /* contains argv[0] */
92 1.1 cgd int verbose = 0; /* Print out what's going on */
93 1.1 cgd int needroot = 1; /* Root privs are necessary */
94 1.1 cgd int noaction = 0; /* Don't do anything, just show it */
95 1.1 cgd char *conf = CONF; /* Configuration file to use */
96 1.1 cgd time_t timenow;
97 1.1 cgd int syslog_pid; /* read in from /etc/syslog.pid */
98 1.1 cgd char hostname[64]; /* hostname */
99 1.1 cgd char *daytime; /* timenow in human readable form */
100 1.1 cgd
101 1.1 cgd
102 1.1 cgd struct conf_entry *parse_file();
103 1.1 cgd char *sob(), *son(), *strdup(), *missing_field();
104 1.1 cgd
105 1.1 cgd main(argc,argv)
106 1.1 cgd int argc;
107 1.1 cgd char **argv;
108 1.1 cgd {
109 1.1 cgd struct conf_entry *p, *q;
110 1.1 cgd
111 1.1 cgd PRS(argc,argv);
112 1.1 cgd if (needroot && getuid() && geteuid()) {
113 1.1 cgd fprintf(stderr,"%s: must have root privs\n",progname);
114 1.1 cgd exit(1);
115 1.1 cgd }
116 1.1 cgd p = q = parse_file();
117 1.1 cgd while (p) {
118 1.1 cgd do_entry(p);
119 1.1 cgd p=p->next;
120 1.1 cgd free((char *) q);
121 1.1 cgd q=p;
122 1.1 cgd }
123 1.1 cgd exit(0);
124 1.1 cgd }
125 1.1 cgd
126 1.1 cgd do_entry(ent)
127 1.1 cgd struct conf_entry *ent;
128 1.1 cgd
129 1.1 cgd {
130 1.1 cgd int size, modtime;
131 1.1 cgd
132 1.1 cgd if (verbose) {
133 1.1 cgd if (ent->flags & CE_COMPACT)
134 1.1 cgd printf("%s <%dZ>: ",ent->log,ent->numlogs);
135 1.1 cgd else
136 1.1 cgd printf("%s <%d>: ",ent->log,ent->numlogs);
137 1.1 cgd }
138 1.1 cgd size = sizefile(ent->log);
139 1.1 cgd modtime = age_old_log(ent->log);
140 1.1 cgd if (size < 0) {
141 1.1 cgd if (verbose)
142 1.1 cgd printf("does not exist.\n");
143 1.1 cgd } else {
144 1.1 cgd if (verbose && (ent->size > 0))
145 1.1 cgd printf("size (Kb): %d [%d] ", size, ent->size);
146 1.1 cgd if (verbose && (ent->hours > 0))
147 1.1 cgd printf(" age (hr): %d [%d] ", modtime, ent->hours);
148 1.1 cgd if (((ent->size > 0) && (size >= ent->size)) ||
149 1.1 cgd ((ent->hours > 0) && ((modtime >= ent->hours)
150 1.1 cgd || (modtime < 0)))) {
151 1.1 cgd if (verbose)
152 1.1 cgd printf("--> trimming log....\n");
153 1.1 cgd if (noaction && !verbose) {
154 1.1 cgd if (ent->flags & CE_COMPACT)
155 1.1 cgd printf("%s <%dZ>: trimming",
156 1.1 cgd ent->log,ent->numlogs);
157 1.1 cgd else
158 1.1 cgd printf("%s <%d>: trimming",
159 1.1 cgd ent->log,ent->numlogs);
160 1.1 cgd }
161 1.1 cgd dotrim(ent->log, ent->numlogs, ent->flags,
162 1.1 cgd ent->permissions, ent->uid, ent->gid);
163 1.1 cgd } else {
164 1.1 cgd if (verbose)
165 1.1 cgd printf("--> skipping\n");
166 1.1 cgd }
167 1.1 cgd }
168 1.1 cgd }
169 1.1 cgd
170 1.1 cgd PRS(argc,argv)
171 1.1 cgd int argc;
172 1.1 cgd char **argv;
173 1.1 cgd {
174 1.1 cgd int c;
175 1.1 cgd FILE *f;
176 1.1 cgd char line[BUFSIZ];
177 1.1 cgd
178 1.1 cgd progname = argv[0];
179 1.1 cgd timenow = time((time_t *) 0);
180 1.1 cgd daytime = ctime(&timenow);
181 1.1 cgd daytime[strlen(daytime)-1] = '\0';
182 1.1 cgd
183 1.1 cgd /* Let's find the pid of syslogd */
184 1.1 cgd syslog_pid = 0;
185 1.1 cgd f = fopen(PIDFILE,"r");
186 1.1 cgd if (f && fgets(line,BUFSIZ,f))
187 1.1 cgd syslog_pid = atoi(line);
188 1.1 cgd
189 1.1 cgd /* Let's get our hostname */
190 1.1 cgd if (gethostname(hostname, 64)) {
191 1.1 cgd perror("gethostname");
192 1.1 cgd (void) strcpy(hostname,"Mystery Host");
193 1.1 cgd }
194 1.1 cgd
195 1.1 cgd optind = 1; /* Start options parsing */
196 1.1 cgd while ((c=getopt(argc,argv,"nrvf:t:")) != EOF)
197 1.1 cgd switch (c) {
198 1.1 cgd case 'n':
199 1.1 cgd noaction++; /* This implies needroot as off */
200 1.1 cgd /* fall through */
201 1.1 cgd case 'r':
202 1.1 cgd needroot = 0;
203 1.1 cgd break;
204 1.1 cgd case 'v':
205 1.1 cgd verbose++;
206 1.1 cgd break;
207 1.1 cgd case 'f':
208 1.1 cgd conf = optarg;
209 1.1 cgd break;
210 1.1 cgd default:
211 1.1 cgd usage();
212 1.1 cgd }
213 1.1 cgd }
214 1.1 cgd
215 1.1 cgd usage()
216 1.1 cgd {
217 1.1 cgd fprintf(stderr,
218 1.1 cgd "Usage: %s <-nrv> <-f config-file>\n");
219 1.1 cgd exit(1);
220 1.1 cgd }
221 1.1 cgd
222 1.1 cgd /* Parse a configuration file and return a linked list of all the logs
223 1.1 cgd * to process
224 1.1 cgd */
225 1.1 cgd struct conf_entry *parse_file()
226 1.1 cgd {
227 1.1 cgd FILE *f;
228 1.1 cgd char line[BUFSIZ], *parse, *q;
229 1.1 cgd char *errline, *group;
230 1.1 cgd struct conf_entry *first = NULL;
231 1.1 cgd struct conf_entry *working;
232 1.1 cgd struct passwd *pass;
233 1.1 cgd struct group *grp;
234 1.1 cgd
235 1.1 cgd if (strcmp(conf,"-"))
236 1.1 cgd f = fopen(conf,"r");
237 1.1 cgd else
238 1.1 cgd f = stdin;
239 1.1 cgd if (!f) {
240 1.1 cgd (void) fprintf(stderr,"%s: ",progname);
241 1.1 cgd perror(conf);
242 1.1 cgd exit(1);
243 1.1 cgd }
244 1.1 cgd while (fgets(line,BUFSIZ,f)) {
245 1.1 cgd if ((line[0]== '\n') || (line[0] == '#'))
246 1.1 cgd continue;
247 1.1 cgd errline = strdup(line);
248 1.1 cgd if (!first) {
249 1.1 cgd working = (struct conf_entry *) malloc(sizeof(struct conf_entry));
250 1.1 cgd first = working;
251 1.1 cgd } else {
252 1.1 cgd working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry));
253 1.1 cgd working = working->next;
254 1.1 cgd }
255 1.1 cgd
256 1.1 cgd q = parse = missing_field(sob(line),errline);
257 1.1 cgd *(parse = son(line)) = '\0';
258 1.1 cgd working->log = strdup(q);
259 1.1 cgd
260 1.1 cgd q = parse = missing_field(sob(++parse),errline);
261 1.1 cgd *(parse = son(parse)) = '\0';
262 1.1 cgd if ((group = index(q, '.')) != NULL) {
263 1.1 cgd *group++ = '\0';
264 1.1 cgd if (*q) {
265 1.1 cgd if (!(isnumber(q))) {
266 1.1 cgd if ((pass = getpwnam(q)) == NULL) {
267 1.1 cgd fprintf(stderr,
268 1.1 cgd "Error in config file; unknown user:\n");
269 1.1 cgd fputs(errline,stderr);
270 1.1 cgd exit(1);
271 1.1 cgd }
272 1.1 cgd working->uid = pass->pw_uid;
273 1.1 cgd } else
274 1.1 cgd working->uid = atoi(q);
275 1.1 cgd } else
276 1.1 cgd working->uid = NONE;
277 1.1 cgd
278 1.1 cgd q = group;
279 1.1 cgd if (*q) {
280 1.1 cgd if (!(isnumber(q))) {
281 1.1 cgd if ((grp = getgrnam(q)) == NULL) {
282 1.1 cgd fprintf(stderr,
283 1.1 cgd "Error in config file; unknown group:\n");
284 1.1 cgd fputs(errline,stderr);
285 1.1 cgd exit(1);
286 1.1 cgd }
287 1.1 cgd working->gid = grp->gr_gid;
288 1.1 cgd } else
289 1.1 cgd working->gid = atoi(q);
290 1.1 cgd } else
291 1.1 cgd working->gid = NONE;
292 1.1 cgd
293 1.1 cgd q = parse = missing_field(sob(++parse),errline);
294 1.1 cgd *(parse = son(parse)) = '\0';
295 1.1 cgd }
296 1.1 cgd else
297 1.1 cgd working->uid = working->gid = NONE;
298 1.1 cgd
299 1.1 cgd if (!sscanf(q,"%o",&working->permissions)) {
300 1.1 cgd fprintf(stderr,
301 1.1 cgd "Error in config file; bad permissions:\n");
302 1.1 cgd fputs(errline,stderr);
303 1.1 cgd exit(1);
304 1.1 cgd }
305 1.1 cgd
306 1.1 cgd q = parse = missing_field(sob(++parse),errline);
307 1.1 cgd *(parse = son(parse)) = '\0';
308 1.1 cgd if (!sscanf(q,"%d",&working->numlogs)) {
309 1.1 cgd fprintf(stderr,
310 1.1 cgd "Error in config file; bad number:\n");
311 1.1 cgd fputs(errline,stderr);
312 1.1 cgd exit(1);
313 1.1 cgd }
314 1.1 cgd
315 1.1 cgd q = parse = missing_field(sob(++parse),errline);
316 1.1 cgd *(parse = son(parse)) = '\0';
317 1.1 cgd if (isdigit(*q))
318 1.1 cgd working->size = atoi(q);
319 1.1 cgd else
320 1.1 cgd working->size = -1;
321 1.1 cgd
322 1.1 cgd q = parse = missing_field(sob(++parse),errline);
323 1.1 cgd *(parse = son(parse)) = '\0';
324 1.1 cgd if (isdigit(*q))
325 1.1 cgd working->hours = atoi(q);
326 1.1 cgd else
327 1.1 cgd working->hours = -1;
328 1.1 cgd
329 1.1 cgd q = parse = sob(++parse); /* Optional field */
330 1.1 cgd *(parse = son(parse)) = '\0';
331 1.1 cgd working->flags = 0;
332 1.1 cgd while (q && *q && !isspace(*q)) {
333 1.1 cgd if ((*q == 'Z') || (*q == 'z'))
334 1.1 cgd working->flags |= CE_COMPACT;
335 1.1 cgd else if ((*q == 'B') || (*q == 'b'))
336 1.1 cgd working->flags |= CE_BINARY;
337 1.1 cgd else {
338 1.1 cgd fprintf(stderr,
339 1.1 cgd "Illegal flag in config file -- %c\n",
340 1.1 cgd *q);
341 1.1 cgd exit(1);
342 1.1 cgd }
343 1.1 cgd q++;
344 1.1 cgd }
345 1.1 cgd
346 1.1 cgd free(errline);
347 1.1 cgd }
348 1.1 cgd if (working)
349 1.1 cgd working->next = (struct conf_entry *) NULL;
350 1.1 cgd (void) fclose(f);
351 1.1 cgd return(first);
352 1.1 cgd }
353 1.1 cgd
354 1.1 cgd char *missing_field(p,errline)
355 1.1 cgd char *p,*errline;
356 1.1 cgd {
357 1.1 cgd if (!p || !*p) {
358 1.1 cgd fprintf(stderr,"Missing field in config file:\n");
359 1.1 cgd fputs(errline,stderr);
360 1.1 cgd exit(1);
361 1.1 cgd }
362 1.1 cgd return(p);
363 1.1 cgd }
364 1.1 cgd
365 1.1 cgd dotrim(log,numdays,flags,perm,owner_uid,group_gid)
366 1.1 cgd char *log;
367 1.1 cgd int numdays;
368 1.1 cgd int flags;
369 1.1 cgd int perm;
370 1.1 cgd int owner_uid;
371 1.1 cgd int group_gid;
372 1.1 cgd {
373 1.1 cgd char file1[128], file2[128];
374 1.1 cgd char zfile1[128], zfile2[128];
375 1.1 cgd int fd;
376 1.1 cgd struct stat st;
377 1.1 cgd
378 1.1 cgd #ifdef _IBMR2
379 1.1 cgd /* AIX 3.1 has a broken fchown- if the owner_uid is -1, it will actually */
380 1.1 cgd /* change it to be owned by uid -1, instead of leaving it as is, as it is */
381 1.1 cgd /* supposed to. */
382 1.1 cgd if (owner_uid == -1)
383 1.1 cgd owner_uid = geteuid();
384 1.1 cgd #endif
385 1.1 cgd
386 1.1 cgd /* Remove oldest log */
387 1.1 cgd (void) sprintf(file1,"%s.%d",log,numdays);
388 1.1 cgd (void) strcpy(zfile1, file1);
389 1.3 cgd (void) strcat(zfile1, COMPRESS_POSTFIX);
390 1.1 cgd
391 1.1 cgd if (noaction) {
392 1.1 cgd printf("rm -f %s\n", file1);
393 1.1 cgd printf("rm -f %s\n", zfile1);
394 1.1 cgd } else {
395 1.1 cgd (void) unlink(file1);
396 1.1 cgd (void) unlink(zfile1);
397 1.1 cgd }
398 1.1 cgd
399 1.1 cgd /* Move down log files */
400 1.1 cgd while (numdays--) {
401 1.1 cgd (void) strcpy(file2,file1);
402 1.1 cgd (void) sprintf(file1,"%s.%d",log,numdays);
403 1.1 cgd (void) strcpy(zfile1, file1);
404 1.1 cgd (void) strcpy(zfile2, file2);
405 1.1 cgd if (lstat(file1, &st)) {
406 1.3 cgd (void) strcat(zfile1, COMPRESS_POSTFIX);
407 1.3 cgd (void) strcat(zfile2, COMPRESS_POSTFIX);
408 1.1 cgd if (lstat(zfile1, &st)) continue;
409 1.1 cgd }
410 1.1 cgd if (noaction) {
411 1.1 cgd printf("mv %s %s\n",zfile1,zfile2);
412 1.1 cgd printf("chmod %o %s\n", perm, zfile2);
413 1.1 cgd printf("chown %d.%d %s\n",
414 1.1 cgd owner_uid, group_gid, zfile2);
415 1.1 cgd } else {
416 1.1 cgd (void) rename(zfile1, zfile2);
417 1.1 cgd (void) chmod(zfile2, perm);
418 1.1 cgd (void) chown(zfile2, owner_uid, group_gid);
419 1.1 cgd }
420 1.1 cgd }
421 1.1 cgd if (!noaction && !(flags & CE_BINARY))
422 1.1 cgd (void) log_trim(log); /* Report the trimming to the old log */
423 1.1 cgd
424 1.1 cgd if (noaction)
425 1.1 cgd printf("mv %s to %s\n",log,file1);
426 1.1 cgd else
427 1.1 cgd (void) rename(log,file1);
428 1.1 cgd if (noaction)
429 1.1 cgd printf("Start new log...");
430 1.1 cgd else {
431 1.1 cgd fd = creat(log,perm);
432 1.1 cgd if (fd < 0) {
433 1.1 cgd perror("can't start new log");
434 1.1 cgd exit(1);
435 1.1 cgd }
436 1.1 cgd if (fchown(fd, owner_uid, group_gid)) {
437 1.1 cgd perror("can't chmod new log file");
438 1.1 cgd exit(1);
439 1.1 cgd }
440 1.1 cgd (void) close(fd);
441 1.1 cgd if (!(flags & CE_BINARY))
442 1.1 cgd if (log_trim(log)) { /* Add status message */
443 1.1 cgd perror("can't add status message to log");
444 1.1 cgd exit(1);
445 1.1 cgd }
446 1.1 cgd }
447 1.1 cgd if (noaction)
448 1.1 cgd printf("chmod %o %s...",perm,log);
449 1.1 cgd else
450 1.1 cgd (void) chmod(log,perm);
451 1.1 cgd if (noaction)
452 1.1 cgd printf("kill -HUP %d (syslogd)\n",syslog_pid);
453 1.1 cgd else
454 1.1 cgd if (kill(syslog_pid,SIGHUP)) {
455 1.1 cgd fprintf(stderr,"%s: ",progname);
456 1.1 cgd perror("warning - could not restart syslogd");
457 1.1 cgd }
458 1.1 cgd if (flags & CE_COMPACT) {
459 1.1 cgd if (noaction)
460 1.1 cgd printf("Compress %s.0\n",log);
461 1.1 cgd else
462 1.1 cgd compress_log(log);
463 1.1 cgd }
464 1.1 cgd }
465 1.1 cgd
466 1.1 cgd /* Log the fact that the logs were turned over */
467 1.1 cgd log_trim(log)
468 1.1 cgd char *log;
469 1.1 cgd {
470 1.1 cgd FILE *f;
471 1.1 cgd if ((f = fopen(log,"a")) == NULL)
472 1.1 cgd return(-1);
473 1.1 cgd fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n",
474 1.1 cgd daytime, hostname, getpid());
475 1.1 cgd if (fclose(f) == EOF) {
476 1.1 cgd perror("log_trim: fclose:");
477 1.1 cgd exit(1);
478 1.1 cgd }
479 1.1 cgd return(0);
480 1.1 cgd }
481 1.1 cgd
482 1.1 cgd /* Fork of /usr/ucb/compress to compress the old log file */
483 1.1 cgd compress_log(log)
484 1.1 cgd char *log;
485 1.1 cgd {
486 1.1 cgd int pid;
487 1.1 cgd char tmp[128];
488 1.1 cgd
489 1.1 cgd pid = fork();
490 1.1 cgd (void) sprintf(tmp,"%s.0",log);
491 1.1 cgd if (pid < 0) {
492 1.1 cgd fprintf(stderr,"%s: ",progname);
493 1.1 cgd perror("fork");
494 1.1 cgd exit(1);
495 1.1 cgd } else if (!pid) {
496 1.1 cgd (void) execl(COMPRESS,"compress","-f",tmp,0);
497 1.1 cgd fprintf(stderr,"%s: ",progname);
498 1.1 cgd perror(COMPRESS);
499 1.1 cgd exit(1);
500 1.1 cgd }
501 1.1 cgd }
502 1.1 cgd
503 1.1 cgd /* Return size in kilobytes of a file */
504 1.1 cgd int sizefile(file)
505 1.1 cgd char *file;
506 1.1 cgd {
507 1.1 cgd struct stat sb;
508 1.1 cgd
509 1.1 cgd if (stat(file,&sb) < 0)
510 1.1 cgd return(-1);
511 1.1 cgd return(kbytes(dbtob(sb.st_blocks)));
512 1.1 cgd }
513 1.1 cgd
514 1.1 cgd /* Return the age of old log file (file.0) */
515 1.1 cgd int age_old_log(file)
516 1.1 cgd char *file;
517 1.1 cgd {
518 1.1 cgd struct stat sb;
519 1.1 cgd char tmp[80];
520 1.1 cgd
521 1.1 cgd (void) strcpy(tmp,file);
522 1.1 cgd if (stat(strcat(tmp,".0"),&sb) < 0)
523 1.3 cgd if (stat(strcat(tmp,COMPRESS_POSTFIX), &sb) < 0)
524 1.1 cgd return(-1);
525 1.1 cgd return( (int) (timenow - sb.st_mtime + 1800) / 3600);
526 1.1 cgd }
527 1.1 cgd
528 1.1 cgd
529 1.1 cgd #ifndef OSF
530 1.1 cgd /* Duplicate a string using malloc */
531 1.1 cgd
532 1.1 cgd char *strdup(strp)
533 1.1 cgd register char *strp;
534 1.1 cgd {
535 1.1 cgd register char *cp;
536 1.1 cgd
537 1.1 cgd if ((cp = malloc((unsigned) strlen(strp) + 1)) == NULL)
538 1.1 cgd abort();
539 1.1 cgd return(strcpy (cp, strp));
540 1.1 cgd }
541 1.1 cgd #endif
542 1.1 cgd
543 1.1 cgd /* Skip Over Blanks */
544 1.1 cgd char *sob(p)
545 1.1 cgd register char *p;
546 1.1 cgd {
547 1.1 cgd while (p && *p && isspace(*p))
548 1.1 cgd p++;
549 1.1 cgd return(p);
550 1.1 cgd }
551 1.1 cgd
552 1.1 cgd /* Skip Over Non-Blanks */
553 1.1 cgd char *son(p)
554 1.1 cgd register char *p;
555 1.1 cgd {
556 1.1 cgd while (p && *p && !isspace(*p))
557 1.1 cgd p++;
558 1.1 cgd return(p);
559 1.1 cgd }
560 1.1 cgd
561 1.1 cgd
562 1.1 cgd /* Check if string is actually a number */
563 1.1 cgd
564 1.1 cgd isnumber(string)
565 1.1 cgd char *string;
566 1.1 cgd {
567 1.1 cgd while (*string != '\0') {
568 1.1 cgd if (*string < '0' || *string > '9') return(0);
569 1.1 cgd string++;
570 1.1 cgd }
571 1.1 cgd return(1);
572 1.1 cgd }
573 1.1 cgd
574 1.1 cgd #if !defined(__SABER__) && !defined(lint) && !defined(NO_WHAT_STRINGS)
575 1.3 cgd static char *what_string = "@(#)newsyslog.c\t$Revision: 1.3 $ $Date: 1993/05/22 03:52:20 $ $Locker: $";
576 1.1 cgd #endif
577 1.1 cgd
578 1.1 cgd /*
579 1.1 cgd * HISTORY
580 1.1 cgd * $Log: newsyslog.c,v $
581 1.3 cgd * Revision 1.3 1993/05/22 03:52:20 cgd
582 1.3 cgd * add use of "COMPRESS_POSTFIX" define, to determine what postfix
583 1.3 cgd * (e.g. ".Z", ".z", etc.) to append to compressed log files.
584 1.2 cgd *
585 1.2 cgd * Revision 1.2 1993/05/21 14:47:30 cgd
586 1.2 cgd * use the correct (or so john brezak says) copyright.
587 1.1 cgd *
588 1.1 cgd * Revision 1.1 1993/05/21 14:44:02 cgd
589 1.1 cgd * initial import of this log-rotation program to NetBSD
590 1.1 cgd *
591 1.1 cgd * Revision 3.0.2.2 1993/02/06 04:14:51 brezak
592 1.1 cgd * Fix up rcsid.
593 1.1 cgd * [1993/02/06 04:14:03 brezak]
594 1.1 cgd *
595 1.1 cgd * Revision 3.0 1993/01/01 07:39:17 ede
596 1.1 cgd * Initial revision for OSF/1 R1.3
597 1.1 cgd *
598 1.1 cgd * Revision 1.2 1991/08/16 09:50:26 devrcs
599 1.1 cgd * From John Brezak, brezak (at) apollo.com, originally from Project Athena
600 * [91/07/24 09:33:18 meissner]
601 *
602 * $EndLog$
603 */
604