home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / misc / hwgrcs / src / rcs.rcsfiles / maketime.c,v < prev    next >
Encoding:
Text File  |  1995-06-25  |  20.9 KB  |  843 lines

  1. head    5.3;
  2. branch    5.3.1;
  3. access;
  4. symbols
  5.     HWGRCSP12F:5.3.1.2
  6.     HWGRCSP11F:5.3.1.2
  7.     HWGRCSP10F:5.3.1.2
  8.     HWGRCSP9:5.3.1.2
  9.     HWGRCSP8F:5.3.1.2
  10.     HWGRCSP7F:5.3.1.2
  11.     HWGRCSP6F:5.3.1.2
  12.     HWGRCSP5F:5.3.1.1
  13.     HWGRCSp4:5.3.1.1
  14.     HWGRCSp3:5.3.1
  15.     HWGRCS_Fish:5.3.1
  16.     HWGRCS:5.3.1;
  17. locks; strict;
  18. comment    @ * @;
  19.  
  20.  
  21. 5.3
  22. date    91.08.19.03.13.55;    author eggert;    state Exp;
  23. branches
  24.     5.3.1.1;
  25. next    ;
  26.  
  27. 5.3.1.1
  28. date    93.01.18.14.37.32;    author heinz;    state Exp;
  29. branches;
  30. next    5.3.1.2;
  31.  
  32. 5.3.1.2
  33. date    93.12.04.11.06.37;    author heinz;    state Exp;
  34. branches;
  35. next    ;
  36.  
  37.  
  38. desc
  39. @Checked in with -k 16.jan.93 HWG
  40. @
  41.  
  42.  
  43. 5.3
  44. log
  45. @checked in with -k by heinz at 1993/01/17 01:53:17
  46. @
  47. text
  48. @#
  49. /*
  50.  * MAKETIME        derive 32-bit time value from TM structure.
  51.  *
  52.  * Usage:
  53.  *    int zone;    Minutes west of GMT, or
  54.  *            48*60 for localtime
  55.  *    time_t t;
  56.  *    struct tm *tp;    Pointer to TM structure from <time.h>
  57.  *    t = maketime(tp,zone);
  58.  *
  59.  * Returns:
  60.  *    -1 if failure; parameter out of range or nonsensical.
  61.  *    else time-value.
  62.  * Notes:
  63.  *    This code is quasi-public; it may be used freely in like software.
  64.  *    It is not to be sold, nor used in licensed software without
  65.  *    permission of the author.
  66.  *    For everyone's benefit, please report bugs and improvements!
  67.  *     Copyright 1981 by Ken Harrenstien, SRI International.
  68.  *    (ARPANET: KLH @@ SRI)
  69.  */
  70. /* $Log: maketime.c,v $
  71.  * Revision 5.3  1991/08/19  03:13:55  eggert
  72.  * Add setfiledate, str2time, TZ_must_be_set.
  73.  *
  74.  * Revision 5.2  1990/11/01  05:03:30  eggert
  75.  * Remove lint.
  76.  *
  77.  * Revision 5.1  1990/10/04  06:30:13  eggert
  78.  * Calculate the GMT offset of 'xxx LT' as of xxx, not as of now.
  79.  * Don't assume time_t is 32 bits.  Fix bugs near epoch and near end of time.
  80.  *
  81.  * Revision 5.0  1990/08/22  08:12:38  eggert
  82.  * Switch to GMT and fix the bugs exposed thereby.
  83.  * Permit dates past 1999/12/31.  Ansify and Posixate.
  84.  *
  85.  * Revision 1.8  88/11/08  13:54:53  narten
  86.  * allow negative timezones (-24h <= x <= 24h)
  87.  * 
  88.  * Revision 1.7  88/08/28  14:47:52  eggert
  89.  * Allow cc -R.  Remove unportable "#endif XXX"s.
  90.  * 
  91.  * Revision 1.6  87/12/18  17:05:58  narten
  92.  * include rcsparam.h
  93.  * 
  94.  * Revision 1.5  87/12/18  11:35:51  narten
  95.  * maketime.c: fixed USG code - you have tgo call "tzset" in order to have
  96.  * "timezone" set. ("localtime" calls it, but it's probably better not to 
  97.  * count on "localtime" having been called.)
  98.  * 
  99.  * Revision 1.4  87/10/18  10:26:57  narten
  100.  * Updating version numbers. Changes relative to 1.0 are actually 
  101.  * relative to 1.2
  102.  * 
  103.  * Revision 1.3  87/09/24  13:58:45  narten
  104.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  105.  * warnings)
  106.  * 
  107.  * Revision 1.2  87/03/27  14:21:48  jenkins
  108.  * Port to suns
  109.  * 
  110.  * Revision 1.2  83/12/05  10:12:56  wft
  111.  * added cond. compilation for USG Unix; long timezone;
  112.  * 
  113.  * Revision 1.1  82/05/06  11:38:00  wft
  114.  * Initial revision
  115.  * 
  116.  */
  117.  
  118.  
  119. #include "rcsbase.h"
  120.  
  121. libId(maketId, "$Id: maketime.c,v 5.3 1991/08/19 03:13:55 eggert Exp $")
  122.  
  123. static struct tm const *time2tm P((time_t));
  124.  
  125. #define given(v) (0 <= (v)) /* Negative values are unspecified. */
  126.  
  127. static int const daytb[] = {
  128.     /* # days in year thus far, indexed by month (0-12!!) */
  129.     0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
  130. };
  131.  
  132.     static time_t
  133. maketime(atm,zone)
  134.     struct tm const *atm;
  135.     int zone;
  136. {
  137.     register struct tm const *tp;
  138.     register int i;
  139.     int year, yday, mon, day, hour, min, sec, leap, localzone;
  140.     int attempts;
  141.     time_t t, tres;
  142.  
  143.     attempts = 2;
  144.     localzone = zone==48*60;
  145.     tres = -1;
  146.     year = mon = day = 0;  /* Keep lint happy.  */
  147.  
  148.     do {
  149.  
  150.     if (localzone || !given(atm->tm_year)) {
  151.         if (tres == -1)
  152.             if ((tres = time((time_t*)0))  ==  -1)
  153.                 return -1;
  154.         tp = time2tm(tres);
  155.         /* Get breakdowns of default time, adjusting to zone. */
  156.         year = tp->tm_year;        /* Use to set up defaults */
  157.         yday = tp->tm_yday;
  158.         mon = tp->tm_mon;
  159.         day = tp->tm_mday;
  160.         hour = tp->tm_hour;
  161.         min = tp->tm_min;
  162.         if (localzone) {
  163.             tp = localtime(&tres);
  164.             zone =
  165.             min - tp->tm_min + 60*(
  166.                 hour - tp->tm_hour + 24*(
  167.                     /* If years differ, it's by one day. */
  168.                         year - tp->tm_year
  169.                     ?    year - tp->tm_year
  170.                     :    yday - tp->tm_yday));
  171.         }
  172.         /* Adjust the default day, month and year according to zone.  */
  173.         if ((min -= zone) < 0) {
  174.             if (hour-(59-min)/60 < 0  &&  --day <= 0) {
  175.             if (--mon < 0) {
  176.                 --year;
  177.                 mon = 11;
  178.             }
  179.             day  =  daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3));
  180.             }
  181.         } else
  182.             if (
  183.               24 <= hour+min/60  &&
  184.               daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3))  <  ++day
  185.             ) {
  186.                 if (11 < ++mon) {
  187.                     ++year;
  188.                     mon = 0;
  189.                 }
  190.                 day = 1;
  191.             }
  192.     }
  193.     if (zone < -24*60  ||  24*60 < zone)
  194.         return -1;
  195.  
  196.  
  197. #ifdef DEBUG
  198. printf("first YMD: %d %d %d\n",year,mon,day);
  199. #endif
  200.     tp = atm;
  201.  
  202.     /* First must find date, using specified year, month, day.
  203.      * If one of these is unspecified, it defaults either to the
  204.      * current date (if no more global spec was given) or to the
  205.      * zero-value for that spec (i.e. a more global spec was seen).
  206.      * Reject times that do not fit in time_t,
  207.      * without assuming that time_t is 32 bits or is signed.
  208.      */
  209.     if (given(tp->tm_year))
  210.       {
  211.         year = tp->tm_year;
  212.         mon = 0;        /* Since year was given, default */
  213.         day = 1;        /* for remaining specs is zero */
  214.       }
  215.     if (year < 69)            /* 1969/12/31 OK in some timezones.  */
  216.         return -1;        /* ERR: year out of range */
  217.     leap   =   !(year&3)  &&  (year%100 || !((year+300)%400));
  218.     year -= 70;            /* UNIX time starts at 1970 */
  219.  
  220.     /*
  221.      * Find day of year.
  222.      */
  223.     {
  224.         if (given(tp->tm_mon))
  225.           {    mon = tp->tm_mon;    /* Month was specified */
  226.             day = 1;        /* so set remaining default */
  227.           }
  228.         if (11 < (unsigned)mon)
  229.             return -1;        /* ERR: bad month */
  230.         if (given(tp->tm_mday)) day = tp->tm_mday;
  231.         if(day < 1
  232.          || (((daytb[mon+1]-daytb[mon]) < day)
  233.             && (day!=29 || mon!=1 || !leap) ))
  234.                 return -1;    /* ERR: bad day */
  235.         yday = daytb[mon]    /* Add # of days in months so far */
  236.           + ((leap        /* Leap year, and past Feb?  If */
  237.               && mon>1)? 1:0)    /* so, add leap day for this year */
  238.           + day-1;        /* And finally add # days this mon */
  239.  
  240.     }
  241.     if (leap+365 <= (unsigned)yday)
  242.         return -1;        /* ERR: bad YDAY */
  243.  
  244.     if (year < 0) {
  245.         if (yday != 364)
  246.         return -1;        /* ERR: too early */
  247.         t = -1;
  248.     } else {
  249.         tres = year*365;        /* Get # days of years so far */
  250.         if (tres/365 != year)
  251.             return -1;        /* ERR: overflow */
  252.         t = tres
  253.         + ((year+1)>>2)        /* plus # of leap days since 1970 */
  254.         + yday;            /* and finally add # days this year */
  255.         if (t+4 < tres)
  256.             return -1;        /* ERR: overflow */
  257.     }
  258.     tres = t;
  259.  
  260.     if (given(i = tp->tm_wday)) /* Check WDAY if present */
  261.         if (i != (tres+4)%7)    /* 1970/01/01 was Thu = 4 */
  262.             return -1;    /* ERR: bad WDAY */
  263.  
  264. #ifdef DEBUG
  265. printf("YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
  266. #endif
  267.     /*
  268.      * Now determine time.  If not given, default to zeros
  269.      * (since time is always the least global spec)
  270.      */
  271.     tres *= 86400L;            /* Get # seconds (24*60*60) */
  272.     if (tres/86400L != t)
  273.         return -1;        /* ERR: overflow */
  274.     hour = min = sec = 0;
  275.     if (given(tp->tm_hour)) hour = tp->tm_hour;
  276.     if (given(tp->tm_min )) min  = tp->tm_min;
  277.     if (given(tp->tm_sec )) sec  = tp->tm_sec;
  278.     if (60 <= (unsigned)min  ||  60 < (unsigned)sec)
  279.         return -1;        /* ERR: MS out of range */
  280.     if (24 <= (unsigned)hour)
  281.         if(hour != 24 || (min+sec) !=0)    /* Allow 24:00 */
  282.             return -1;    /* ERR: H out of range */
  283.  
  284.     t = tres;
  285.     tres += sec + 60L*(zone + min + 60*hour);
  286.  
  287. #ifdef DEBUG
  288. printf("HMS: %d %d %d T=%ld\n",hour,min,sec,tres);
  289. #endif
  290.  
  291.     if (!localzone)            /* check for overflow */
  292.         return (year<0 ? (tres<0||86400L<=tres) : tres<t)  ?  -1  :  tres;
  293.  
  294.     /* Check results; LT may have had a different GMT offset back then.  */
  295.     tp = localtime(&tres);
  296.     if (given(atm->tm_sec)  &&  atm->tm_sec != tp->tm_sec)
  297.         return -1; /* If seconds don't match, we're in trouble.  */
  298.     if (!(
  299.         given(atm->tm_min)  &&  atm->tm_min != tp->tm_min  ||
  300.         given(atm->tm_hour)  &&  atm->tm_hour != tp->tm_hour  ||
  301.         given(atm->tm_mday)  &&  atm->tm_mday != tp->tm_mday  ||
  302.         given(atm->tm_mon)  &&  atm->tm_mon != tp->tm_mon  ||
  303.         given(atm->tm_year)  &&  atm->tm_year != tp->tm_year
  304.     ))
  305.         return tres; /* Everything matches.  */
  306.  
  307.     } while (--attempts);
  308.  
  309.     return -1;
  310. }
  311.  
  312. /*
  313. * Convert Unix time to struct tm format.
  314. * Use Coordinated Universal Time (UTC) if version 5 or newer;
  315. * use local time otherwise.
  316. */
  317.     static struct tm const *
  318. time2tm(unixtime)
  319.     time_t unixtime;
  320. {
  321.     struct tm const *tm;
  322. #    if TZ_must_be_set
  323.         static char const *TZ;
  324.         if (!TZ  &&  !(TZ = getenv("TZ")))
  325.             faterror("TZ is not set");
  326. #    endif
  327.     if (!(tm  =  (RCSversion<VERSION(5) ? localtime : gmtime)(&unixtime)))
  328.         faterror("UTC is not available; perhaps TZ is not set?");
  329.     return tm;
  330. }
  331.  
  332. /*
  333. * Convert Unix time to RCS format.
  334. * For compatibility with older versions of RCS,
  335. * dates before AD 2000 are stored without the leading "19".
  336. */
  337.     void
  338. time2date(unixtime,date)
  339.     time_t unixtime;
  340.     char date[datesize];
  341. {
  342.     register struct tm const *tm = time2tm(unixtime);
  343.     VOID sprintf(date, DATEFORM,
  344.         tm->tm_year  +  (tm->tm_year<100 ? 0 : 1900),
  345.         tm->tm_mon+1, tm->tm_mday,
  346.         tm->tm_hour, tm->tm_min, tm->tm_sec
  347.     );
  348. }
  349.  
  350.  
  351.  
  352.     static time_t
  353. str2time(source)
  354.     char const *source;
  355. /* Parse a free-format date in SOURCE, yielding a Unix format time.  */
  356. {
  357.     int zone;
  358.     time_t unixtime;
  359.     struct tm parseddate;
  360.  
  361.     if (!partime(source, &parseddate, &zone))
  362.         faterror("can't parse date/time: %s", source);
  363.     if ((unixtime = maketime(&parseddate, zone))  ==  -1)
  364.         faterror("bad date/time: %s", source);
  365.     return unixtime;
  366. }
  367.  
  368.     void
  369. str2date(source, target)
  370.     char const *source;
  371.     char target[datesize];
  372. /* Parse a free-format date in SOURCE, convert it
  373.  * into RCS internal format, and store the result into TARGET.
  374.  */
  375. {
  376.     time2date(str2time(source), target);
  377. }
  378.  
  379.     int
  380. setfiledate(file, date)
  381.     char const *file, date[datesize];
  382. /* Set the access and modification time of FILE to DATE.  */
  383. {
  384.     static struct utimbuf times; /* static so unused fields are zero */
  385.     char datebuf[datesize];
  386.  
  387.     if (!date)
  388.         return 0;
  389.     times.actime = times.modtime = str2time(date2str(date, datebuf));
  390.     return utime(file, ×);
  391. }
  392. @
  393.  
  394.  
  395. 5.3.1.1
  396. log
  397. @Start of the AMIGA port of RCS 5.6. I call it HWGRCS now ;^)
  398. @
  399. text
  400. @d20 1
  401. a20 1
  402.  *    Copyright 1981 by Ken Harrenstien, SRI International.
  403. d40 1
  404. a40 1
  405.  *
  406. d43 1
  407. a43 1
  408.  *
  409. d46 1
  410. a46 1
  411.  *
  412. d49 1
  413. a49 1
  414.  * "timezone" set. ("localtime" calls it, but it's probably better not to
  415. d51 1
  416. a51 1
  417.  *
  418. d53 1
  419. a53 1
  420.  * Updating version numbers. Changes relative to 1.0 are actually
  421. d55 1
  422. a55 1
  423.  *
  424. d57 1
  425. a57 1
  426.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf
  427. d59 1
  428. a59 1
  429.  *
  430. d62 1
  431. a62 1
  432.  *
  433. d65 1
  434. a65 1
  435.  *
  436. d68 1
  437. a68 1
  438.  *
  439. d99 1
  440. a99 1
  441.     year = mon = day = 0;  /* Keep lint happy.    */
  442. d132 1
  443. a132 1
  444.             day  =    daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3));
  445. d168 1
  446. a168 1
  447.     if (year < 69)                  /* 1969/12/31 OK in some timezones.  */
  448. d189 1
  449. a189 1
  450.           + ((leap              /* Leap year, and past Feb?  If */
  451. d206 2
  452. a207 2
  453.         + ((year+1)>>2)         /* plus # of leap days since 1970 */
  454.         + yday;         /* and finally add # days this year */
  455. d214 1
  456. a214 1
  457.         if (i != (tres+4)%7)    /* 1970/01/01 was Thu = 4 */
  458. d221 1
  459. a221 1
  460.      * Now determine time.    If not given, default to zeros
  461. d224 1
  462. a224 1
  463.     tres *= 86400L;         /* Get # seconds (24*60*60) */
  464. d234 1
  465. a234 1
  466.         if(hour != 24 || (min+sec) !=0) /* Allow 24:00 */
  467. d244 1
  468. a244 1
  469.     if (!localzone)                 /* check for overflow */
  470. a275 5
  471. #ifdef AMIGA
  472.         static char const *tz;
  473.         if (!tz  &&  !(tz = getenv("TZ")))
  474.             faterror("TZ is not set");
  475. #else
  476. a278 1
  477. #endif
  478. d297 1
  479. a297 1
  480.         tm->tm_year  +    (tm->tm_year<100 ? 0 : 1900),
  481. @
  482.  
  483.  
  484. 5.3.1.2
  485. log
  486. @Took out the AMIGA define. Not needed with _STRICT_ANSI.
  487. @
  488. text
  489. @d3 1
  490. a3 1
  491.  * MAKETIME             derive 32-bit time value from TM structure.
  492. d6 5
  493. a10 5
  494.  *      int zone;       Minutes west of GMT, or
  495.  *                      48*60 for localtime
  496.  *      time_t t;
  497.  *      struct tm *tp;  Pointer to TM structure from <time.h>
  498.  *      t = maketime(tp,zone);
  499. d13 2
  500. a14 2
  501.  *      -1 if failure; parameter out of range or nonsensical.
  502.  *      else time-value.
  503. d16 6
  504. a21 6
  505.  *      This code is quasi-public; it may be used freely in like software.
  506.  *      It is not to be sold, nor used in licensed software without
  507.  *      permission of the author.
  508.  *      For everyone's benefit, please report bugs and improvements!
  509.  *      Copyright 1981 by Ken Harrenstien, SRI International.
  510.  *      (ARPANET: KLH @@ SRI)
  511. a23 3
  512.  * Revision 5.3.1.1  1993/01/18  14:37:32  heinz
  513.  * Start of the AMIGA port of RCS 5.6. I call it HWGRCS now ;^)
  514.  *
  515. d74 1
  516. a74 1
  517. libId(maketId, "$Id: maketime.c,v 5.3.1.1 1993/01/18 14:37:32 heinz Exp heinz $")
  518. d81 2
  519. a82 2
  520.         /* # days in year thus far, indexed by month (0-12!!) */
  521.         0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
  522. d85 1
  523. a85 1
  524.         static time_t
  525. d87 2
  526. a88 2
  527.         struct tm const *atm;
  528.         int zone;
  529. d99 1
  530. a99 1
  531.     year = mon = day = 0;  /* Keep lint happy.  */
  532. d103 45
  533. a147 45
  534.         if (localzone || !given(atm->tm_year)) {
  535.                 if (tres == -1)
  536.                         if ((tres = time((time_t*)0))  ==  -1)
  537.                                 return -1;
  538.                 tp = time2tm(tres);
  539.                 /* Get breakdowns of default time, adjusting to zone. */
  540.                 year = tp->tm_year;             /* Use to set up defaults */
  541.                 yday = tp->tm_yday;
  542.                 mon = tp->tm_mon;
  543.                 day = tp->tm_mday;
  544.                 hour = tp->tm_hour;
  545.                 min = tp->tm_min;
  546.                 if (localzone) {
  547.                     tp = localtime(&tres);
  548.                     zone =
  549.                         min - tp->tm_min + 60*(
  550.                                 hour - tp->tm_hour + 24*(
  551.                                         /* If years differ, it's by one day. */
  552.                                                 year - tp->tm_year
  553.                                         ?       year - tp->tm_year
  554.                                         :       yday - tp->tm_yday));
  555.                 }
  556.                 /* Adjust the default day, month and year according to zone.  */
  557.                 if ((min -= zone) < 0) {
  558.                     if (hour-(59-min)/60 < 0  &&  --day <= 0) {
  559.                         if (--mon < 0) {
  560.                                 --year;
  561.                                 mon = 11;
  562.                         }
  563.                         day  =  daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3));
  564.                     }
  565.                 } else
  566.                     if (
  567.                       24 <= hour+min/60  &&
  568.                       daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3))  <  ++day
  569.                     ) {
  570.                             if (11 < ++mon) {
  571.                                     ++year;
  572.                                     mon = 0;
  573.                             }
  574.                             day = 1;
  575.                     }
  576.         }
  577.         if (zone < -24*60  ||  24*60 < zone)
  578.                 return -1;
  579. d153 1
  580. a153 1
  581.         tp = atm;
  582. d155 61
  583. a215 61
  584.         /* First must find date, using specified year, month, day.
  585.          * If one of these is unspecified, it defaults either to the
  586.          * current date (if no more global spec was given) or to the
  587.          * zero-value for that spec (i.e. a more global spec was seen).
  588.          * Reject times that do not fit in time_t,
  589.          * without assuming that time_t is 32 bits or is signed.
  590.          */
  591.         if (given(tp->tm_year))
  592.           {
  593.                 year = tp->tm_year;
  594.                 mon = 0;                /* Since year was given, default */
  595.                 day = 1;                /* for remaining specs is zero */
  596.           }
  597.         if (year < 69)                  /* 1969/12/31 OK in some timezones.  */
  598.                 return -1;              /* ERR: year out of range */
  599.         leap   =   !(year&3)  &&  (year%100 || !((year+300)%400));
  600.         year -= 70;                     /* UNIX time starts at 1970 */
  601.  
  602.         /*
  603.          * Find day of year.
  604.          */
  605.         {
  606.                 if (given(tp->tm_mon))
  607.                   {     mon = tp->tm_mon;       /* Month was specified */
  608.                         day = 1;                /* so set remaining default */
  609.                   }
  610.                 if (11 < (unsigned)mon)
  611.                         return -1;              /* ERR: bad month */
  612.                 if (given(tp->tm_mday)) day = tp->tm_mday;
  613.                 if(day < 1
  614.                  || (((daytb[mon+1]-daytb[mon]) < day)
  615.                         && (day!=29 || mon!=1 || !leap) ))
  616.                                 return -1;      /* ERR: bad day */
  617.                 yday = daytb[mon]       /* Add # of days in months so far */
  618.                   + ((leap              /* Leap year, and past Feb?  If */
  619.                       && mon>1)? 1:0)   /* so, add leap day for this year */
  620.                   + day-1;              /* And finally add # days this mon */
  621.  
  622.         }
  623.         if (leap+365 <= (unsigned)yday)
  624.                 return -1;              /* ERR: bad YDAY */
  625.  
  626.         if (year < 0) {
  627.             if (yday != 364)
  628.                 return -1;              /* ERR: too early */
  629.             t = -1;
  630.         } else {
  631.             tres = year*365;            /* Get # days of years so far */
  632.             if (tres/365 != year)
  633.                     return -1;          /* ERR: overflow */
  634.             t = tres
  635.                 + ((year+1)>>2)         /* plus # of leap days since 1970 */
  636.                 + yday;                 /* and finally add # days this year */
  637.             if (t+4 < tres)
  638.                     return -1;          /* ERR: overflow */
  639.         }
  640.         tres = t;
  641.  
  642.         if (given(i = tp->tm_wday)) /* Check WDAY if present */
  643.                 if (i != (tres+4)%7)    /* 1970/01/01 was Thu = 4 */
  644.                         return -1;      /* ERR: bad WDAY */
  645. d220 16
  646. a235 16
  647.         /*
  648.          * Now determine time.  If not given, default to zeros
  649.          * (since time is always the least global spec)
  650.          */
  651.         tres *= 86400L;                 /* Get # seconds (24*60*60) */
  652.         if (tres/86400L != t)
  653.                 return -1;              /* ERR: overflow */
  654.         hour = min = sec = 0;
  655.         if (given(tp->tm_hour)) hour = tp->tm_hour;
  656.         if (given(tp->tm_min )) min  = tp->tm_min;
  657.         if (given(tp->tm_sec )) sec  = tp->tm_sec;
  658.         if (60 <= (unsigned)min  ||  60 < (unsigned)sec)
  659.                 return -1;              /* ERR: MS out of range */
  660.         if (24 <= (unsigned)hour)
  661.                 if(hour != 24 || (min+sec) !=0) /* Allow 24:00 */
  662.                         return -1;      /* ERR: H out of range */
  663. d237 2
  664. a238 2
  665.         t = tres;
  666.         tres += sec + 60L*(zone + min + 60*hour);
  667. d244 2
  668. a245 2
  669.         if (!localzone)                 /* check for overflow */
  670.             return (year<0 ? (tres<0||86400L<=tres) : tres<t)  ?  -1  :  tres;
  671. d247 12
  672. a258 12
  673.         /* Check results; LT may have had a different GMT offset back then.  */
  674.         tp = localtime(&tres);
  675.         if (given(atm->tm_sec)  &&  atm->tm_sec != tp->tm_sec)
  676.                 return -1; /* If seconds don't match, we're in trouble.  */
  677.         if (!(
  678.             given(atm->tm_min)  &&  atm->tm_min != tp->tm_min  ||
  679.             given(atm->tm_hour)  &&  atm->tm_hour != tp->tm_hour  ||
  680.             given(atm->tm_mday)  &&  atm->tm_mday != tp->tm_mday  ||
  681.             given(atm->tm_mon)  &&  atm->tm_mon != tp->tm_mon  ||
  682.             given(atm->tm_year)  &&  atm->tm_year != tp->tm_year
  683.         ))
  684.                 return tres; /* Everything matches.  */
  685. d270 1
  686. a270 1
  687.         static struct tm const *
  688. d272 1
  689. a272 1
  690.         time_t unixtime;
  691. d274 15
  692. a288 9
  693.         struct tm const *tm;
  694. #       if TZ_must_be_set
  695.                 static char const *TZ;
  696.                 if (!TZ  &&  !(TZ = getenv("TZ")))
  697.                         faterror("TZ is not set");
  698. #       endif
  699.         if (!(tm  =  (RCSversion<VERSION(5) ? localtime : gmtime)(&unixtime)))
  700.                 faterror("UTC is not available; perhaps TZ is not set?");
  701.         return tm;
  702. d296 1
  703. a296 1
  704.         void
  705. d298 2
  706. a299 2
  707.         time_t unixtime;
  708.         char date[datesize];
  709. d301 6
  710. a306 6
  711.         register struct tm const *tm = time2tm(unixtime);
  712.         VOID sprintf(date, DATEFORM,
  713.                 tm->tm_year  +  (tm->tm_year<100 ? 0 : 1900),
  714.                 tm->tm_mon+1, tm->tm_mday,
  715.                 tm->tm_hour, tm->tm_min, tm->tm_sec
  716.         );
  717. d311 1
  718. a311 1
  719.         static time_t
  720. d313 1
  721. a313 1
  722.         char const *source;
  723. d316 9
  724. a324 9
  725.         int zone;
  726.         time_t unixtime;
  727.         struct tm parseddate;
  728.  
  729.         if (!partime(source, &parseddate, &zone))
  730.             faterror("can't parse date/time: %s", source);
  731.         if ((unixtime = maketime(&parseddate, zone))  ==  -1)
  732.             faterror("bad date/time: %s", source);
  733.         return unixtime;
  734. d327 1
  735. a327 1
  736.         void
  737. d329 2
  738. a330 2
  739.         char const *source;
  740.         char target[datesize];
  741. d335 1
  742. a335 1
  743.         time2date(str2time(source), target);
  744. d338 1
  745. a338 1
  746.         int
  747. d340 1
  748. a340 1
  749.         char const *file, date[datesize];
  750. d343 2
  751. a344 2
  752.         static struct utimbuf times; /* static so unused fields are zero */
  753.         char datebuf[datesize];
  754. d346 4
  755. a349 4
  756.         if (!date)
  757.                 return 0;
  758.         times.actime = times.modtime = str2time(date2str(date, datebuf));
  759.         return utime(file, ×);
  760. @
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.