home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume6 / datediffs < prev    next >
Text File  |  1986-11-30  |  25KB  |  978 lines

  1. Subject: v06i012:  patches for date to use elsie!ado's localtime (datediffs)
  2. Newsgroups: mod.sources
  3. Approved:  kre@munnari.OZ
  4.  
  5. Submitted by: seismo!munnari!kre (Robert Elz)
  6. Mod.sources: Volume 6, Issue 12
  7. Archive-name: datediffs
  8.  
  9. This shell archive (below the line) contains diffs for various
  10. versions of date.c to make them compatible with Arthur Olson's
  11. modified localtime(3).  See the READ_ME for more details.
  12.  
  13. : ---------------------------------------- cut here
  14.  
  15. echo x - "READ_ME" 2>&1
  16. sed "s/^X//" >"READ_ME" <<'!The!End!'
  17. XThis posting contains diffs for 4 popular versions of "date.c"
  18. Xto enable it to work correctly with Arthur Olson's posted
  19. Xmodifications to localtime().  (in mod.sources, in March 86).
  20. X
  21. XAlmost no programs need to be modified to use that localtime,
  22. Xhowever "date" is one of those that do (as it "knew" that daylight
  23. Xsaving means 1 hour added on, and nothing else, and it used a
  24. Xrather crude mechanism to correct for the local timezone when
  25. Xsetting the date).
  26. X
  27. XThere are 3 changes of substance (and a few minor cleanups).
  28. X
  29. X1) If the TZ environment variable is set to something that doesn't
  30. Xmake sense, prevent the date from being set (its likely to end up
  31. Xbeing not quite what was intended).
  32. X
  33. X2) Correct the time given properly, where its given in local time
  34. X(in Sys V date there's no alternative).  Handle all variations of
  35. Xdaylight saving, etc, that Arthur Olson's localtime can handle,
  36. Xand that's practically everything.
  37. X
  38. X3) Print the time-zone name that the new localtime returns (in
  39. Xthe global tz_abbr), rather than using the old ways of obtaining
  40. Xtimezone names.
  41. X
  42. XAssumption: before these diffs will be useful, you must have installed
  43. Xthe new localtime() in libc.  To do that you have to merge your
  44. Xcurrent libc/ctime.c with the new one, changing the name of
  45. Xnewlocaltime() to localtime() as you do it.  This is not particularly
  46. Xdifficult.  You should compile it so that TZDIR is /etc/tzdir.
  47. X
  48. XProcedure: Select one of the following 4 diffs files.  If you are
  49. Xa BSD 4.2 4.3 beta or 4.3 site take diffs.4.2, diffs.4.3beta, or
  50. Xdiffs.4.3 respectively.  AT&T system sites should take diffs.SysV.
  51. XV7 and BSD4.1 are on their own, sorry.  If you look at all four diffs
  52. Xfiles you will see how similar they are, you shouldn't find it difficult
  53. Xto install in any other version of date.  In particular, the major piece
  54. Xof code is identical (modulo indentation) in all of these versions.
  55. X
  56. XThen use "patch" to apply the diffs as
  57. X
  58. X    cp /..../date.c .
  59. X    chmod +w date.c
  60. X    patch date.c < diffs.XXX
  61. X
  62. XThen check what was produced, make sure that it all makes sense.
  63. XCompile & install the modified "date".
  64. X
  65. XRobert Elz        kre%munnari.oz@seismo.css.gov
  66. X            seismo!munnari!kre
  67. !The!End!
  68.  
  69. echo x - "diffs.4.2" 2>&1
  70. sed "s/^X//" >"diffs.4.2" <<'!The!End!'
  71. X*** date.c.4.2    Mon Apr 28 02:32:47 1986
  72. X--- date.c.4.2.new    Mon Apr 28 02:33:37 1986
  73. X***************
  74. X*** 12,18
  75. X  #define WTMP "/usr/adm/wtmp"
  76. X  
  77. X  struct    timeval tv;
  78. X- struct    timezone tz;
  79. X  char    *ap, *ep, *sp;
  80. X  int    uflag;
  81. X  
  82. X
  83. X--- 12,17 -----
  84. X  #define WTMP "/usr/adm/wtmp"
  85. X  
  86. X  struct    timeval tv;
  87. X  char    *ap, *ep, *sp;
  88. X  int    uflag;
  89. X  
  90. X***************
  91. X*** 16,22
  92. X  char    *ap, *ep, *sp;
  93. X  int    uflag;
  94. X  
  95. X- char    *timezone();
  96. X  static    int    dmsize[12] =
  97. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  98. X  static char *usage = "usage: date [-u] [yymmddhhmm[.ss]]\n";
  99. X
  100. X--- 15,20 -----
  101. X  char    *ap, *ep, *sp;
  102. X  int    uflag;
  103. X  
  104. X  static    int    dmsize[12] =
  105. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  106. X  static char *usage = "usage: date [-u] [yymmddhhmm[.ss]]\n";
  107. X***************
  108. X*** 26,31
  109. X      { "{", "", "", 0 }
  110. X  };
  111. X  
  112. X  char    *ctime();
  113. X  char    *asctime();
  114. X  struct    tm *localtime();
  115. X
  116. X--- 24,30 -----
  117. X      { "{", "", "", 0 }
  118. X  };
  119. X  
  120. X+ char    *getenv();
  121. X  char    *ctime();
  122. X  char    *asctime();
  123. X  struct    tm *localtime();
  124. X***************
  125. X*** 30,35
  126. X  char    *asctime();
  127. X  struct    tm *localtime();
  128. X  struct    tm *gmtime();
  129. X  
  130. X  main(argc, argv)
  131. X      int argc;
  132. X
  133. X--- 29,35 -----
  134. X  char    *asctime();
  135. X  struct    tm *localtime();
  136. X  struct    tm *gmtime();
  137. X+ extern char *tz_abbr;
  138. X  
  139. X  main(argc, argv)
  140. X      int argc;
  141. X***************
  142. X*** 39,45
  143. X      int wf, rc;
  144. X  
  145. X      rc = 0;
  146. X!     gettimeofday(&tv, &tz);
  147. X      if (argc > 1 && strcmp(argv[1], "-u") == 0) {
  148. X          argc--;
  149. X          argv++;
  150. X
  151. X--- 39,45 -----
  152. X      int wf, rc;
  153. X  
  154. X      rc = 0;
  155. X!     gettimeofday(&tv, (struct timezone *)0);
  156. X      if (argc > 1 && strcmp(argv[1], "-u") == 0) {
  157. X          argc--;
  158. X          argv++;
  159. X***************
  160. X*** 46,51
  161. X          uflag++;
  162. X      }
  163. X      if (argc > 1) {
  164. X          ap = argv[1];
  165. X          wtmp[0].ut_time = tv.tv_sec;
  166. X          if (gtime()) {
  167. X
  168. X--- 46,56 -----
  169. X          uflag++;
  170. X      }
  171. X      if (argc > 1) {
  172. X+         if (settz(ap = getenv("TZ")) < 0) {
  173. X+             fprintf(stderr, "Unknown timezone \"%s\"\n",
  174. X+                 ap ? ap : "null");
  175. X+             exit(1);
  176. X+         }
  177. X          ap = argv[1];
  178. X          wtmp[0].ut_time = tv.tv_sec;
  179. X          if (gtime()) {
  180. X***************
  181. X*** 54,63
  182. X          }
  183. X          /* convert to GMT assuming local time */
  184. X          if (uflag == 0) {
  185. X!             tv.tv_sec += (long)tz.tz_minuteswest*60;
  186. X!             /* now fix up local daylight time */
  187. X!             if (localtime(&tv.tv_sec)->tm_isdst)
  188. X!                 tv.tv_sec -= 60*60;
  189. X          }
  190. X          tv.tv_sec = tv.tv_sec;
  191. X          if (settimeofday(&tv, (struct timezone *)0) < 0) {
  192. X
  193. X--- 59,119 -----
  194. X          }
  195. X          /* convert to GMT assuming local time */
  196. X          if (uflag == 0) {
  197. X!             /*
  198. X!              * Do this by determining what the given time
  199. X!              * is when converted to local time, and when
  200. X!              * converted to GMT and taking the difference.
  201. X!              * This works correctly regardless of whether
  202. X!              * local time is DST or not.
  203. X!              * The loop usually runs twice, once to correct the
  204. X!              * time, and once to check the correction was accurate.
  205. X!              * An extra iteration can be caused by setting the time
  206. X!              * just about when DST turns on or off.
  207. X!              * If we iterate more than a couple of times, then
  208. X!              * the idiot root moron has asked to set the time to
  209. X!              * something in the "dead" zone where DST has just
  210. X!              * turned on, and the times don't exist!
  211. X!              * The ugly "if" statements are to handle wierd cases
  212. X!              * that arise setting the time just about midnight on
  213. X!              * Jan 1 after a year that was a leap year.
  214. X!              * How close to midnight it has to be depends on how
  215. X!              * close to Greenwich you are, whether before or after
  216. X!              * midnight depends on whether you are East or West.
  217. X!              */
  218. X!             struct tm gmt;
  219. X!             struct tm local;
  220. X!             register long diff;
  221. X!             register int iters = 0;
  222. X!      
  223. X!             gmt = *gmtime(&tv.tv_sec);
  224. X!             do {
  225. X! #define    isleap(yr)    ((yr) % 4 == 0 && ((yr) % 100 != 0 || (yr) % 400 == 0))
  226. X!                 local = *localtime(&tv.tv_sec);
  227. X!                 diff = gmt.tm_year - local.tm_year;
  228. X!                 diff *= 365;
  229. X!                 if (gmt.tm_year > local.tm_year) {
  230. X!                     if (isleap(local.tm_year))
  231. X!                         diff++;
  232. X!                 } else if (local.tm_year > gmt.tm_year) {
  233. X!                     if (isleap(gmt.tm_year))
  234. X!                         diff--;
  235. X!                 }
  236. X!                 diff += gmt.tm_yday - local.tm_yday;
  237. X!                 diff *= 24;
  238. X!                 diff += gmt.tm_hour - local.tm_hour;
  239. X!                 diff *= 60;
  240. X!                 diff += gmt.tm_min - local.tm_min;
  241. X!                 diff *= 60;
  242. X!                 diff += gmt.tm_sec - local.tm_sec;
  243. X!                 tv.tv_sec += diff;
  244. X! #undef    isleap
  245. X!             } while (diff != 0 && ++iters < 5);
  246. X!             if (iters >= 5) {
  247. X!                 fprintf(stderr,
  248. X!                     "date: %.24s is in the time warp!\n",
  249. X!                     asctime(&gmt));
  250. X!                 exit(1);
  251. X!             }
  252. X          }
  253. X          tv.tv_sec = tv.tv_sec;
  254. X          if (settimeofday(&tv, (struct timezone *)0) < 0) {
  255. X***************
  256. X*** 76,85
  257. X          ap = asctime(gmtime(&tv.tv_sec));
  258. X          tzn = "GMT";
  259. X      } else {
  260. X!         struct tm *tp;
  261. X!         tp = localtime(&tv.tv_sec);
  262. X!         ap = asctime(tp);
  263. X!         tzn = timezone(tz.tz_minuteswest, tp->tm_isdst);
  264. X      }
  265. X      printf("%.20s", ap);
  266. X      if (tzn)
  267. X
  268. X--- 132,139 -----
  269. X          ap = asctime(gmtime(&tv.tv_sec));
  270. X          tzn = "GMT";
  271. X      } else {
  272. X!         ap = ctime(&tv.tv_sec);
  273. X!         tzn = tz_abbr;
  274. X      }
  275. X      printf("%.20s", ap);
  276. X      if (tzn)
  277. X***************
  278. X*** 83,90
  279. X      }
  280. X      printf("%.20s", ap);
  281. X      if (tzn)
  282. X!         printf("%s", tzn);
  283. X!     printf("%s", ap+19);
  284. X      exit(rc);
  285. X  }
  286. X  
  287. X
  288. X--- 137,144 -----
  289. X      }
  290. X      printf("%.20s", ap);
  291. X      if (tzn)
  292. X!         printf("%s ", tzn);
  293. X!     printf("%s", ap+20);
  294. X      exit(rc);
  295. X  }
  296. X  
  297. !The!End!
  298.  
  299. echo x - "diffs.4.3" 2>&1
  300. sed "s/^X//" >"diffs.4.3" <<'!The!End!'
  301. X*** date.c.4.3    Sat Jun 21 18:14:04 1986
  302. X--- date.c.4.3.new    Sat Jun 21 18:14:04 1986
  303. X***************
  304. X*** 29,35
  305. X  #define WTMP    "/usr/adm/wtmp"
  306. X  
  307. X  struct    timeval tv, now;
  308. X- struct    timezone tz;
  309. X  char    *ap, *ep, *sp;
  310. X  int    uflag, nflag;
  311. X  int    retval;
  312. X
  313. X--- 29,34 -----
  314. X  #define WTMP    "/usr/adm/wtmp"
  315. X  
  316. X  struct    timeval tv, now;
  317. X  char    *ap, *ep, *sp;
  318. X  int    uflag, nflag;
  319. X  int    retval;
  320. X***************
  321. X*** 34,40
  322. X  int    uflag, nflag;
  323. X  int    retval;
  324. X  
  325. X- char    *timezone();
  326. X  static    int dmsize[12] =
  327. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  328. X  static    char *usage = "usage: date [-n] [-u] [yymmddhhmm[.ss]]\n";
  329. X
  330. X--- 33,38 -----
  331. X  int    uflag, nflag;
  332. X  int    retval;
  333. X  
  334. X  static    int dmsize[12] =
  335. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  336. X  static    char *usage = "usage: date [-n] [-u] [yymmddhhmm[.ss]]\n";
  337. X***************
  338. X*** 50,55
  339. X  struct    tm *gmtime();
  340. X  char    *strcpy(), *strncpy();
  341. X  char    *username, *getlogin();
  342. X  long    time();
  343. X  uid_t    getuid();
  344. X  
  345. X
  346. X--- 48,54 -----
  347. X  struct    tm *gmtime();
  348. X  char    *strcpy(), *strncpy();
  349. X  char    *username, *getlogin();
  350. X+ char    *getenv();
  351. X  long    time();
  352. X  uid_t    getuid();
  353. X  
  354. X***************
  355. X*** 53,58
  356. X  long    time();
  357. X  uid_t    getuid();
  358. X  
  359. X  main(argc, argv)
  360. X      int argc;
  361. X      char *argv[];
  362. X
  363. X--- 52,59 -----
  364. X  long    time();
  365. X  uid_t    getuid();
  366. X  
  367. X+ extern char *tz_abbr;
  368. X+ 
  369. X  main(argc, argv)
  370. X      int argc;
  371. X      char *argv[];
  372. X***************
  373. X*** 60,66
  374. X      register char *tzn;
  375. X  
  376. X      openlog("date", LOG_ODELAY, LOG_AUTH);
  377. X!     (void) gettimeofday(&tv, &tz);
  378. X      now = tv;
  379. X  
  380. X      while (argc > 1 && argv[1][0] == '-') {
  381. X
  382. X--- 61,67 -----
  383. X      register char *tzn;
  384. X  
  385. X      openlog("date", LOG_ODELAY, LOG_AUTH);
  386. X!     (void) gettimeofday(&tv, (struct timezone *)0);
  387. X      now = tv;
  388. X  
  389. X      while (argc > 1 && argv[1][0] == '-') {
  390. X***************
  391. X*** 94,99
  392. X          retval = 1;
  393. X          goto display;
  394. X      }
  395. X      username = getlogin();
  396. X      if (username == NULL || *username == '\0')  /* single-user or no tty */
  397. X          username = "root";
  398. X
  399. X--- 95,104 -----
  400. X          retval = 1;
  401. X          goto display;
  402. X      }
  403. X+     if (settz(tzn = getenv("TZ")) < 0) {
  404. X+         fprintf(stderr, "Unknown timezone \"%s\"\n", tzn ? tzn : "null");
  405. X+         exit(1);
  406. X+     }
  407. X      username = getlogin();
  408. X      if (username == NULL || *username == '\0')  /* single-user or no tty */
  409. X          username = "root";
  410. X***************
  411. X*** 107,116
  412. X      }
  413. X      /* convert to GMT assuming local time */
  414. X      if (uflag == 0) {
  415. X!         tv.tv_sec += (long)tz.tz_minuteswest*60;
  416. X!         /* now fix up local daylight time */
  417. X!         if (localtime((time_t *)&tv.tv_sec)->tm_isdst)
  418. X!             tv.tv_sec -= 60*60;
  419. X      }
  420. X      if (nflag || !settime(tv)) {
  421. X          int wf;
  422. X
  423. X--- 112,171 -----
  424. X      }
  425. X      /* convert to GMT assuming local time */
  426. X      if (uflag == 0) {
  427. X!         /*
  428. X!          * Do this by determining what the given time
  429. X!          * is when converted to local time, and when
  430. X!          * converted to GMT and taking the difference.
  431. X!          * This works correctly regardless of whether
  432. X!          * local time is DST or not.
  433. X!          * The loop usually runs twice, once to correct the
  434. X!          * time, and once to check the correction was accurate.
  435. X!          * An extra iteration can be caused by setting the time
  436. X!          * just about when DST turns on or off.
  437. X!          * If we iterate more than a couple of times, then
  438. X!          * the idiot root moron has asked to set the time to
  439. X!          * something in the "dead" zone where DST has just
  440. X!          * turned on, and the times don't exist!
  441. X!          * The ugly "if" statements are to handle wierd cases
  442. X!          * that arise setting the time just about midnight on
  443. X!          * Jan 1 after a year that was a leap year.
  444. X!          * How close to midnight it has to be depends on how close
  445. X!          * to Greenwich you are, whether before or after midnight
  446. X!          * depends on whether you are East or West.
  447. X!          */
  448. X!         struct tm gmt;
  449. X!         struct tm local;
  450. X!         register long diff;
  451. X!         register int iters = 0;
  452. X! 
  453. X!         gmt = *gmtime((time_t *)&tv.tv_sec);
  454. X!         do {
  455. X! #define    isleap(yr)    ((yr) % 4 == 0 && ((yr) % 100 != 0 || (yr) % 400 == 0))
  456. X!             local = *localtime((time_t *)&tv.tv_sec);
  457. X!             diff = gmt.tm_year - local.tm_year;
  458. X!             diff *= 365;
  459. X!             if (gmt.tm_year > local.tm_year) {
  460. X!                 if (isleap(local.tm_year))
  461. X!                     diff++;
  462. X!             } else if (local.tm_year > gmt.tm_year) {
  463. X!                 if (isleap(gmt.tm_year))
  464. X!                     diff--;
  465. X!             }
  466. X!             diff += gmt.tm_yday - local.tm_yday;
  467. X!             diff *= 24;
  468. X!             diff += gmt.tm_hour - local.tm_hour;
  469. X!             diff *= 60;
  470. X!             diff += gmt.tm_min - local.tm_min;
  471. X!             diff *= 60;
  472. X!             diff += gmt.tm_sec - local.tm_sec;
  473. X!             tv.tv_sec += diff;
  474. X! #undef    isleap
  475. X!         } while (diff != 0 && ++iters < 5);
  476. X!         if (iters >= 5) {
  477. X!             fprintf(stderr, "date: %.24s is in the time warp!\n",
  478. X!                 asctime(&gmt));
  479. X!             exit(1);
  480. X!         }
  481. X      }
  482. X      if (nflag || !settime(tv)) {
  483. X          int wf;
  484. X***************
  485. X*** 134,143
  486. X          ap = asctime(gmtime((time_t *)&tv.tv_sec));
  487. X          tzn = "GMT";
  488. X      } else {
  489. X!         struct tm *tp;
  490. X!         tp = localtime((time_t *)&tv.tv_sec);
  491. X!         ap = asctime(tp);
  492. X!         tzn = timezone(tz.tz_minuteswest, tp->tm_isdst);
  493. X      }
  494. X      printf("%.20s", ap);
  495. X      if (tzn)
  496. X
  497. X--- 189,196 -----
  498. X          ap = asctime(gmtime((time_t *)&tv.tv_sec));
  499. X          tzn = "GMT";
  500. X      } else {
  501. X!         ap = ctime((time_t *)&tv.tv_sec);
  502. X!         tzn = tz_abbr;
  503. X      }
  504. X      printf("%.20s", ap);
  505. X      if (tzn)
  506. X***************
  507. X*** 141,148
  508. X      }
  509. X      printf("%.20s", ap);
  510. X      if (tzn)
  511. X!         printf("%s", tzn);
  512. X!     printf("%s", ap+19);
  513. X      exit(retval);
  514. X  }
  515. X  
  516. X
  517. X--- 194,201 -----
  518. X      }
  519. X      printf("%.20s", ap);
  520. X      if (tzn)
  521. X!         printf("%s ", tzn);
  522. X!     printf("%s", ap+20);
  523. X      exit(retval);
  524. X  }
  525. X  
  526. !The!End!
  527.  
  528. echo x - "diffs.4.3beta" 2>&1
  529. sed "s/^X//" >"diffs.4.3beta" <<'!The!End!'
  530. X*** date.c.4.3    Mon Apr 28 02:04:30 1986
  531. X--- date.c.4.3.new    Mon Apr 28 02:34:09 1986
  532. X***************
  533. X*** 25,31
  534. X  #define WAITDATEACK    5    /* seconds */
  535. X  
  536. X  struct    timeval tv, now;
  537. X- struct    timezone tz;
  538. X  char    *ap, *ep, *sp;
  539. X  int    uflag;
  540. X  
  541. X
  542. X--- 25,30 -----
  543. X  #define WAITDATEACK    5    /* seconds */
  544. X  
  545. X  struct    timeval tv, now;
  546. X  char    *ap, *ep, *sp;
  547. X  int    uflag;
  548. X  
  549. X***************
  550. X*** 29,35
  551. X  char    *ap, *ep, *sp;
  552. X  int    uflag;
  553. X  
  554. X- char    *timezone();
  555. X  static    int    dmsize[12] =
  556. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  557. X  static char *usage = "usage: date [-u] [yymmddhhmm[.ss]]\n";
  558. X
  559. X--- 28,33 -----
  560. X  char    *ap, *ep, *sp;
  561. X  int    uflag;
  562. X  
  563. X  static    int    dmsize[12] =
  564. X      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  565. X  static char *usage = "usage: date [-u] [yymmddhhmm[.ss]]\n";
  566. X***************
  567. X*** 39,44
  568. X      { "{", "", "", 0 }
  569. X  };
  570. X  
  571. X  char    *ctime();
  572. X  char    *asctime();
  573. X  struct    tm *localtime();
  574. X
  575. X--- 37,43 -----
  576. X      { "{", "", "", 0 }
  577. X  };
  578. X  
  579. X+ char    *getenv();
  580. X  char    *ctime();
  581. X  char    *asctime();
  582. X  struct    tm *localtime();
  583. X***************
  584. X*** 43,48
  585. X  char    *asctime();
  586. X  struct    tm *localtime();
  587. X  struct    tm *gmtime();
  588. X  
  589. X  char *strcpy();
  590. X  char *username, *getlogin();
  591. X
  592. X--- 42,48 -----
  593. X  char    *asctime();
  594. X  struct    tm *localtime();
  595. X  struct    tm *gmtime();
  596. X+ extern char *tz_abbr;
  597. X  
  598. X  char *strcpy();
  599. X  char *username, *getlogin();
  600. X***************
  601. X*** 66,72
  602. X      extern int errno;
  603. X      int bytenetorder(), bytehostorder();
  604. X  
  605. X!     (void) gettimeofday(&tv, &tz);
  606. X      now = tv;
  607. X  
  608. X      if (argc > 1 && strcmp(argv[1], "-u") == 0) {
  609. X
  610. X--- 66,72 -----
  611. X      extern int errno;
  612. X      int bytenetorder(), bytehostorder();
  613. X  
  614. X!     (void) gettimeofday(&tv, (struct timezone *)0);
  615. X      now = tv;
  616. X  
  617. X      if (argc > 1 && strcmp(argv[1], "-u") == 0) {
  618. X***************
  619. X*** 85,90
  620. X          printf("You are not superuser: date not set\n");
  621. X          goto display;
  622. X      }
  623. X      username = getlogin();
  624. X      if (username == NULL)        /* single-user or no tty */
  625. X          username = "root";
  626. X
  627. X--- 85,94 -----
  628. X          printf("You are not superuser: date not set\n");
  629. X          goto display;
  630. X      }
  631. X+     if (settz(ap = getenv("TZ")) < 0) {
  632. X+         fprintf(stderr, "Unknown timezone \"%s\"\n", ap ? ap : "null");
  633. X+         exit(1);
  634. X+     }
  635. X      username = getlogin();
  636. X      if (username == NULL)        /* single-user or no tty */
  637. X          username = "root";
  638. X***************
  639. X*** 98,107
  640. X      }
  641. X      /* convert to GMT assuming local time */
  642. X      if (uflag == 0) {
  643. X!         tv.tv_sec += (long)tz.tz_minuteswest*60;
  644. X!         /* now fix up local daylight time */
  645. X!         if (localtime((time_t *)&tv.tv_sec)->tm_isdst)
  646. X!             tv.tv_sec -= 60*60;
  647. X      }
  648. X      
  649. X  /*
  650. X
  651. X--- 102,161 -----
  652. X      }
  653. X      /* convert to GMT assuming local time */
  654. X      if (uflag == 0) {
  655. X!         /*
  656. X!          * Do this by determining what the given time
  657. X!          * is when converted to local time, and when
  658. X!          * converted to GMT and taking the difference.
  659. X!          * This works correctly regardless of whether
  660. X!          * local time is DST or not.
  661. X!          * The loop usually runs twice, once to correct the
  662. X!          * time, and once to check the correction was accurate.
  663. X!          * An extra iteration can be caused by setting the time
  664. X!          * just about when DST turns on or off.
  665. X!          * If we iterate more than a couple of times, then
  666. X!          * the idiot root moron has asked to set the time to
  667. X!          * something in the "dead" zone where DST has just
  668. X!          * turned on, and the times don't exist!
  669. X!          * The ugly "if" statements are to handle wierd cases
  670. X!          * that arise setting the time just about midnight on
  671. X!          * Jan 1 after a year that was a leap year.
  672. X!          * How close to midnight it has to be depends on how close
  673. X!          * to Greenwich you are, whether before or after midnight
  674. X!          * depends on whether you are East or West.
  675. X!          */
  676. X!         struct tm gmt;
  677. X!         struct tm local;
  678. X!         register long diff;
  679. X!         register int iters = 0;
  680. X! 
  681. X!         gmt = *gmtime((time_t *)&tv.tv_sec);
  682. X!         do {
  683. X! #define    isleap(yr)    ((yr) % 4 == 0 && ((yr) % 100 != 0 || (yr) % 400 == 0))
  684. X!             local = *localtime((time_t *)&tv.tv_sec);
  685. X!             diff = gmt.tm_year - local.tm_year;
  686. X!             diff *= 365;
  687. X!             if (gmt.tm_year > local.tm_year) {
  688. X!                 if (isleap(local.tm_year))
  689. X!                     diff++;
  690. X!             } else if (local.tm_year > gmt.tm_year) {
  691. X!                 if (isleap(gmt.tm_year))
  692. X!                     diff--;
  693. X!             }
  694. X!             diff += gmt.tm_yday - local.tm_yday;
  695. X!             diff *= 24;
  696. X!             diff += gmt.tm_hour - local.tm_hour;
  697. X!             diff *= 60;
  698. X!             diff += gmt.tm_min - local.tm_min;
  699. X!             diff *= 60;
  700. X!             diff += gmt.tm_sec - local.tm_sec;
  701. X!             tv.tv_sec += diff;
  702. X! #undef    isleap
  703. X!         } while (diff != 0 && ++iters < 5);
  704. X!         if (iters >= 5) {
  705. X!             fprintf(stderr, "date: %.24s is in the time warp!\n",
  706. X!                 asctime(&gmt));
  707. X!             exit(1);
  708. X!         }
  709. X      }
  710. X      
  711. X  /*
  712. X***************
  713. X*** 215,224
  714. X          ap = asctime(gmtime((time_t *)&tv.tv_sec));
  715. X          tzn = "GMT";
  716. X      } else {
  717. X!         struct tm *tp;
  718. X!         tp = localtime((time_t *)&tv.tv_sec);
  719. X!         ap = asctime(tp);
  720. X!         tzn = timezone(tz.tz_minuteswest, tp->tm_isdst);
  721. X      }
  722. X      printf("%.20s", ap);
  723. X      if (tzn)
  724. X
  725. X--- 269,276 -----
  726. X          ap = asctime(gmtime((time_t *)&tv.tv_sec));
  727. X          tzn = "GMT";
  728. X      } else {
  729. X!         ap = ctime((time_t *)&tv.tv_sec);
  730. X!         tzn = tz_abbr;
  731. X      }
  732. X      printf("%.20s", ap);
  733. X      if (tzn)
  734. X***************
  735. X*** 222,229
  736. X      }
  737. X      printf("%.20s", ap);
  738. X      if (tzn)
  739. X!         printf("%s", tzn);
  740. X!     printf("%s", ap+19);
  741. X  }
  742. X  
  743. X  gtime()
  744. X
  745. X--- 274,281 -----
  746. X      }
  747. X      printf("%.20s", ap);
  748. X      if (tzn)
  749. X!         printf("%s ", tzn);
  750. X!     printf("%s", ap+20);
  751. X  }
  752. X  
  753. X  gtime()
  754. !The!End!
  755.  
  756. echo x - "diffs.SysV" 2>&1
  757. sed "s/^X//" >"diffs.SysV" <<'!The!End!'
  758. X*** date.c.SysV    Tue Apr 29 03:05:41 1986
  759. X--- date.c.SysV.new    Tue Apr 29 03:05:42 1986
  760. X***************
  761. X*** 17,23
  762. X  #define    JULIAN    itoa(tim->tm_yday+1,cp,3)
  763. X  #define    WEEKDAY    itoa(tim->tm_wday,cp,1)
  764. X  #define    MODHOUR    itoa(h,cp,2)
  765. X! #define    dysize(A) (((A)%4)? 365: 366)
  766. X  
  767. X  int dmsize[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  768. X  
  769. X
  770. X--- 17,24 -----
  771. X  #define    JULIAN    itoa(tim->tm_yday+1,cp,3)
  772. X  #define    WEEKDAY    itoa(tim->tm_wday,cp,1)
  773. X  #define    MODHOUR    itoa(h,cp,2)
  774. X! #define    isleap(yr) ((yr) % 4 == 0 && ((yr) % 100 != 0 || (yr) % 400 == 0))
  775. X! #define    dysize(A) (isleap(A)? 366: 365)
  776. X  
  777. X  int dmsize[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  778. X  
  779. X***************
  780. X*** 32,37
  781. X      "Thu","Fri","Sat"
  782. X  };
  783. X  
  784. X  char    *itoa();
  785. X  char    *cbp;
  786. X  long    timbuf;
  787. X
  788. X--- 33,39 -----
  789. X      "Thu","Fri","Sat"
  790. X  };
  791. X  
  792. X+ char    *getenv();
  793. X  char    *itoa();
  794. X  char    *cbp;
  795. X  long    timbuf;
  796. X***************
  797. X*** 35,40
  798. X  char    *itoa();
  799. X  char    *cbp;
  800. X  long    timbuf;
  801. X  
  802. X  struct    utmp    wtmp[2] = { {"","",OTIME_MSG,0,OLD_TIME,0,0,0},
  803. X                  {"","",NTIME_MSG,0,NEW_TIME,0,0,0} };
  804. X
  805. X--- 37,43 -----
  806. X  char    *itoa();
  807. X  char    *cbp;
  808. X  long    timbuf;
  809. X+ extern    char *tz_abbr;
  810. X  
  811. X  struct    utmp    wtmp[2] = { {"","",OTIME_MSG,0,OLD_TIME,0,0,0},
  812. X                  {"","",NTIME_MSG,0,NEW_TIME,0,0,0} };
  813. X***************
  814. X*** 48,53
  815. X      long    tbuf, time(), lseek();
  816. X      struct    tm  *tim;
  817. X      char     buf[200], *tzn;
  818. X  
  819. X      tfailed = 0;
  820. X      if(argc > 1) {
  821. X
  822. X--- 51,60 -----
  823. X      long    tbuf, time(), lseek();
  824. X      struct    tm  *tim;
  825. X      char     buf[200], *tzn;
  826. X+     struct    tm gmt;
  827. X+     struct    tm local;
  828. X+     register long diff;
  829. X+     register int iters = 0;
  830. X  
  831. X      tfailed = 0;
  832. X      if(argc > 1) {
  833. X***************
  834. X*** 153,158
  835. X              exit(2);
  836. X          }
  837. X  
  838. X          if(gtime()) {
  839. X              (void) fprintf(stderr,"date: bad conversion\n");
  840. X              exit(2);
  841. X
  842. X--- 160,170 -----
  843. X              exit(2);
  844. X          }
  845. X  
  846. X+         if (settz(cp = getenv("TZ")) < 0) {
  847. X+             (void) fprintf(stderr,"date: unknown zone \"%s\"\n",cp);
  848. X+             exit(2);
  849. X+         }
  850. X+ 
  851. X          if(gtime()) {
  852. X              (void) fprintf(stderr,"date: bad conversion\n");
  853. X              exit(2);
  854. X***************
  855. X*** 159,165
  856. X          }
  857. X  
  858. X      /* convert to Greenwich time, on assumption of Standard time. */
  859. X!         timbuf += timezone;
  860. X  
  861. X      /* Now fix up to local daylight time. */
  862. X          if (localtime(&timbuf)->tm_isdst)
  863. X
  864. X--- 171,225 -----
  865. X          }
  866. X  
  867. X      /* convert to Greenwich time, on assumption of Standard time. */
  868. X!         /*
  869. X!          * Do this by determining what the given time
  870. X!          * is when converted to local time, and when
  871. X!          * converted to GMT and taking the difference.
  872. X!          * This works correctly regardless of whether
  873. X!          * local time is DST or not.
  874. X!          * The loop usually runs twice, once to correct the
  875. X!          * time, and once to check the correction was accurate.
  876. X!          * An extra iteration can be caused by setting the time
  877. X!          * just about when DST turns on or off.
  878. X!          * If we iterate more than a couple of times, then
  879. X!          * the idiot root moron has asked to set the time to
  880. X!          * something in the "dead" zone where DST has just
  881. X!          * turned on, and the times don't exist!
  882. X!          * The ugly "if" statements are to handle wierd cases
  883. X!          * that arise setting the time just about midnight on
  884. X!          * Jan 1 after a year that was a leap year.
  885. X!          * How close to midnight it has to be depends on how
  886. X!          * close to Greenwich you are, whether before or after
  887. X!          * midnight depends on whether you are East or West.
  888. X!          */
  889. X!  
  890. X!         gmt = *gmtime(&tv.tv_sec);
  891. X!         do {
  892. X!             local = *localtime(&tv.tv_sec);
  893. X!             diff = gmt.tm_year - local.tm_year;
  894. X!             diff *= 365;
  895. X!             if (gmt.tm_year > local.tm_year) {
  896. X!                 if (isleap(local.tm_year))
  897. X!                     diff++;
  898. X!             } else if (local.tm_year > gmt.tm_year) {
  899. X!                 if (isleap(gmt.tm_year))
  900. X!                     diff--;
  901. X!             }
  902. X!             diff += gmt.tm_yday - local.tm_yday;
  903. X!             diff *= 24;
  904. X!             diff += gmt.tm_hour - local.tm_hour;
  905. X!             diff *= 60;
  906. X!             diff += gmt.tm_min - local.tm_min;
  907. X!             diff *= 60;
  908. X!             diff += gmt.tm_sec - local.tm_sec;
  909. X!             tv.tv_sec += diff;
  910. X!         } while (diff != 0 && ++iters < 5);
  911. X!         if (iters >= 5) {
  912. X!             fprintf(stderr,
  913. X!                 "date: %.24s is in the time warp!\n",
  914. X!                 asctime(&gmt));
  915. X!             exit(1);
  916. X!         }
  917. X  
  918. X          (void) time(&wtmp[0].ut_time);
  919. X  
  920. X***************
  921. X*** 161,170
  922. X      /* convert to Greenwich time, on assumption of Standard time. */
  923. X          timbuf += timezone;
  924. X  
  925. X-     /* Now fix up to local daylight time. */
  926. X-         if (localtime(&timbuf)->tm_isdst)
  927. X-             timbuf += -1*60*60;
  928. X- 
  929. X          (void) time(&wtmp[0].ut_time);
  930. X  
  931. X          if(stime(&timbuf) < 0) {
  932. X
  933. X--- 221,226 -----
  934. X              exit(1);
  935. X          }
  936. X  
  937. X          (void) time(&wtmp[0].ut_time);
  938. X  
  939. X          if(stime(&timbuf) < 0) {
  940. X***************
  941. X*** 188,194
  942. X          (void) time(&timbuf);
  943. X      cbp = ctime(&timbuf);
  944. X      (void) write(1, cbp, 20);
  945. X!     tzn = tzname[localtime(&timbuf)->tm_isdst];
  946. X      if (tzn)
  947. X          (void) write(1, tzn, 3);
  948. X      (void) write(1, cbp+19, 6);
  949. X
  950. X--- 244,250 -----
  951. X          (void) time(&timbuf);
  952. X      cbp = ctime(&timbuf);
  953. X      (void) write(1, cbp, 20);
  954. X!     tzn = tz_abbr;
  955. X      if (tzn)
  956. X          (void) write(1, tzn, strlen(tzn));
  957. X      (void) write(1, cbp+19, 6);
  958. X***************
  959. X*** 190,196
  960. X      (void) write(1, cbp, 20);
  961. X      tzn = tzname[localtime(&timbuf)->tm_isdst];
  962. X      if (tzn)
  963. X!         (void) write(1, tzn, 3);
  964. X      (void) write(1, cbp+19, 6);
  965. X      exit(tfailed?2:0);
  966. X  }
  967. X
  968. X--- 246,252 -----
  969. X      (void) write(1, cbp, 20);
  970. X      tzn = tz_abbr;
  971. X      if (tzn)
  972. X!         (void) write(1, tzn, strlen(tzn));
  973. X      (void) write(1, cbp+19, 6);
  974. X      exit(tfailed?2:0);
  975. X  }
  976. !The!End!
  977. exit
  978.