home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3163 / funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-04  |  4.6 KB  |  276 lines

  1. /*
  2. **    f u n c s . c
  3. **
  4. **    functions for UPS monitor daemon
  5. **
  6. **    Arthur W. Neilson III
  7. **    art@pilikia.pegasus.com
  8. **    Sat Mar 30 1991
  9. */
  10.  
  11. #include "common.h"
  12.  
  13. /*
  14. **    g e t v a r s
  15. **
  16. **    retrieve environment variables
  17. */
  18. void
  19. getvars()
  20. {
  21.     char   *s, *getenv();
  22.  
  23.     if ((s = getenv(UPSPORT)) != NULL)
  24.         ups_port = s;
  25.     if ((s = getenv(UPSSHUT)) != NULL)
  26.         ups_shut = s;
  27.     if ((s = getenv(UPSLOG)) != NULL)
  28.         ups_log = s;
  29.     if ((s = getenv(UPSTIME)) != NULL)
  30.         ups_time = atoi(s) * SECS_PER_MIN;
  31. }
  32.  
  33. /*
  34. **    g e t o p t i o n s
  35. **
  36. **    retrieve and process command line options
  37. */
  38. void
  39. getoptions(ac, av)
  40. int     ac;
  41. char   *av[];
  42. {
  43.     int     c;
  44.  
  45.     void    usage();
  46.  
  47.     extern char *optarg;
  48.     extern int optind, opterr;
  49.  
  50.     /* parse the command line */
  51.     while ((c = getopt(ac, av, "d:c:l:t:")) != EOF)
  52.         switch (c) {
  53.         case 'd':    /* device option */
  54.             ups_port = optarg;
  55.             break;
  56.         case 'c':    /* command option */
  57.             ups_shut = optarg;
  58.             break;
  59.         case 'l':    /* logfile option */
  60.             ups_log = optarg;
  61.             break;
  62.         case 't':    /* time option */
  63.             ups_time = atoi(optarg) * SECS_PER_MIN;
  64.             break;
  65.         case '\?':    /* illegal option */
  66.             usage(av[0]);
  67.             exit(1);
  68.         }
  69. }
  70.  
  71. /*
  72. **    c h k o p t i o n s
  73. **
  74. **    check runtime options
  75. */
  76. void
  77. chkoptions()
  78. {
  79.     struct stat st;
  80.     char   *p, buf[64];
  81.  
  82.     /* UPS port must exist */
  83.     if (stat(ups_port, &st) == ERR) {
  84.         perror(ups_port);
  85.         exit(1);
  86.     }
  87.     /* and must be character special */
  88.     if ((st.st_mode & S_IFMT) != S_IFCHR) {
  89.         fprintf(stderr, "%s not character special\n", ups_port);
  90.         exit(1);
  91.     }
  92.     /* get command name out of shutdown command */
  93.     strcpy(buf, ups_shut);
  94.     if ((p = strtok(buf, " ")) == NULL)
  95.         p = buf;
  96.  
  97.     /* shutdown command must exist */
  98.     if (stat(p, &st) == ERR) {
  99.         perror(ups_shut);
  100.         exit(1);
  101.     }
  102.     /* and must be readable/executable by owner */
  103.     if (!(st.st_mode & SHUT_PERMS)) {
  104.         fprintf(stderr, "%s must be readable/executable by owner\n", ups_port);
  105.         exit(1);
  106.     }
  107.     /* delay time must be > 0 and <= MAX_TIME */
  108.     if (ups_time < 1 || ups_time > MAX_TIME) {
  109.         fprintf(stderr, "time must be between 1 and %d\n", MAX_TIME);
  110.         exit(1);
  111.     }
  112. }
  113.  
  114. /*
  115. **    m k d a e m o n
  116. **
  117. **    create daemon process
  118. */
  119. void
  120. mkdaemon()
  121. {
  122.     char    c;
  123.  
  124.     void    sigcatch();
  125.     void    writelog();
  126.     void    shutdown();
  127.  
  128.     if (!fork()) {
  129.  
  130.         /* close standard files */
  131.         close(0);    /* stdin */
  132.         close(1);    /* stdout */
  133.         close(2);    /* stderr */
  134.  
  135.         setpgrp();    /* disassociate from terminal */
  136.  
  137.         /* ignore interrupts */
  138.         signal(SIGHUP, SIG_IGN);
  139.         signal(SIGINT, SIG_IGN);
  140.         signal(SIGQUIT, SIG_IGN);
  141.  
  142.         /* catch termination signal */
  143.         signal(SIGTERM, sigcatch);
  144.  
  145.         /* and shutdown on alarm */
  146.         signal(SIGALRM, shutdown);
  147.  
  148.         /* open log file for append */
  149.         if ((log_fd = open(ups_log, LOG_FLAGS, LOG_PERMS)) == ERR)
  150.             exit(1);
  151.  
  152.         writelog(START_MSG);
  153.  
  154.         /* open blocks on UPS switch to battery */
  155.         if ((ups_fd = open(ups_port, O_RDWR)) == ERR) {
  156.             writelog(OPEN_MSG);
  157.             exit(1);
  158.         }
  159.         writelog(BATTERY_MSG);
  160.  
  161.         alarm(ups_time);/* set the alarm clock */
  162.  
  163.         /* read blocks on UPS switch to online */
  164.         if (read(ups_fd, &c, 1) == ERR)
  165.             exit(1);
  166.  
  167.         writelog(ONLINE_MSG);
  168.  
  169.         close(log_fd);
  170.         close(ups_fd);
  171.  
  172.         mkdaemon();
  173.     }
  174. }
  175.  
  176. /*
  177. **    s i g c a t c h
  178. **
  179. **    catch termination signal
  180. */
  181. void
  182. sigcatch()
  183. {
  184.     writelog(TERM_MSG);
  185.     close(log_fd);
  186.     close(ups_fd);
  187.     exit(1);
  188. }
  189.  
  190. /*
  191. **    w r i t e l o g
  192. **
  193. **    write message to the UPS log file
  194. */
  195. void
  196. writelog(msg)
  197. char   *msg;
  198. {
  199.     struct tm *t;
  200.     time_t  ticks;
  201.     char   *p, ctime_buf[26];
  202.     char    msg_buf[80];
  203.  
  204.     time(&ticks);
  205.     strcpy(ctime_buf, ctime(&ticks));
  206.  
  207.     /* find newline in buffer */
  208.     if ((p = strrchr(ctime_buf, '\n')) != NULL)
  209.         *p = NULL;    /* and zap it */
  210.  
  211.     sprintf(msg_buf, "%s -- %s\n", ctime_buf, msg);
  212.     write(log_fd, msg_buf, strlen(msg_buf));
  213. }
  214.  
  215. /*
  216. **    s h u t d o w n
  217. **
  218. **    shutdown the system
  219. */
  220. void
  221. shutdown()
  222. {
  223.     void    attach();
  224.  
  225.     writelog(SHUTDOWN_MSG);
  226.  
  227.     close(log_fd);
  228.     close(ups_fd);
  229.  
  230.     attach(CONSOLE);
  231.  
  232.     chdir(ROOT);
  233.  
  234.     /* execute shutdown command */
  235.     execlp(SH, SH, "-c", ups_shut, NULL);
  236. }
  237.  
  238. /*
  239. **    a t t a c h
  240. **
  241. **    attach standard i/o to a device
  242. */
  243. void
  244. attach(dev)
  245. char   *dev;
  246. {
  247.     int     fd;
  248.  
  249.     /* close standard files */
  250.     close(0);        /* stdin */
  251.     close(1);        /* stdout */
  252.     close(2);        /* stderr */
  253.  
  254.     /* attach stdin to named device */
  255.     if ((fd = open(dev, O_RDWR)) == ERR)
  256.         exit(1);
  257.     dup(fd);        /* and stdout */
  258.     dup(fd);        /* and stderr */
  259. }
  260.  
  261. /*
  262. **    u s a g e
  263. **
  264. **    display program usage
  265. */
  266. void
  267. usage(s)
  268. char   *s;
  269. {
  270.     fprintf(stderr, "usage: %s [-d tty][-c cmd][-l log][-t min]\n", s);
  271.     fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n");
  272.     fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n");
  273.     fprintf(stderr, "\t-l log\t\tpathname of UPS log file\n");
  274.     fprintf(stderr, "\t-t min\t\tdelay time in minutes\n");
  275. }
  276.