home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2787 < prev    next >
Internet Message Format  |  1991-02-19  |  51KB

  1. From: dfs@doe.carleton.ca (David F. Skoll)
  2. Newsgroups: alt.sources
  3. Subject: REMIND 2.3.0 2/4
  4. Message-ID: <dfs.666901099@data>
  5. Date: 18 Feb 91 18:18:19 GMT
  6.  
  7. #!/bin/sh
  8. # This is part 02 of Remind 2.3.0
  9. if touch 2>&1 | fgrep 'amc' > /dev/null
  10.  then TOUCH=touch
  11.  else TOUCH=true
  12. fi
  13. # ============= files.c ==============
  14. if test X"$1" != X"-c" -a -f 'files.c'; then
  15.     echo "File already exists: skipping 'files.c'"
  16. else
  17. echo "x - extracting files.c (Text)"
  18. sed 's/^X//' << 'SHAR_EOF' > files.c &&
  19. X#include <stdio.h>
  20. X#ifndef UNIX
  21. X#include <stdlib.h>
  22. X#endif
  23. X#include <string.h>
  24. X#ifndef NO_MALLOC_H
  25. X#include <malloc.h>
  26. X#endif
  27. X#ifndef UNIX
  28. X#include <dos.h>
  29. X#endif
  30. X#include <fcntl.h>
  31. X#ifdef UNIX
  32. X#include <sys/types.h>
  33. X#include <sys/stat.h>
  34. X#include <time.h>
  35. X#endif
  36. X#include "defines.h"
  37. X#include "globals.h"
  38. X#include "protos.h"
  39. X
  40. X#ifdef __STDC__
  41. Xstatic int PopFile(void);
  42. X#else
  43. Xstatic int PopFile();
  44. X#endif
  45. X
  46. X/***************************************************************/
  47. X/*                                                             */
  48. X/*  FILES.C                                                    */
  49. X/*                                                             */
  50. X/*  All the routines for opening initial file, getting         */
  51. X/*  and settting initial file's date, closing files,           */
  52. X/*  handling INCLUDE commands, etc.                            */
  53. X/*                                                             */
  54. X/***************************************************************/
  55. X
  56. X/* Define the structure for saving info about a file */
  57. Xtypedef struct {
  58. X   long offset;
  59. X   int  curline;
  60. X   char *name;
  61. X} FileSave;
  62. X
  63. X#define MAXINCLUDE 10
  64. X/* Set up array of MAXINCLUDE file save areas */
  65. Xstatic FileSave stack[MAXINCLUDE];
  66. Xstatic int      SP;
  67. X
  68. Xstatic FILE *fp;
  69. X
  70. X/***************************************************************/
  71. X/*                                                             */
  72. X/*  OpenFile                                                   */
  73. X/*                                                             */
  74. X/*  Open the named file, initialize stack, get file date.      */
  75. X/*  If there's a problem, print an error msg and die.          */
  76. X/*                                                             */
  77. X/***************************************************************/
  78. X#ifdef __STDC__
  79. Xvoid OpenFile(char *s)
  80. X#else
  81. Xvoid OpenFile(s)
  82. X     char *s;
  83. X     
  84. X#endif
  85. X{
  86. X   unsigned date, time;
  87. X#ifndef UNIX
  88. X   unsigned handle;
  89. X#endif
  90. X   int d, m, y;
  91. X#ifndef UNIX
  92. X   
  93. X   /* Get the file's modification date */
  94. X   if(_dos_open(s, O_RDONLY, &handle)) {
  95. X      fprintf(stderr, "remind: Can't open %s.\n", s);
  96. X      exit(1);
  97. X#else
  98. X   struct stat t;
  99. X   struct tm *t1;
  100. X      
  101. X   /* Get the file's access date */
  102. X   if (stat(s, &t)) {
  103. X     fprintf(stderr, "remind: Can't find file %s.\n", s);
  104. X     exit(1);
  105. X#endif
  106. X   }
  107. X#ifndef UNIX
  108. X   _dos_getftime(handle, &date, &time);
  109. X   d = date & 0x1F;
  110. X   m = (date >> 5) & 0xF;
  111. X   y = (date >> 9) + 1980;
  112. X#else
  113. X   t1 = localtime(&(t.st_atime));
  114. X#endif
  115. X   
  116. X#ifndef UNIX
  117. X   if (y < BASE) LastRun = 0; else LastRun = Julian(d, m-1, y);
  118. X   _dos_close(handle);
  119. X#else
  120. X   y = t1->tm_year + 1900;
  121. X   m = t1->tm_mon;
  122. X   d = t1->tm_mday;
  123. X   
  124. X   if (y < BASE) LastRun = 0; else LastRun = Julian(d, m, y);
  125. X#endif
  126. X   fp = fopen(s, "r");
  127. X   if (fp == NULL) {
  128. X      fprintf(stderr, "remind: Can't open %s.\n", s);
  129. X      exit(1);
  130. X   }
  131. X   
  132. X   CurLine = 0;
  133. X   strcpy(FileName, s);
  134. X   SP = 0;
  135. X   
  136. X   return;
  137. X}   
  138. X
  139. X/***************************************************************/
  140. X/*                                                             */
  141. X/*  DoInclude                                                  */
  142. X/*                                                             */
  143. X/*  Push the state of the current file and open a new file.    */
  144. X/*                                                             */
  145. X/***************************************************************/
  146. X#ifdef __STDC__
  147. Xvoid DoInclude(char **s)
  148. X#else
  149. Xvoid DoInclude(s)
  150. X     char **s;
  151. X     
  152. X#endif
  153. X{
  154. X   Token tok;
  155. X   tok = ParseToken(s);
  156. X   
  157. X   /* First, check if there's room on the stack */
  158. X   if (SP == MAXINCLUDE) {
  159. X      Eprint("Too many levels of INCLUDE\n");
  160. X      return;
  161. X   }
  162. X   
  163. X   /* Save current data */
  164. X#ifndef UNIX
  165. X   stack[SP].offset = ftell(fp) - 1L;
  166. X#else
  167. X   stack[SP].offset = ftell(fp);
  168. X#endif
  169. X   stack[SP].curline = CurLine;
  170. X   stack[SP].name = (char *) malloc(strlen(FileName)+1);
  171. X   if (stack[SP].name == NULL) {
  172. X      Eprint("Out of memory for INCLUDE\n");
  173. X      return;
  174. X   }
  175. X   strcpy(stack[SP].name, FileName);
  176. X   
  177. X   SP++;
  178. X   
  179. X   /* Close the current file */
  180. X   fclose(fp);
  181. X   
  182. X   /* Open the new file */
  183. X   fp = fopen(tok.str, "r");
  184. X   if (fp == NULL) {
  185. X      Eprint("Can't open %s for INCLUDE\n", tok.str);
  186. X      PopFile();
  187. X      return;
  188. X   }
  189. X   if (Debug || Purge) {
  190. X      Eprint("INCLUDING file %s\n", tok.str);
  191. X   }
  192. X   
  193. X   /* Set the global variables */
  194. X   CurLine = 0;
  195. X   strcpy(FileName, tok.str);
  196. X   return;
  197. X}
  198. X
  199. X/***************************************************************/
  200. X/*                                                             */
  201. X/*  PopFile                                                    */
  202. X/*                                                             */
  203. X/*  Pop to the previous file, if there is one.  Return 0 for   */
  204. X/*  OK, non-zero for no more files.  If we can't pop back      */
  205. X/*  to a file, print an error message and die.                 */
  206. X/*                                                             */
  207. X/***************************************************************/
  208. X#ifdef __STDC__
  209. Xstatic int PopFile(void)
  210. X#else
  211. Xstatic int PopFile()
  212. X#endif
  213. X{
  214. X#ifndef UNIX
  215. X   unsigned handle, date, time;
  216. X   struct dostime_t t;
  217. X#endif
  218. X
  219. X   if (fp) fclose(fp);
  220. X#ifndef UNIX
  221. X   if (!SP) {
  222. X      if (!Debug && !Purge && (JulianToday == RealToday)) {
  223. X         if (_dos_open(FileName, O_RDONLY, &handle)) {
  224. X            fprintf(stderr, "Could not reset date of %s\n", FileName);
  225. X            return 1;
  226. X         }
  227. X     _dos_gettime(&t);
  228. X     date = CurDay;
  229. X     date |= (CurMon + 1) << 5;
  230. X     date |= (CurYear - 1980) << 9;
  231. X     time = t.second / 2;
  232. X     time |= t.minute << 5;
  233. X     time |= t.hour << 11;
  234. X     _dos_setftime(handle, date, time);
  235. X      }
  236. X      return 1;
  237. X   }
  238. X      
  239. X#else
  240. X   if (!SP) return -1;
  241. X         
  242. X#endif
  243. X   SP--;
  244. X   fp = fopen(stack[SP].name, "r");
  245. X   if (fp == NULL) {
  246. X      Eprint("Argh! Can't return to %s from INCLUDE file %s\n", stack[SP].name, FileName);
  247. X      exit(1);
  248. X   }
  249. X#ifndef UNIX
  250. X   if (fseek(fp, stack[SP].offset, SEEK_SET)) {
  251. X#else
  252. X   if (fseek(fp, stack[SP].offset, 0)) {
  253. X#endif
  254. X      Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s\n", stack[SP].name, FileName);
  255. X      exit(1);
  256. X   }
  257. X   
  258. X   if (Debug || Purge) {
  259. X      Eprint("Returning to file %s\n", stack[SP].name);
  260. X   }
  261. X   CurLine = stack[SP].curline;
  262. X   strcpy(FileName, stack[SP].name);
  263. X   free(stack[SP].name);
  264. X   return 0;
  265. X}
  266. X/***************************************************************/
  267. X/*                                                             */
  268. X/*  ReadLine                                                   */
  269. X/*                                                             */
  270. X/*  Reads a line from the file.  If EOF, pops to previous file */
  271. X/*  if there was one.  Returns 0 if more input, non-zero       */
  272. X/*  if no more input.  Updates CurLine.                        */
  273. X/*                                                             */
  274. X/***************************************************************/
  275. Xint ReadLine()
  276. X{
  277. X   int done = 0;
  278. X   int len;
  279. X   
  280. X   Fresh = 1;
  281. X   while (!done) {
  282. X      CurLine++;
  283. X      if (fgets(Line, 512, fp) == NULL) {
  284. X         if (ferror(fp)) Eprint("Error reading %s\n", FileName);
  285. X     if (PopFile()) return 1;
  286. X      } else {
  287. X         len = strlen(Line);
  288. X         /* Remove the newline */
  289. X         if (*Line && (*(Line + len-1)=='\n')) {
  290. X            *(Line + strlen(Line)-1) = 0;
  291. X            len--;
  292. X         }
  293. X         done = 1;
  294. X         while(*Line && (*(Line + len-1) == '\\') && len<512) {
  295. X         *(Line + len-1) = '\n';
  296. X            if (fgets(Line+len, 512-len,fp) == NULL) {
  297. X               *(Line + len) = 0;
  298. X             break;
  299. X        }
  300. X
  301. X        CurLine++;
  302. X        len = strlen(Line);
  303. X            /* Remove the newline */
  304. X            if (*Line && (*(Line + len-1)=='\n')) {
  305. X               *(Line + strlen(Line)-1) = 0;
  306. X               len--;
  307. X            }
  308. X         }
  309. X      }     
  310. X   }
  311. X   return 0;
  312. X}
  313. X
  314. X/***************************************************************/
  315. X/*                                                             */
  316. X/*  TopLevel - Returns 1 if current file is top level, 0       */
  317. X/*  if it is INCLUDEd.                                         */
  318. X/*                                                             */
  319. X/***************************************************************/
  320. X#ifdef __STDC__
  321. Xint TopLevel(void) { return (SP == 0); }
  322. X#else
  323. Xint TopLevel()
  324. X{
  325. X  return (SP == 0);
  326. X}
  327. X#endif
  328. SHAR_EOF
  329. $TOUCH -am 0218130591 files.c &&
  330. chmod 0600 files.c ||
  331. echo "restore of files.c failed"
  332. set `wc -c files.c`;Wc_c=$1
  333. if test "$Wc_c" != "8388"; then
  334.     echo original size 8388, current size $Wc_c
  335. fi
  336. fi
  337. # ============= globals.h ==============
  338. if test X"$1" != X"-c" -a -f 'globals.h'; then
  339.     echo "File already exists: skipping 'globals.h'"
  340. else
  341. echo "x - extracting globals.h (Text)"
  342. sed 's/^X//' << 'SHAR_EOF' > globals.h &&
  343. X/***************************************************************/
  344. X/*                                                             */
  345. X/*  GLOBALS.H                                                  */
  346. X/*                                                             */
  347. X/*  Global variables for REMIND.                               */
  348. X/*                                                             */
  349. X/*  By David Skoll - 30 Sept. 1990                             */
  350. X/*                                                             */
  351. X/***************************************************************/
  352. X
  353. Xextern char *MonthName[];
  354. Xextern char *DayName[];
  355. Xextern Token keywd[];
  356. Xextern int   MonthDays[];
  357. Xextern int   MonthIndex[2][12];
  358. Xextern int   FullOmitArray[];
  359. Xextern int   PartOmitArray[];
  360. Xextern char  Line[];
  361. Xextern char  WorkBuf[];
  362. Xextern char  TmpBuf[];
  363. Xextern char  Fresh;
  364. Xextern char  Purge;
  365. Xextern char  Debug;
  366. Xextern char  Verbose;
  367. Xextern char  Next;
  368. Xextern char  FileName[];
  369. Xextern int   CurLine;
  370. Xextern int   NumEmitted;
  371. Xextern int   NumRem;
  372. Xextern int   NumFullOmit;
  373. Xextern int   NumPartOmit;
  374. Xextern int   JulianToday;
  375. Xextern int   LastRun;
  376. Xextern int   CurYear;
  377. Xextern int   CurMon;
  378. Xextern int   CurDay;
  379. Xextern char  Banner[];
  380. Xextern int   RealToday;
  381. Xextern char  IgRun;
  382. Xextern char  IgOnce;
  383. Xextern int   NumAtsQueued;
  384. Xextern char  QueueAts;
  385. Xextern char  PrintAts;
  386. Xextern int   Calendar;
  387. Xextern int   CalTime;
  388. Xextern int   CalWidth;
  389. Xextern int   SimpleCalendar;
  390. SHAR_EOF
  391. $TOUCH -am 0218130591 globals.h &&
  392. chmod 0600 globals.h ||
  393. echo "restore of globals.h failed"
  394. set `wc -c globals.h`;Wc_c=$1
  395. if test "$Wc_c" != "1469"; then
  396.     echo original size 1469, current size $Wc_c
  397. fi
  398. fi
  399. # ============= init.c ==============
  400. if test X"$1" != X"-c" -a -f 'init.c'; then
  401.     echo "File already exists: skipping 'init.c'"
  402. else
  403. echo "x - extracting init.c (Text)"
  404. sed 's/^X//' << 'SHAR_EOF' > init.c &&
  405. X#include <stdio.h>
  406. X#ifndef UNIX
  407. X#include <stdlib.h>
  408. X#endif
  409. X#include <string.h>
  410. X#include "defines.h"
  411. X#include "globals.h"
  412. X#include "protos.h"
  413. X
  414. X#define PATCHLEVEL 0
  415. X
  416. Xstatic char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
  417. Xstatic char DPCMsg[] = "Calendar overrides Debug and Purge options.\n";
  418. Xstatic char NMsg[] = "Next overrides Calendar, Debug and Purge options.\n";
  419. X
  420. X/***************************************************************/
  421. X/*                                                             */
  422. X/*  void initialize(int argc, char *argv[])                    */
  423. X/*                                                             */
  424. X/*  Reads command line options, sets appropriate flags         */
  425. X/*  and FileName.  Also exits with error if invoked            */
  426. X/*  incorrectly.                                               */
  427. X/*                                                             */
  428. X/***************************************************************/
  429. X#ifdef __STDC__
  430. Xvoid initialize(int argc, char *argv[])
  431. X#else
  432. Xvoid initialize(argc, argv)
  433. X     int argc;
  434. X     char *argv[];
  435. X#endif
  436. X{
  437. X   int i;
  438. X   char *s;
  439. X   int d, m, y, t;
  440. X   Token tok;
  441. X
  442. X   Debug    = 0;
  443. X   Purge    = 0;
  444. X   Verbose  = 0;
  445. X   IgOnce   = 0;
  446. X   IgRun    = 0;
  447. X   Calendar = 0;
  448. X   Next     = 0;
  449. X   PrintAts = 1;
  450. X   QueueAts = 1;
  451. X   CalWidth = 10;
  452. X   SimpleCalendar = 0;
  453. X
  454. X   if(argc == 1) {
  455. X     fprintf(stderr, "\nREMIND 2.3 Patch Level %d (C) 1990, 1991 by David Skoll.\n\n", PATCHLEVEL);
  456. X#ifdef UNIX
  457. X     fprintf(stderr, "Usage: remind [-n | -d | -p | -c# [-w# | -s]] [-voraq] filename [date]\n\n");
  458. X#else
  459. X     fprintf(stderr, "Usage: remind [-n | -d | -p | -c# [-w# | -s]] [-vor] filename [date]\n\n");
  460. X#endif
  461. X     fprintf(stderr, "-n   Output next occurrence of reminders in simple format\n");
  462. X     fprintf(stderr, "-d   Debug reminder file\n-p   Purge reminder file\n");
  463. X     fprintf(stderr, "-c#  Produce calendar for # months\n");
  464. X     fprintf(stderr, "-w#  Make calendar # columns wide\n");
  465. X     fprintf(stderr, "-s   Produce simple calendar listing (used with -c)\n");
  466. X     fprintf(stderr, "-v   Verbose messages\n-o   Ignore ONCE directives\n");
  467. X     fprintf(stderr, "-r   Ignore RUN directives\n");
  468. X#ifdef UNIX
  469. X     fprintf(stderr, "-a   Do not trigger current AT reminders in foreground\n");
  470. X     fprintf(stderr, "-q   Do not queue current AT reminders\n\n");
  471. X#endif
  472. X     exit(1);
  473. X   }
  474. X
  475. X   i = 1;
  476. X   s = argv[i];
  477. X
  478. X   /* Process options */
  479. X   while (*s == '-') {
  480. X      while (*++s) {
  481. X         switch(upper(*s)) {
  482. X
  483. X        case 'N': Next = 1;
  484. X                 if (Calendar || Debug || Purge) {
  485. X                Calendar = Debug = Purge = 0;
  486. X            fprintf(stderr, NMsg);
  487. X                 }
  488. X             break;
  489. X
  490. X            case 'P':  Purge = 1;
  491. X             if (Next) {
  492. X                Calendar = Debug = Purge = 0;
  493. X            fprintf(stderr, NMsg);
  494. X             }
  495. X             if (Calendar) {
  496. X                Debug = Purge = 0;
  497. X            fprintf(stderr, DPCMsg);
  498. X                 }
  499. X                     if (Debug) {
  500. X                        Debug = 0;
  501. X                        fprintf(stderr, DPMsg);
  502. X                     }
  503. X             break;
  504. X
  505. X            case 'D': Debug = 1;
  506. X             if (Next) {
  507. X                Calendar = Debug = Purge = 0;
  508. X            fprintf(stderr, NMsg);
  509. X             }
  510. X             if (Calendar) {
  511. X                Debug = Purge = 0;
  512. X            fprintf(stderr, DPCMsg);
  513. X                 }
  514. X                  if (Purge) {
  515. X                 Debug = 0;
  516. X             fprintf(stderr, DPMsg);
  517. X              }
  518. X              break;
  519. X
  520. X            case 'C': Calendar = 1;
  521. X             if (Next) {
  522. X                Calendar = Debug = Purge = 0;
  523. X            fprintf(stderr, NMsg);
  524. X             }
  525. X             if (Debug || Purge) {
  526. X                Debug = Purge = 0;
  527. X            fprintf(stderr, DPCMsg);
  528. X                 }
  529. X                     t = atoi(s + 1);
  530. X             if (t > 0 && t <= 12) Calendar = t;
  531. X                     /* Skip remaining chars on this option */
  532. X                 while (*++s) ;
  533. X                 s--;
  534. X             break;
  535. X
  536. X        case 'W': CalWidth = (atoi(s+1)-9)/7;
  537. X                 if (CalWidth < 10) CalWidth = 10;
  538. X             if (CalWidth > 40) CalWidth = 40;
  539. X                 while (*++s) ;
  540. X                 s--;
  541. X             break;
  542. X
  543. X            case 'S': SimpleCalendar = 1; break;
  544. X
  545. X        case 'V': Verbose = 1; break;
  546. X
  547. X        case 'O': IgOnce = 1; break;
  548. X
  549. X        case 'R': IgRun = 1; break;
  550. X#ifdef UNIX
  551. X        case 'A': PrintAts = 0; break;
  552. X
  553. X            case 'Q': QueueAts = 0; break;          
  554. X#endif        
  555. X        default: fprintf(stderr, "Unknown option '%c' ignored.\n", *s);
  556. X     }                  
  557. X      }
  558. X      i++;
  559. X      if (i >= argc) {
  560. X    fprintf(stderr, "Missing filename - type 'remind' for usage information.\n");
  561. X     exit(1);
  562. X      }
  563. X      s = argv[i];
  564. X   }     
  565. X   
  566. X   /* Set FileName */
  567. X   strcpy(FileName, argv[i++]);
  568. X   
  569. X   /* Get date, if supplied */
  570. X   if (i < argc) {
  571. X      *WorkBuf = 0;
  572. X      while (i < argc) {
  573. X         strcat(WorkBuf, argv[i++]);
  574. X     strcat(WorkBuf, " ");
  575. X      }
  576. X      /* Parse the date */
  577. X      d = m = y = -1;
  578. X      tok.type = Unknown_t;
  579. X      s = WorkBuf;
  580. X      while (tok.type != Eol_t) {
  581. X         tok = ParseToken(&s);
  582. X     switch(tok.type) {
  583. X
  584. X        case Eol_t: break;
  585. X
  586. X        case Year_t: if (y == -1) 
  587. X                        y = tok.val;
  588. X             else {
  589. X                fprintf(stderr, "Year specified twice!\n");
  590. X                exit(1);
  591. X             }
  592. X             break;
  593. X
  594. X        case Month_t: if (m == -1) 
  595. X                        m = tok.val;
  596. X             else {
  597. X                fprintf(stderr, "Month specified twice!\n");
  598. X                exit(1);
  599. X             }
  600. X             break;
  601. X             
  602. X        case Day_t: if (d == -1) 
  603. X                        d = tok.val;
  604. X             else {
  605. X                fprintf(stderr, "Day specified twice!\n");
  606. X                exit(1);
  607. X             }
  608. X             break;
  609. X       
  610. X            default: fprintf(stderr, "Illegal token %s on command line.\n", tok.str);
  611. X                 exit(1);
  612. X   
  613. X         }
  614. X      } 
  615. X      
  616. X      if (d == -1 || m == -1 || y == -1) {
  617. X         fprintf(stderr, "Date on command line must be fully specified.\n");
  618. X     exit(1);
  619. X      }
  620. X      if (CheckDate(d, m, y)) {
  621. X         fprintf(stderr, "Illegal date on command line.\n");
  622. X     exit(1);
  623. X      }
  624. X
  625. X      CurDay = d;
  626. X      CurMon = m;
  627. X      CurYear = y;
  628. X      JulianToday = Julian(d, m, y);
  629. X   }
  630. X   OpenFile(FileName);
  631. X   if (Debug) {
  632. X      FromJulian(LastRun, &d, &m, &y);
  633. X#ifndef UNIX
  634. X      fprintf(stderr, "\nFile %s last modified on %s, %d %s, %d\n", FileName,
  635. X#else
  636. X      fprintf(stderr, "\nFile %s last accessed on %s, %d %s, %d\n", FileName,
  637. X#endif
  638. X                       DayName[LastRun % 7], d, MonthName[m], y);
  639. X   }
  640. X   return;
  641. X}
  642. SHAR_EOF
  643. $TOUCH -am 0218130591 init.c &&
  644. chmod 0600 init.c ||
  645. echo "restore of init.c failed"
  646. set `wc -c init.c`;Wc_c=$1
  647. if test "$Wc_c" != "6305"; then
  648.     echo original size 6305, current size $Wc_c
  649. fi
  650. fi
  651. # ============= kall ==============
  652. if test X"$1" != X"-c" -a -f 'kall'; then
  653.     echo "File already exists: skipping 'kall'"
  654. else
  655. echo "x - extracting kall (Text)"
  656. sed 's/^X//' << 'SHAR_EOF' > kall &&
  657. X#!/bin/sh
  658. X#
  659. X# kall - kill all processes belonging to this user that match
  660. X#           specified string.
  661. X
  662. Xsignal=`echo $1 | grep '^\-.*'`
  663. Xme=`basename $0`
  664. X
  665. Xif [ "$signal" != "" ]; then
  666. X    shift
  667. Xelse
  668. X    signal="-TERM"
  669. Xfi
  670. X
  671. Xif [ "$1" = "" ]; then
  672. X    echo "usage: $me [-signal] string [string...]"
  673. X    echo "       kills all of your processes where command name matches"
  674. X    echo "       any of the given strings."
  675. X    exit
  676. Xfi
  677. X
  678. Xmsg="0"
  679. X
  680. Xwhile [ "$1" != "" ]; do
  681. X
  682. X# NOTE:  You may have to modify the next line, since PS is non-portable.
  683. X# The 'awk' command picks out the process IDs to pass them on to kill.
  684. X    rprocs=`ps -cx | awk '{if(prog == $5) print $1}' prog=$1 -`
  685. X    if [ "$rprocs" != "" ]; then
  686. X        msg="1"
  687. X        echo -n "${me}: Sending $signal signal to $1 process(es)"
  688. X        echo '...'
  689. X        kill $signal $rprocs
  690. X    fi
  691. X    shift
  692. Xdone
  693. X
  694. Xif [ $msg = "1" ]; then
  695. X    echo "${me}: Done."
  696. Xfi
  697. SHAR_EOF
  698. $TOUCH -am 0218130591 kall &&
  699. chmod 0700 kall ||
  700. echo "restore of kall failed"
  701. set `wc -c kall`;Wc_c=$1
  702. if test "$Wc_c" != "852"; then
  703.     echo original size 852, current size $Wc_c
  704. fi
  705. fi
  706. # ============= main.c ==============
  707. if test X"$1" != X"-c" -a -f 'main.c'; then
  708.     echo "File already exists: skipping 'main.c'"
  709. else
  710. echo "x - extracting main.c (Text)"
  711. sed 's/^X//' << 'SHAR_EOF' > main.c &&
  712. X/***************************************************************/
  713. X/*                                                             */
  714. X/*  REMIND - version 2.3                                       */
  715. X/*                                                             */
  716. X/*  By David Skoll - 11 February 1991                          */
  717. X/*                                                             */
  718. X/*  (C) 1990, 1991 by David Skoll - all rights reserved        */
  719. X/*                                                             */
  720. X/***************************************************************/
  721. X
  722. X#include <stdio.h>
  723. X#include <string.h>
  724. X#include <ctype.h>
  725. X
  726. X#ifndef UNIX
  727. X#include <stdlib.h>
  728. X#include <dos.h>
  729. X#include <stdarg.h>
  730. X#else
  731. X#include <varargs.h>
  732. X#include <sys/types.h>
  733. X#ifdef SYSV
  734. X#include <time.h>
  735. X#else
  736. X#include <sys/time.h>
  737. X#endif
  738. X#endif
  739. X
  740. X#include "defines.h"
  741. X#include "protos.h"
  742. X
  743. X
  744. X/* List of months */
  745. Xchar *MonthName[] = {
  746. X   "January", "February", "March", "April", "May", "June",
  747. X   "July", "August", "September", "October", "November", "December"
  748. X};
  749. X
  750. X/* List of weekdays */
  751. Xchar *DayName[] = {
  752. X   "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
  753. X};
  754. X
  755. X/* List of recognized tokens - Keep them SORTED (case insensitive.) */
  756. X
  757. XToken keywd[] = {
  758. X   { "AFTER",     Skip_t,    3, 3 },
  759. X   { "April",     Month_t,  3, 3 },
  760. X   { "AT",        At_t,      0, 2 },
  761. X   { "August",    Month_t,  7, 3 },
  762. X   { "BANNER",    Banner_t, 0, 3 },
  763. X   { "BEFORE",    Skip_t,    2, 3 },
  764. X   { "CLEAR-OMIT-CONTEXT", Clear_t, 0, 3},
  765. X   { "December",  Month_t,  11, 3 },
  766. X   { "February",  Month_t,  1, 3 },
  767. X   { "Friday",    WkDay_t,  4, 3 },
  768. X   { "INCLUDE",   Include_t, 0, 3 },
  769. X   { "January",   Month_t,  0, 3 },
  770. X   { "July",      Month_t,  6, 3 },
  771. X   { "June",      Month_t,  5, 3 },
  772. X   { "March",     Month_t,  2, 3 },
  773. X   { "May",       Month_t,  4, 3 },
  774. X   { "Monday",    WkDay_t,  0, 3 },
  775. X   { "MSG",       Msg_t,    0, 3 },
  776. X   { "November",  Month_t,  10, 3 },
  777. X   { "October",   Month_t,  9, 3 },
  778. X   { "OMIT",      Omit_t,   0, 3 },
  779. X   { "ONCE",      Once_t,   0, 3 },
  780. X   { "POP-OMIT-CONTEXT", Pop_t, 0, 3},
  781. X   { "PUSH-OMIT-CONTEXT", Push_t, 0, 3 },
  782. X   { "REM",       Rem_t,    0, 3 },
  783. X   { "RUN",       Run_t,    0, 3 },
  784. X   { "Saturday",  WkDay_t,  5, 3 },
  785. X   { "September", Month_t,  8, 3 },
  786. X   { "SKIP",      Skip_t,    1, 3 },
  787. X   { "Sunday",    WkDay_t,  6, 3 },
  788. X   { "Thursday",  WkDay_t,  3, 3 },
  789. X   { "Tuesday",   WkDay_t,  1, 3 },
  790. X   { "UNTIL",      Until_t,   0, 3 },
  791. X   { "Wednesday", WkDay_t,  2, 3 }
  792. X};
  793. X
  794. X/* List of days in month - Feb MUST be 29 for CheckDate to work. */
  795. Xint MonthDays[] = {
  796. X   31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  797. X};
  798. X
  799. X/* Index of the first day of each month.  First array is non-leap-year;
  800. X   second is leap-year. */
  801. Xint MonthIndex[2][12] = {
  802. X   { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
  803. X   { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
  804. X};
  805. X
  806. X/* Global ommissions array */
  807. Xint FullOmitArray[FOMITSIZE];
  808. X
  809. X/* Global partial omissions array */
  810. Xint PartOmitArray[POMITSIZE];
  811. X
  812. X/* Define the working buffers */
  813. Xchar Line[512], WorkBuf[512];
  814. Xchar TmpBuf[512];
  815. Xchar Fresh;  /* True if the contents of Line are fresh */
  816. X
  817. X/* Global variables */
  818. Xchar Purge, Debug, Verbose, IgRun, IgOnce, Next;
  819. Xint LastRun;
  820. Xchar FileName[200];
  821. Xint CurLine;
  822. Xchar Banner[200] = "Reminders for %w, %d%s %m, %y%o:";
  823. Xint NumEmitted, NumRem;
  824. Xint NumFullOmit, NumPartOmit;
  825. Xint JulianToday, RealToday;
  826. Xint CurYear, CurMon, CurDay;
  827. Xchar QueueAts, PrintAts;
  828. Xint  NumAtsQueued;
  829. Xint Calendar, CalTime, CalWidth, SimpleCalendar;
  830. X
  831. Xstatic int JulFirst; /* Julian date of 1 Jan Current_year */
  832. Xstatic int FirstYear;
  833. X
  834. X/***************************************************************/
  835. X/*                                                             */
  836. X/* Output                                                      */
  837. X/* Output a string with line separators.                       */
  838. X/*                                                             */
  839. X/***************************************************************/
  840. X#ifdef __STDC__
  841. Xvoid Output(char *s)
  842. X#else
  843. Xvoid Output(s)
  844. Xchar *s;
  845. X#endif
  846. X{
  847. X   while (*s) {
  848. X      if (*s == '\n') putchar('\\');
  849. X      putchar(*s++);
  850. X   }
  851. X   putchar('\n');
  852. X}
  853. X
  854. X/***************************************************************/
  855. X/*                                                             */
  856. X/*  int MoveBack(...)                                          */
  857. X/*                                                             */
  858. X/*  Move back by specified number of days, skipping holidays   */
  859. X/*  if the amound to move back is positive; otherwise, just    */
  860. X/*  move back (-back) days, ignoring holidays.                 */
  861. X/*                                                             */
  862. X/***************************************************************/
  863. X#ifdef __STDC__
  864. Xint MoveBack (int jul, int back, int omit)
  865. X#else
  866. Xint MoveBack (jul, back, omit)
  867. X     int jul;
  868. X     int back;
  869. X     int omit;
  870. X#endif
  871. X{
  872. X   if (back <= 0) return jul+back;
  873. X   
  874. X   if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
  875. X   while (back) {
  876. X      jul--;
  877. X      if (!IsOmitted(jul, omit)) back--;
  878. X   }
  879. X   return jul;
  880. X}
  881. X
  882. X/***************************************************************/
  883. X/*                                                             */
  884. X/*  int ProcessLine()                                          */
  885. X/*                                                             */
  886. X/*  Process the line in the "Line" buffer.                     */
  887. X/*                                                             */
  888. X/*  Normally returns 0.  Returns 1 only if we're in Calendar   */
  889. X/*  mode and we hit a reminder which should be placed in the   */
  890. X/*  calendar.                                                  */
  891. X/*                                                             */
  892. X/***************************************************************/
  893. X#ifdef __STDC__
  894. Xint ProcessLine(void)
  895. X#else
  896. Xint ProcessLine()
  897. X#endif
  898. X{
  899. X   char *s = Line;
  900. X   Token tok;
  901. X   int i;
  902. X
  903. X   while (isspace(*s)) s++;
  904. X
  905. X   /* Skip comments and blank lines */
  906. X   if (*s == '#' || *s == 0) {
  907. X      if (Purge && TopLevel()) Output(Line);
  908. X      return 0;
  909. X   }
  910. X
  911. X   tok = ParseToken(&s);
  912. X   switch(tok.type) {
  913. X      case Push_t:   PushOmitContext();
  914. X                      if (Purge && TopLevel()) Output(Line);
  915. X             break;
  916. X
  917. X      case Pop_t:    PopOmitContext();
  918. X                      if (Purge && TopLevel()) Output(Line);
  919. X             break;
  920. X
  921. X      case Clear_t:  ClearOmitContext();
  922. X                      if (Purge && TopLevel()) Output(Line);
  923. X             break;
  924. X
  925. X      case Banner_t: DoBanner(&s);
  926. X             if (Purge && TopLevel()) Output(Line);
  927. X             break;
  928. X
  929. X      case Omit_t:   i = DoGlobalOmit(&s);
  930. X             if (Calendar) return i;
  931. X             if (Purge && TopLevel())
  932. X            if (i == -1) Eprint("Purged '%s'\n", Line);
  933. X            else       Output(Line);
  934. X             break;
  935. X
  936. X      case Rem_t:    i = DoRem(&s);
  937. X                 if (Calendar) return i;
  938. X             if (Purge && TopLevel())
  939. X            if (i < 0) Eprint("Purged '%s'\n", Line);
  940. X            else       Output(Line);
  941. X             NumRem++;
  942. X             break;
  943. X
  944. X      case Include_t: if (Purge && TopLevel()) Output(Line);
  945. X              DoInclude(&s);
  946. X              break;
  947. X
  948. X      default:       if (Purge && TopLevel()) Output(Line);
  949. X             Eprint("Unknown command '%s'\n", tok.str);
  950. X   }
  951. X   return 0;
  952. X}
  953. X
  954. X/***************************************************************/
  955. X/*                                                             */
  956. X/*  Standard: void Eprint(const char *f, ...)                  */
  957. X/*  Unix: void Eprint(va_alist)                                */
  958. X/*                                                             */
  959. X/*  Prints an error message.                                   */
  960. X/*                                                             */
  961. X/***************************************************************/
  962. X#ifndef UNIX
  963. Xvoid Eprint(const char *f, ...)
  964. X#else
  965. X/*VARARGS0*/
  966. Xvoid Eprint(va_alist)
  967. Xva_dcl
  968. X#endif
  969. X{
  970. X#ifndef UNIX
  971. X   va_list args;
  972. X#else
  973. X  va_list args;
  974. X  char *f;
  975. X#endif
  976. X
  977. X#ifndef UNIX
  978. X   if (Verbose & Fresh) {
  979. X#else
  980. X  if (Verbose & Fresh) {
  981. X#endif
  982. X      fprintf(stderr, "\n--- %s\n", Line);
  983. X      Fresh = 0;
  984. X   }
  985. X   if (Verbose) fprintf(stderr, "--- ");
  986. X   fprintf(stderr, "%s(%d): ", FileName, CurLine);
  987. X#ifndef UNIX
  988. X   va_start(args, f);
  989. X#else
  990. X   va_start(args);
  991. X   f = va_arg(args, char *);
  992. X#endif
  993. X   vfprintf(stderr, f, args);
  994. X#ifdef UNIX
  995. X   va_end(args);
  996. X#endif
  997. X}
  998. X
  999. X/***************************************************************/
  1000. X/*                                                             */
  1001. X/*  int DoBanner(char **s)                                     */
  1002. X/*                                                             */
  1003. X/*  Sets the "Reminders for..." banner.                        */
  1004. X/*                                                             */
  1005. X/***************************************************************/
  1006. X#ifdef __STDC__
  1007. Xint DoBanner(char **s)
  1008. X#else
  1009. Xint DoBanner(s)
  1010. X     char **s;
  1011. X#endif
  1012. X{
  1013. X   if (Purge || Next) return 0;
  1014. X   while (isspace(**s)) (*s)++;
  1015. X   strcpy(Banner, *s);
  1016. X   if (! *Banner)
  1017. X   {
  1018. X      if (Debug) Eprint("Empty banner.\n");
  1019. X      strcpy(Banner, "Reminders for %w, %d%s %m, %y%o:");
  1020. X   }
  1021. X   if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
  1022. X   return 0;
  1023. X}
  1024. X
  1025. X/***************************************************************/
  1026. X/*                                                             */
  1027. X/* int CheckDate(int d, int m, int y)                          */
  1028. X/*                                                             */
  1029. X/* Checks that a date is valid - returns 0 for OK, 1 for BAD.  */
  1030. X/*                                                             */
  1031. X/* If y=-1, just checks that month & day are valid, giving     */
  1032. X/* benefit of the doubt for February 29.                       */
  1033. X/*                                                             */
  1034. X/* No point in checking if month is valid - months are named   */
  1035. X/* and thus a month out of range can never be entered into     */
  1036. X/* the system.                                                 */
  1037. X/*                                                             */
  1038. X/***************************************************************/
  1039. X#ifdef __STDC__
  1040. Xint CheckDate(int d, int m, int y)
  1041. X#else
  1042. Xint CheckDate(d, m, y)
  1043. X     int d;
  1044. X     int m;
  1045. X     int y;
  1046. X#endif
  1047. X{
  1048. X   if (y == -1)
  1049. X      if (d > 0 && d <= MonthDays[m]) return 0; else return 1;
  1050. X   else
  1051. X      if (y < BASE || y > BASE + 85) return 1;
  1052. X      else if (d > 0 && d <= DaysInMonth(m, y)) return 0; else return 1;
  1053. X}
  1054. X
  1055. X/***************************************************************/
  1056. X/*                                                             */
  1057. X/*  int strncmpi(char *s1, char*s1, int n)                     */
  1058. X/*                                                             */
  1059. X/*  Compares first n chars of string ignoring case.            */
  1060. X/*                                                             */
  1061. X/***************************************************************/
  1062. X#ifdef __STDC__
  1063. Xint strncmpi(char *s1, char *s2, int n)
  1064. X#else
  1065. Xint strncmpi(s1, s2, n)
  1066. X     char *s1;
  1067. X     char *s2;
  1068. X     int n;
  1069. X#endif
  1070. X{
  1071. X   register int u1, u2;
  1072. X   while (n)
  1073. X   {
  1074. X      if (!*s1 || !*s2) return upper(*s1) - upper(*s2);
  1075. X      u1 = upper(*s1);
  1076. X      u2 = upper(*s2);
  1077. X      if (u1 != u2) return (u1 - u2);
  1078. X      n--;
  1079. X      s1++;
  1080. X      s2++;
  1081. X   }
  1082. X   return 0;
  1083. X}
  1084. X
  1085. X/***************************************************************/
  1086. X/*                                                             */
  1087. X/*  ParseToken(char **s);                                      */
  1088. X/*                                                             */
  1089. X/*  Parse the next token and adjust the character pointer.     */
  1090. X/*                                                             */
  1091. X/***************************************************************/
  1092. X#ifdef __STDC__
  1093. XToken ParseToken(char **s)
  1094. X#else
  1095. XToken ParseToken(s)
  1096. X     char **s;
  1097. X#endif
  1098. X{
  1099. X
  1100. X   Token tok;
  1101. X   char *t = TmpBuf;
  1102. X   int i, h, m;
  1103. X   int len;
  1104. X   int top, bot, mid;
  1105. X   char *colon = (char *) NULL;
  1106. X
  1107. X   *t = 0;
  1108. X   tok.str = TmpBuf;
  1109. X
  1110. X   /* Skip blank space */
  1111. X   while (isspace(**s)) (*s)++;
  1112. X
  1113. X   /* End of line ? */
  1114. X   if (**s == 0) {
  1115. X      tok.type = Eol_t;
  1116. X      tok.val = 0;
  1117. X      return tok;
  1118. X   }
  1119. X
  1120. X   /* Grab a space-delimited token */
  1121. X   while (**s != 0 && !isspace(**s)) {
  1122. X      *t++ = **s;
  1123. X      (*s)++;
  1124. X   }
  1125. X   *t = 0;
  1126. X   len = t - TmpBuf;
  1127. X
  1128. X   /* Check if it's a built-in token */
  1129. X   if (*TmpBuf >= 'A' && *TmpBuf <= 'z') {
  1130. X      top = sizeof(keywd)/sizeof(keywd[0])-1;
  1131. X      bot = 0;
  1132. X      mid = (top+bot)/2;
  1133. X      while (top >= bot && 
  1134. X              (i=strncmpi(TmpBuf, keywd[mid].str, MAX(len, (int) keywd[mid].len)))) {
  1135. X         if (i>0) bot = mid+1; else top = mid-1;
  1136. X     mid = (top+bot)/2;
  1137. X      }
  1138. X      if (top >= bot) return keywd[mid];
  1139. X   }
  1140. X
  1141. X   tok.type = Unknown_t;
  1142. X
  1143. X   /* If it's a comment, ignore the rest of the line */
  1144. X   if (*(tok.str) == '#') {
  1145. X      tok.type = Eol_t;
  1146. X      return tok;
  1147. X   }
  1148. X
  1149. X   /* Check if it's a number (optional + / - / * ahead of number */
  1150. X   t = TmpBuf;
  1151. X   i = 1;  /* multiplication factor */
  1152. X   if (isdigit(*t)) {
  1153. X      while (*++t){
  1154. X         if (*t == ':') {
  1155. X            if (colon) return tok; else colon = t;
  1156. X         } else if (!isdigit(*t)) return tok;
  1157. X      }
  1158. X   }
  1159. X   else if (*t == '+' || *t == '-' || *t == '*') {
  1160. X      /* Check if it's a "++" or a "--" */
  1161. X      if ((*t == '+' && *(t+1) == '+') || (*t == '-' && *(t+1) == '-')) {
  1162. X         i = -1;
  1163. X         t++;
  1164. X      }
  1165. X      if (!isdigit(*++t)) return tok;
  1166. X      while (*++t) if (!isdigit(*t)) return tok;
  1167. X   }
  1168. X   else return tok;
  1169. X
  1170. X   /* OK, here we have a number - either a pure number, a delta, a time,
  1171. X      back or a repeat marker */
  1172. X
  1173. X   if (colon) { /* got a time here */
  1174. X      h = atoi(TmpBuf);
  1175. X      m = atoi(colon + 1);
  1176. X      if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
  1177. X         tok.type = Time_t;
  1178. X     tok.val = 60*h+m;
  1179. X      }
  1180. X      else return tok;
  1181. X   }
  1182. X   else if (*TmpBuf == '+') {
  1183. X      tok.type = Delta_t;
  1184. X      if (i == 1) tok.val = atoi(TmpBuf + 1);
  1185. X      else        tok.val = -atoi(TmpBuf + 2);
  1186. X   }
  1187. X   else if (*TmpBuf == '-') {
  1188. X      tok.type = Back_t;
  1189. X      if (i == 1) tok.val = atoi(TmpBuf + 1);
  1190. X      else        tok.val = -atoi(TmpBuf + 2);
  1191. X   }
  1192. X   else if (*TmpBuf == '*') {
  1193. X      tok.type = Repeat_t;
  1194. X      tok.val = atoi(TmpBuf + 1);
  1195. X   }
  1196. X   else {
  1197. X      tok.val = atoi(TmpBuf);
  1198. X      if (tok.val > 0 && tok.val <= 31) tok.type = Day_t;
  1199. X      else if (tok.val >= 100) tok.type = Year_t;
  1200. X      else {
  1201. X     tok.type = Year_t;
  1202. X     tok.val += 1900;
  1203. X      }
  1204. X   }
  1205. X   return tok;
  1206. X}
  1207. X
  1208. X/***************************************************************/
  1209. X/*                                                             */
  1210. X/*  int FromJulian(int jul, int *d, int *m, int *y)            */
  1211. X/*                                                             */
  1212. X/*  Convert a date from Julian to normal form.  Returns        */
  1213. X/*  0 if conversion ok, -1 otherwise.                          */
  1214. X/*                                                             */
  1215. X/***************************************************************/
  1216. X#ifdef __STDC__
  1217. Xint FromJulian(int jul, int *d, int *m, int *y)
  1218. X#else
  1219. Xint FromJulian(jul, d, m, y)
  1220. X     int jul;
  1221. X     int *d;
  1222. X     int *m;
  1223. X     int *y;
  1224. X#endif
  1225. X{
  1226. X   int t;
  1227. X
  1228. X   if (jul < 0) return -1;
  1229. X
  1230. X   if (jul >= JulFirst && JulFirst != -1) {
  1231. X      *y = FirstYear;
  1232. X      jul -= JulFirst;
  1233. X   } else *y = BASE;
  1234. X
  1235. X   *m = 0;
  1236. X
  1237. X   t = DaysInYear(*y);
  1238. X   while (jul >= t) {
  1239. X      jul -= t;
  1240. X      (*y)++;
  1241. X      t = DaysInYear(*y);
  1242. X   }
  1243. X
  1244. X   t = DaysInMonth(*m, *y);
  1245. X   while (jul >= t) {
  1246. X      jul -= t;
  1247. X      (*m)++;
  1248. X      t = DaysInMonth(*m, *y);
  1249. X   }
  1250. X   *d = jul + 1;
  1251. X   return 0;
  1252. X}
  1253. X
  1254. X/***************************************************************/
  1255. X/*                                                             */
  1256. X/*  int Julian(d, m, y)                                        */
  1257. X/*                                                             */
  1258. X/*  Converts a date to the number of days after Jan 1 1990.    */
  1259. X/*  Returns -1 if date is before Jan 1 1990.                   */
  1260. X/*                                                             */
  1261. X/***************************************************************/
  1262. X#ifdef __STDC__
  1263. Xint Julian(int d, int m, int y)
  1264. X#else
  1265. Xint Julian(d, m, y)
  1266. X     int d;
  1267. X     int m;
  1268. X     int y;
  1269. X#endif
  1270. X{
  1271. X   int iy;
  1272. X   int jul = 0;
  1273. X
  1274. X   if (y < BASE) return -1;
  1275. X   if (JulFirst == -1 || y < FirstYear)
  1276. X      for (iy = BASE; iy < y; iy++) jul += DaysInYear(iy);
  1277. X   else {
  1278. X      jul = JulFirst;
  1279. X      for (iy = FirstYear; iy < y; iy++) jul += DaysInYear(iy);
  1280. X   }
  1281. X
  1282. X   return jul + MonthIndex[IsLeapYear(y)][m] + d - 1;
  1283. X}
  1284. X
  1285. X/***************************************************************/
  1286. X/*                                                             */
  1287. X/*  int FindTodaysDate(int *d, int *m, int *y)                 */
  1288. X/*                                                             */
  1289. X/*  Obtains today's date.  Returns Julian date or -1 for       */
  1290. X/*  failure.                                                   */
  1291. X/*                                                             */
  1292. X/***************************************************************/
  1293. X#ifdef __STDC__
  1294. Xint FindTodaysDate(int *d, int *m, int *y)
  1295. X#else
  1296. Xint FindTodaysDate(d, m, y)
  1297. X     int *d;
  1298. X     int *m;
  1299. X     int *y;
  1300. X#endif
  1301. X{
  1302. X#ifndef UNIX
  1303. X   struct dosdate_t buf;
  1304. X
  1305. X   _dos_getdate(&buf);
  1306. X
  1307. X   *d = buf.day;
  1308. X   *m = buf.month - 1;
  1309. X   *y = buf.year;
  1310. X#else
  1311. X  time_t tloc;
  1312. X  struct tm *t;
  1313. X
  1314. X   (void) time(&tloc);
  1315. X   t = localtime(&tloc);
  1316. X
  1317. X   *d = t->tm_mday;
  1318. X   *m = t->tm_mon;
  1319. X   *y = t->tm_year + 1900;
  1320. X
  1321. X#endif
  1322. X   if (CheckDate(*d, *m, *y)) return -1;
  1323. X   return Julian(*d, *m, *y);
  1324. X}
  1325. X/***************************************************************/
  1326. X/***************************************************************/
  1327. X/**                                                           **/
  1328. X/** MAIN PROGRAM ENTRY POINT                                  **/
  1329. X/**                                                           **/
  1330. X/***************************************************************/
  1331. X/***************************************************************/
  1332. X#ifdef __STDC__
  1333. Xint main(int argc, char *argv[])
  1334. X#else
  1335. Xint main(argc, argv)
  1336. X     int argc;
  1337. X     char *argv[];
  1338. X#endif
  1339. X{
  1340. X#ifdef UNIX
  1341. X#ifdef SYSV
  1342. X   pid_t pid;
  1343. X#else
  1344. X   int pid;
  1345. X#endif
  1346. X#endif
  1347. X
  1348. X   NumEmitted = 0;
  1349. X   NumRem = 0;
  1350. X   JulFirst = -1;  /* Initialize JulFirst so it's not used by Julian */
  1351. X      
  1352. X   JulianToday = FindTodaysDate(&CurDay, &CurMon, &CurYear);
  1353. X   if (JulianToday < 0) {
  1354. X      fprintf(stderr, "remind: System date is illegal - Ensure that year is at least %d.\n", BASE);
  1355. X      return 1;
  1356. X   }
  1357. X   
  1358. X   RealToday = JulianToday;
  1359. X   
  1360. X   initialize(argc, argv);
  1361. X
  1362. X   FirstYear = CurYear;
  1363. X   JulFirst = Julian(1, 0, CurYear);  /* Do expensive computation once */
  1364. X   FirstYear = CurYear;
  1365. X
  1366. X   if (Calendar) {
  1367. X      DoCalendar();
  1368. X      return 0;
  1369. X   }
  1370. X   while (1) {
  1371. X      if (ReadLine()) break;
  1372. X      ProcessLine();
  1373. X   }
  1374. X/* Get rid of any spurious OMIT contexts */
  1375. X   FreeStackedOmits();
  1376. X   if (NumEmitted == 0 && NumAtsQueued == 0 && !Purge && !Debug && !Next) 
  1377. X       printf("No reminders.\n");
  1378. X#ifdef UNIX
  1379. X   if (NumEmitted == 0 && NumAtsQueued != 0 && !Purge && !Debug)
  1380. X       printf("%d reminder%s queued for later today.\n", NumAtsQueued,
  1381. X              (NumAtsQueued == 1) ? "" : "s");
  1382. X
  1383. X   fflush(stdout); /* Flush output so we don't get 2 copies when directing */
  1384. X           /* stdout to a file. */
  1385. X
  1386. X   if (NumAtsQueued) {
  1387. X      pid = fork();
  1388. X      if (pid == -1) Eprint("Can't fork to perform ATs!\n");
  1389. X      if (pid != 0) return 0;
  1390. X      HandleQueuedAts();
  1391. X   }
  1392. X#endif
  1393. X   return 0;
  1394. X}
  1395. X/***************************************************************/
  1396. X/*                                                             */
  1397. X/* SystemTime                                                  */
  1398. X/*                                                             */
  1399. X/* Returns current system time in seconds past midnight.       */
  1400. X/*                                                             */
  1401. X/***************************************************************/
  1402. X#ifdef __STDC__
  1403. Xlong SystemTime(void)
  1404. X#else
  1405. Xlong SystemTime()
  1406. X#endif
  1407. X{
  1408. X#ifdef UNIX
  1409. X  time_t tloc;
  1410. X  struct tm *t;
  1411. X
  1412. X   (void) time(&tloc);
  1413. X   t = localtime(&tloc);
  1414. X   return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L + (long) t->tm_sec;
  1415. X
  1416. X#else
  1417. X   struct dostime_t tloc;
  1418. X   _dos_gettime(&tloc);
  1419. X   return (long) tloc.hour * 3600L + (long) tloc.minute * 60L + (long) tloc.second;
  1420. X#endif
  1421. X}
  1422. SHAR_EOF
  1423. $TOUCH -am 0218130591 main.c &&
  1424. chmod 0600 main.c ||
  1425. echo "restore of main.c failed"
  1426. set `wc -c main.c`;Wc_c=$1
  1427. if test "$Wc_c" != "20411"; then
  1428.     echo original size 20411, current size $Wc_c
  1429. fi
  1430. fi
  1431. # ============= nextdate.c ==============
  1432. if test X"$1" != X"-c" -a -f 'nextdate.c'; then
  1433.     echo "File already exists: skipping 'nextdate.c'"
  1434. else
  1435. echo "x - extracting nextdate.c (Text)"
  1436. sed 's/^X//' << 'SHAR_EOF' > nextdate.c &&
  1437. X#include "defines.h"
  1438. X#include "globals.h"
  1439. X#include "protos.h"
  1440. X
  1441. X/***************************************************************/
  1442. X/*                                                             */
  1443. X/*  int TryNextDate(int *retday, int *retmon, int *retyr,      */
  1444. X/*                  int startday, int startmon, int startyr,   */
  1445. X/*                  int conday, int conmon, int conyr,         */
  1446. X/*                  int wkday, int cons, int inc)              */
  1447. X/*                                                             */
  1448. X/*  This function tries to find the next date satisfying       */
  1449. X/*  the given constraints.  Returns                            */
  1450. X/*  0 for success.  Returns non-zero if a constraint would     */
  1451. X/*  be violated.  Note that if DAY and WEEKDAY are both        */
  1452. X/*  constrained, then MONTH and YEAR may be violated.          */
  1453. X/*  Otherwise, all constraints are honoured.                   */
  1454. X/*  The starting point for the search is thisday, etc.         */
  1455. X/*                                                             */
  1456. X/*  If inc is non-zero, then the search begins from the day    */
  1457. X/*  after the specified date.  Note that this function assumes */
  1458. X/*  that the given date is valid.                              */
  1459. X/*                                                             */
  1460. X/***************************************************************/
  1461. X#ifdef __STDC__
  1462. Xint TryNextDate(int *retday, int *retmon, int *retyr,
  1463. X        int d, int m, int y,
  1464. X        int conday, int conmon, int conyr,
  1465. X        int wkday, int cons, int inc)
  1466. X#else
  1467. Xint TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
  1468. X                wkday, cons, inc)
  1469. X     int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
  1470. X     
  1471. X#endif
  1472. X
  1473. X{
  1474. X   int jul, jul2;
  1475. X   int dd = d, mm = m, yy = y;
  1476. X
  1477. X   if (inc)
  1478. X   {
  1479. X      d++;
  1480. X      if (d > DaysInMonth(m, y)) {
  1481. X     m++; d = 1;
  1482. X     if (m > 11) {
  1483. X        y++; m = 0;
  1484. X     }
  1485. X      }
  1486. X   }
  1487. X
  1488. X
  1489. X   switch (cons & 15) {
  1490. X
  1491. X      case 0:  /* No constraints - just use the start date */
  1492. X     *retday = d;
  1493. X     *retmon = m;
  1494. X     *retyr  = y;
  1495. X     return 0;
  1496. X
  1497. X      case 1: /* Day constrained to be d */
  1498. X     *retday = conday;
  1499. X     if (d > conday) {
  1500. X        m++;
  1501. X        if (m > 11) {y++; m=0;}
  1502. X     }
  1503. X     while (conday > DaysInMonth(m, y)) {
  1504. X        m++;
  1505. X        if (m > 11) {y++; m=0;}
  1506. X     }
  1507. X     *retmon = m;
  1508. X     *retyr = y;
  1509. X     return 0;
  1510. X
  1511. X      case 2: /* Month constrained to be m */
  1512. X     *retmon = conmon;
  1513. X     if (m > conmon) {y++; d = 1;}
  1514. X     else if (m < conmon) d = 1;
  1515. X     *retday = d;
  1516. X     *retyr = y;
  1517. X     return 0;
  1518. X
  1519. X      case 3: /* Month and day constrained */
  1520. X     *retmon = conmon;
  1521. X     *retday = conday;
  1522. X     if (m > conmon || (m == conmon && d > conday)) y++;
  1523. X     while (conday > DaysInMonth(conmon, y)) y++;
  1524. X     *retyr = y;
  1525. X     return 0;
  1526. X
  1527. X      case 4: /* Year alone constrained */
  1528. X     if (y > conyr) return 1;
  1529. X     *retyr = conyr;
  1530. X     if (y < conyr) {
  1531. X        *retmon = 0;
  1532. X        *retday = 1;
  1533. X     }
  1534. X     else {
  1535. X        *retmon = m;
  1536. X        *retday = d;
  1537. X     }
  1538. X     return 0;
  1539. X
  1540. X      case 5: /* Year and day constrained */
  1541. X     if (y > conyr) return 1;
  1542. X     *retyr = conyr;
  1543. X     *retday = conday;
  1544. X     if (y < conyr) {
  1545. X        *retmon = 0;
  1546. X        return 0;
  1547. X     }
  1548. X     if (d > conday) {
  1549. X       m++;
  1550. X       if (m > 11) return 1;
  1551. X     }
  1552. X     while (conday > DaysInMonth(m, y)) {
  1553. X        m++;
  1554. X        if (m > 11) return 1;
  1555. X     }
  1556. X     *retmon = m;
  1557. X     return 0;
  1558. X
  1559. X      case 6: /* Year and month constrained */
  1560. X     if (y > conyr || (y == conyr && m > conmon)) return 1;
  1561. X     *retyr = conyr;
  1562. X     *retmon = conmon;
  1563. X     if (y < conyr || (y == conyr && m < conmon)) {
  1564. X        *retday = 1;
  1565. X        return 0;
  1566. X     }
  1567. X     *retday = d;
  1568. X     return 0;
  1569. X
  1570. X      case 7: /* Year, month and day constrained */
  1571. X     *retday = conday;
  1572. X     *retmon = conmon;
  1573. X     *retyr = conyr;
  1574. X     if (y > conyr || (y == conyr && m > conmon) ||
  1575. X         (y == conyr && m == conmon && d > conday)) return 1;
  1576. X     return 0;
  1577. X
  1578. X      case 8: /* Only the weekday constrained.  Let's go to Julian mode */
  1579. X     jul = Julian(d, m, y);
  1580. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1581. X     FromJulian(jul, retday, retmon, retyr);
  1582. X     return 0;
  1583. X
  1584. X      case 9: /* GASP! day and weekday constrained .. bleah! */
  1585. X     /* First, try last month. */
  1586. X     jul2 = Julian(d, m, y);
  1587. X     if (m != 0 || y != BASE)
  1588. X     {
  1589. X        mm--;
  1590. X        if (mm < 0) {yy--; mm = 11;}
  1591. X
  1592. X        /* If there are fewer days in month than required, it
  1593. X           can't possibly match.  */
  1594. X        if (conday <= DaysInMonth(mm, yy)) {
  1595. X           jul = Julian(conday, mm, yy);
  1596. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  1597. X           if (jul >= jul2) { /* SUCCESS! */
  1598. X          FromJulian(jul, retday, retmon, retyr);
  1599. X          return 0;
  1600. X           }
  1601. X        }
  1602. X     }
  1603. X     /* Didn't work - try this month */
  1604. X     if (conday <= DaysInMonth(m, y)) {
  1605. X        jul = Julian(conday, m, y);
  1606. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1607. X        if (jul >= jul2) { /* SUCCESS! */
  1608. X           FromJulian(jul, retday, retmon, retyr);
  1609. X           return 0;
  1610. X        }
  1611. X     }
  1612. X     /* Argh!  Try next available month */
  1613. X     mm = m;
  1614. X     yy = y;
  1615. X     do {
  1616. X        mm++;
  1617. X        if (mm > 11) {mm = 0; yy++;}
  1618. X     } while (conday > DaysInMonth(mm, yy));
  1619. X     jul = Julian(conday, mm, yy);
  1620. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1621. X     FromJulian(jul, retday, retmon, retyr);
  1622. X     return 0;
  1623. X
  1624. X      case 10: /* Month and Weekday constrained */
  1625. X     if (m < conmon) {
  1626. X        jul = Julian(1, conmon, y);
  1627. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1628. X        FromJulian(jul, retday, retmon, retyr);
  1629. X        return 0;
  1630. X     } else if (m == conmon) {
  1631. X        jul = Julian(d, conmon, y);
  1632. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1633. X        FromJulian(jul, retday, retmon, retyr);
  1634. X        if (*retmon != conmon) {
  1635. X           jul = Julian(1, conmon, y+1);
  1636. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  1637. X           FromJulian(jul, retday, retmon, retyr);
  1638. X        }
  1639. X        return 0;
  1640. X     } else { /* m > conmon */
  1641. X        jul = Julian(1, conmon, y+1);
  1642. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1643. X        FromJulian(jul, retday, retmon, retyr);
  1644. X        return 0;
  1645. X     }
  1646. X
  1647. X      case 11: /* Day, Month and Weekday constrained */
  1648. X     jul2 = Julian(d, m, y);
  1649. X
  1650. X     /* Blip up to next valid year */
  1651. X     while (conday > DaysInMonth(conmon, y)) y++;
  1652. X
  1653. X     /* Try this year */
  1654. X     jul = Julian(conday, conmon, y);
  1655. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1656. X     if (jul >= jul2) {
  1657. X        FromJulian(jul, retday, retmon, retyr);
  1658. X        return 0;
  1659. X     }
  1660. X
  1661. X     /* Must be next year */
  1662. X     jul = Julian(conday, conmon, y+1);
  1663. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1664. X     FromJulian(jul, retday, retmon, retyr);
  1665. X     return 0;
  1666. X
  1667. X      case 12: /* Weekday and year specified */
  1668. X     if (y > conyr) return 1;
  1669. X     if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
  1670. X     jul = Julian(dd, mm, conyr);
  1671. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1672. X     FromJulian(jul, retday, retmon, retyr);
  1673. X     if (*retyr == conyr) return 0; else return 1;
  1674. X
  1675. X      case 13: /* Weekday, year and day specified */
  1676. X     if (y > conyr+1 || (y > conyr && m>0)) return 1;
  1677. X     jul2 = Julian(d, m, y);
  1678. X     if (y > conyr ) {
  1679. X        jul = Julian(conday, 11, conyr);
  1680. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1681. X        if (jul >= jul2) {
  1682. X           FromJulian(jul, retday, retmon, retyr);
  1683. X           return 0;
  1684. X        }
  1685. X     } else if (y < conyr) {
  1686. X        jul = Julian(conday, 0, conyr);
  1687. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1688. X        FromJulian(jul, retday, retmon, retyr);
  1689. X        return 0;
  1690. X     }
  1691. X     else {
  1692. X        /* Try last month */
  1693. X        if (m > 0) {
  1694. X           mm = m - 1;
  1695. X           while (conday > DaysInMonth(mm, y)) mm--;
  1696. X           jul = Julian(conday, mm, y);
  1697. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  1698. X           if (jul >= jul2) {
  1699. X          FromJulian(jul, retday, retmon, retyr);
  1700. X          return 0;
  1701. X           }
  1702. X        }
  1703. X        /* Try this month */
  1704. X        if (conday <= DaysInMonth(m,y)) {
  1705. X           jul = Julian(conday, m, y);
  1706. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  1707. X           if (jul >= jul2) {
  1708. X          FromJulian(jul, retday, retmon, retyr);
  1709. X          return 0;
  1710. X           }
  1711. X        }
  1712. X        /* Try next month */
  1713. X        if (m == 11) return 1;
  1714. X        m++;
  1715. X        while (conday > DaysInMonth(m, y)) m++;
  1716. X        jul = Julian(conday, m, y);
  1717. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1718. X        FromJulian(jul, retday, retmon, retyr);
  1719. X        return 0;
  1720. X     }
  1721. X
  1722. X      case 14:  /* Weekday, Month and Year specified */
  1723. X     if (y > conyr || (y == conyr && m > conmon)) return 1;
  1724. X     if (conyr > y || (conyr == y && conmon > m)) {
  1725. X        jul = Julian(1, conmon, conyr);
  1726. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1727. X        FromJulian(jul, retday, retmon, retyr);
  1728. X        if (*retmon == conmon) return 0; else return 1;
  1729. X     } else {
  1730. X        jul = Julian(d, m, y);
  1731. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  1732. X        FromJulian(jul, retday, retmon, retyr);
  1733. X        if (*retmon == conmon) return 0; else return 1;
  1734. X
  1735. X     }
  1736. X
  1737. X      case 15: /* Weekday, day, month and year specified */
  1738. X     jul2 = Julian(d, m, y);
  1739. X     jul = Julian(conday, conmon, conyr);
  1740. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  1741. X     FromJulian(jul, retday, retmon, retyr);
  1742. X     if (jul < jul2) return 1;
  1743. X     return 0;
  1744. X   }
  1745. X}
  1746. SHAR_EOF
  1747. $TOUCH -am 0218130591 nextdate.c &&
  1748. chmod 0600 nextdate.c ||
  1749. echo "restore of nextdate.c failed"
  1750. set `wc -c nextdate.c`;Wc_c=$1
  1751. if test "$Wc_c" != "8719"; then
  1752.     echo original size 8719, current size $Wc_c
  1753. fi
  1754. fi
  1755. echo "End of part 2, continue with part 3"
  1756. exit 0
  1757.