home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume38 / remind / patch07c / patch.07.B
Text File  |  1993-07-22  |  32KB  |  1,018 lines

  1. ***************
  2. *** 1376,1381 ****
  3. --- 1390,1426 ----
  4.   
  5.   /***************************************************************/
  6.   /*                                                             */
  7. + /*  FFiledir                                                   */
  8. + /*                                                             */
  9. + /*  Return directory of current file                           */
  10. + /*                                                             */
  11. + /***************************************************************/
  12. + #ifdef HAVE_PROTOS
  13. + PRIVATE int FFiledir(void)
  14. + #else
  15. + static int FFiledir()
  16. + #endif
  17. + {
  18. +    char TmpBuf[LINELEN];  /* Should be _POSIX_PATH_MAX ? */
  19. +    char *s;
  20. + #ifdef __MSDOS__
  21. + #define PATHSEP '\\'
  22. + #else
  23. + #define PATHSEP '/'
  24. + #endif
  25. +    strcpy(TmpBuf, FileName);
  26. +    s = TmpBuf + strlen(TmpBuf) - 1;
  27. +    if (s < TmpBuf) return RetStrVal(".");
  28. +    while (s > TmpBuf && *s != PATHSEP) s--;
  29. +    if (*s == PATHSEP) {
  30. +          *s = 0;
  31. +      return RetStrVal(TmpBuf);
  32. +    } else return RetStrVal(".");
  33. + }
  34. + /***************************************************************/
  35. + /*                                                             */
  36.   /*  FAccess                                                    */
  37.   /*                                                             */
  38.   /*  The UNIX access() system call.                             */
  39. ***************
  40. *** 1571,1576 ****
  41. --- 1616,1622 ----
  42.      int year, day, mon, jahr;
  43.      int mout, dout;
  44.      int ans, r;
  45. +    int adarbehave;
  46.   
  47.      if (ARG(0).type != INT_TYPE || ARG(1).type != STR_TYPE) return E_BAD_TYPE;
  48.      day = ARG(0).v.val;
  49. ***************
  50. *** 1580,1591 ****
  51.         return E_BAD_DATE;
  52.      }
  53.      if (Nargs == 2) {
  54. !       r = GetNextHebrewDate(JulianToday, mon, day, 0, &ans);
  55.         if (r) return r;
  56.         RetVal.type = DATE_TYPE;
  57.         RetVal.v.val = ans;
  58.         return OK;
  59.      }
  60.      if (Nargs == 4) {
  61.         if (ARG(3).type != INT_TYPE) return E_BAD_TYPE;
  62.         jahr = ARG(3).v.val;
  63. --- 1626,1644 ----
  64.         return E_BAD_DATE;
  65.      }
  66.      if (Nargs == 2) {
  67. !       r = GetNextHebrewDate(JulianToday, mon, day, 0, 0, &ans);
  68.         if (r) return r;
  69.         RetVal.type = DATE_TYPE;
  70.         RetVal.v.val = ans;
  71.         return OK;
  72.      }
  73. +    if (Nargs == 5) {
  74. +       if (ARG(4).type != INT_TYPE) return E_BAD_TYPE;
  75. +       adarbehave = ARG(4).v.val;
  76. +       if (adarbehave < 0) return E_2LOW;
  77. +       if (adarbehave > 2) return E_2HIGH;
  78. +    } else adarbehave = 0;
  79.      if (Nargs == 4) {
  80.         if (ARG(3).type != INT_TYPE) return E_BAD_TYPE;
  81.         jahr = ARG(3).v.val;
  82. ***************
  83. *** 1599,1605 ****
  84.   
  85.      if (ARG(2).type == INT_TYPE) {
  86.         year = ARG(2).v.val;
  87. !       r = GetValidHebDate(year, mon, day, &mout, &dout, jahr);
  88.         if (r) return r;
  89.         r = HebToJul(year, mout, dout);
  90.         if (r<0) return E_DATE_OVER;
  91. --- 1652,1658 ----
  92.   
  93.      if (ARG(2).type == INT_TYPE) {
  94.         year = ARG(2).v.val;
  95. !       r = GetValidHebDate(year, mon, day, 0, &mout, &dout, jahr);
  96.         if (r) return r;
  97.         r = HebToJul(year, mout, dout);
  98.         if (r<0) return E_DATE_OVER;
  99. ***************
  100. *** 1607,1613 ****
  101.         RetVal.type = DATE_TYPE;
  102.         return OK;
  103.      } else if (ARG(2).type == DATE_TYPE) {
  104. !       r = GetNextHebrewDate(ARG(2).v.val, mon, day, jahr, &ans);
  105.         if (r) return r;
  106.         RetVal.v.val = ans;
  107.         RetVal.type = DATE_TYPE;
  108. --- 1660,1666 ----
  109.         RetVal.type = DATE_TYPE;
  110.         return OK;
  111.      } else if (ARG(2).type == DATE_TYPE) {
  112. !       r = GetNextHebrewDate(ARG(2).v.val, mon, day, jahr, adarbehave, &ans);
  113.         if (r) return r;
  114.         RetVal.v.val = ans;
  115.         RetVal.type = DATE_TYPE;
  116. ***************
  117. *** 1681,1684 ****
  118. --- 1734,2008 ----
  119.      RetVal.type = INT_TYPE;
  120.      RetVal.v.val = y;
  121.      return OK;
  122. + }
  123. + /****************************************************************/
  124. + /*                                                              */
  125. + /*  FEasterdate - calc. easter Sunday from a year.              */
  126. + /*                                                              */
  127. + /*    from The Art of Computer Programming Vol 1.               */
  128. + /*            Fundamental Algorithms                            */
  129. + /*    by Donald Knuth.                                          */
  130. + /*                                                              */
  131. + /* Donated by Michael Salmon - thanks!                          */
  132. + /*                                                              */
  133. + /* I haven't examined this in detail, but I *think* int         */
  134. + /* arithmetic is fine, even on 16-bit machines.                 */
  135. + /*                                                              */
  136. + /****************************************************************/
  137. + #ifdef HAVE_PROTOS
  138. + PRIVATE int FEasterdate(void)
  139. + #else
  140. + static int FEasterdate()
  141. + #endif
  142. + {
  143. +    int y, m, d;
  144. +    int g, c, x, z, e, n;
  145. +    if (ARG(0).type == INT_TYPE) {
  146. +       y = ARG(0).v.val;
  147. +       if (y < BASE) return E_2LOW;
  148. +       else if (y > BASE+YR_RANGE) return E_2HIGH;
  149. +    } else if (ARG(0).type == DATE_TYPE) {
  150. +       FromJulian(ARG(0).v.val, &y, &m, &d);  /* We just want the year */
  151. +    } else return E_BAD_TYPE;
  152. +    do {
  153. +       g = (y % 19) + 1;  /* golden number */
  154. +       c = (y / 100) + 1; /* century */
  155. +       x = (3 * c)/4 - 12;        /* correction for non-leap year centuries */
  156. +       z = (8 * c + 5)/25 - 5;    /* special constant for moon sync */
  157. +       d = (5 * y)/4 - x - 10;    /* find sunday */
  158. +       e = (11 * g + 20 + z - x) % 30;    /* calc epact */
  159. +       if ( e < 0 ) e += 30;
  160. +       if ( e == 24 || (e == 25 && g > 11)) e++;
  161. +       n = 44 - e;                        /* find full moon */
  162. +       if ( n < 21 ) n += 30;     /* after 21st */
  163. +       d = n + 7 - (d + n)%7;     /* calc sunday after */
  164. +       if (d <= 31) m = 2;
  165. +       else
  166. +       {
  167. +          d = d - 31;
  168. +          m = 3;
  169. +       }
  170. +       RetVal.type = DATE_TYPE;
  171. +       RetVal.v.val = Julian(y, m, d);
  172. +       y++; } while (ARG(0).type == DATE_TYPE && RetVal.v.val < ARG(0).v.val);
  173. +    return OK;
  174. + }
  175. + /***************************************************************/
  176. + /*                                                             */
  177. + /*  FIsdst and FMinsfromutc                                    */
  178. + /*                                                             */
  179. + /*  Check whether daylight savings time is in effect, and      */
  180. + /*  get minutes from UTC.                                      */
  181. + /*                                                             */
  182. + /***************************************************************/
  183. + PRIVATE int FTimeStuff ARGS ((int wantmins));
  184. + #ifdef HAVE_PROTOS
  185. + PRIVATE int FIsdst(void)
  186. + #else
  187. + static int FIsdst()
  188. + #endif
  189. + {
  190. +    return FTimeStuff(0);
  191. + }
  192. + #ifdef HAVE_PROTOS
  193. + PRIVATE int FMinsfromutc(void)
  194. + #else
  195. + static int FMinsfromutc()
  196. + #endif
  197. + {
  198. +    return FTimeStuff(1);
  199. + }
  200. + #ifdef HAVE_PROTOS
  201. + PRIVATE int FTimeStuff(int wantmins)
  202. + #else
  203. + static int FTimeStuff(wantmins)
  204. + int wantmins;
  205. + #endif
  206. + {
  207. +    int jul, tim;
  208. +    int mins, dst;
  209. +    jul = JulianToday;
  210. +    tim = 0;
  211. +    if (Nargs >= 1) {
  212. +       if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
  213. +       jul = ARG(0).v.val;
  214. +       if (Nargs >= 2) {
  215. +          if (ARG(1).type != TIM_TYPE) return E_BAD_TYPE;
  216. +      tim = ARG(1).v.val;
  217. +       }
  218. +    }
  219. +    if (CalcMinsFromUTC(jul, tim, &mins, &dst)) return E_MKTIME_PROBLEM;
  220. +    RetVal.type = INT_TYPE;
  221. +    if (wantmins) RetVal.v.val = mins; else RetVal.v.val = dst;
  222. +    return OK;
  223. + }
  224. + /***************************************************************/
  225. + /*                                                             */
  226. + /*  Sunrise and sunset functions.                              */
  227. + /*                                                             */
  228. + /*  Algorithm from "Almanac for computers for the year 1978"   */
  229. + /*  by L. E. Doggett, Nautical Almanac Office, USNO.           */
  230. + /*                                                             */
  231. + /*  This code also uses some ideas found in programs written   */
  232. + /*  by Michael Schwartz and Marc T. Kaufman.                   */
  233. + /*                                                             */
  234. + /***************************************************************/
  235. + #define PI 3.1415926536
  236. + #define DEGRAD (PI/180.0)
  237. + #define RADDEG (180.0/PI)
  238. + #ifdef HAVE_PROTOS
  239. + PRIVATE int SunStuff(int rise, double cosz, int jul)
  240. + #else
  241. + static int SunStuff(rise, cosz, jul)
  242. + int rise;
  243. + double cosz;
  244. + int jul;
  245. + #endif
  246. + {
  247. +    int year, mon, day;
  248. +    int jan0;
  249. +    int mins, hours;
  250. +    double M, L, tanA, sinDelta, cosDelta, a, a_hr, cosH, t, H, T;
  251. +    double latitude, longdeg, UT, local;
  252. + /* Get offset from UTC */
  253. +    if (CalculateUTC) {
  254. +       if (CalcMinsFromUTC(jul, 12*60, &mins, NULL)) {
  255. +          Eprint(ErrMsg[E_MKTIME_PROBLEM]);
  256. +      return NO_TIME;
  257. +       }
  258. +    } else mins = MinsFromUTC;
  259. + /* Get latitude and longitude */
  260. +    longdeg = (double) LongDeg + (double) LongMin / 60.0
  261. +               + (double) LongSec / 3600.0;
  262. +    latitude = DEGRAD * ((double) LatDeg + (double) LatMin / 60.0
  263. +                  + (double) LatSec / 3600.0);
  264. +    FromJulian(jul, &year, &mon, &day);
  265. +    jan0 = jul - Julian(year, 0, 1);
  266. + /* Following formula on page B6 exactly... */
  267. +    t = (double) jan0;
  268. +    if (rise) t += (6.0 + longdeg/15.0) / 24.0;
  269. +    else      t += (18.0 + longdeg/15.0) / 24.0;
  270. + /* Mean anomaly of sun for 1978 ... how accurate for other years??? */
  271. +    M = 0.985600 * t - 3.251;  /* In degrees */
  272. + /* Sun's true longitude */
  273. +    L = M + 1.916*sin(DEGRAD*M) + 0.02*sin(2*DEGRAD*M) + 282.565;
  274. +    if (L > 360.0) L -= 360.0;
  275. + /* Tan of sun's right ascension */
  276. +    tanA = 0.91746 * tan(DEGRAD*L);
  277. +    a = RADDEG * atan(tanA);
  278. + /* Move a into same quadrant as L */
  279. +    if (0.0 <= L && L < 90.0) {
  280. +       if (a < 0.0) a += 180.0;
  281. +    } else if (90.0 <= L && L < 180.0) {
  282. +       a += 180.0;
  283. +    } else if (180.0 <= L && L < 270.0) {
  284. +       a += 180.0;
  285. +    } else {
  286. +       if (a > 0.0) a += 180.0;
  287. +    }
  288. + /*   if (fabs(a - L) > 90.0)
  289. +       a += 180.0; */
  290. +    if (a > 360.0)
  291. +       a -= 360.0;
  292. +    a_hr = a / 15.0;
  293. + /* Sine of sun's declination */
  294. +    sinDelta = 0.39782 * sin(DEGRAD*L);
  295. +    cosDelta = sqrt(1 - sinDelta*sinDelta);
  296. + /* Cosine of sun's local hour angle */
  297. +    cosH = (cosz - sinDelta * sin(latitude)) / (cosDelta * cos(latitude));
  298. +    if (cosH > 1.0 || cosH < -1.0) return NO_TIME;
  299. +    H = RADDEG * acos(cosH);
  300. +    if (rise) H = 360.0 - H;
  301. +    T = H / 15.0 + a_hr - 0.065710*t - 6.620;
  302. +    if (T >= 24.0) T -= 24.0;
  303. +    else if (T < 0.0) T+= 24.0;
  304. +    UT = T + longdeg / 15.0;
  305. +    local = UT + (double) mins / 60.0;
  306. +    if (local < 0.0) local += 24.0;
  307. +    else if (local >= 24.0) local -= 24.0;
  308. +    hours = (int) local;
  309. +    mins = (int) ((local - hours) * 60.0);
  310. +    return hours*60 + mins;
  311. + }
  312. + /***************************************************************/
  313. + /*                                                             */
  314. + /*  Sunrise and Sunset functions.                              */
  315. + /*                                                             */
  316. + /***************************************************************/
  317. + #ifdef HAVE_PROTOS
  318. + PRIVATE int FSun(int rise)
  319. + #else
  320. + static int FSun(rise)
  321. + int rise;
  322. + #endif
  323. + {
  324. +    int jul = JulianToday;
  325. +    static double cosz = -0.014543897;  /* for sunrise and sunset */
  326. +    int r;
  327. +    if (Nargs >= 1) {
  328. +       if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
  329. +       jul = ARG(0).v.val;
  330. +    }
  331. +    
  332. +    r = SunStuff(rise, cosz, jul);
  333. +    if (r == NO_TIME) {
  334. +       RetVal.v.val = 0;
  335. +       RetVal.type = INT_TYPE;
  336. +    } else {
  337. +       RetVal.v.val = r;
  338. +       RetVal.type = TIM_TYPE;
  339. +    }
  340. +    return OK;
  341. + }
  342. +       
  343. + #ifdef HAVE_PROTOS
  344. + PRIVATE int FSunrise(void)
  345. + #else
  346. + static int FSunrise()
  347. + #endif
  348. + {
  349. +    return FSun(1);
  350. + }
  351. + #ifdef HAVE_PROTOS
  352. + PRIVATE int FSunset(void)
  353. + #else
  354. + static int FSunset()
  355. + #endif
  356. + {
  357. +    return FSun(0);
  358.   }
  359. *** ../p6/globals.h    Thu Apr 22 10:24:07 1993
  360. --- ./globals.h    Mon Jun 28 12:29:31 1993
  361. ***************
  362. *** 31,69 ****
  363.   EXTERN    int    CurMon;
  364.   EXTERN    int    CurYear;
  365.   EXTERN  int    LineNo;
  366. ! EXTERN  char    FreshLine;
  367.   EXTERN  char    LineBuffer[LINELEN];
  368.   EXTERN  char    SubstBuffer[LINELEN];
  369.   EXTERN  char    TokBuffer[TOKSIZE+1];
  370.   EXTERN  INIT(   char    *MsgCommand, NULL);
  371. ! EXTERN  INIT(    char    ShowAllErrors, 0);
  372.   EXTERN  INIT(    int     DebugFlag, 0);
  373. ! EXTERN  INIT(   char    DoCalendar, 0);
  374. ! EXTERN  INIT(   char    DoSimpleCalendar, 0);
  375. ! EXTERN  INIT(   char    PsCal, 0);
  376.   EXTERN  INIT(   int     CalWidth, 80);
  377.   EXTERN  INIT(   int     CalWeeks, 0);
  378.   EXTERN  INIT(   int     CalMonths, 0);
  379. ! EXTERN  INIT(    char    Hush, 0);
  380. ! EXTERN  INIT(    char    NextMode, 0);
  381. ! EXTERN  INIT(    char    InfiniteDelta, 0);
  382. ! EXTERN  INIT(   char    RunDisabled, 0);
  383. ! EXTERN  INIT(   char    IgnoreOnce, 0);
  384.   EXTERN  INIT(   char    Banner[LINELEN], L_BANNER);
  385. ! EXTERN  INIT(   char    SortByTime, 0);
  386. ! EXTERN  INIT(   char    SortByDate, 0);
  387.   
  388.   EXTERN    char    *InitialFile;
  389.   EXTERN    int    FileAccessDate;
  390.   
  391. ! #ifdef HAVE_QUEUED
  392. ! EXTERN  INIT(    char    DontFork, 0);
  393. ! EXTERN  INIT(    char    DontQueue, 0);
  394.   EXTERN  INIT(   int     NumQueued, 0);
  395. ! EXTERN  INIT(   char    DontIssueAts, 0);
  396. ! EXTERN  INIT(   char    Daemon, 0);
  397. ! #endif
  398.   
  399.   EXTERN  INIT(   int     ScFormat, SC_AMPM);
  400.   EXTERN  INIT(   int     MaxSatIter, 150);
  401.   EXTERN  INIT(    char    *FileName, NULL);
  402. --- 31,68 ----
  403.   EXTERN    int    CurMon;
  404.   EXTERN    int    CurYear;
  405.   EXTERN  int    LineNo;
  406. ! EXTERN  int     FreshLine;
  407.   EXTERN  char    LineBuffer[LINELEN];
  408.   EXTERN  char    SubstBuffer[LINELEN];
  409.   EXTERN  char    TokBuffer[TOKSIZE+1];
  410.   EXTERN  INIT(   char    *MsgCommand, NULL);
  411. ! EXTERN  INIT(    int     ShowAllErrors, 0);
  412.   EXTERN  INIT(    int     DebugFlag, 0);
  413. ! EXTERN  INIT(   int    DoCalendar, 0);
  414. ! EXTERN  INIT(   int     DoSimpleCalendar, 0);
  415. ! EXTERN  INIT(   int     PsCal, 0);
  416.   EXTERN  INIT(   int     CalWidth, 80);
  417.   EXTERN  INIT(   int     CalWeeks, 0);
  418.   EXTERN  INIT(   int     CalMonths, 0);
  419. ! EXTERN  INIT(    int     Hush, 0);
  420. ! EXTERN  INIT(    int     NextMode, 0);
  421. ! EXTERN  INIT(    int     InfiniteDelta, 0);
  422. ! EXTERN  INIT(   int     RunDisabled, 0);
  423. ! EXTERN  INIT(   int     IgnoreOnce, 0);
  424.   EXTERN  INIT(   char    Banner[LINELEN], L_BANNER);
  425. ! EXTERN  INIT(   int     SortByTime, 0);
  426. ! EXTERN  INIT(   int     SortByDate, 0);
  427.   
  428.   EXTERN    char    *InitialFile;
  429.   EXTERN    int    FileAccessDate;
  430.   
  431. ! EXTERN  INIT(    int     DontFork, 0);
  432. ! EXTERN  INIT(    int     DontQueue, 0);
  433.   EXTERN  INIT(   int     NumQueued, 0);
  434. ! EXTERN  INIT(   int     DontIssueAts, 0);
  435. ! EXTERN  INIT(   int     Daemon, 0);
  436.   
  437.   EXTERN  INIT(   int     ScFormat, SC_AMPM);
  438.   EXTERN  INIT(   int     MaxSatIter, 150);
  439.   EXTERN  INIT(    char    *FileName, NULL);
  440. ***************
  441. *** 71,79 ****
  442.   EXTERN  INIT(   int     NumIfs,    0);
  443.   EXTERN  INIT(   unsigned int IfFlags,   0);
  444.   EXTERN  INIT(   int     LastTriggerDate, 0);
  445. ! EXTERN  INIT(   char    LastTrigValid, 0);
  446.   EXTERN  INIT(   int     LastTriggerTime, 0);
  447. ! EXTERN  INIT(   char    ShouldCache, 0);
  448.   EXTERN  char    *CurLine;
  449.   EXTERN  INIT(   int     NumTriggered, 0);
  450.   EXTERN  int ArgC;
  451. --- 70,78 ----
  452.   EXTERN  INIT(   int     NumIfs,    0);
  453.   EXTERN  INIT(   unsigned int IfFlags,   0);
  454.   EXTERN  INIT(   int     LastTriggerDate, 0);
  455. ! EXTERN  INIT(   int     LastTrigValid, 0);
  456.   EXTERN  INIT(   int     LastTriggerTime, 0);
  457. ! EXTERN  INIT(   int     ShouldCache, 0);
  458.   EXTERN  char    *CurLine;
  459.   EXTERN  INIT(   int     NumTriggered, 0);
  460.   EXTERN  int ArgC;
  461. ***************
  462. *** 81,86 ****
  463. --- 80,97 ----
  464.   EXTERN  INIT(   int     CalLines, CAL_LINES);
  465.   EXTERN  INIT(   int     CalPad, 1);
  466.   
  467. + /* Latitude and longitude */
  468. + EXTERN  INIT(    int      LatDeg, LAT_DEG);
  469. + EXTERN  INIT(    int      LatMin, LAT_MIN);
  470. + EXTERN  INIT(    int      LatSec, LAT_SEC);
  471. + EXTERN  INIT(    int      LongDeg, LONG_DEG);
  472. + EXTERN  INIT(    int      LongMin, LONG_MIN);
  473. + EXTERN  INIT(    int      LongSec, LONG_SEC);
  474. + /* UTC calculation stuff */
  475. + EXTERN  INIT(    int      MinsFromUTC, 0);
  476. + EXTERN    INIT(    int      CalculateUTC, 1);
  477. + EXTERN  INIT(   int      FoldYear, 0);
  478.   /* List of months */
  479.   EXTERN    char    *MonthName[]
  480.   #ifdef MK_GLOBALS
  481. *** ../p6/hbcal.c    Mon May  3 11:34:29 1993
  482. --- ./hbcal.c    Mon Jun 28 12:29:49 1993
  483. ***************
  484. *** 48,53 ****
  485. --- 48,57 ----
  486.   #define JAHR_FORWARD  1
  487.   #define JAHR_BACKWARD 2
  488.   
  489. + #define ADAR2ADARB 0
  490. + #define ADAR2ADARA 1
  491. + #define ADAR2BOTH  2
  492.   static char *HebMonthNames[] = {
  493.      "Tishrey", "Heshvan", "Kislev", "Tevet", "Shvat", "Adar A", "Adar B",
  494.      "Nisan", "Iyar", "Sivan", "Tamuz", "Av", "Elul", "Adar"};
  495. ***************
  496. *** 324,334 ****
  497.   /*                                                             */
  498.   /***************************************************************/
  499.   #ifdef HAVE_PROTOS
  500. ! PUBLIC int GetValidHebDate(int yin, int min, int din,
  501.                              int *mout, int *dout, int jahr)
  502.   #else
  503. ! int GetValidHebDate(yin, min, din, mout, dout, jahr)
  504. ! int yin, min, din, *mout, *dout, jahr;
  505.   #endif
  506.   {
  507.      char *monlen;
  508. --- 328,338 ----
  509.   /*                                                             */
  510.   /***************************************************************/
  511.   #ifdef HAVE_PROTOS
  512. ! PUBLIC int GetValidHebDate(int yin, int min, int din, int adarbehave,
  513.                              int *mout, int *dout, int jahr)
  514.   #else
  515. ! int GetValidHebDate(yin, min, din, adarbehave, mout, dout, jahr)
  516. ! int yin, min, din, adarbehave, *mout, *dout, jahr;
  517.   #endif
  518.   {
  519.      char *monlen;
  520. ***************
  521. *** 344,355 ****
  522.         return E_BAD_DATE;
  523.      }
  524.   
  525. -    /* Convert ADAR to ADAR-B */
  526. -    if (min == ADAR) *mout = min = ADARB;
  527.      ylen = DaysInHebYear(yin);
  528.      monlen = DaysInHebMonths(ylen);
  529.   
  530.      if (din <= monlen[min]) return OK;
  531.   
  532.      switch(jahr) {
  533. --- 348,371 ----
  534.         return E_BAD_DATE;
  535.      }
  536.   
  537.      ylen = DaysInHebYear(yin);
  538.      monlen = DaysInHebMonths(ylen);
  539.   
  540. +    /* Convert ADAR as necessary */
  541. +    if (min == ADAR) {
  542. +       switch(adarbehave) {
  543. +          case ADAR2ADARA: if (monlen[ADARA]) *mout = min = ADARA;
  544. +               else             *mout = min = ADARB;
  545. +               break;
  546. +      case ADAR2ADARB: *mout = min = ADARB; break;
  547. +      default:
  548. +         Eprint("GetValidHebDate: Bad adarbehave value %d", adarbehave);
  549. +         return E_SWERR;
  550. +       }
  551. +    }
  552.      if (din <= monlen[min]) return OK;
  553.   
  554.      switch(jahr) {
  555. ***************
  556. *** 418,443 ****
  557.   /*                                                             */
  558.   /***************************************************************/
  559.   #ifdef HAVE_PROTOS
  560. ! PUBLIC int GetNextHebrewDate(int julstart, int hm, int hd, int jahr, int *ans)
  561.   #else
  562. ! int GetNextHebrewDate(julstart, hm, hd, jahr, ans)
  563. ! int julstart, hm, hd, jahr, *ans;
  564.   #endif
  565.   {
  566.      int r, yout, mout, dout, jul=1;
  567.   
  568.      /* I initialize jul above to stop gcc from complaining about
  569.         possible use of uninitialized variable.  You can take it
  570.         out if the small inefficiency really bothers you. */
  571.   
  572.      JulToHeb(julstart, &yout, &mout, &dout);
  573.   
  574.      r = 1;
  575.      while(r) {
  576. !       r = GetValidHebDate(yout, hm, hd, &mout, &dout, jahr);
  577.         if (dout == -1) return r;
  578.         if (r) {
  579. !          yout++;
  580.        continue;
  581.         }
  582.         jul = HebToJul(yout, mout, dout);
  583. --- 434,471 ----
  584.   /*                                                             */
  585.   /***************************************************************/
  586.   #ifdef HAVE_PROTOS
  587. ! PUBLIC int GetNextHebrewDate(int julstart, int hm, int hd,
  588. !                  int jahr, int adarbehave, int *ans)
  589.   #else
  590. ! int GetNextHebrewDate(julstart, hm, hd, jahr, adarbehave, ans)
  591. ! int julstart, hm, hd, jahr, adarbehave, *ans;
  592.   #endif
  593.   {
  594.      int r, yout, mout, dout, jul=1;
  595. +    int adarflag = adarbehave;
  596.   
  597.      /* I initialize jul above to stop gcc from complaining about
  598.         possible use of uninitialized variable.  You can take it
  599.         out if the small inefficiency really bothers you. */
  600.   
  601. +    /* If adarbehave == ADAR2BOTH, set adarflag to ADAR2ADARA for now */
  602. +    if (adarbehave == ADAR2BOTH) adarflag = ADAR2ADARA;
  603.      JulToHeb(julstart, &yout, &mout, &dout);
  604.   
  605.      r = 1;
  606.      while(r) {
  607. !       r = GetValidHebDate(yout, hm, hd, adarflag, &mout, &dout, jahr);
  608.         if (dout == -1) return r;
  609.         if (r) {
  610. !          if (adarbehave == ADAR2BOTH && hm == ADAR) {
  611. !         if (adarflag == ADAR2ADARA) {
  612. !            adarflag = ADAR2ADARB;
  613. !             } else {
  614. !            adarflag = ADAR2ADARA;
  615. !            yout++;
  616. !             }
  617. !          } else yout++;
  618.        continue;
  619.         }
  620.         jul = HebToJul(yout, mout, dout);
  621. ***************
  622. *** 444,450 ****
  623.         if (jul < 0) return E_DATE_OVER;
  624.         if (jul >= julstart) break;
  625.         else {
  626. !          yout++;
  627.            r=1;  /* Force loop to continue */
  628.         }
  629.      }
  630. --- 472,485 ----
  631.         if (jul < 0) return E_DATE_OVER;
  632.         if (jul >= julstart) break;
  633.         else {
  634. !          if (adarbehave == ADAR2BOTH && hm == ADAR) {
  635. !         if (adarflag == ADAR2ADARA) {
  636. !            adarflag = ADAR2ADARB;
  637. !             } else {
  638. !            adarflag = ADAR2ADARA;
  639. !            yout++;
  640. !             }
  641. !          } else yout++;
  642.            r=1;  /* Force loop to continue */
  643.         }
  644.      }
  645. *** ../p6/init.c    Thu Apr 29 15:08:41 1993
  646. --- ./init.c    Mon Jun 28 12:29:50 1993
  647. ***************
  648. *** 61,67 ****
  649.    *  -z[n]    = Daemon mode waking up every n (def 5) minutes.
  650.    *  -bn      = Time format for cal (0, 1, or 2)
  651.    *  -xn      = Max. number of iterations for SATISFY
  652. !  *  -uname   = Run as user 'name' - only valid when run by root.
  653.    *  -kcmd    = Run 'cmd' for MSG-type reminders instead of printing to stdout
  654.    *  -iVAR=EXPR = Initialize and preserve VAR.
  655.    *
  656. --- 61,68 ----
  657.    *  -z[n]    = Daemon mode waking up every n (def 5) minutes.
  658.    *  -bn      = Time format for cal (0, 1, or 2)
  659.    *  -xn      = Max. number of iterations for SATISFY
  660. !  *  -uname   = Run as user 'name' - only valid when run by root.  If run
  661. !  *             by non-root, changes environment but not effective uid.
  662.    *  -kcmd    = Run 'cmd' for MSG-type reminders instead of printing to stdout
  663.    *  -iVAR=EXPR = Initialize and preserve VAR.
  664.    *
  665. ***************
  666. *** 116,121 ****
  667. --- 117,130 ----
  668.      JulianToday = RealToday;
  669.      FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
  670.   
  671. + #if !defined(HAVE_QUEUED)
  672. +    DontFork = 1;
  673. +    DontQueue = 1;
  674. +    NumQueued = 0;
  675. +    DontIssueAts = 0;
  676. +    Daemon = 0;
  677. + #endif
  678.      /* Parse the command-line options */
  679.      i = 1;
  680.      while (i < argc) {
  681. ***************
  682. *** 229,236 ****
  683.           case 's':
  684.           case 'S':
  685.              DoSimpleCalendar = 1;
  686. !            PARSENUM(CalMonths, arg);
  687. !            if (!CalMonths) CalMonths = 1;
  688.              break;
  689.   
  690.           case 'p':
  691. --- 238,251 ----
  692.           case 's':
  693.           case 'S':
  694.              DoSimpleCalendar = 1;
  695. !            if (*arg == '+') {
  696. !               arg++;
  697. !               PARSENUM(CalWeeks, arg);
  698. !           if (!CalWeeks) CalWeeks = 1;
  699. !                } else {
  700. !                  PARSENUM(CalMonths, arg);
  701. !               if (!CalMonths) CalMonths = 1;
  702. !                }
  703.              break;
  704.   
  705.           case 'p':
  706. ***************
  707. *** 357,363 ****
  708. --- 372,383 ----
  709.         CurMon = m;
  710.         CurDay = d;
  711.         if (JulianToday != RealToday) IgnoreOnce = 1;
  712.      }
  713. + /* Figure out the offset from UTC */
  714. +    if (CalculateUTC)
  715. +       (void) CalcMinsFromUTC(JulianToday, SystemTime()/60,
  716. +                  &MinsFromUTC, NULL);
  717.   }
  718.   
  719.   /***************************************************************/
  720. ***************
  721. *** 384,390 ****
  722.      fprintf(ErrFp, " -c[n]  Produce a calendar for n (default 1) months\n");
  723.      fprintf(ErrFp, " -c+[n] Produce a calendar for n (default 1) weeks\n");
  724.      fprintf(ErrFp, " -w[n[,p[,s]]]  Specify width, padding and spacing of calendar\n");
  725. !    fprintf(ErrFp, " -s[n]  Produce 'simple calendar' for n (1) months\n");
  726.      fprintf(ErrFp, " -p[n]  Same as -s, but input compatible with rem2ps\n");
  727.      fprintf(ErrFp, " -v     Verbose mode\n");
  728.      fprintf(ErrFp, " -o     Ignore ONCE directives\n");
  729. --- 404,410 ----
  730.      fprintf(ErrFp, " -c[n]  Produce a calendar for n (default 1) months\n");
  731.      fprintf(ErrFp, " -c+[n] Produce a calendar for n (default 1) weeks\n");
  732.      fprintf(ErrFp, " -w[n[,p[,s]]]  Specify width, padding and spacing of calendar\n");
  733. !    fprintf(ErrFp, " -s[+][n] Produce 'simple calendar' for n (1) months (weeks)\n");
  734.      fprintf(ErrFp, " -p[n]  Same as -s, but input compatible with rem2ps\n");
  735.      fprintf(ErrFp, " -v     Verbose mode\n");
  736.      fprintf(ErrFp, " -o     Ignore ONCE directives\n");
  737. ***************
  738. *** 402,408 ****
  739.      fprintf(ErrFp, " -x[n]  Iteration limit for SATISFY clause (def=150)\n");
  740.      fprintf(ErrFp, " -kcmd  Run 'cmd' for MSG-type reminders\n");
  741.      fprintf(ErrFp, " -g[d[d]] Sort reminders by date and time before issuing\n");
  742. !    fprintf(ErrFp, "-ivar=val Initialize var to val and preserve var\n");
  743.      exit(1);
  744.   }
  745.   
  746. --- 422,428 ----
  747.      fprintf(ErrFp, " -x[n]  Iteration limit for SATISFY clause (def=150)\n");
  748.      fprintf(ErrFp, " -kcmd  Run 'cmd' for MSG-type reminders\n");
  749.      fprintf(ErrFp, " -g[d[d]] Sort reminders by date and time before issuing\n");
  750. !    fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");
  751.      exit(1);
  752.   }
  753.   
  754. ***************
  755. *** 436,445 ****
  756.      static char *home, *shell, *username, *logname;
  757.   
  758.      myuid = getuid();
  759. -    if (myuid) {
  760. -       fprintf(ErrFp, "Remind: Only the super-user can use the '-u' option.\n");
  761. -       exit(1);
  762. -    }
  763.   
  764.      pwent = getpwnam(user);
  765.   
  766. --- 456,461 ----
  767. ***************
  768. *** 448,459 ****
  769.         exit(1);
  770.      }
  771.   
  772. !    if (setgid(pwent->pw_gid)) {
  773.         fprintf(ErrFp, "Remind: Could not change gid to %d\n", pwent->pw_gid);
  774.         exit(1);
  775.      }
  776.   
  777. !    if (setuid(pwent->pw_uid)) {
  778.         fprintf(ErrFp, "Remind: Could not change uid to %d\n", pwent->pw_uid);
  779.         exit(1);
  780.      }
  781. --- 464,475 ----
  782.         exit(1);
  783.      }
  784.   
  785. !    if (!myuid && setgid(pwent->pw_gid)) {
  786.         fprintf(ErrFp, "Remind: Could not change gid to %d\n", pwent->pw_gid);
  787.         exit(1);
  788.      }
  789.   
  790. !    if (!myuid && setuid(pwent->pw_uid)) {
  791.         fprintf(ErrFp, "Remind: Could not change uid to %d\n", pwent->pw_uid);
  792.         exit(1);
  793.      }
  794. ***************
  795. *** 535,540 ****
  796. --- 551,566 ----
  797.      r=EvalExpr(&expr, &val);
  798.      if (r) {
  799.         fprintf(ErrFp, Err, ErrMsg[r]);
  800. +       return;
  801. +    }
  802. +    if (*varname == '$') {
  803. +       if (val.type != INT_TYPE) {
  804. +          fprintf(ErrFp, Err, ErrMsg[E_BAD_TYPE]);
  805. +      return;
  806. +       }
  807. +       r=SetSysVar(varname+1, val.v.val);
  808. +       if (r) fprintf(ErrFp, Err, ErrMsg[r]);
  809.         return;
  810.      }
  811.   
  812. *** ../p6/kall    Thu Apr 22 10:24:09 1993
  813. --- ./kall    Mon Jun 28 12:30:15 1993
  814. ***************
  815. *** 25,31 ****
  816.   
  817.   # NOTE:  You may have to modify the next line, since PS is non-portable.
  818.   # The 'awk' command picks out the process IDs to pass them on to kill.
  819. !     rprocs=`ps cx | awk '{if(prog == $NF) print $1}' prog=$1 -`
  820.       if [ "$rprocs" != "" ]; then
  821.           msg="1"
  822.           echo -n "${me}: Sending $signal signal to $1 process(es)"
  823. --- 25,31 ----
  824.   
  825.   # NOTE:  You may have to modify the next line, since PS is non-portable.
  826.   # The 'awk' command picks out the process IDs to pass them on to kill.
  827. !     rprocs=`ps cx | awk '{if(prog == $NF && $1 != mypid) print $1}' prog=$1 mypid=$$ -`
  828.       if [ "$rprocs" != "" ]; then
  829.           msg="1"
  830.           echo -n "${me}: Sending $signal signal to $1 process(es)"
  831. *** ../p6/main.c    Thu Apr 22 10:24:10 1993
  832. --- ./main.c    Mon Jun 28 12:39:37 1993
  833. ***************
  834. *** 30,38 ****
  835.   
  836.   #ifdef __MSDOS__
  837.   #include <dos.h>
  838. ! # ifdef __MSC__
  839. ! # include <time.h>
  840. ! # endif
  841.   #endif
  842.   
  843.   
  844. --- 30,36 ----
  845.   
  846.   #ifdef __MSDOS__
  847.   #include <dos.h>
  848. ! #include <time.h>
  849.   #endif
  850.   
  851.   
  852. ***************
  853. *** 92,98 ****
  854.      /* Not doing a calendar.  Do the regular remind loop */
  855.      DoReminders();
  856.   
  857. !    if (DebugFlag & DB_DUMP_VARS) DumpVarTable();
  858.   
  859.      if (!Hush) {
  860.         if (DestroyOmitContexts())
  861. --- 90,99 ----
  862.      /* Not doing a calendar.  Do the regular remind loop */
  863.      DoReminders();
  864.   
  865. !    if (DebugFlag & DB_DUMP_VARS) {
  866. !       DumpVarTable();
  867. !       DumpSysVarByName(NULL);
  868. !    }
  869.   
  870.      if (!Hush) {
  871.         if (DestroyOmitContexts())
  872. ***************
  873. *** 482,488 ****
  874.         if (err) return err;
  875.      }
  876.      if (!c) return E_EOLN;
  877. !    if (c != '_' && !isalpha(c)) return E_BAD_ID;
  878.      *out++ = c;
  879.      *out = 0;
  880.      len++;
  881. --- 483,489 ----
  882.         if (err) return err;
  883.      }
  884.      if (!c) return E_EOLN;
  885. !    if (c != '$' && c != '_' && !isalpha(c)) return E_BAD_ID;
  886.      *out++ = c;
  887.      *out = 0;
  888.      len++;
  889. ***************
  890. *** 1048,1058 ****
  891.      if ( (r=ParseToken(p, TokBuffer)) ) return r;
  892.   
  893.   /* Only allow RUN ON in top-level script */
  894. !    if (StriEq(TokBuffer, "ON")) {
  895.         if (TopLevel()) RunDisabled &= ~RUN_SCRIPT;
  896.      }
  897.   /* But allow RUN OFF anywhere */
  898. !    else if (StriEq(TokBuffer, "OFF"))
  899.         RunDisabled |= RUN_SCRIPT;
  900.      else return E_PARSE_ERR;
  901.   
  902. --- 1049,1059 ----
  903.      if ( (r=ParseToken(p, TokBuffer)) ) return r;
  904.   
  905.   /* Only allow RUN ON in top-level script */
  906. !    if (! StrCmpi(TokBuffer, "ON")) {
  907.         if (TopLevel()) RunDisabled &= ~RUN_SCRIPT;
  908.      }
  909.   /* But allow RUN OFF anywhere */
  910. !    else if (! StrCmpi(TokBuffer, "OFF"))
  911.         RunDisabled |= RUN_SCRIPT;
  912.      else return E_PARSE_ERR;
  913.   
  914. ***************
  915. *** 1088,1090 ****
  916. --- 1089,1164 ----
  917.      return OK;
  918.   }
  919.   
  920. + /***************************************************************/
  921. + /*                                                             */
  922. + /*  CalcMinsFromUTC                                            */
  923. + /*                                                             */
  924. + /*  Attempt to calculate the minutes from UTC for a specific   */
  925. + /*  date.                                                      */
  926. + /*                                                             */
  927. + /***************************************************************/
  928. + /* The array FoldArray[2][7] contains sample years which begin
  929. +    on the specified weekday.  For example, FoldArray[0][2] is a
  930. +    non-leapyear beginning on Wednesday, and FoldArray[1][5] is a
  931. +    leapyear beginning on Saturday.  Used to fold back dates which
  932. +    are too high for the standard Unix representation. 
  933. +    NOTE:  This implies that you cannot set BASE > 2001!!!!! */
  934. + static int FoldArray[2][7] = {
  935. +    {2001, 2002, 2003, 2009, 2010, 2005, 2006},
  936. +    {2024, 2008, 2020, 2004, 2016, 2000, 2012}
  937. + };
  938. + #ifdef HAVE_PROTOS
  939. + PUBLIC int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
  940. + #else
  941. + int CalcMinsFromUTC(jul, tim, mins, isdst)
  942. + int jul, tim, *mins, *isdst;
  943. + #endif
  944. + {
  945. + /* Convert jul and tim to an Unix tm struct */
  946. +    int yr, mon, day;
  947. +    struct tm local, utc, *temp;
  948. +    time_t loc_t, utc_t;
  949. +    FromJulian(jul, &yr, &mon, &day);
  950. + /* If the year is greater than 2037, some Unix machines have problems.
  951. +    Fold it back to a "similar" year and trust that the UTC calculations
  952. +    are still valid... */
  953. +    if (FoldYear && yr>2037) {
  954. +       jul = Julian(yr, 0, 1);
  955. +       yr = FoldArray[IsLeapYear(yr)][jul%7];
  956. +    }
  957. +    local.tm_sec = 0;
  958. +    local.tm_min = tim % 60;
  959. +    local.tm_hour = tim / 60;
  960. +    local.tm_mday = day;
  961. +    local.tm_mon = mon;
  962. +    local.tm_year = yr-1900;
  963. +    local.tm_isdst = -1;  /* We don't know whether or not dst is in effect */
  964.