home *** CD-ROM | disk | FTP | other *** search
- /*
- * expired.c
- * 11/6/90
- * John A. Limpert (johnl@n3dmc.svr.md.us)
- *
- * 'smart' news expiration daemon for UNIX System V Release 3
- *
- * This program will expire the oldest 1/3 of news whenever
- * free space is less than 10% on the news filesystem.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/statfs.h>
- #include <sys/stat.h>
- #include <signal.h>
- #include <errno.h>
- #include <time.h>
- #include <string.h>
-
- #ifndef SPOOL
- #define SPOOL "/usr/spool/news" /* news spool directory */
- #endif
-
- #ifndef ETFILE
- #define ETFILE "/usr/lib/news/expire_time" /* expiration cutoff time */
- #endif
-
- #ifndef LOGFILE
- #define LOGFILE "/usr/lib/news/expired.log" /* expired log file */
- #endif
-
- #ifndef MINFREE
- #define MINFREE 0.1 /* desired free space */
- #endif
-
- /* prototype expire command */
- #ifndef CMD
- #define CMD "/bin/su news -c \"/usr/lib/news/expire -e%f -E%f\""
- #endif
-
- /* seconds in day */
- #define DAY (24L*60L*60L)
-
- struct utimbuf {
- time_t actime; /* access time */
- time_t modtime; /* modification time */
- };
-
- /* external */
- extern void exit();
- extern void perror();
- extern unsigned sleep();
- extern time_t time();
-
- /* forward */
- extern time_t get_mtime();
- extern void log();
- extern void set_mtime();
-
- /* program name */
- char *pname;
-
- /*ARGSUSED*/
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct statfs part_stat;
- time_t delta, now, oldest_news;
- double keep;
- char cmdbuf[256];
- int pid;
- long minfree;
-
- pname = argv[0];
-
- /* ignore user signals */
- (void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
-
- /* go into background */
- if ((pid = fork()) < 0) {
- perror(pname);
- exit(1);
- }
- if (pid != 0)
- exit(0);
-
- log("running...");
-
- for (;;) {
- /* wait for exhaustion of disk space */
- for (;;) {
- if (statfs(SPOOL, &part_stat, sizeof(struct statfs), 0) < 0) {
- perror(SPOOL);
- exit(1);
- }
-
- minfree = part_stat.f_blocks*MINFREE;
-
- if (part_stat.f_bfree < minfree)
- break;
-
- (void) sleep(60);
- }
-
- /* discard oldest 1/3 of news */
- oldest_news = get_mtime(ETFILE);
- now = time((time_t *) 0);
- delta = now - oldest_news;
- delta = (delta*2)/3;
- oldest_news = now - delta;
- set_mtime(ETFILE, oldest_news);
- keep = ((double) delta)/((double) DAY);
-
- /* generate expire command */
- sprintf(cmdbuf, CMD, keep, keep);
-
- /* update log file */
- log(cmdbuf);
-
- /* run expire */
- if (system(cmdbuf) < 0) {
- perror(pname);
- exit(1);
- }
- }
- /*NOTREACHED*/
- }
-
- /* get_mtime -- get modification time of specified file */
-
- time_t
- get_mtime(path)
- char *path;
- {
- struct stat file_stat;
- struct utimbuf ut;
- int fd;
-
- /* does file exist? */
- if (stat(path, &file_stat) < 0 && errno == ENOENT) {
- /* create it */
- if ((fd = creat(path, 0)) < 0) {
- perror(path);
- exit(1);
- }
- if (close(fd) < 0) {
- perror(path);
- exit(1);
- }
- /* backdate two weeks */
- ut.actime = ut.modtime = time((time_t *) 0) - 14L*DAY;
- if (utime(path, &ut) < 0) {
- perror(path);
- exit(1);
- }
- }
-
- /* get inode info */
- if (stat(path, &file_stat) < 0) {
- perror(path);
- exit(1);
- }
-
- /* return modification time */
- return file_stat.st_mtime;
- }
-
- /* set_mtime -- set modification and access time of specified file */
-
- void
- set_mtime(path, t)
- char *path;
- time_t t;
- {
- struct stat file_stat;
- struct utimbuf ut;
- int fd;
-
- /* does file exist? */
- if (stat(path, &file_stat) < 0 && errno == ENOENT) {
- /* create it */
- if ((fd = creat(path, 0)) < 0) {
- perror(path);
- exit(1);
- }
- if (close(fd) < 0) {
- perror(path);
- exit(1);
- }
- }
-
- /* record time in file inode */
- ut.actime = ut.modtime = t;
- if (utime(path, &ut) < 0) {
- perror(path);
- exit(1);
- }
- }
-
- /* log -- write time tagged string to log file */
-
- void
- log(s)
- char *s;
- {
- FILE *logf;
- time_t t;
- char *p, tbuf[32];
-
- /* open log file */
- if ((logf = fopen(LOGFILE, "a")) == NULL) {
- fprintf(stderr, "%s: can't append to %s\n", pname, LOGFILE);
- exit(1);
- }
-
- /* time in ASCII without newline */
- t = time((time_t *) 0);
- (void) strcpy(tbuf, ctime(&t));
- if ((p = strchr(tbuf, '\n')) != NULL)
- *p = '\0';
-
- /* append time tagged entry to log file */
- fprintf(logf, "%s: %s\n", tbuf, s);
- fclose(logf);
- }
-