home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d139 / amicron.lha / AmiCron / Amicron25.c < prev    next >
C/C++ Source or Header  |  1988-05-15  |  10KB  |  374 lines

  1. /*
  2.  *    amicron.c    (Version 2.5(a&L) by <CB>)
  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.  
  8.  *
  9.  *    Put in startup-sequence like:
  10.  *        run newcli con:0/140/160/50/CronTask s:startcron
  11.  *    The startcron file needs to contains just 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.  * Modified path for CronTab & CronErr to suit Amiga enviroment better
  45.  * Version 2.31  <CB> 15.12.87 
  46.  *
  47.  * Fixed bug with CronTab entries specifying an event by date (month)
  48.  * i.e. "* * 24 12 * say Merry christmas", now works!
  49.  * Version 2.32 <CB> 25.12.87
  50.  *
  51.  * Removed "CronErr", an obvious Unix "feature"
  52.  * Version 2.33 <CB> 31.12.87 
  53.  *
  54.  * Additional support for Lattice 4.0, changed to complete sleep (no more  
  55.  * 5 I/O ints. per second), added command line parameter for CronTab path.
  56.  * Added feature to align Cron to start on 01 seconds, including "loss"
  57.  * due to lengthy command calls or extensive I/O.
  58.  * Version 2.4 <CB> 10.01.88 
  59.  *
  60.  * GRRRRRRR. Just when I thought it was safe to release that thing, C=A brings
  61.  * out AmyDos 1.3. So to have the output of programs called by Cron visible, I
  62.  * changed the "Run >nil:" parameter for execute() back to "Run ". This means,                         
  63.  * that you will have to look at the annoying CLI[#] messages, each time some 
  64.  * program is called. I was pleased with the way the old RUN >nil: worked, and
  65.  * will try to convince Andy Finkel to bring it back.
  66.  * In the meantime, this is:
  67.  * Version 2.5 <CB> 27.03.88
  68.  
  69.                          
  70. ______  /          
  71. ______\O                    - The Software Brewery - 
  72.       \\                          
  73.        o            Sparkling, fresh software from W.-Germany
  74.                  
  75.      @@@@@          Straight from the bar to your Amiga
  76.      |~~~|\        
  77.      | | |/        
  78.      |___|        With our regards to the Software Distillery
  79.  
  80. Members are (listed alphabetically):
  81. Christian Balzer alias <CB>, Lattice C, user interfaces, beer addict. 
  82. Christof Bonnkirch, Aztec C, telecommunications, money adict.
  83. Heiko Rath alias <HR>, Assembler, ROM-Kernal stuff, Marabou addict. 
  84. Peter Stark alias PS, Lattice C, IO & utilities, WordStar addict.
  85. Ralf Woitinas alias RAF, Assembler, anything, Ray-Tracing addict.
  86. Torsten Wronski alias MM, Assembler, anything, girls addict.
  87.  
  88. Beverages: Altenmuenster Brauer Bier, Urfraenkisches Landbier, Grohe Bock.
  89.  
  90. Send exotic drinks, comments, critizism, flames to:
  91.  
  92. The Software Brewery
  93. Christian Balzer
  94. Im Wingertsberg 45
  95. D-6108 Weiterstadt
  96. West-Germany
  97.  
  98. Our BBS "AmigaNode" isn't online yet. As soon as it becomes available, 
  99. you'll be the first to know :-).
  100.  
  101.  *
  102.  * Compilation notes:
  103.  * Just use the supplied "makefile.manx" for Aztec C 3.4(b) or later. 
  104.  * Lattice C 4.0 users just execute "lmake" or use "makefile.lattice".
  105.  * The whole compilation and link procedure (including timer.c) from RAM
  106.  * took me 50 seconds with Lattice 4.0 and 67 seconds with Aztec 3.4b.
  107.  * Please note that you need to link timer.o for the TimeDelay() function
  108.  * if you don't use make or execute lmake.
  109.  *
  110.  * Well, the Lattice folks claim that LATTICE get's defined by their 
  111.  * compiler, but it didn't work for me. So, if you don't use make or lmake, 
  112.  * or define LATTICE, you'll get blasted by (my) Lattice if ya don't remove 
  113.  * all the lines marked with "LK" below...
  114.  *                        <CB>
  115.  */
  116.  
  117. #include <stdio.h>
  118. #include <time.h>
  119.  
  120. #ifndef LATTICE            /*LK*/
  121. #include <functions.h>        /*LK*/
  122. #endif                /*LK*/
  123.  
  124. #ifdef LATTICE            /*LK*/
  125. #include <string.h>
  126. #include <proto/dos.h>
  127. #endif                /*LK -the last one*/
  128.  
  129. #define TRUE 1
  130. #define FALSE 0
  131.  
  132. #define CRONTAB "S:CronTab"    /* Our default path */
  133.  
  134. #define MAXLINE    132
  135. #define SIZE    64
  136.  
  137. #define TITLE "\x9B1;33mAmiCron v2.5\x9B0m by \x9B1m<CB>\x9B0m & - \x9B3mThe Software Brewery\x9B0m -\n"
  138. #define WHERE "Im Wingertsberg 45, D-6108 Weiterstadt, \x9B1mW-Germany\x9B0m\n"
  139.  
  140. int    eof;
  141. short    sleepy;
  142. char    min[SIZE], hour[SIZE], day[SIZE],
  143.     month[SIZE], wday[SIZE], command[SIZE];
  144. char    *tokv[] = { min, hour, day, month, wday };
  145. char    crontabs[200];  /* You might define quite a path! <CB> */
  146. FILE    *fd;
  147.  
  148.  
  149. /*
  150.  *    This is the basics, ready for bells and whistles
  151.  *
  152.  */
  153.  
  154.  
  155. void main(argc, argv)
  156. int argc;
  157. char *argv[];
  158. {
  159.     void showhelp();
  160.     void wakeup();
  161.  
  162.     /* Below we use the same functions & variables as in wakeup()
  163.        just to get the current second  <CB>*/
  164.  
  165.     register struct tm *tm;
  166.     struct tm *localtime();
  167.     long cur_time;
  168.      
  169.     /* Tell the guy out there what he might do with this deamon
  170.      * and who made it. <CB>*/
  171.  
  172.     printf(TITLE);
  173.     printf(WHERE);
  174.     printf("Usage: %s [Path & Filename]\n",argv[0]);
  175.     printf("       or '%s ?' for help\n",argv[0]);
  176.  
  177.     /* Now let's see if the user told us to look someplace else
  178.      * for our input file or if he want's some more usage hints <CB> */
  179.   
  180.     if (argc == 2) {
  181.         if (argv[1][0] == '?') { 
  182.             showhelp();
  183.             exit(10);
  184.         }
  185.         else (void)strcpy(crontabs, argv[1]);
  186.         
  187.     }
  188.     else (void)strcpy(crontabs, CRONTAB);    
  189.     /* If there isn't a user path, we'll use the default <CB>*/
  190.  
  191.     /*Now tell the user with what path & filename we wound up*/
  192.     printf("CronTab path = %s \n",crontabs);
  193.  
  194.     for (;;)  {
  195.  
  196.         wakeup();
  197.  
  198.         time(&cur_time);        /* get the current time */
  199.         tm = localtime(&cur_time);    /* break it down */
  200.  
  201.         /* Now we calculate the amount of seconds
  202.          * 'till the next minute <CB>*/
  203.  
  204.         sleepy = (60-tm->tm_sec);    
  205.         /* PLEASE don't decrease the 60 above, believe me,
  206.          * I know what I'm doing there! <CB> */ 
  207.  
  208.         TimeDelay(sleepy,0,0);    
  209.         /* sleep 'till next minute */
  210.     }
  211. }
  212.  
  213. void wakeup()
  214. {
  215.     register struct tm *tm;
  216.     struct tm *localtime();
  217.     long cur_time;
  218.     
  219.     char doit[80];
  220.      
  221.     time(&cur_time);        /* get the current time */
  222.     tm = localtime(&cur_time);    /* break it down */
  223.  
  224.     /* Now let's see if there is a CronTab file out there <CB> */     
  225.  
  226.     if ((fd = fopen(crontabs, "r")) == NULL) {
  227.     fprintf(stderr, "Can't open %s\nTry again\n", crontabs);
  228.     exit(1);
  229.     }
  230.  
  231.  
  232.     eof = FALSE;
  233.  
  234.     while (!eof)  {
  235.         if (getline() && match(min,tm->tm_min) &&
  236.            match(hour,tm->tm_hour) && match(day,tm->tm_mday) &&
  237.            match(month,tm->tm_mon+1) && match(wday,tm->tm_wday))  {
  238.         /* Weird localtime months ^ range from 0-11 !!! <CB>*/
  239.             (void)strcpy(doit,"RUN ");
  240.             (void)strcat(doit,command);
  241.             (void)Execute(doit,NULL,NULL);
  242.             }
  243.         }
  244.     fclose(fd);
  245. }
  246.  
  247.  
  248. /*
  249.  *    A line consists of six fields.  The first five are:
  250.  *
  251.  *        minute:         0-59
  252.  *        hour:           0-23
  253.  *        day:            1-31
  254.  *        month:          1-12
  255.  *        weekday:        0-6 (Sunday = 0)
  256.  *
  257.  *    The fields are seperated by spaces or tabs, with the
  258.  *    first field left justified (no leading spaces or tabs).
  259.  *    See below for optional field syntax.
  260.  *
  261.  *    The last field is the command field.  This command will
  262.  *    be executed by the CLI just as if typed from a console.
  263.  */
  264.  
  265. int getline()
  266. {
  267.     register char *p;
  268.     register int   i;
  269.     char    buffer[MAXLINE], *scanner(), *fgets();
  270.  
  271.     if (fgets(buffer, sizeof buffer, fd) == NULL)  {
  272.         eof = TRUE;
  273.         return(FALSE);
  274.         }
  275.  
  276.     for (p = buffer, i = 0; i < 5; i++)  {
  277.         if ((p = scanner(tokv[i], p)) == (char *)NULL)
  278.             return(FALSE);
  279.         }
  280.  
  281.     (void)strcpy(command, p);     /* scoop the command */
  282.     return(TRUE);
  283. }
  284.  
  285.  
  286. char *scanner(token, offset)
  287. register char   *token;        /* target buffer to receive scanned token */
  288. register char   *offset;    /* place holder into source buffer */
  289. {
  290.     while ((*offset != ' ') && (*offset != '\t') && *offset)
  291.         *token++ = *offset++;
  292.  
  293.     /*
  294.      *      Check for possible error condition
  295.      */
  296.          
  297.     if (!*offset)
  298.         return ((char *)NULL);
  299.  
  300.     *token = '\0';
  301.         
  302.     while ((*offset == ' ') || (*offset == '\t'))
  303.         offset++;
  304.  
  305.     return (offset);
  306. }
  307.  
  308.  
  309. /*
  310.  *    This routine will match the left string with the right number.
  311.  *
  312.  *    The string can contain the following syntax:
  313.  *
  314.  *    *        This will return TRUE for any number
  315.  *    x,y [,z, ...]    This will return TRUE for any number given.
  316.  *    x-y        This will return TRUE for any number within
  317.  *            the range of x thru y.
  318.  */
  319.  
  320. int match(left, right)
  321. register char   *left;
  322. register int    right;
  323. {
  324.     register int    n;
  325.     register char    c;
  326.  
  327.     n = 0;
  328.  
  329.     if (!strcmp(left, "*"))
  330.         return(TRUE);
  331.  
  332.     while ((c = *left++) && (c >= '0') && (c <= '9'))
  333.         n  =  (n * 10) + c - '0';
  334.  
  335.     switch (c)  {
  336.         case '\0':
  337.             return (right == n);
  338.  
  339.         case ',':
  340.             if (right == n)
  341.                 return(TRUE);
  342.             do {
  343.                 n = 0;
  344.                 while ((c = *left++) && (c >= '0') && (c <= '9'))
  345.                     n = (n * 10) + c - '0';
  346.                  if (right == n)
  347.                     return(TRUE);
  348.                 } while (c == ',');
  349.             return(FALSE);
  350.  
  351.         case '-':
  352.             if (right < n)
  353.                 return(FALSE);
  354.  
  355.             n = 0;
  356.             while ((c = *left++) && (c >= '0') && (c <= '9'))
  357.                 n = (n * 10) + c - '0';
  358.  
  359.             return(right <= n);
  360.         }
  361. }
  362.  
  363. void showhelp()        /* by <CB> */
  364.  
  365.     printf("\nWell, you really should read the .doc file,\n");
  366.     printf("but here are some more hints:\n");
  367.     printf("You might specify only ONE command line parameter,\n");
  368.     printf("the path were AmiCron should look for it's command table,\n");
  369.     printf("including the filename of the command table.\n");
  370.     printf("If you don't supply a path, AmiCron will use it's default\n");
  371.     printf("path (S:CronTab).\n");
  372. }
  373.