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