home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2211 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  34.5 KB

  1. From: dfs@doe.carleton.ca (David F. Skoll)
  2. Newsgroups: alt.sources
  3. Subject: REMIND 2.2 Patch 05
  4. Message-ID: <dfs.660260100@data>
  5. Date: 3 Dec 90 21:35:00 GMT
  6.  
  7. This is the official Patch 05 for Remind version 2.2.  This patch
  8. cleans up the code and man page, fixes some bugs, and adds new keywords
  9. to the program.
  10.  
  11. The BEFORE, SKIP and AFTER keywords allow you to specify how to handle
  12. reminders which fall on holidays.  By default, these reminders are simply
  13. triggered.  Now, however, you can specify that they should be skipped,
  14. moved ahead of the holiday, or moved behind the holiday.
  15.  
  16. NOTE: The definition of the 'tok' type has changed; you should do a
  17. FULL REBUILD of remind after applying this patch!  Here are the steps:
  18.  
  19. 1)    Extract the file patch.05 from this shar.
  20. 2)    Make sure you've already applied patches 1 through 4
  21. 3)    Type patch < patch.05
  22. 4)    Edit the Makefile if necessary
  23. 5)     Type make clean
  24. 6)    Type make.
  25.  
  26. See the file WHATSNEW.22 or the man page after applying the patch for more
  27. details on the added features.
  28.  
  29. --
  30. David F. Skoll
  31.  
  32. #!/bin/sh
  33. # This is Remind-2.2-patch.05, a shell archive (shar 3.32)
  34. # made 12/03/1990 21:32 UTC by dfs@data
  35. # Source directory /enterprise/transporter/dfs/work/.rem/remind-2.2
  36. #
  37. # existing files will NOT be overwritten
  38. #
  39. # This shar contains:
  40. # length  mode       name
  41. # ------ ---------- ------------------------------------------
  42. #  32338 -rw------- patch.05
  43. #
  44. if touch 2>&1 | fgrep 'amc' > /dev/null
  45.  then TOUCH=touch
  46.  else TOUCH=true
  47. fi
  48. # ============= patch.05 ==============
  49. if test X"$1" != X"-c" -a -f 'patch.05'; then
  50.     echo "File already exists: skipping 'patch.05'"
  51. else
  52. echo "x - extracting patch.05 (Text)"
  53. sed 's/^X//' << 'SHAR_EOF' > patch.05 &&
  54. X*** ../work/Makefile    Thu Nov 29 09:10:23 1990
  55. X--- ./Makefile    Mon Dec  3 12:50:21 1990
  56. X***************
  57. X*** 21,27 ****
  58. X  #--------------- SHOULDN'T CHANGE STUFF BELOW HERE ---------------
  59. X  
  60. X  all: dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  61. X!     $(LINK.c) -o remind dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  62. X  
  63. X  dorem.o: dorem.c
  64. X  
  65. X--- 21,27 ----
  66. X  #--------------- SHOULDN'T CHANGE STUFF BELOW HERE ---------------
  67. X  
  68. X  all: dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  69. X!     $(CC) -o remind dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  70. X  
  71. X  dorem.o: dorem.c
  72. X  
  73. X*** ../work/WHATSNEW.22    Fri Nov 16 13:22:35 1990
  74. X--- ./WHATSNEW.22    Mon Dec  3 15:50:20 1990
  75. X***************
  76. X*** 10,12 ****
  77. X--- 10,19 ----
  78. X  
  79. X  Version 2.2 - Added the AT keyword, the timed reminders daemon, and the
  80. X  calendar facility.
  81. X+ 
  82. X+ Version 2.2 - Patch 3  - Added the MSG or RUN tokens in an OMIT command; also
  83. X+ allowed RUN-type reminders to be explicitly included in the calendar by
  84. X+ using the %" escape sequence.
  85. X+ 
  86. X+ Version 2.2 - Patch 5 - Added the BEFORE, AFTER and SKIP tokens to make the
  87. X+ handling of holidays more sensible.  Also corrected a few more bugs.
  88. X*** ../work/cache.c    Thu Nov 29 09:10:24 1990
  89. X--- ./cache.c    Mon Dec  3 12:25:04 1990
  90. X***************
  91. X*** 12,20 ****
  92. X  #ifndef NO_MALLOC_H
  93. X  #include <malloc.h>
  94. X  #endif
  95. X- #ifndef UNIX
  96. X  #include <string.h>
  97. X- #endif
  98. X  #include "defines.h"
  99. X  #include "globals.h"
  100. X  #include "protos.h"
  101. X--- 12,18 ----
  102. X*** ../work/calendar.c    Thu Nov 29 09:11:53 1990
  103. X--- ./calendar.c    Mon Dec  3 12:25:15 1990
  104. X***************
  105. X*** 13,20 ****
  106. X  #include <malloc.h>
  107. X  #endif
  108. X  #include <ctype.h>
  109. X- #ifndef UNIX
  110. X  #include <string.h>
  111. X  #include <stdlib.h>
  112. X  #endif
  113. X  #include "defines.h"
  114. X--- 13,20 ----
  115. X  #include <malloc.h>
  116. X  #endif
  117. X  #include <ctype.h>
  118. X  #include <string.h>
  119. X+ #ifndef UNIX
  120. X  #include <stdlib.h>
  121. X  #endif
  122. X  #include "defines.h"
  123. X*** ../work/defines.h    Thu Nov 29 09:10:26 1990
  124. X--- ./defines.h    Mon Dec  3 11:09:55 1990
  125. X***************
  126. X*** 32,38 ****
  127. X  
  128. X  enum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
  129. X             Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t, 
  130. X!                Repeat_t, At_t, Time_t, Eol_t };
  131. X                 
  132. X  /* Define the Token structure */
  133. X  
  134. X--- 32,38 ----
  135. X  
  136. X  enum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
  137. X             Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t, 
  138. X!                Repeat_t, At_t, Time_t, Skip_t, Eol_t };
  139. X                 
  140. X  /* Define the Token structure */
  141. X  
  142. X***************
  143. X*** 40,45 ****
  144. X--- 40,46 ----
  145. X     char *str;
  146. X     enum Token_t type;
  147. X     int val;
  148. X+    char len;    /* Minimum length to match */
  149. X  } Token;
  150. X  
  151. X  #ifdef UNIX
  152. X*** ../work/dorem.c    Thu Nov 29 09:10:27 1990
  153. X--- ./dorem.c    Mon Dec  3 15:56:27 1990
  154. X***************
  155. X*** 1,8 ****
  156. X  #include <stdio.h>
  157. X  #ifndef UNIX
  158. X  #include <stdlib.h>
  159. X- #include <string.h>
  160. X  #endif
  161. X  #include <ctype.h>
  162. X  #include "defines.h"
  163. X  #include "globals.h"
  164. X--- 1,8 ----
  165. X  #include <stdio.h>
  166. X  #ifndef UNIX
  167. X  #include <stdlib.h>
  168. X  #endif
  169. X+ #include <string.h>
  170. X  #include <ctype.h>
  171. X  #include "defines.h"
  172. X  #include "globals.h"
  173. X***************
  174. X*** 25,31 ****
  175. X       
  176. X  #endif
  177. X  {
  178. X!    int d, m, y, wd, cons, delta, back, omit, done, jul, once, repeat;
  179. X     int tim, tdelta, trep;
  180. X     int d2, m2, y2;
  181. X     Token tok;
  182. X--- 25,31 ----
  183. X       
  184. X  #endif
  185. X  {
  186. X!    int d, m, y, wd, cons, delta, back, omit, done, jul, once, repeat, skip;
  187. X     int tim, tdelta, trep;
  188. X     int d2, m2, y2;
  189. X     Token tok;
  190. X***************
  191. X*** 32,38 ****
  192. X     int trigger;
  193. X  
  194. X     d = m = y = back = delta = tim = tdelta = trep = -1;
  195. X!    repeat = cons = wd = omit = once = 0;
  196. X  
  197. X  
  198. X     done = 0;
  199. X--- 32,38 ----
  200. X     int trigger;
  201. X  
  202. X     d = m = y = back = delta = tim = tdelta = trep = -1;
  203. X!    repeat = cons = wd = omit = once = skip = 0;
  204. X  
  205. X  
  206. X     done = 0;
  207. X***************
  208. X*** 48,53 ****
  209. X--- 48,61 ----
  210. X       case Run_t:
  211. X       case Msg_t: done = 1; break;
  212. X  
  213. X+      case Skip_t:
  214. X+         if (skip) {
  215. X+            Eprint("Can only have one of BEFORE, AFTER or SKIP.\n");
  216. X+            return 0;
  217. X+             }
  218. X+         skip = tok.val;
  219. X+         break;
  220. X+ 
  221. X       case Unknown_t:
  222. X          Eprint("Unknown token %s in reminder.\n", tok.str);
  223. X          return 0;
  224. X***************
  225. X*** 205,214 ****
  226. X--- 213,228 ----
  227. X     }
  228. X  
  229. X  
  230. X+    /* Do some sanity checking on the reminder */
  231. X     if (repeat && (d == -1 || m == -1 || y == -1)) {
  232. X        Eprint("Can't use repeat counter unless you fully specify the date.\n");
  233. X        return 0;
  234. X     }
  235. X+ 
  236. X+    if (skip && (wd & omit)) {
  237. X+       Eprint("Conflict between weekday list and local OMIT\n");
  238. X+       return 0;
  239. X+    }
  240. X     
  241. X     if (d != -1 && m != -1 && CheckDate(d, m, y)) {
  242. X        Eprint("Illegal date specification.\n");
  243. X***************
  244. X*** 240,246 ****
  245. X     if (back == -1) back = 0;
  246. X     if (delta == -1) delta = 0;
  247. X  
  248. X!    jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit);
  249. X     if (Calendar) {
  250. X        if (jul == JulianToday) {
  251. X           while (isspace(**s)) (*s)++;
  252. X--- 254,260 ----
  253. X     if (back == -1) back = 0;
  254. X     if (delta == -1) delta = 0;
  255. X  
  256. X!    jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip);
  257. X     if (Calendar) {
  258. X        if (jul == JulianToday) {
  259. X           while (isspace(**s)) (*s)++;
  260. X***************
  261. X*** 253,264 ****
  262. X     if (jul == -1) {
  263. X        if (Debug) Eprint("Reminder has expired.\n");
  264. X        return -1;
  265. X!    }
  266. X     FromJulian(jul, &d2, &m2, &y2);
  267. X  
  268. X     /* Figure out if the reminder should be triggered */
  269. X     
  270. X!    trigger = MoveBack(jul, delta, d2, m2, y2, omit);
  271. X  
  272. X     if(Debug) {
  273. X        Eprint("%sTrigger date: %s, %d %s, %d.\n", 
  274. X--- 267,279 ----
  275. X     if (jul == -1) {
  276. X        if (Debug) Eprint("Reminder has expired.\n");
  277. X        return -1;
  278. X!    } else if (jul == -2) return 0;
  279. X! 
  280. X     FromJulian(jul, &d2, &m2, &y2);
  281. X  
  282. X     /* Figure out if the reminder should be triggered */
  283. X     
  284. X!    trigger = MoveBack(jul, delta, omit);
  285. X  
  286. X     if(Debug) {
  287. X        Eprint("%sTrigger date: %s, %d %s, %d.\n", 
  288. X***************
  289. X*** 304,347 ****
  290. X  /*                                                             */
  291. X  /* Gets the trigger date for a reminder, returns the julian    */
  292. X  /* date, or -1 if the reminder has expired.                    */
  293. X  /*                                                             */
  294. X  /***************************************************************/
  295. X  #ifndef UNIX
  296. X! int GetTriggerDate(int d, int m, int y, int wd, int cons, int back, int repeat, int omit)
  297. X  #else
  298. X! int GetTriggerDate(d, m, y, wd, cons, back, repeat, omit)
  299. X! int d, m, y, wd, cons, back, repeat, omit;
  300. X  #endif
  301. X  {
  302. X     int i, d2, m2, y2, jul;
  303. X  
  304. X!    i = TryNextDate(&d2, &m2, &y2, CurDay, CurMon, CurYear,
  305. X!            d, m, y, wd, cons, 0);
  306. X  
  307. X!    if (i && !repeat) return -1;
  308. X  
  309. X     jul = Julian(d2, m2, y2);
  310. X!    if (repeat) {
  311. X!       if (back) jul = MoveBack(jul, back, d2, m2, y2, omit);
  312. X  
  313. X!       if (jul < JulianToday) {
  314. X!          jul += ((JulianToday - jul) / repeat) * repeat;
  315. X!          if (jul < JulianToday) jul += repeat;
  316. X!       }
  317. X!       return jul;
  318. X  
  319. X!    } else {
  320. X!       if (back) {
  321. X!          jul = MoveBack(jul, back, d2, m2, y2, omit);
  322. X!          while (jul < JulianToday) {
  323. X!             i = TryNextDate(&d2, &m2, &y2, d2, m2, y2,
  324. X!              d, m, y, wd, cons, 1);
  325. X!         if (i) return -1;
  326. X!             jul = Julian(d2, m2, y2);
  327. X!         jul = MoveBack(jul, back, d2, m2, y2, omit);
  328. X           }
  329. X-          
  330. X        }
  331. X!    return jul;
  332. X     }
  333. X  }
  334. X--- 319,379 ----
  335. X  /*                                                             */
  336. X  /* Gets the trigger date for a reminder, returns the julian    */
  337. X  /* date, or -1 if the reminder has expired.                    */
  338. X+ /* Returns -2 if an error occurs.                              */
  339. X  /*                                                             */
  340. X  /***************************************************************/
  341. X  #ifndef UNIX
  342. X! int GetTriggerDate(int d, int m, int y, int wd, int cons, int back, int repeat, int omit, int skip)
  343. X  #else
  344. X! int GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip)
  345. X! int d, m, y, wd, cons, back, repeat, omit, skip;
  346. X  #endif
  347. X+ #define MAXATTEMPTS 25  /* Maximum number of attempts before giving up */
  348. X+ 
  349. X  {
  350. X     int i, d2, m2, y2, jul;
  351. X+    int d1, m1, y1, julstart;
  352. X+    int nattempts = 0;
  353. X  
  354. X!    julstart = JulianToday;
  355. X  
  356. X!    /* If we have a skip factor of 3 (AFTER), then we must back up to
  357. X!       the beginning of the block of omitted days. */
  358. X!    if (skip == 3) while(julstart>=1 && IsOmitted(julstart-1, omit)) julstart--;
  359. X  
  360. X+    FromJulian(julstart, &d1, &m1, &y1);
  361. X+    
  362. X+    /* Make a first stab at the date */
  363. X+    i = TryNextDate(&d2, &m2, &y2, d1, m1, y1, d, m, y, wd, cons, 0);
  364. X     jul = Julian(d2, m2, y2);
  365. X!    
  366. X!    if (!repeat && !back && !skip) {
  367. X!       if (i) return -1; else return jul;
  368. X!    }
  369. X  
  370. X!    if (i && !repeat) return -1;
  371. X  
  372. X!    while (nattempts++ < MAXATTEMPTS) {
  373. X!       if (back) jul = MoveBack(jul, back, omit);
  374. X!       if (repeat) {
  375. X!          if (jul < julstart) {
  376. X!         jul += ((julstart - jul) / repeat) * repeat;
  377. X!         if (jul < julstart) jul += repeat;
  378. X           }
  379. X        }
  380. X!       if (skip == 2)      while (IsOmitted(jul, omit)) jul--;
  381. X!       else if (skip == 3) while (IsOmitted(jul, omit)) jul++;
  382. X!       if ((skip == 1 && IsOmitted(jul, omit)) || jul < JulianToday) {
  383. X!          if (!repeat) {
  384. X!             i = TryNextDate(&d2, &m2, &y2, d2, m2, y2, d, m, y, wd, cons, 1);
  385. X!             if (i) return -1;
  386. X!             jul = Julian(d2, m2, y2);
  387. X!          } else {
  388. X!             jul += repeat;
  389. X!         back = 0;  /* We've already handled the back! */
  390. X!          }
  391. X!       } else return jul;
  392. X     }
  393. X+    Eprint("Couldn't compute a trigger date - check that date is sensible.\n");
  394. X+    return -2;
  395. X  }
  396. X*** ../work/dosubst.c    Fri Nov 16 09:57:14 1990
  397. X--- ./dosubst.c    Mon Dec  3 12:26:31 1990
  398. X***************
  399. X*** 1,8 ****
  400. X  #include <ctype.h>
  401. X  #include <stdio.h>
  402. X- #ifndef UNIX
  403. X  #include <string.h>
  404. X- #endif
  405. X  #include "defines.h"
  406. X  #include "globals.h"
  407. X  #include "protos.h"
  408. X--- 1,6 ----
  409. X*** ../work/files.c    Thu Nov 29 09:10:28 1990
  410. X--- ./files.c    Mon Dec  3 14:16:03 1990
  411. X***************
  412. X*** 203,209 ****
  413. X     if (!SP) {
  414. X        if (!Debug && !Purge && (JulianToday == RealToday)) {
  415. X           if (_dos_open(FileName, O_RDONLY, &handle)) {
  416. X!             fprintf(stderr, "Could not reset date of %s", FileName);
  417. X              return 1;
  418. X           }
  419. X       _dos_gettime(&t);
  420. X--- 203,209 ----
  421. X     if (!SP) {
  422. X        if (!Debug && !Purge && (JulianToday == RealToday)) {
  423. X           if (_dos_open(FileName, O_RDONLY, &handle)) {
  424. X!             fprintf(stderr, "Could not reset date of %s\n", FileName);
  425. X              return 1;
  426. X           }
  427. X       _dos_gettime(&t);
  428. X***************
  429. X*** 225,231 ****
  430. X     SP--;
  431. X     fp = fopen(stack[SP].name, "r");
  432. X     if (fp == NULL) {
  433. X!       Eprint("Argh! Can't return to %s from INCLUDE file %s", stack[SP].name, FileName);
  434. X        exit(1);
  435. X     }
  436. X  #ifndef UNIX
  437. X--- 225,231 ----
  438. X     SP--;
  439. X     fp = fopen(stack[SP].name, "r");
  440. X     if (fp == NULL) {
  441. X!       Eprint("Argh! Can't return to %s from INCLUDE file %s\n", stack[SP].name, FileName);
  442. X        exit(1);
  443. X     }
  444. X  #ifndef UNIX
  445. X***************
  446. X*** 233,239 ****
  447. X  #else
  448. X     if (fseek(fp, stack[SP].offset, 0)) {
  449. X  #endif
  450. X!       Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s", stack[SP].name, FileName);
  451. X        exit(1);
  452. X     }
  453. X     
  454. X--- 233,239 ----
  455. X  #else
  456. X     if (fseek(fp, stack[SP].offset, 0)) {
  457. X  #endif
  458. X!       Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s\n", stack[SP].name, FileName);
  459. X        exit(1);
  460. X     }
  461. X     
  462. X***************
  463. X*** 263,269 ****
  464. X     while (!done) {
  465. X        CurLine++;
  466. X        if (fgets(Line, 512, fp) == NULL) {
  467. X!          if (ferror(fp)) Eprint("Error reading %s", FileName);
  468. X       if (PopFile()) return 1;
  469. X        } else {
  470. X           len = strlen(Line);
  471. X--- 263,269 ----
  472. X     while (!done) {
  473. X        CurLine++;
  474. X        if (fgets(Line, 512, fp) == NULL) {
  475. X!          if (ferror(fp)) Eprint("Error reading %s\n", FileName);
  476. X       if (PopFile()) return 1;
  477. X        } else {
  478. X           len = strlen(Line);
  479. X*** ../work/init.c    Thu Nov 29 09:12:03 1990
  480. X--- ./init.c    Fri Nov 30 14:07:02 1990
  481. X***************
  482. X*** 7,13 ****
  483. X  #include "globals.h"
  484. X  #include "protos.h"
  485. X  
  486. X! #define PATCHLEVEL 4
  487. X  
  488. X  static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
  489. X  static char DPCMsg[] = "Calendar overrides Debug and Purge options.\n";
  490. X--- 7,13 ----
  491. X  #include "globals.h"
  492. X  #include "protos.h"
  493. X  
  494. X! #define PATCHLEVEL 5
  495. X  
  496. X  static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
  497. X  static char DPCMsg[] = "Calendar overrides Debug and Purge options.\n";
  498. X*** ../work/main.c    Thu Nov 29 09:10:30 1990
  499. X--- ./main.c    Mon Dec  3 15:35:57 1990
  500. X***************
  501. X*** 24,29 ****
  502. X--- 24,30 ----
  503. X  #include <sys/time.h>
  504. X  #endif
  505. X  #endif
  506. X+ 
  507. X  #include "defines.h"
  508. X  #include "protos.h"
  509. X  
  510. X***************
  511. X*** 42,74 ****
  512. X  /* List of recognized tokens */
  513. X  
  514. X  Token keywd[] = {
  515. X!    { "BANNER",    Banner_t, 0 },
  516. X!    { "OMIT",      Omit_t,   0 },
  517. X!    { "REM",       Rem_t,    0 },
  518. X!    { "January",   Month_t,  0 },
  519. X!    { "February",  Month_t,  1 },
  520. X!    { "March",     Month_t,  2 },
  521. X!    { "April",     Month_t,  3 },
  522. X!    { "May",       Month_t,  4 },
  523. X!    { "June",      Month_t,  5 },
  524. X!    { "July",      Month_t,  6 },
  525. X!    { "August",    Month_t,  7 },
  526. X!    { "September", Month_t,  8 },
  527. X!    { "October",   Month_t,  9 },
  528. X!    { "November",  Month_t,  10 },
  529. X!    { "December",  Month_t,  11 },
  530. X!    { "Monday",    WkDay_t,  0  },
  531. X!    { "Tuesday",   WkDay_t,  1  },
  532. X!    { "Wednesday", WkDay_t,  2  },
  533. X!    { "Thursday",  WkDay_t,  3  },
  534. X!    { "Friday",    WkDay_t,  4  },
  535. X!    { "Saturday",  WkDay_t,  5  },
  536. X!    { "Sunday",    WkDay_t,  6  },
  537. X!    { "MSG",       Msg_t,    0 },
  538. X!    { "RUN",       Run_t,    0 },
  539. X!    { "ONCE",      Once_t,   0 },
  540. X!    { "INCLUDE",   Include_t, 0},
  541. X!    { "AT",        At_t,      0}
  542. X  };
  543. X  
  544. X  /* List of days in month - Feb MUST be 29 for CheckDate to work. */
  545. X--- 43,78 ----
  546. X  /* List of recognized tokens */
  547. X  
  548. X  Token keywd[] = {
  549. X!    { "BANNER",    Banner_t, 0, 3 },
  550. X!    { "OMIT",      Omit_t,   0, 3 },
  551. X!    { "REM",       Rem_t,    0, 3 },
  552. X!    { "January",   Month_t,  0, 3 },
  553. X!    { "February",  Month_t,  1, 3 },
  554. X!    { "March",     Month_t,  2, 3 },
  555. X!    { "April",     Month_t,  3, 3 },
  556. X!    { "May",       Month_t,  4, 3 },
  557. X!    { "June",      Month_t,  5, 3 },
  558. X!    { "July",      Month_t,  6, 3 },
  559. X!    { "August",    Month_t,  7, 3 },
  560. X!    { "September", Month_t,  8, 3 },
  561. X!    { "October",   Month_t,  9, 3 },
  562. X!    { "November",  Month_t,  10, 3 },
  563. X!    { "December",  Month_t,  11, 3 },
  564. X!    { "Monday",    WkDay_t,  0, 3 },
  565. X!    { "Tuesday",   WkDay_t,  1, 3 },
  566. X!    { "Wednesday", WkDay_t,  2, 3 },
  567. X!    { "Thursday",  WkDay_t,  3, 3 },
  568. X!    { "Friday",    WkDay_t,  4, 3 },
  569. X!    { "Saturday",  WkDay_t,  5, 3 },
  570. X!    { "Sunday",    WkDay_t,  6, 3 },
  571. X!    { "MSG",       Msg_t,    0, 3 },
  572. X!    { "RUN",       Run_t,    0, 3 },
  573. X!    { "ONCE",      Once_t,   0, 3 },
  574. X!    { "INCLUDE",   Include_t, 0, 3 },
  575. X!    { "AT",        At_t,      0, 2 },
  576. X!    { "SKIP",      Skip_t,    1, 3 },
  577. X!    { "BEFORE",    Skip_t,    2, 3 },
  578. X!    { "AFTER",     Skip_t,    3, 3 }
  579. X  };
  580. X  
  581. X  /* List of days in month - Feb MUST be 29 for CheckDate to work. */
  582. X***************
  583. X*** 109,122 ****
  584. X  
  585. X  static int JulFirst; /* Julian date of 1 Jan Current_year */
  586. X  static int FirstYear;
  587. X- #ifndef UNIX
  588. X- int int_comp(int *a, int *b) { return *a - *b; }
  589. X- #else
  590. X- int int_comp(a, b) 
  591. X-    int *a;
  592. X-    int *b;
  593. X- { return *a - *b; }
  594. X- #endif
  595. X  
  596. X  /***************************************************************/
  597. X  /*                                                             */
  598. X--- 113,118 ----
  599. X***************
  600. X*** 146,159 ****
  601. X  /*                                                             */
  602. X  /***************************************************************/
  603. X  #ifndef UNIX
  604. X! int MoveBack (int jul, int back, int d, int m, int y, int omit)
  605. X  #else
  606. X! int MoveBack (jul, back, d, m, y, omit)
  607. X       int jul;
  608. X       int back;
  609. X-      int d;
  610. X-      int m;
  611. X-      int y;
  612. X       int omit;
  613. X  #endif
  614. X  {
  615. X--- 142,152 ----
  616. X  /*                                                             */
  617. X  /***************************************************************/
  618. X  #ifndef UNIX
  619. X! int MoveBack (int jul, int back, int omit)
  620. X  #else
  621. X! int MoveBack (jul, back, omit)
  622. X       int jul;
  623. X       int back;
  624. X       int omit;
  625. X  #endif
  626. X  {
  627. X***************
  628. X*** 162,186 ****
  629. X     if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
  630. X     while (back) {
  631. X        jul--;
  632. X!       if (omit & 1 << (jul % 7)) continue; /* Omitted due to weekday */
  633. X! 
  634. X!       /* Omit if in fully-specified omit list */
  635. X!       if (NumFullOmit && bsearch(&jul, FullOmitArray, NumFullOmit, sizeof(int), int_comp)) continue;
  636. X! 
  637. X!       if (NumPartOmit) {
  638. X!      d--;
  639. X!      if (d == 0) {
  640. X!         m--;
  641. X!         if (m < 0) {
  642. X!            y--;
  643. X!            m = 11;
  644. X!         }
  645. X!         d = DaysInMonth(m, y);
  646. X!      }
  647. X!      temp = (m << 5) + d;
  648. X!      if (bsearch(&temp, PartOmitArray, NumPartOmit, sizeof(int), int_comp)) continue;
  649. X!       }
  650. X!       back--;
  651. X     }
  652. X     return jul;
  653. X  }
  654. X--- 155,161 ----
  655. X     if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
  656. X     while (back) {
  657. X        jul--;
  658. X!       if (!IsOmitted(jul, omit)) back--;
  659. X     }
  660. X     return jul;
  661. X  }
  662. X***************
  663. X*** 427,436 ****
  664. X       return -2;
  665. X        }
  666. X        omit = Julian(d, m, y);
  667. X-       if (omit < JulianToday) {
  668. X-      if (Debug) Eprint("Omit has expired.\n");
  669. X-      return -1;
  670. X-       }
  671. X  
  672. X        ptr = FullOmitArray + NumFullOmit;
  673. X        NumFullOmit++;
  674. X--- 402,407 ----
  675. X***************
  676. X*** 449,454 ****
  677. X--- 420,429 ----
  678. X          ptr++;
  679. X       }
  680. X        }
  681. X+       if (omit < JulianToday) {
  682. X+      if (Debug) Eprint("Omit has expired.\n");
  683. X+      return -1;
  684. X+       }
  685. X        /* If we got a MSG or a RUN, then execute DoRem */
  686. X        if (tok.type == Run_t || tok.type == Msg_t) return DoRem(&olds);
  687. X     }
  688. X***************
  689. X*** 529,542 ****
  690. X  
  691. X     /* Check if it's a built-in token */
  692. X     for (i=0; i < sizeof(keywd)/sizeof(keywd[0]); i++)
  693. X!       if (len >= 3 && !strncmpi(TmpBuf, keywd[i].str, len)) return keywd[i];
  694. X  
  695. X-    /* ARGH.  Check for "AT" as special case: < 3 chars */
  696. X-    if (len == 2 && !strncmpi(TmpBuf, "AT", 2)) {
  697. X-       tok.type = At_t;
  698. X-       return tok;
  699. X-    }
  700. X- 
  701. X     tok.type = Unknown_t;
  702. X  
  703. X     /* If it's a comment, ignore the rest of the line */
  704. X--- 504,511 ----
  705. X  
  706. X     /* Check if it's a built-in token */
  707. X     for (i=0; i < sizeof(keywd)/sizeof(keywd[0]); i++)
  708. X!       if (len >= keywd[i].len && !strncmpi(TmpBuf, keywd[i].str, len)) return keywd[i];
  709. X  
  710. X     tok.type = Unknown_t;
  711. X  
  712. X     /* If it's a comment, ignore the rest of the line */
  713. X***************
  714. X*** 545,551 ****
  715. X        return tok;
  716. X     }
  717. X  
  718. X!    /* Check if it's a number (optional +/-/* ahead of number */
  719. X     t = TmpBuf;
  720. X     if (isdigit(*t)) {
  721. X        while (*++t){
  722. X--- 514,520 ----
  723. X        return tok;
  724. X     }
  725. X  
  726. X!    /* Check if it's a number (optional + / - / * ahead of number */
  727. X     t = TmpBuf;
  728. X     if (isdigit(*t)) {
  729. X        while (*++t){
  730. X***************
  731. X*** 713,719 ****
  732. X     if (CheckDate(*d, *m, *y)) return -1;
  733. X     return Julian(*d, *m, *y);
  734. X  }
  735. X! 
  736. X  #ifndef UNIX
  737. X  int main(int argc, char *argv[])
  738. X  #else
  739. X--- 682,694 ----
  740. X     if (CheckDate(*d, *m, *y)) return -1;
  741. X     return Julian(*d, *m, *y);
  742. X  }
  743. X! /***************************************************************/
  744. X! /***************************************************************/
  745. X! /**                                                           **/
  746. X! /** MAIN PROGRAM ENTRY POINT                                  **/
  747. X! /**                                                           **/
  748. X! /***************************************************************/
  749. X! /***************************************************************/
  750. X  #ifndef UNIX
  751. X  int main(int argc, char *argv[])
  752. X  #else
  753. X***************
  754. X*** 773,778 ****
  755. X--- 748,754 ----
  756. X        HandleQueuedAts();
  757. X     }
  758. X  #endif
  759. X+    return 0;
  760. X  }
  761. X  /***************************************************************/
  762. X  /*                                                             */
  763. X***************
  764. X*** 800,803 ****
  765. X--- 776,842 ----
  766. X     _dos_gettime(&tloc);
  767. X     return (long) tloc.hour * 3600L + (long) tloc.minute * 60L + (long) tloc.second;
  768. X  #endif
  769. X+ }
  770. X+ /***************************************************************/
  771. X+ /*                                                             */
  772. X+ /*  my_bsearch                                                 */
  773. X+ /*                                                             */
  774. X+ /*  A simplified version of bsearch() for people whose library */
  775. X+ /*  does not have the full version.  This only works when      */
  776. X+ /*  searching a sorted array of integers.                      */
  777. X+ /*                                                             */
  778. X+ /***************************************************************/
  779. X+ #ifndef UNIX
  780. X+ int *my_bsearch(int key, int *array, int number)
  781. X+ #else
  782. X+ int *my_bsearch(key, array, number)
  783. X+ int key, *array, number;
  784. X+ #endif
  785. X+ {
  786. X+    int top = number - 1;
  787. X+    int bot = 0;
  788. X+    int mid;
  789. X+ 
  790. X+    while (top >= bot) {
  791. X+       mid = (top+bot)/2;
  792. X+       if (*(array+mid) == key) return array+mid;
  793. X+       else if (*(array+mid) > key) top = mid-1;
  794. X+       else bot = mid+1;
  795. X+    }
  796. X+ 
  797. X+    /* Oh, well - unsuccessful search.  Return NULL */
  798. X+    return NULL;
  799. X+ }
  800. X+      
  801. X+ /***************************************************************/
  802. X+ /*                                                             */
  803. X+ /* IsOmitted                                                   */
  804. X+ /*                                                             */
  805. X+ /* Returns non-zero if the julian date should be omitted, 0    */
  806. X+ /* otherwise.                                                  */
  807. X+ /*                                                             */
  808. X+ /***************************************************************/
  809. X+ #ifndef UNIX
  810. X+ int IsOmitted(int jul, int localomit)
  811. X+ #else
  812. X+ int IsOmitted(jul, localomit)
  813. X+ int jul, localomit;
  814. X+ #endif
  815. X+ {
  816. X+    int d, m, y;
  817. X+ 
  818. X+    /* Check if we should omit because of local omit */
  819. X+    if (localomit & 1 << (jul % 7)) return 1;
  820. X+ 
  821. X+    /* Check if we should omit because of fully-specified global omit */
  822. X+    if (NumFullOmit && my_bsearch(jul, FullOmitArray, NumFullOmit)) return 1;
  823. X+ 
  824. X+    /* Check if we should omit because of partially-specified global omits */
  825. X+    if (NumPartOmit) {
  826. X+       FromJulian(jul, &d, &m, &y);
  827. X+       if (my_bsearch((m << 5)+d, PartOmitArray, NumPartOmit)) return 1;
  828. X+    }
  829. X+ 
  830. X+    /* Looks cool - don't omit */
  831. X+    return 0;
  832. X  }
  833. X*** ../work/protos.h    Thu Nov 15 09:58:04 1990
  834. X--- ./protos.h    Mon Dec  3 14:17:47 1990
  835. X***************
  836. X*** 12,23 ****
  837. X  void  Eprint(const char *f, ...);
  838. X  int   FindTodaysDate(int *d, int *m, int *y);
  839. X  int   FromJulian  (int jul, int *d, int *m, int *y);
  840. X! int   GetTriggerDate (int d, int m, int y, int wd, int cons, int back, int repeat, int omit);
  841. X  void  HandleQueuedAts(void);
  842. X  void  initialize  (int argc, char *argv[]);
  843. X  int   int_comp    (int *, int *);
  844. X  int   Julian      (int d,   int m,  int y);
  845. X! int   MoveBack    (int jul, int back, int d, int m, int y, int omit);
  846. X  void  OpenFile    (char *s);
  847. X  void  Output      (char *s);
  848. X  Token ParseToken  (char **s);
  849. X--- 12,25 ----
  850. X  void  Eprint(const char *f, ...);
  851. X  int   FindTodaysDate(int *d, int *m, int *y);
  852. X  int   FromJulian  (int jul, int *d, int *m, int *y);
  853. X! int   GetTriggerDate (int d, int m, int y, int wd, int cons, int back, int repeat, int omit, int skip);
  854. X! int   IsOmitted   (int jul, int localomit);
  855. X  void  HandleQueuedAts(void);
  856. X  void  initialize  (int argc, char *argv[]);
  857. X  int   int_comp    (int *, int *);
  858. X  int   Julian      (int d,   int m,  int y);
  859. X! int   MoveBack    (int jul, int back, int omit);
  860. X! int   *my_bsearch (int key, int *array, int number);
  861. X  void  OpenFile    (char *s);
  862. X  void  Output      (char *s);
  863. X  Token ParseToken  (char **s);
  864. X***************
  865. X*** 41,51 ****
  866. X--- 43,55 ----
  867. X  int   FindTodaysDate();
  868. X  int   FromJulian  ();
  869. X  int   GetTriggerDate();
  870. X+ int   IsOmitted   ();
  871. X  void  HandleQueuedAts();
  872. X  void  initialize  ();
  873. X  int   int_comp    ();
  874. X  int   Julian      ();
  875. X  int   MoveBack    ();
  876. X+ int  *my_bsearch  ();
  877. X  void  OpenFile    ();
  878. X  void  Output      ();
  879. X  Token ParseToken  ();
  880. X*** ../work/remind.1    Thu Nov 29 09:12:19 1990
  881. X--- ./remind.1    Mon Dec  3 16:28:48 1990
  882. X***************
  883. X*** 1,4 ****
  884. X! .TH REMIND 1 "25 October 1990"
  885. X  .UC 4
  886. X  .SH NAME
  887. X  remind \- a sophisticated reminder service
  888. X--- 1,4 ----
  889. X! .TH REMIND 1 "29 November 1990"
  890. X  .UC 4
  891. X  .SH NAME
  892. X  remind \- a sophisticated reminder service
  893. X***************
  894. X*** 158,165 ****
  895. X      REM 1 -1 OMIT Sat Sun RUN do_backup
  896. X  
  897. X      # Introduce some holidays
  898. X!     OMIT 25 Dec        # Christmas
  899. X!     OMIT  1 July        # Canada Day
  900. X      OMIT 22 Nov 1990    # American Thanksgiving
  901. X  
  902. X      # Business things
  903. X--- 158,165 ----
  904. X      REM 1 -1 OMIT Sat Sun RUN do_backup
  905. X  
  906. X      # Introduce some holidays
  907. X!     OMIT 25 Dec +2 MSG %"Christmas%" is %b.
  908. X!     OMIT  1 July MSG Canada Day
  909. X      OMIT 22 Nov 1990    # American Thanksgiving
  910. X  
  911. X      # Business things
  912. X***************
  913. X*** 201,206 ****
  914. X--- 201,207 ----
  915. X  [\fIdelta\fR]
  916. X  [\fIback\fR]
  917. X  [\fIrepeat\fR]
  918. X+ [\fISKIP\fR | \fIBEFORE\fR | \fIAFTER\fR]
  919. X  [OMIT \fIomit_list\fR]
  920. X  [AT \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
  921. X  [MSG | RUN]
  922. X***************
  923. X*** 208,219 ****
  924. X  .RE
  925. X  .PP
  926. X  The
  927. X! .I date_spec, delta, back
  928. X  and
  929. X! .I repeat
  930. X  can be specified in any order.  The 
  931. X  .I OMIT, 
  932. X! if present, must follow these three
  933. X  items.  The 
  934. X  .I AT,
  935. X  if present, must follow the
  936. X--- 209,220 ----
  937. X  .RE
  938. X  .PP
  939. X  The
  940. X! .I date_spec, delta, back, repeat, SKIP, BEFORE
  941. X  and
  942. X! .I AFTER
  943. X  can be specified in any order.  The 
  944. X  .I OMIT, 
  945. X! if present, must follow these
  946. X  items.  The 
  947. X  .I AT,
  948. X  if present, must follow the
  949. X***************
  950. X*** 349,355 ****
  951. X  present.  Examples:
  952. X  .nf
  953. X      REM Sat 1 MSG First Saturday of every month
  954. X!     REM Mon Tue Wed Thu Fri MSG 1st working day after 15th of every month
  955. X  .fi
  956. X  .PP
  957. X  11.
  958. X--- 350,357 ----
  959. X  present.  Examples:
  960. X  .nf
  961. X      REM Sat 1 MSG First Saturday of every month
  962. X!     REM Mon Tue Wed Thu Fri 15 \\
  963. X!         MSG 1st working day after 15th of every month
  964. X  .fi
  965. X  .PP
  966. X  11.
  967. X***************
  968. X*** 388,395 ****
  969. X  present.  Examples:
  970. X  .nf
  971. X      REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
  972. X!     REM Mon Tue Wed Thu Fri 1 1990 MSG 1st working day of every
  973. X!         month in 1990
  974. X  .fi
  975. X  .PP
  976. X  15.
  977. X--- 390,397 ----
  978. X  present.  Examples:
  979. X  .nf
  980. X      REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
  981. X!     REM Mon Tue Wed Thu Fri 1 1990 \\
  982. X!         MSG 1st working day of every month in 1990
  983. X  .fi
  984. X  .PP
  985. X  15.
  986. X***************
  987. X*** 407,414 ****
  988. X  .I year
  989. X  present.  Example:
  990. X  .nf
  991. X!     REM Mon Tue Wed Thu Fri 28 Oct 1990 MSG 1st working day
  992. X!         on or after 28 October 1990.
  993. X  .fi
  994. X  .PP
  995. X  Note that when
  996. X--- 409,416 ----
  997. X  .I year
  998. X  present.  Example:
  999. X  .nf
  1000. X!     REM Mon Tue Wed Thu Fri 28 Oct 1990 \\
  1001. X!         MSG 1st working day on or after 28 October 1990.
  1002. X  .fi
  1003. X  .PP
  1004. X  Note that when
  1005. X***************
  1006. X*** 556,563 ****
  1007. X  when calculating the trigger date.  The final trigger date is strictly
  1008. X  a multiple of
  1009. X  .I repeat
  1010. X! days from the start date.
  1011. X  .PP
  1012. X  .B THE MSG KEYWORD
  1013. X  .PP
  1014. X  The
  1015. X--- 558,625 ----
  1016. X  when calculating the trigger date.  The final trigger date is strictly
  1017. X  a multiple of
  1018. X  .I repeat
  1019. X! days from the start date.  The only exceptions are those cases covered
  1020. X! by the \fIBEFORE, AFTER\fR and \fISKIP\fR keywords, discussed in the
  1021. X! next section.
  1022. X  .PP
  1023. X+ .B THE BEFORE, AFTER AND SKIP KEYWORDS
  1024. X+ .PP
  1025. X+ Should a reminder's trigger date happen to fall on an OMITted day, the
  1026. X+ default action is to go ahead and trigger the reminder anyway.  For example,
  1027. X+ suppose you have a meeting every Tuesday.  Consider the following:
  1028. X+ .PP
  1029. X+ .nf
  1030. X+     OMIT 1 Jan MSG New Year's Day
  1031. X+     OMIT 25 December MSG Christmas
  1032. X+     REM Tue AT 13:00 MSG Code review meeting.
  1033. X+ .fi
  1034. X+ .PP
  1035. X+ Even though Christmas 1990 is on a Tuesday, you will still be reminded
  1036. X+ of a code review meeting on that day.  Surely that is not desirable.  You
  1037. X+ can tell \fBremind\fR to skip reminders which fall on OMITted days with the
  1038. X+ .I SKIP
  1039. X+ keyword.  Assuming we have the same \fIOMIT\fR commands, then:
  1040. X+ .PP
  1041. X+ .nf
  1042. X+     REM Tue SKIP AT 13:00 MSG Code review meeting.
  1043. X+ .fi
  1044. X+ .PP
  1045. X+ would be triggered every Tuesday, but not on Christmas or New Year's
  1046. X+ Day, because both of these holidays happen to fall on Tuesdays.
  1047. X+ .PP
  1048. X+ In some situations, we don't want to skip the reminder; we want to move
  1049. X+ it to just before or just after a holiday.  Consider these examples:
  1050. X+ .PP
  1051. X+ .nf
  1052. X+     REM Fri AFTER OMIT Sat Sun MSG Do your backup!
  1053. X+ .fi
  1054. X+ .PP
  1055. X+ This reminder is normally triggered every Friday.  However, if a particular
  1056. X+ Friday happens to be a holiday, it will be triggered on the Monday after
  1057. X+ the holiday instead.  Note that the \fIAFTER\fR keyword keeps scanning
  1058. X+ forwards until it hits a day which is not in the global or local \fIOMIT\fR
  1059. X+ lists.  (Of course, if both the Friday and Monday are holidays, then the
  1060. X+ reminder would be deferred until Tuesday, and so on.)
  1061. X+ .PP
  1062. X+ .nf
  1063. X+     REM Fri BEFORE MSG Do your backup!
  1064. X+ .fi
  1065. X+ .PP
  1066. X+ This is similar, except that the reminder is issued on the previous Thursday
  1067. X+ if a particular Friday happens to be a holiday.  This form, too, will
  1068. X+ move back to Wednesday if Thursday also happens to be a holiday, and so on.
  1069. X+ .PP
  1070. X+ Note:  These keywords skip both local and global \fIOMIT\fRs.  Also,
  1071. X+ \fBremind\fR will complain about certain illegal constructions, such as:
  1072. X+ .PP
  1073. X+ .nf
  1074. X+     REM Mon SKIP OMIT Mon MSG Impossible!
  1075. X+ .fi
  1076. X+ .PP
  1077. X+ If \fBremind\fR makes too many attempts to find a trigger date for
  1078. X+ certain forms, it assumes that no satisfiable date exists, and will warn
  1079. X+ you to check the date specification.  In practice, this should never happen.
  1080. X+ .PP
  1081. X  .B THE MSG KEYWORD
  1082. X  .PP
  1083. X  The
  1084. X***************
  1085. X*** 860,869 ****
  1086. X--- 922,933 ----
  1087. X  The
  1088. X  .I INCLUDE
  1089. X  command has the following form:
  1090. X+ .PP
  1091. X  .RS
  1092. X  INCLUDE
  1093. X  .I filename
  1094. X  .RE
  1095. X+ .PP
  1096. X  This causes
  1097. X  .B remind
  1098. X  to suspend the current file and read the contents of the specified
  1099. X***************
  1100. X*** 905,912 ****
  1101. X  Before being processed, the body of a
  1102. X  .I REM
  1103. X  command is passed through a substitution filter.  The filter scans for
  1104. X! sequences "%x" where "x" is any letter and certain other characters,
  1105. X!  and performs substitutions as
  1106. X  shown below.  (All dates refer to the trigger date of the reminder.)
  1107. X  .TP
  1108. X  .B %a
  1109. X--- 969,976 ----
  1110. X  Before being processed, the body of a
  1111. X  .I REM
  1112. X  command is passed through a substitution filter.  The filter scans for
  1113. X! sequences "%x" (where "x" is any letter and certain other characters)
  1114. X! and performs substitutions as
  1115. X  shown below.  (All dates refer to the trigger date of the reminder.)
  1116. X  .TP
  1117. X  .B %a
  1118. X***************
  1119. X*** 1196,1202 ****
  1120. X  will get many error messages apparently coming from the file "*cache*"
  1121. X  This is because \fBremind\fR caches the reminder file for efficient
  1122. X  production of the calendar.  Thus, you should check that your reminder
  1123. X! file is error-free (by running \fBremind\fR with the \fB\-\d\fR option)
  1124. X  before attempting to produce a calendar.
  1125. X  .SH THE BANNER COMMAND
  1126. X  When
  1127. X--- 1260,1266 ----
  1128. X  will get many error messages apparently coming from the file "*cache*"
  1129. X  This is because \fBremind\fR caches the reminder file for efficient
  1130. X  production of the calendar.  Thus, you should check that your reminder
  1131. X! file is error-free (by running \fBremind\fR with the \fB\-d\fR option)
  1132. X  before attempting to produce a calendar.
  1133. X  .SH THE BANNER COMMAND
  1134. X  When
  1135. X***************
  1136. X*** 1332,1334 ****
  1137. X--- 1396,1403 ----
  1138. X  The MS-DOS version of \fBremind\fR does not support queuing or timed
  1139. X  activation of reminders.  It does, however, support the other semantics
  1140. X  of the \fIAT\fR keyword.
  1141. X+ .PP
  1142. X+ .B Remind
  1143. X+ has some built-in limits on total line length (511 characters),
  1144. X+ the length of an expanded \fIREM\fR body (511 characters), the number
  1145. X+ of global \fIOMIT\fRs, etc.
  1146. X*** ../work/timed.c    Thu Nov 29 09:10:32 1990
  1147. X--- ./timed.c    Mon Dec  3 12:24:41 1990
  1148. X***************
  1149. X*** 1,5 ****
  1150. X--- 1,6 ----
  1151. X  #include <stdio.h>
  1152. X  #include <signal.h>
  1153. X+ #include <string.h>
  1154. X  #ifndef NO_MALLOC_H
  1155. X  #include <malloc.h>
  1156. X  #endif
  1157. SHAR_EOF
  1158. $TOUCH -am 1203163090 patch.05 &&
  1159. chmod 0600 patch.05 ||
  1160. echo "restore of patch.05 failed"
  1161. set `wc -c patch.05`;Wc_c=$1
  1162. if test "$Wc_c" != "32338"; then
  1163.     echo original size 32338, current size $Wc_c
  1164. fi
  1165. fi
  1166. exit 0
  1167.