home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 100-199 / ff113.lzh / AmiCron / Amicron.c < prev    next >
C/C++ Source or Header  |  1987-11-21  |  5KB  |  231 lines

  1. /*
  2.  *    amicron.c
  3.  *
  4.  *    Public Domain (p) No Rights Reserved
  5.  *
  6.  *    This program operates as a daemon, waking up every minute
  7.  *    to execute the CRONTAB table.  Logging errors to CRONERR.
  8.  *
  9.  *    Put in startup-sequence as:
  10.  *        run newcli con:0/140/160/50/CronTask s:startcron
  11.  *  The startcron file contains one line:
  12.  *        amicron
  13.  *
  14.  *    Some notes are included below concerning the cron table
  15.  *    file format.  In this version the cron table file is left
  16.  *    on disk and not moved to core, and  the command character
  17.  *    to signify a newline '%' is not used.
  18.  *
  19.  *    Some cron table entry examples:
  20.  *
  21.  *    Print the date in the crontask window every minute:
  22.  *        * * * * * date
  23.  *
  24.  *    Print the date in the crontask window on the hour, every hour:
  25.  *        0 * * * * date
  26.  *
  27.  *    Run uupc at 4:30 am every day except Sat and Sun:
  28.  *        30 4 * * 1-5 uupc -siscuva
  29.  *
  30.  *    Backup the files every other day at 7:30 pm:
  31.  *        30 19 * * 1,3,5 sdbackup -s LAST dh0: incbkup_1:
  32.  *
  33.  */
  34.  
  35. /* 
  36.  * Public Domain (p) by S. R. Sampson
  37.  * Version 2.3, October 1987
  38.  * Amiga port by Rick Schaeffer October 1987
  39.  *
  40.  * Rick Schaeffer          UUCP:  seismo!uunet!iscuva!ricks!ricks
  41.  * E. 13611 26th Ave.      Phone: (509)928-3533
  42.  * Spokane, WA  99216
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include <time.h>
  47. #include <errno.h>
  48.  
  49. #define TRUE 1
  50. #define FALSE 0
  51.  
  52. #define CRONTAB "Sys:usr/spool/cron/crontab"
  53. #define CRONERR "Sys:usr/spool/cron/cronerr"
  54.  
  55. #define MAXLINE    132
  56. #define SIZE    64
  57.  
  58. extern    int    errno;
  59.  
  60. int    eof;
  61. char    min[SIZE], hour[SIZE], day[SIZE],
  62.     month[SIZE], wday[SIZE], command[SIZE];
  63. char    *tokv[] = { min, hour, day, month, wday };
  64. FILE    *fd, *err;
  65.  
  66.  
  67. /*
  68.  *    This is the basics, ready for bells and whistles
  69.  *
  70.  */
  71.  
  72. void main()
  73. {
  74.     void wakeup();
  75.  
  76.     /*
  77.      *    fopen() will create the file if it does not exist.
  78.      *    Any other errors will be output to stderr at startup.
  79.      */
  80.         
  81.     if ((err = fopen(CRONERR, "a")) == (FILE *)NULL)  {
  82.         perror("cron");
  83.         exit(1);
  84.         }
  85.  
  86.     for (;;)  {
  87.         wakeup();
  88.         Delay(50*59);    /* sleep for one minute */
  89.         }
  90. }
  91.  
  92. void wakeup()
  93. {
  94.     register struct tm *tm;
  95.     struct tm *localtime();
  96.     char *ctime();
  97.     long cur_time;
  98.  
  99.     time(&cur_time);        /* get the current time */
  100.     tm = localtime(&cur_time);    /* break it down */
  101.  
  102.     fd = fopen(CRONTAB, "r");
  103.  
  104.     eof = FALSE;
  105.  
  106.     while (!eof)  {
  107.         if (getline() && match(min,tm->tm_min) &&
  108.            match(hour,tm->tm_hour) && match(day,tm->tm_mday) &&
  109.            match(month,tm->tm_mon) && match(wday,tm->tm_wday))  {
  110.  
  111.             fexecl("Run","Run",command,NULL);
  112.             }
  113.         }
  114.     fclose(fd);
  115. }
  116.  
  117.  
  118. /*
  119.  *    A line consists of six fields.  The first five are:
  120.  *
  121.  *        minute:         0-59
  122.  *        hour:           0-23
  123.  *        day:            1-31
  124.  *        month:          1-12
  125.  *        weekday:        0-6 (Sunday = 0)
  126.  *
  127.  *    The fields are seperated by spaces or tabs, with the
  128.  *    first field left justified (no leading spaces or tabs).
  129.  *    See below for optional field syntax.
  130.  *
  131.  *    The last field is the command field.  This command will
  132.  *    be executed by the CLI just as if typed from a console.
  133.  */
  134.  
  135. int getline()
  136. {
  137.     register char *p;
  138.     register int   i;
  139.     char    buffer[MAXLINE], *scanner(), *fgets();
  140.  
  141.     if (fgets(buffer, sizeof buffer, fd) == NULL)  {
  142.         eof = TRUE;
  143.         return(FALSE);
  144.         }
  145.  
  146.     for (p = buffer, i = 0; i < 5; i++)  {
  147.         if ((p = scanner(tokv[i], p)) == (char *)NULL)
  148.             return(FALSE);
  149.         }
  150.  
  151.     strcpy(command, p);     /* scoop the command */
  152.     return(TRUE);
  153. }
  154.  
  155.  
  156. char *scanner(token, offset)
  157. register char   *token;        /* target buffer to receive scanned token */
  158. register char   *offset;    /* place holder into source buffer */
  159. {
  160.     while ((*offset != ' ') && (*offset != '\t') && *offset)
  161.         *token++ = *offset++;
  162.  
  163.     /*
  164.      *      Check for possible error condition
  165.      */
  166.          
  167.     if (!*offset)
  168.         return ((char *)NULL);
  169.  
  170.     *token = '\0';
  171.         
  172.     while ((*offset == ' ') || (*offset == '\t'))
  173.         offset++;
  174.  
  175.     return (offset);
  176. }
  177.  
  178.  
  179. /*
  180.  *    This routine will match the left string with the right number.
  181.  *
  182.  *    The string can contain the following syntax:
  183.  *
  184.  *    *        This will return TRUE for any number
  185.  *    x,y [,z, ...]    This will return TRUE for any number given.
  186.  *    x-y        This will return TRUE for any number within
  187.  *            the range of x thru y.
  188.  */
  189.  
  190. int match(left, right)
  191. register char   *left;
  192. register int    right;
  193. {
  194.     register int    n;
  195.     register char    c;
  196.  
  197.     n = 0;
  198.     if (!strcmp(left, "*"))
  199.         return(TRUE);
  200.  
  201.     while ((c = *left++) && (c >= '0') && (c <= '9'))
  202.         n  =  (n * 10) + c - '0';
  203.  
  204.     switch (c)  {
  205.         case '\0':
  206.             return (right == n);
  207.  
  208.         case ',':
  209.             if (right == n)
  210.                 return(TRUE);
  211.             do {
  212.                 n = 0;
  213.                 while ((c = *left++) && (c >= '0') && (c <= '9'))
  214.                     n = (n * 10) + c - '0';
  215.                  if (right == n)
  216.                     return(TRUE);
  217.                 } while (c == ',');
  218.             return(FALSE);
  219.  
  220.         case '-':
  221.             if (right < n)
  222.                 return(FALSE);
  223.  
  224.             n = 0;
  225.             while ((c = *left++) && (c >= '0') && (c <= '9'))
  226.                 n = (n * 10) + c - '0';
  227.  
  228.             return(right <= n);
  229.         }
  230. }
  231.