home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / at.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  5.1 KB  |  306 lines

  1. /*
  2.  * at time mon day
  3.  * at time wday
  4.  * at time wday 'week'
  5.  *
  6.  */
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <time.h>
  10. #include <signal.h>
  11.  
  12. #define HOUR 100
  13. #define HALFDAY    (12*HOUR)
  14. #define DAY    (24*HOUR)
  15. #define THISDAY "/usr/spool/at"
  16.  
  17. char *days[] = {
  18.     "sunday",
  19.     "monday",
  20.     "tuesday",
  21.     "wednesday",
  22.     "thursday",
  23.     "friday",
  24.     "saturday",
  25. };
  26.  
  27. struct monstr {
  28.     char *mname; 
  29.     int mlen;
  30. } months[] = {
  31.     { "january", 31 },
  32.     { "february", 28 },
  33.     { "march", 31 },
  34.     { "april", 30 },
  35.     { "may", 31 },
  36.     { "june", 30 },
  37.     { "july", 31 },
  38.     { "august", 31 },
  39.     { "september", 30 },
  40.     { "october", 31 },
  41.     { "november", 30 },
  42.     { "december", 31 },
  43.     { 0, 0 },
  44. };
  45.  
  46. char    fname[100];
  47. int    utime;  /* requested time in grains */
  48. int    now;    /* when is it */
  49. int    uday; /* day of year to be done */
  50. int    uyear; /* year */
  51. int    today; /* day of year today */
  52. FILE    *file;
  53. FILE    *ifile;
  54. char    **environ;
  55. char    *prefix();
  56. FILE    *popen();
  57.  
  58. main(argc, argv)
  59. char **argv;
  60. {
  61.     extern onintr();
  62.     register c;
  63.     char pwbuf[100];
  64.     FILE *pwfil;
  65.     int larg;
  66.  
  67.     /* argv[1] is the user's time: e.g.,  3AM */
  68.     /* argv[2] is a month name or day of week */
  69.     /* argv[3] is day of month or 'week' */
  70.     /* another argument might be an input file */
  71.     if (argc < 2) {
  72.         fprintf(stderr, "at: arg count\n");
  73.         exit(1);
  74.     }
  75.     makeutime(argv[1]);
  76.     larg = makeuday(argc,argv)+1;
  77.     if (uday==today && larg<=2 && utime<=now)
  78.         uday++;
  79.     c = uyear%4==0? 366: 365;
  80.     if (uday >= c) {
  81.         uday -= c;
  82.         uyear++;
  83.     }
  84.     filename(THISDAY, uyear, uday, utime);
  85.     ifile = stdin;
  86.     if (argc > larg)
  87.         ifile = fopen(argv[larg], "r");
  88.     if (ifile == NULL) {
  89.         fprintf(stderr, "at: cannot open input: %s\n", argv[larg]);
  90.         exit(1);
  91.     }
  92.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  93.         signal(SIGINT, onintr);
  94.     file = fopen(fname, "a");
  95.     chmod(fname, 0644);
  96.     if (file == NULL) {
  97.         fprintf(stderr, "at: cannot open memo file\n");
  98.         exit(1);
  99.     }
  100.     if ((pwfil = popen("pwd", "r")) == NULL) {
  101.         fprintf(stderr, "at: can't execute pwd\n");
  102.         exit(1);
  103.     }
  104.     fgets(pwbuf, 100, pwfil);
  105.     pclose(pwfil);
  106.     fprintf(file, "cd %s", pwbuf);
  107.     if (environ) {
  108.         char **ep = environ;
  109.         while(*ep)
  110.             fprintf(file, "%s\n", *ep++);
  111.     }
  112.     while((c = getc(ifile)) != EOF) {
  113.         putc(c, file);
  114.     }
  115.     exit(0);
  116. }
  117.  
  118. makeutime(pp)
  119. char *pp; 
  120. {
  121.     register val;
  122.     register char *p;
  123.  
  124.     /* p points to a user time */
  125.     p = pp;
  126.     val = 0;
  127.     while(isdigit(*p)) {
  128.         val = val*10+(*p++ -'0');
  129.     }
  130.     if (p-pp < 3)
  131.         val *= HOUR;
  132.  
  133.     for (;;) {
  134.         switch(*p) {
  135.  
  136.         case ':':
  137.             ++p;
  138.             if (isdigit(*p)) {
  139.                 if (isdigit(p[1])) {
  140.                     val +=(10* *p + p[1] - 11*'0');
  141.                     p += 2;
  142.                     continue;
  143.                 }
  144.             }
  145.             fprintf(stderr, "at: bad time format:\n");
  146.             exit(1);
  147.  
  148.         case 'A':
  149.         case 'a':
  150.             if (val >= HALFDAY+HOUR)
  151.                 val = DAY+1;  /* illegal */
  152.             if (val >= HALFDAY && val <(HALFDAY+HOUR))
  153.                 val -= HALFDAY;
  154.             break;
  155.  
  156.         case 'P':
  157.         case 'p':
  158.             if (val >= HALFDAY+HOUR)
  159.                 val = DAY+1;  /* illegal */
  160.             if (val < HALFDAY)
  161.                 val += HALFDAY;
  162.             break;
  163.  
  164.         case 'n':
  165.         case 'N':
  166.             val = HALFDAY;
  167.             break;
  168.  
  169.         case 'M':
  170.         case 'm':
  171.             val = 0;
  172.             break;
  173.  
  174.  
  175.         case '\0':
  176.         case ' ':
  177.             /* 24 hour time */
  178.             if (val == DAY)
  179.                 val -= DAY;
  180.             break;
  181.  
  182.         default:
  183.             fprintf(stderr, "at: bad time format\n");
  184.             exit(1);
  185.  
  186.         }
  187.         break;
  188.     }
  189.     if (val < 0 || val >= DAY) {
  190.         fprintf(stderr, "at: time out of range\n");
  191.         exit(1);
  192.     }
  193.     if (val%HOUR >= 60) {
  194.         fprintf(stderr, "at: illegal minute field\n");
  195.         exit(1);
  196.     }
  197.     utime = val;
  198. }
  199.  
  200.  
  201. makeuday(argc,argv)
  202. char **argv;
  203. {
  204.     /* the presumption is that argv[2], argv[3] are either
  205.        month day OR weekday [week].  Returns either 2 or 3 as last
  206.        argument used */
  207.     /* first of all, what's today */
  208.     long tm;
  209.     int found = -1;
  210.     char **ps;
  211.     struct tm *detail, *localtime();
  212.     struct monstr *pt;
  213.  
  214.     time(&tm);
  215.     detail = localtime(&tm);
  216.     uday = today = detail->tm_yday;
  217.     uyear = detail->tm_year;
  218.     now = detail->tm_hour*100+detail->tm_min;
  219.     if (argc<=2)
  220.         return(1);
  221.     /* is the next argument a month name ? */
  222.     for (pt=months; pt->mname; pt++) {
  223.         if (prefix(argv[2], pt->mname)) {
  224.             if (found<0)
  225.                 found = pt-months;
  226.             else {
  227.                 fprintf(stderr, "at: ambiguous month\n");
  228.                 exit(1);
  229.             }
  230.         }
  231.     }
  232.     if (found>=0) {
  233.         if (argc<=3)
  234.             return(2);
  235.         uday = atoi(argv[3]) - 1;
  236.         if (uday<0) {
  237.             fprintf(stderr, "at: illegal day\n");
  238.             exit(1);
  239.         }
  240.         while(--found>=0)
  241.             uday += months[found].mlen;
  242.         if (detail->tm_year%4==0 && uday>59)
  243.             uday += 1;
  244.         return(3);
  245.     }
  246.     /* not a month, try day of week */
  247.     found = -1;
  248.     for (ps=days; ps<days+7; ps++) {
  249.         if (prefix(argv[2], *ps)) {
  250.             if (found<0)
  251.                 found = ps-days;
  252.             else {
  253.                 fprintf(stderr, "at: ambiguous day of week\n");
  254.                 exit(1);
  255.             }
  256.         }
  257.     }
  258.     if (found<0)
  259.         return(1);
  260.     /* find next day of this sort */
  261.     uday = found - detail->tm_wday;
  262.     if (uday<=0)
  263.         uday += 7;
  264.     uday += today;
  265.     if (argc>3 && strcmp("week", argv[3])==0) {
  266.         uday += 7;
  267.         return(3);
  268.     }
  269.     return(2);
  270. }
  271.  
  272. char *
  273. prefix(begin, full)
  274. char *begin, *full;
  275. {
  276.     int c;
  277.     while (c = *begin++) {
  278.         if (isupper(c))
  279.             c = tolower(c);
  280.         if (*full != c)
  281.             return(0);
  282.         else
  283.             full++;
  284.     }
  285.     return(full);
  286. }
  287.  
  288. filename(dir, y, d, t)
  289. char *dir;
  290. {
  291.     register i;
  292.  
  293.     for (i=0; ; i += 53) {
  294.         sprintf(fname, "%s/%02d.%03d.%04d.%02d", dir, y, d, t,
  295.            (getpid()+i)%100);
  296.         if (access(fname, 0) == -1)
  297.             return;
  298.     }
  299. }
  300.  
  301. onintr()
  302. {
  303.     unlink(fname);
  304.     exit(1);
  305. }
  306.