home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume17 / remind / part02 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-19  |  19.9 KB  |  711 lines

  1. /***************************************************************/
  2. /*                                                             */
  3. /*  REMIND - version 2.3                                       */
  4. /*                                                             */
  5. /*  By David Skoll - 11 February 1991                          */
  6. /*                                                             */
  7. /*  (C) 1990, 1991 by David Skoll - all rights reserved        */
  8. /*                                                             */
  9. /***************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #ifndef UNIX
  16. #include <stdlib.h>
  17. #include <dos.h>
  18. #include <stdarg.h>
  19. #else
  20. #include <varargs.h>
  21. #include <sys/types.h>
  22. #ifdef SYSV
  23. #include <time.h>
  24. #else
  25. #include <sys/time.h>
  26. #endif
  27. #endif
  28.  
  29. #include "defines.h"
  30. #include "protos.h"
  31.  
  32.  
  33. /* List of months */
  34. char *MonthName[] = {
  35.    "January", "February", "March", "April", "May", "June",
  36.    "July", "August", "September", "October", "November", "December"
  37. };
  38.  
  39. /* List of weekdays */
  40. char *DayName[] = {
  41.    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
  42. };
  43.  
  44. /* List of recognized tokens - Keep them SORTED (case insensitive.) */
  45.  
  46. Token keywd[] = {
  47.    { "AFTER",     Skip_t,    3, 3 },
  48.    { "April",     Month_t,  3, 3 },
  49.    { "AT",        At_t,      0, 2 },
  50.    { "August",    Month_t,  7, 3 },
  51.    { "BANNER",    Banner_t, 0, 3 },
  52.    { "BEFORE",    Skip_t,    2, 3 },
  53.    { "CLEAR-OMIT-CONTEXT", Clear_t, 0, 3},
  54.    { "December",  Month_t,  11, 3 },
  55.    { "February",  Month_t,  1, 3 },
  56.    { "Friday",    WkDay_t,  4, 3 },
  57.    { "INCLUDE",   Include_t, 0, 3 },
  58.    { "January",   Month_t,  0, 3 },
  59.    { "July",      Month_t,  6, 3 },
  60.    { "June",      Month_t,  5, 3 },
  61.    { "March",     Month_t,  2, 3 },
  62.    { "May",       Month_t,  4, 3 },
  63.    { "Monday",    WkDay_t,  0, 3 },
  64.    { "MSG",       Msg_t,    0, 3 },
  65.    { "November",  Month_t,  10, 3 },
  66.    { "October",   Month_t,  9, 3 },
  67.    { "OMIT",      Omit_t,   0, 3 },
  68.    { "ONCE",      Once_t,   0, 3 },
  69.    { "POP-OMIT-CONTEXT", Pop_t, 0, 3},
  70.    { "PUSH-OMIT-CONTEXT", Push_t, 0, 3 },
  71.    { "REM",       Rem_t,    0, 3 },
  72.    { "RUN",       Run_t,    0, 3 },
  73.    { "Saturday",  WkDay_t,  5, 3 },
  74.    { "September", Month_t,  8, 3 },
  75.    { "SKIP",      Skip_t,    1, 3 },
  76.    { "Sunday",    WkDay_t,  6, 3 },
  77.    { "Thursday",  WkDay_t,  3, 3 },
  78.    { "Tuesday",   WkDay_t,  1, 3 },
  79.    { "UNTIL",      Until_t,   0, 3 },
  80.    { "Wednesday", WkDay_t,  2, 3 }
  81. };
  82.  
  83. /* List of days in month - Feb MUST be 29 for CheckDate to work. */
  84. int MonthDays[] = {
  85.    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  86. };
  87.  
  88. /* Index of the first day of each month.  First array is non-leap-year;
  89.    second is leap-year. */
  90. int MonthIndex[2][12] = {
  91.    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
  92.    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
  93. };
  94.  
  95. /* Global ommissions array */
  96. int FullOmitArray[FOMITSIZE];
  97.  
  98. /* Global partial omissions array */
  99. int PartOmitArray[POMITSIZE];
  100.  
  101. /* Define the working buffers */
  102. char Line[512], WorkBuf[512];
  103. char TmpBuf[512];
  104. char Fresh;  /* True if the contents of Line are fresh */
  105.  
  106. /* Global variables */
  107. char Purge, Debug, Verbose, IgRun, IgOnce, Next;
  108. int LastRun;
  109. char FileName[200];
  110. int CurLine;
  111. char Banner[200] = "Reminders for %w, %d%s %m, %y%o:";
  112. int NumEmitted, NumRem;
  113. int NumFullOmit, NumPartOmit;
  114. int JulianToday, RealToday;
  115. int CurYear, CurMon, CurDay;
  116. char QueueAts, PrintAts;
  117. int  NumAtsQueued;
  118. int Calendar, CalTime, CalWidth, SimpleCalendar;
  119.  
  120. static int JulFirst; /* Julian date of 1 Jan Current_year */
  121. static int FirstYear;
  122.  
  123. /***************************************************************/
  124. /*                                                             */
  125. /* Output                                                      */
  126. /* Output a string with line separators.                       */
  127. /*                                                             */
  128. /***************************************************************/
  129. #ifdef __STDC__
  130. void Output(char *s)
  131. #else
  132. void Output(s)
  133. char *s;
  134. #endif
  135. {
  136.    while (*s) {
  137.       if (*s == '\n') putchar('\\');
  138.       putchar(*s++);
  139.    }
  140.    putchar('\n');
  141. }
  142.  
  143. /***************************************************************/
  144. /*                                                             */
  145. /*  int MoveBack(...)                                          */
  146. /*                                                             */
  147. /*  Move back by specified number of days, skipping holidays   */
  148. /*  if the amound to move back is positive; otherwise, just    */
  149. /*  move back (-back) days, ignoring holidays.                 */
  150. /*                                                             */
  151. /***************************************************************/
  152. #ifdef __STDC__
  153. int MoveBack (int jul, int back, int omit)
  154. #else
  155. int MoveBack (jul, back, omit)
  156.      int jul;
  157.      int back;
  158.      int omit;
  159. #endif
  160. {
  161.    if (back <= 0) return jul+back;
  162.    
  163.    if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
  164.    while (back) {
  165.       jul--;
  166.       if (!IsOmitted(jul, omit)) back--;
  167.    }
  168.    return jul;
  169. }
  170.  
  171. /***************************************************************/
  172. /*                                                             */
  173. /*  int ProcessLine()                                          */
  174. /*                                                             */
  175. /*  Process the line in the "Line" buffer.                     */
  176. /*                                                             */
  177. /*  Normally returns 0.  Returns 1 only if we're in Calendar   */
  178. /*  mode and we hit a reminder which should be placed in the   */
  179. /*  calendar.                                                  */
  180. /*                                                             */
  181. /***************************************************************/
  182. #ifdef __STDC__
  183. int ProcessLine(void)
  184. #else
  185. int ProcessLine()
  186. #endif
  187. {
  188.    char *s = Line;
  189.    Token tok;
  190.    int i;
  191.  
  192.    while (isspace(*s)) s++;
  193.  
  194.    /* Skip comments and blank lines */
  195.    if (*s == '#' || *s == 0) {
  196.       if (Purge && TopLevel()) Output(Line);
  197.       return 0;
  198.    }
  199.  
  200.    tok = ParseToken(&s);
  201.    switch(tok.type) {
  202.       case Push_t:   PushOmitContext();
  203.                       if (Purge && TopLevel()) Output(Line);
  204.              break;
  205.  
  206.       case Pop_t:    PopOmitContext();
  207.                       if (Purge && TopLevel()) Output(Line);
  208.              break;
  209.  
  210.       case Clear_t:  ClearOmitContext();
  211.                       if (Purge && TopLevel()) Output(Line);
  212.              break;
  213.  
  214.       case Banner_t: DoBanner(&s);
  215.              if (Purge && TopLevel()) Output(Line);
  216.              break;
  217.  
  218.       case Omit_t:   i = DoGlobalOmit(&s);
  219.              if (Calendar) return i;
  220.              if (Purge && TopLevel())
  221.             if (i == -1) Eprint("Purged '%s'\n", Line);
  222.             else       Output(Line);
  223.              break;
  224.  
  225.       case Rem_t:    i = DoRem(&s);
  226.                  if (Calendar) return i;
  227.              if (Purge && TopLevel())
  228.             if (i < 0) Eprint("Purged '%s'\n", Line);
  229.             else       Output(Line);
  230.              NumRem++;
  231.              break;
  232.  
  233.       case Include_t: if (Purge && TopLevel()) Output(Line);
  234.               DoInclude(&s);
  235.               break;
  236.  
  237.       default:       if (Purge && TopLevel()) Output(Line);
  238.              Eprint("Unknown command '%s'\n", tok.str);
  239.    }
  240.    return 0;
  241. }
  242.  
  243. /***************************************************************/
  244. /*                                                             */
  245. /*  Standard: void Eprint(const char *f, ...)                  */
  246. /*  Unix: void Eprint(va_alist)                                */
  247. /*                                                             */
  248. /*  Prints an error message.                                   */
  249. /*                                                             */
  250. /***************************************************************/
  251. #ifndef UNIX
  252. void Eprint(const char *f, ...)
  253. #else
  254. /*VARARGS0*/
  255. void Eprint(va_alist)
  256. va_dcl
  257. #endif
  258. {
  259. #ifndef UNIX
  260.    va_list args;
  261. #else
  262.   va_list args;
  263.   char *f;
  264. #endif
  265.  
  266. #ifndef UNIX
  267.    if (Verbose & Fresh) {
  268. #else
  269.   if (Verbose & Fresh) {
  270. #endif
  271.       fprintf(stderr, "\n--- %s\n", Line);
  272.       Fresh = 0;
  273.    }
  274.    if (Verbose) fprintf(stderr, "--- ");
  275.    fprintf(stderr, "%s(%d): ", FileName, CurLine);
  276. #ifndef UNIX
  277.    va_start(args, f);
  278. #else
  279.    va_start(args);
  280.    f = va_arg(args, char *);
  281. #endif
  282.    vfprintf(stderr, f, args);
  283. #ifdef UNIX
  284.    va_end(args);
  285. #endif
  286. }
  287.  
  288. /***************************************************************/
  289. /*                                                             */
  290. /*  int DoBanner(char **s)                                     */
  291. /*                                                             */
  292. /*  Sets the "Reminders for..." banner.                        */
  293. /*                                                             */
  294. /***************************************************************/
  295. #ifdef __STDC__
  296. int DoBanner(char **s)
  297. #else
  298. int DoBanner(s)
  299.      char **s;
  300. #endif
  301. {
  302.    if (Purge || Next) return 0;
  303.    while (isspace(**s)) (*s)++;
  304.    strcpy(Banner, *s);
  305.    if (! *Banner)
  306.    {
  307.       if (Debug) Eprint("Empty banner.\n");
  308.       strcpy(Banner, "Reminders for %w, %d%s %m, %y%o:");
  309.    }
  310.    if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
  311.    return 0;
  312. }
  313.  
  314. /***************************************************************/
  315. /*                                                             */
  316. /* int CheckDate(int d, int m, int y)                          */
  317. /*                                                             */
  318. /* Checks that a date is valid - returns 0 for OK, 1 for BAD.  */
  319. /*                                                             */
  320. /* If y=-1, just checks that month & day are valid, giving     */
  321. /* benefit of the doubt for February 29.                       */
  322. /*                                                             */
  323. /* No point in checking if month is valid - months are named   */
  324. /* and thus a month out of range can never be entered into     */
  325. /* the system.                                                 */
  326. /*                                                             */
  327. /***************************************************************/
  328. #ifdef __STDC__
  329. int CheckDate(int d, int m, int y)
  330. #else
  331. int CheckDate(d, m, y)
  332.      int d;
  333.      int m;
  334.      int y;
  335. #endif
  336. {
  337.    if (y == -1)
  338.       if (d > 0 && d <= MonthDays[m]) return 0; else return 1;
  339.    else
  340.       if (y < BASE || y > BASE + 85) return 1;
  341.       else if (d > 0 && d <= DaysInMonth(m, y)) return 0; else return 1;
  342. }
  343.  
  344. /***************************************************************/
  345. /*                                                             */
  346. /*  int strncmpi(char *s1, char*s1, int n)                     */
  347. /*                                                             */
  348. /*  Compares first n chars of string ignoring case.            */
  349. /*                                                             */
  350. /***************************************************************/
  351. #ifdef __STDC__
  352. int strncmpi(char *s1, char *s2, int n)
  353. #else
  354. int strncmpi(s1, s2, n)
  355.      char *s1;
  356.      char *s2;
  357.      int n;
  358. #endif
  359. {
  360.    register int u1, u2;
  361.    while (n)
  362.    {
  363.       if (!*s1 || !*s2) return upper(*s1) - upper(*s2);
  364.       u1 = upper(*s1);
  365.       u2 = upper(*s2);
  366.       if (u1 != u2) return (u1 - u2);
  367.       n--;
  368.       s1++;
  369.       s2++;
  370.    }
  371.    return 0;
  372. }
  373.  
  374. /***************************************************************/
  375. /*                                                             */
  376. /*  ParseToken(char **s);                                      */
  377. /*                                                             */
  378. /*  Parse the next token and adjust the character pointer.     */
  379. /*                                                             */
  380. /***************************************************************/
  381. #ifdef __STDC__
  382. Token ParseToken(char **s)
  383. #else
  384. Token ParseToken(s)
  385.      char **s;
  386. #endif
  387. {
  388.  
  389.    Token tok;
  390.    char *t = TmpBuf;
  391.    int i, h, m;
  392.    int len;
  393.    int top, bot, mid;
  394.    char *colon = (char *) NULL;
  395.  
  396.    *t = 0;
  397.    tok.str = TmpBuf;
  398.  
  399.    /* Skip blank space */
  400.    while (isspace(**s)) (*s)++;
  401.  
  402.    /* End of line ? */
  403.    if (**s == 0) {
  404.       tok.type = Eol_t;
  405.       tok.val = 0;
  406.       return tok;
  407.    }
  408.  
  409.    /* Grab a space-delimited token */
  410.    while (**s != 0 && !isspace(**s)) {
  411.       *t++ = **s;
  412.       (*s)++;
  413.    }
  414.    *t = 0;
  415.    len = t - TmpBuf;
  416.  
  417.    /* Check if it's a built-in token */
  418.    if (*TmpBuf >= 'A' && *TmpBuf <= 'z') {
  419.       top = sizeof(keywd)/sizeof(keywd[0])-1;
  420.       bot = 0;
  421.       mid = (top+bot)/2;
  422.       while (top >= bot && 
  423.               (i=strncmpi(TmpBuf, keywd[mid].str, MAX(len, (int) keywd[mid].len)))) {
  424.          if (i>0) bot = mid+1; else top = mid-1;
  425.      mid = (top+bot)/2;
  426.       }
  427.       if (top >= bot) return keywd[mid];
  428.    }
  429.  
  430.    tok.type = Unknown_t;
  431.  
  432.    /* If it's a comment, ignore the rest of the line */
  433.    if (*(tok.str) == '#') {
  434.       tok.type = Eol_t;
  435.       return tok;
  436.    }
  437.  
  438.    /* Check if it's a number (optional + / - / * ahead of number */
  439.    t = TmpBuf;
  440.    i = 1;  /* multiplication factor */
  441.    if (isdigit(*t)) {
  442.       while (*++t){
  443.          if (*t == ':') {
  444.             if (colon) return tok; else colon = t;
  445.          } else if (!isdigit(*t)) return tok;
  446.       }
  447.    }
  448.    else if (*t == '+' || *t == '-' || *t == '*') {
  449.       /* Check if it's a "++" or a "--" */
  450.       if ((*t == '+' && *(t+1) == '+') || (*t == '-' && *(t+1) == '-')) {
  451.          i = -1;
  452.          t++;
  453.       }
  454.       if (!isdigit(*++t)) return tok;
  455.       while (*++t) if (!isdigit(*t)) return tok;
  456.    }
  457.    else return tok;
  458.  
  459.    /* OK, here we have a number - either a pure number, a delta, a time,
  460.       back or a repeat marker */
  461.  
  462.    if (colon) { /* got a time here */
  463.       h = atoi(TmpBuf);
  464.       m = atoi(colon + 1);
  465.       if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
  466.          tok.type = Time_t;
  467.      tok.val = 60*h+m;
  468.       }
  469.       else return tok;
  470.    }
  471.    else if (*TmpBuf == '+') {
  472.       tok.type = Delta_t;
  473.       if (i == 1) tok.val = atoi(TmpBuf + 1);
  474.       else        tok.val = -atoi(TmpBuf + 2);
  475.    }
  476.    else if (*TmpBuf == '-') {
  477.       tok.type = Back_t;
  478.       if (i == 1) tok.val = atoi(TmpBuf + 1);
  479.       else        tok.val = -atoi(TmpBuf + 2);
  480.    }
  481.    else if (*TmpBuf == '*') {
  482.       tok.type = Repeat_t;
  483.       tok.val = atoi(TmpBuf + 1);
  484.    }
  485.    else {
  486.       tok.val = atoi(TmpBuf);
  487.       if (tok.val > 0 && tok.val <= 31) tok.type = Day_t;
  488.       else if (tok.val >= 100) tok.type = Year_t;
  489.       else {
  490.      tok.type = Year_t;
  491.      tok.val += 1900;
  492.       }
  493.    }
  494.    return tok;
  495. }
  496.  
  497. /***************************************************************/
  498. /*                                                             */
  499. /*  int FromJulian(int jul, int *d, int *m, int *y)            */
  500. /*                                                             */
  501. /*  Convert a date from Julian to normal form.  Returns        */
  502. /*  0 if conversion ok, -1 otherwise.                          */
  503. /*                                                             */
  504. /***************************************************************/
  505. #ifdef __STDC__
  506. int FromJulian(int jul, int *d, int *m, int *y)
  507. #else
  508. int FromJulian(jul, d, m, y)
  509.      int jul;
  510.      int *d;
  511.      int *m;
  512.      int *y;
  513. #endif
  514. {
  515.    int t;
  516.  
  517.    if (jul < 0) return -1;
  518.  
  519.    if (jul >= JulFirst && JulFirst != -1) {
  520.       *y = FirstYear;
  521.       jul -= JulFirst;
  522.    } else *y = BASE;
  523.  
  524.    *m = 0;
  525.  
  526.    t = DaysInYear(*y);
  527.    while (jul >= t) {
  528.       jul -= t;
  529.       (*y)++;
  530.       t = DaysInYear(*y);
  531.    }
  532.  
  533.    t = DaysInMonth(*m, *y);
  534.    while (jul >= t) {
  535.       jul -= t;
  536.       (*m)++;
  537.       t = DaysInMonth(*m, *y);
  538.    }
  539.    *d = jul + 1;
  540.    return 0;
  541. }
  542.  
  543. /***************************************************************/
  544. /*                                                             */
  545. /*  int Julian(d, m, y)                                        */
  546. /*                                                             */
  547. /*  Converts a date to the number of days after Jan 1 1990.    */
  548. /*  Returns -1 if date is before Jan 1 1990.                   */
  549. /*                                                             */
  550. /***************************************************************/
  551. #ifdef __STDC__
  552. int Julian(int d, int m, int y)
  553. #else
  554. int Julian(d, m, y)
  555.      int d;
  556.      int m;
  557.      int y;
  558. #endif
  559. {
  560.    int iy;
  561.    int jul = 0;
  562.  
  563.    if (y < BASE) return -1;
  564.    if (JulFirst == -1 || y < FirstYear)
  565.       for (iy = BASE; iy < y; iy++) jul += DaysInYear(iy);
  566.    else {
  567.       jul = JulFirst;
  568.       for (iy = FirstYear; iy < y; iy++) jul += DaysInYear(iy);
  569.    }
  570.  
  571.    return jul + MonthIndex[IsLeapYear(y)][m] + d - 1;
  572. }
  573.  
  574. /***************************************************************/
  575. /*                                                             */
  576. /*  int FindTodaysDate(int *d, int *m, int *y)                 */
  577. /*                                                             */
  578. /*  Obtains today's date.  Returns Julian date or -1 for       */
  579. /*  failure.                                                   */
  580. /*                                                             */
  581. /***************************************************************/
  582. #ifdef __STDC__
  583. int FindTodaysDate(int *d, int *m, int *y)
  584. #else
  585. int FindTodaysDate(d, m, y)
  586.      int *d;
  587.      int *m;
  588.      int *y;
  589. #endif
  590. {
  591. #ifndef UNIX
  592.    struct dosdate_t buf;
  593.  
  594.    _dos_getdate(&buf);
  595.  
  596.    *d = buf.day;
  597.    *m = buf.month - 1;
  598.    *y = buf.year;
  599. #else
  600.   time_t tloc;
  601.   struct tm *t;
  602.  
  603.    (void) time(&tloc);
  604.    t = localtime(&tloc);
  605.  
  606.    *d = t->tm_mday;
  607.    *m = t->tm_mon;
  608.    *y = t->tm_year + 1900;
  609.  
  610. #endif
  611.    if (CheckDate(*d, *m, *y)) return -1;
  612.    return Julian(*d, *m, *y);
  613. }
  614. /***************************************************************/
  615. /***************************************************************/
  616. /**                                                           **/
  617. /** MAIN PROGRAM ENTRY POINT                                  **/
  618. /**                                                           **/
  619. /***************************************************************/
  620. /***************************************************************/
  621. #ifdef __STDC__
  622. int main(int argc, char *argv[])
  623. #else
  624. int main(argc, argv)
  625.      int argc;
  626.      char *argv[];
  627. #endif
  628. {
  629. #ifdef UNIX
  630. #ifdef SYSV
  631.    pid_t pid;
  632. #else
  633.    int pid;
  634. #endif
  635. #endif
  636.  
  637.    NumEmitted = 0;
  638.    NumRem = 0;
  639.    JulFirst = -1;  /* Initialize JulFirst so it's not used by Julian */
  640.       
  641.    JulianToday = FindTodaysDate(&CurDay, &CurMon, &CurYear);
  642.    if (JulianToday < 0) {
  643.       fprintf(stderr, "remind: System date is illegal - Ensure that year is at least %d.\n", BASE);
  644.       return 1;
  645.    }
  646.    
  647.    RealToday = JulianToday;
  648.    
  649.    initialize(argc, argv);
  650.  
  651.    FirstYear = CurYear;
  652.    JulFirst = Julian(1, 0, CurYear);  /* Do expensive computation once */
  653.    FirstYear = CurYear;
  654.  
  655.    if (Calendar) {
  656.       DoCalendar();
  657.       return 0;
  658.    }
  659.    while (1) {
  660.       if (ReadLine()) break;
  661.       ProcessLine();
  662.    }
  663. /* Get rid of any spurious OMIT contexts */
  664.    FreeStackedOmits();
  665.    if (NumEmitted == 0 && NumAtsQueued == 0 && !Purge && !Debug && !Next) 
  666.        printf("No reminders.\n");
  667. #ifdef UNIX
  668.    if (NumEmitted == 0 && NumAtsQueued != 0 && !Purge && !Debug)
  669.        printf("%d reminder%s queued for later today.\n", NumAtsQueued,
  670.               (NumAtsQueued == 1) ? "" : "s");
  671.  
  672.    fflush(stdout); /* Flush output so we don't get 2 copies when directing */
  673.            /* stdout to a file. */
  674.  
  675.    if (NumAtsQueued) {
  676.       pid = fork();
  677.       if (pid == -1) Eprint("Can't fork to perform ATs!\n");
  678.       if (pid != 0) return 0;
  679.       HandleQueuedAts();
  680.    }
  681. #endif
  682.    return 0;
  683. }
  684. /***************************************************************/
  685. /*                                                             */
  686. /* SystemTime                                                  */
  687. /*                                                             */
  688. /* Returns current system time in seconds past midnight.       */
  689. /*                                                             */
  690. /***************************************************************/
  691. #ifdef __STDC__
  692. long SystemTime(void)
  693. #else
  694. long SystemTime()
  695. #endif
  696. {
  697. #ifdef UNIX
  698.   time_t tloc;
  699.   struct tm *t;
  700.  
  701.    (void) time(&tloc);
  702.    t = localtime(&tloc);
  703.    return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L + (long) t->tm_sec;
  704.  
  705. #else
  706.    struct dostime_t tloc;
  707.    _dos_gettime(&tloc);
  708.    return (long) tloc.hour * 3600L + (long) tloc.minute * 60L + (long) tloc.second;
  709. #endif
  710. }
  711.