home *** CD-ROM | disk | FTP | other *** search
- /*
- ** f u n c s . c
- **
- ** functions for UPS monitor daemon
- **
- ** Arthur W. Neilson III
- ** art@pilikia.pegasus.com
- ** Sat Mar 30 1991
- */
-
- #include "common.h"
-
- /*
- ** g e t v a r s
- **
- ** retrieve environment variables
- */
- void
- getvars()
- {
- char *s, *getenv();
-
- if ((s = getenv(UPSPORT)) != NULL)
- ups_port = s;
- if ((s = getenv(UPSSHUT)) != NULL)
- ups_shut = s;
- if ((s = getenv(UPSLOG)) != NULL)
- ups_log = s;
- if ((s = getenv(UPSTIME)) != NULL)
- ups_time = atoi(s) * SECS_PER_MIN;
- }
-
- /*
- ** g e t o p t i o n s
- **
- ** retrieve and process command line options
- */
- void
- getoptions(ac, av)
- int ac;
- char *av[];
- {
- int c;
-
- void usage();
-
- extern char *optarg;
- extern int optind, opterr;
-
- /* parse the command line */
- while ((c = getopt(ac, av, "d:c:l:t:")) != EOF)
- switch (c) {
- case 'd': /* device option */
- ups_port = optarg;
- break;
- case 'c': /* command option */
- ups_shut = optarg;
- break;
- case 'l': /* logfile option */
- ups_log = optarg;
- break;
- case 't': /* time option */
- ups_time = atoi(optarg) * SECS_PER_MIN;
- break;
- case '\?': /* illegal option */
- usage(av[0]);
- exit(1);
- }
- }
-
- /*
- ** c h k o p t i o n s
- **
- ** check runtime options
- */
- void
- chkoptions()
- {
- struct stat st;
- char *p, buf[64];
-
- /* UPS port must exist */
- if (stat(ups_port, &st) == ERR) {
- perror(ups_port);
- exit(1);
- }
- /* and must be character special */
- if ((st.st_mode & S_IFMT) != S_IFCHR) {
- fprintf(stderr, "%s not character special\n", ups_port);
- exit(1);
- }
- /* get command name out of shutdown command */
- strcpy(buf, ups_shut);
- if ((p = strtok(buf, " ")) == NULL)
- p = buf;
-
- /* shutdown command must exist */
- if (stat(p, &st) == ERR) {
- perror(ups_shut);
- exit(1);
- }
- /* and must be readable/executable by owner */
- if (!(st.st_mode & SHUT_PERMS)) {
- fprintf(stderr, "%s must be readable/executable by owner\n", ups_port);
- exit(1);
- }
- /* delay time must be > 0 and <= MAX_TIME */
- if (ups_time < 1 || ups_time > MAX_TIME) {
- fprintf(stderr, "time must be between 1 and %d\n", MAX_TIME);
- exit(1);
- }
- }
-
- /*
- ** m k d a e m o n
- **
- ** create daemon process
- */
- void
- mkdaemon()
- {
- char c;
-
- void sigcatch();
- void writelog();
- void shutdown();
-
- if (!fork()) {
-
- /* close standard files */
- close(0); /* stdin */
- close(1); /* stdout */
- close(2); /* stderr */
-
- setpgrp(); /* disassociate from terminal */
-
- /* ignore interrupts */
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-
- /* catch termination signal */
- signal(SIGTERM, sigcatch);
-
- /* and shutdown on alarm */
- signal(SIGALRM, shutdown);
-
- /* open log file for append */
- if ((log_fd = open(ups_log, LOG_FLAGS, LOG_PERMS)) == ERR)
- exit(1);
-
- writelog(START_MSG);
-
- /* open blocks on UPS switch to battery */
- if ((ups_fd = open(ups_port, O_RDWR)) == ERR) {
- writelog(OPEN_MSG);
- exit(1);
- }
- writelog(BATTERY_MSG);
-
- alarm(ups_time);/* set the alarm clock */
-
- /* read blocks on UPS switch to online */
- if (read(ups_fd, &c, 1) == ERR)
- exit(1);
-
- writelog(ONLINE_MSG);
-
- close(log_fd);
- close(ups_fd);
-
- mkdaemon();
- }
- }
-
- /*
- ** s i g c a t c h
- **
- ** catch termination signal
- */
- void
- sigcatch()
- {
- writelog(TERM_MSG);
- close(log_fd);
- close(ups_fd);
- exit(1);
- }
-
- /*
- ** w r i t e l o g
- **
- ** write message to the UPS log file
- */
- void
- writelog(msg)
- char *msg;
- {
- struct tm *t;
- time_t ticks;
- char *p, ctime_buf[26];
- char msg_buf[80];
-
- time(&ticks);
- strcpy(ctime_buf, ctime(&ticks));
-
- /* find newline in buffer */
- if ((p = strrchr(ctime_buf, '\n')) != NULL)
- *p = NULL; /* and zap it */
-
- sprintf(msg_buf, "%s -- %s\n", ctime_buf, msg);
- write(log_fd, msg_buf, strlen(msg_buf));
- }
-
- /*
- ** s h u t d o w n
- **
- ** shutdown the system
- */
- void
- shutdown()
- {
- void attach();
-
- writelog(SHUTDOWN_MSG);
-
- close(log_fd);
- close(ups_fd);
-
- attach(CONSOLE);
-
- chdir(ROOT);
-
- /* execute shutdown command */
- execlp(SH, SH, "-c", ups_shut, NULL);
- }
-
- /*
- ** a t t a c h
- **
- ** attach standard i/o to a device
- */
- void
- attach(dev)
- char *dev;
- {
- int fd;
-
- /* close standard files */
- close(0); /* stdin */
- close(1); /* stdout */
- close(2); /* stderr */
-
- /* attach stdin to named device */
- if ((fd = open(dev, O_RDWR)) == ERR)
- exit(1);
- dup(fd); /* and stdout */
- dup(fd); /* and stderr */
- }
-
- /*
- ** u s a g e
- **
- ** display program usage
- */
- void
- usage(s)
- char *s;
- {
- fprintf(stderr, "usage: %s [-d tty][-c cmd][-l log][-t min]\n", s);
- fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n");
- fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n");
- fprintf(stderr, "\t-l log\t\tpathname of UPS log file\n");
- fprintf(stderr, "\t-t min\t\tdelay time in minutes\n");
- }
-