This is funcs.c in view mode; [Download] [Up]
/* ** f u n c s . c ** ** functions for UPS monitor daemon ** ** Arthur W. Neilson III ** art@pilikia.pegasus.com ** Sat Mar 30 1991 */ #include <sys/ioctl.h> #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(UPSFAIL)) != NULL) ups_fail = s; if ((s = getenv(UPSREST)) != NULL) ups_rest = s; if ((s = getenv(UPSTIME)) != NULL) ups_time = atoi(s); } /* ** 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 version(); void usage(); extern char *optarg; extern int optind, opterr; /* display program version */ version(av[0]); /* parse the command line */ while ((c = getopt(ac, av, "d:c:l:f:r: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 'f': /* failure option */ ups_fail = optarg; break; case 'r': /* restore option */ ups_rest = optarg; break; case 't': /* time option */ ups_time = atoi(optarg); break; case '\?': /* illegal option */ usage(av[0]); exit(1); } } /* ** c h k o p t i o n s ** ** check runtime options ** with various sanity tests */ 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 a regular file */ if ((st.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "%s not regular\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; int stat; unsigned int modembits; unsigned int oldbits; void sigcatch(); void writelog(); void writeall(); void shutdown(); writelog(START_MSG); 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) { perror("could not open log file"); exit(1); } /* and advisory lock it */ /* if (lockf(log_fd, F_TLOCK, 0L) == ERR) { perror("could not open lock file"); exit(1); } */ writelog(START_MSG); ups_fd = open(ups_port,O_RDONLY,0); if (stat<0) { perror("cant open port"); exit(1); } /* get old bits first time */ stat = ioctl(ups_fd,TIOCMGET,&oldbits); while (1) { stat = ioctl(ups_fd,TIOCMGET,&modembits); if (modembits!=oldbits) { if (state==UPS_LINE) { state = UPS_BATTERY; } else { state = UPS_LINE; } switch(state) { case UPS_LINE : writelog(ONLINE_MSG); writeall(ups_rest); alarm(0); break; case UPS_BATTERY : writelog(BATTERY_MSG); writeall(ups_fail); alarm(ups_time * SECS_PER_MIN/4); break; } oldbits = modembits; } sleep(interval); } close(log_fd); close(ups_fd); } else { printf("process forked\n"); } } /* ** 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; { time_t ticks; char *p, *ct; char msg_buf[80]; char *strrchr(); time(&ticks); ct = ctime(&ticks); /* find newline in buffer */ if ((p = strrchr(ct, '\n')) != NULL) *p = NULL; /* and zap it */ sprintf(msg_buf, "%s -- %s\n", ct, msg); write(log_fd, msg_buf, strlen(msg_buf)); } /* ** w r i t e a l l ** ** write to all users */ void writeall(fn) char *fn; { struct stat st; void attach(); /* message file must exist */ if (stat(fn, &st) == ERR) return; /* and must be a regular file */ if ((st.st_mode & S_IFMT) != S_IFREG) return; if (!fork()) { attach(CONSOLE); /* write message file to users */ execlp(WALL, WALL, fn, NULL); } } /* ** s h u t d o w n ** ** shutdown the system */ void shutdown() { void attach(); writelog(SHUTDOWN_MSG); close(ups_log); close(ups_port); if (!fork()) { attach(CONSOLE); chdir(ROOT); /* execute shutdown command */ execlp(SH, SH, 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 */ } /* ** b a s e n a m e ** ** remove absolute path from filename ** */ char * basename(s) char *s; { register char *p; /* point to char after last '/' */ if ((p = strrchr(s, '/')) != NULL) return (++p); return (s); } /* ** v e r s i o n ** ** display program version */ void version(s) char *s; { char *basename(); /* display version in foreground */ if (signal(SIGINT, SIG_IGN) != SIG_IGN) fprintf(stderr, "%s release %s version %d.%d patchlevel %d\n", basename(s), RELEASE_DATE, RELEASE, REVISION, PATCHLEVEL); } /* ** u s a g e ** ** display program usage */ void usage(s) char *s; { char *basename(); fprintf(stderr, "usage: %s [-d tty][-c cmd][-l file][-f file][-r file][-t min]\n", basename(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 file\t\tpathname of UPS log file\n"); fprintf(stderr, "\t-f file\t\tpathname of UPS fail message file\n"); fprintf(stderr, "\t-r file\t\tpathname of UPS restore message file\n"); fprintf(stderr, "\t-t min\t\tdelay time in minutes\n"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.