home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume15 / gc1000 / part01 next >
Encoding:
Text File  |  1990-10-05  |  9.3 KB  |  344 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: mrapple@quack.sac.ca.us
  3. organization: The Duck Pond, Stockton, CA
  4. subject: v15i009: Heathkit GC-1000 reader for unix, v1.4
  5. from: mrapple@quack.sac.ca.us (Nick Sayer)
  6. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7.  
  8. Posting-number: Volume 15, Issue 9
  9. Submitted-by: mrapple@quack.sac.ca.us (Nick Sayer)
  10. Archive-name: gc1000/part01
  11.  
  12. #! /bin/sh
  13. # This file was wrapped with "dummyshar".  "sh" this file to extract.
  14. # Contents:  gc1000.c
  15. echo extracting 'gc1000.c'
  16. if test -f 'gc1000.c' -a -z "$1"; then echo Not overwriting 'gc1000.c'; else
  17. sed 's/^X//' << \EOF > 'gc1000.c'
  18. X/*
  19. X
  20. Xsetclock.c - get time from the Heathkit GC-1000
  21. X
  22. XCopyright 1990, Nick Sayer
  23. XPermission to distribute granted as long as no fee is charged and
  24. Xthose to whom you distribute are also free to do so. All other
  25. Xrights reserved. No warrantees are extended regarding this software's
  26. Xcorrectness or applicability to any specific purpose.
  27. X
  28. Xrevision history:
  29. X
  30. Xv1.4  10/01/90 - minor bug fixes. -d flag now ignores -l. -l 0 disables -l.
  31. Xv1.3  09/22/90 - added limitation on time "displacement" -l option
  32. Xv1.2  03/31/90 - added command line option -d (debug)
  33. Xv1.1  02/01/90 - added configuration section & changed to settimeofday()
  34. Xv1.0 the epoch - created
  35. X
  36. XBUGS -    adjtime() would be preferable to settimeofday().
  37. X
  38. X                USAGE
  39. X
  40. X% setclock [-d] [-l minutes]
  41. X
  42. XHave cron run this program as often as necessary to maintain system
  43. Xclock accuracy. If the clock is not set, or if the tenth-of-a-second digit
  44. Xis dimmed, the system time will not be changed.
  45. X
  46. XIf -d is specified, the system will print out what time it is according
  47. Xto the clock. It will not try to set the system time. Use this to debug
  48. Xthe switch and/or options settings (see below).
  49. X
  50. XIf the time is off by more than a certain number of minutes (specified
  51. Xby -l, default 5), the time will not be changed and an error message
  52. Xgenerated instead. The WWV signal has no check-bits and some computers
  53. Xdon't have the best shielding in the world. The result is that despite
  54. Xthe clock's heuristics it can occasionally get the wrong idea of what
  55. Xtime it is. Having the system time suddenly change by a large amount
  56. Xcan cause great confusion, and that confusion is complicated when the
  57. Xtime has to be changed back again. For small numbers of minutes though
  58. Xthis isn't such a big problem. If you know the clock is right and the
  59. Xsystem is wrong, you can use "-l 0" to turn this checking off.
  60. X
  61. X               CONFIGURATION
  62. X
  63. XYour clock should be set to constantly give the time every second or
  64. Xso. I.e. the handshaking option should be off, and the continuous
  65. Xoption should be on. On my clock, using this configuration, the
  66. Xtime reported is exactly one second slow, so this second is added back
  67. Xlater. To remove this, simply find the line that says
  68. X"convert.tm_sec=....." and remove the "+1".
  69. X
  70. XThe time sent to the RS-232 reads exactly the same way as it does on
  71. Xthe display, so if your clock displays UT1, so will your unix box.
  72. XIf the section below is not right, all hell will break loose. :-)
  73. X
  74. XSet DEVICE to the full path of the entry in /dev (or a link to it)
  75. Xthat talks to the clock
  76. X*/
  77. X#define DEVICE "/dev/clock" /* file for clock device */
  78. X
  79. X/*
  80. XSet baud rate for clock (like in sgtty.h)
  81. X*/
  82. X#define BAUD B2400 /* baud rate for clock */
  83. X
  84. X/*
  85. XSet the default minute limit here
  86. X*/
  87. X#define DEFAULT_MINUS_L 5
  88. X
  89. X/*
  90. XIf your clock displays AM/PM, define this.
  91. X*/
  92. X#define AMPM                /* define if clock shows AM/PM */
  93. X
  94. X/*
  95. XIf you've set the clock up to display local time rather than GMT, then
  96. Xthe clock must also be set properly for your local interpretation of
  97. Xdaylight savings time. If your area has DST, it is NOT a good idea to
  98. Xrun this program less than 24 hours before DST kicks in or turns off.
  99. XYou may find your clock changing DST status early. Unix will figure out
  100. XDST by itself. For no-hassle results, use GMT and undef LOCAL. For
  101. Xhuman-readibility of the clock, grin and bear it. :-)
  102. X*/
  103. X#define LOCAL               /* undef this if your clock displays GMT */
  104. X
  105. X/*
  106. XSince the BCD time code doesn't include any indication of what year it
  107. Xis, heath used internal dipswitches to set the year. Since it's a pain
  108. Xto get in there on December 31 every year, two options have been
  109. Xincluded to get around this. If you define CLOCKYEAR, the clock's idea
  110. Xof what year it is will be used. If you define YEARFILE, and set it
  111. Xto a filename, that file is assumed to have two digits and a newline
  112. Xin it, and those two digits will be used as the year. If you don't
  113. Xdefine either, the system's current notion of what year it is will
  114. Xbe retained. If you do it this way, it is NOT a good idea to run
  115. Xthis program close to 23:59:59 on December 31.
  116. X*/
  117. X/* #define CLOCKYEAR        /* define this to use the clock's year */
  118. X/* #define YEARFILE "/usr/local/lib/year" /* define this for file */
  119. X
  120. X/*
  121. XFor best results, define NICE and set to the priority level desired. -20
  122. Xis highly recommended. This program doesn't load the CPU much, but
  123. Xaccuracy will suffer if it gets swapped.
  124. X*/
  125. X#define NICE -20
  126. X
  127. X/*
  128. X                        END OF CONFIGURATION
  129. X*/
  130. X
  131. X/* spoof 'em for gmtime if necessary */
  132. X
  133. X#ifdef LOCAL
  134. X#define LOCALTIME localtime
  135. X#define TIMELOCAL timelocal
  136. X#else
  137. X#define LOCALTIME gmtime
  138. X#define TIMELOCAL timegm
  139. X#endif
  140. X
  141. X#include <stdio.h>
  142. X#include <sgtty.h>
  143. X#include <signal.h>
  144. X#include <sys/types.h>
  145. X#include <sys/time.h>
  146. Xextern int errno;               /* perror(3) */
  147. Xextern char *sys_errlist[];
  148. Xextern int optind,opterr;       /* getopt(3) */
  149. Xextern char *optarg;
  150. X
  151. X/* We'll set a timer later. If it goes off, something's messed up. */
  152. Xbomb()
  153. X{
  154. X
  155. X  printf("Timeout. Check clock.\n");
  156. X  exit(1);
  157. X
  158. X}
  159. X
  160. X/* A hack. getc() didn't work for some reason. */
  161. Xchar get_c(fildes)
  162. Xint fildes;
  163. X{
  164. X  char c;
  165. X  read(fildes,&c,1);
  166. X  return c;
  167. X}
  168. X
  169. Xmain(argc,argv)
  170. Xint argc;
  171. Xchar **argv;
  172. X{
  173. X
  174. X  int clkfil,dbg_flag=0,usec,hr,timedif=DEFAULT_MINUS_L,errflag=0;
  175. X  char a[255],*b,optchar;
  176. X  time_t hydrant;
  177. X
  178. X  struct timeval tv;
  179. X  struct timezone tz;
  180. X  struct tm convert;
  181. X
  182. X  struct sgttyb ttystuff;
  183. X
  184. X#ifdef YEARFILE
  185. X  FILE *yf;
  186. X  int yf_yr;
  187. X#endif
  188. X
  189. X  opterr=0;
  190. X
  191. X  while((optchar=getopt(argc,argv,"dl:"))!=-1)
  192. X  {
  193. X    switch(optchar)
  194. X    {
  195. X      case 'd':dbg_flag++; break;
  196. X      case 'l':timedif=atoi(optarg); break;
  197. X      default:errflag++;
  198. X    }
  199. X  }
  200. X  if (errflag)
  201. X  {
  202. X    printf("Usage: %s [-d] [-l min]\n",*argv);
  203. X    exit(1);
  204. X  }
  205. X
  206. X/* if YEARFILE, we'd better read it now so it won't interfere with the
  207. Xtight timing section later */
  208. X#ifdef YEARFILE
  209. X  yf=fopen(YEARFILE,"r");
  210. X  scanf("%d\n",&yf_yr);
  211. X  fclose(yf);
  212. X#endif
  213. X
  214. X#ifdef NICE
  215. X  nice(NICE);
  216. X#endif
  217. X
  218. X  alarm(15);
  219. X  signal(SIGALRM,bomb);
  220. X
  221. X  if ((clkfil=open(DEVICE,2))==NULL)
  222. X  {
  223. X    printf("Error opening %s.\n",DEVICE);
  224. X    exit(1);
  225. X  }
  226. X
  227. X/* set for baud rate and RAW */
  228. X  ttystuff.sg_ispeed=BAUD;
  229. X  ttystuff.sg_ospeed=BAUD;
  230. X  ttystuff.sg_kill=' ';
  231. X  ttystuff.sg_erase=' ';
  232. X  ttystuff.sg_flags=RAW;
  233. X  if (ioctl(clkfil,TIOCSETP,&ttystuff)==-1)
  234. X  {
  235. X    printf("Error setting up %s.\n",DEVICE);
  236. X    exit(1);
  237. X  }
  238. X/*
  239. XWait for end of line, then read until another. If seconds>50,
  240. Xwait for it to go to 0. We have to add 1 to the seconds, and if it's
  241. X:59..... Also, if the line's too short, read it again.
  242. X*/
  243. X  while((get_c(clkfil) & '')!='\r');
  244. X  do {
  245. X    b=a;
  246. X    while((*b=get_c(clkfil) & '')!='\r') b++;
  247. X    *b='\0';
  248. X  } while (a[6]=='5' || strlen(a)!=23);
  249. X/*
  250. X
  251. X     START OF TIME CRITICAL SECTION
  252. X
  253. XFrom here to end of critical section must be executed as quickly as
  254. Xpossible to (try to) insure accuracy
  255. X
  256. Xa[9] is the tenth of a second digit. The clock outputs a ? here if
  257. Xeither the clock is not set, or if it hasn't been updated in 24
  258. Xhours and therefore isn't sure of itself.
  259. X*/
  260. X  if (a[9]=='?')
  261. X  {
  262. X    printf("Clock not set.\n");
  263. X    exit(1);
  264. X  }
  265. X
  266. X  usec=atoi(a+9)*100;
  267. X  hr=atoi(a);
  268. X
  269. X#ifdef AMPM
  270. X  if (a[11]=='P') 
  271. X  {
  272. X    if (hr!=12) hr+=12;
  273. X  }
  274. X  if (a[11]=='A')
  275. X  {
  276. X    if (hr==12) hr=0;
  277. X  }
  278. X#endif
  279. X
  280. X  time(&hydrant);
  281. X  convert=*LOCALTIME(&hydrant);
  282. X  convert.tm_min=atoi(a+3);
  283. X  convert.tm_sec=atoi(a+6)+1;
  284. X  convert.tm_hour=hr;
  285. X  convert.tm_mon=atoi(a+15)-1;
  286. X  convert.tm_mday=atoi(a+18);
  287. X
  288. X#ifdef CLOCKYEAR
  289. X  convert.tm_year=atoi(a+21);
  290. X#endif
  291. X
  292. X#ifdef YEARFILE
  293. X  convert.tm_year=yf_yr;
  294. X#endif
  295. X
  296. X  hydrant=TIMELOCAL(&convert);
  297. X
  298. X  if (dbg_flag)
  299. X  {
  300. X    printf("%s",ctime(&hydrant));
  301. X    exit(0);
  302. X  }
  303. X
  304. X  if ( (abs(time(0L)-hydrant)>(timedif*60)) && (timedif) )
  305. X  {
  306. X    printf("Clock shows substantially different time. Check clock.\n");
  307. X    exit(1);
  308. X  }
  309. X
  310. X/*
  311. XNow hydrant is the current ctime (num of secs since epoch)
  312. X*/
  313. X
  314. X  gettimeofday(&tv,&tz);
  315. X  tv.tv_sec=hydrant;
  316. X  tv.tv_usec=usec;
  317. X  if (!dbg_flag)
  318. X    if (settimeofday(&tv,&tz)!=0)
  319. X    {
  320. X      printf("settimeofday(): %s\n",sys_errlist[errno]);
  321. X      exit(1);
  322. X    }
  323. X
  324. X/*
  325. X
  326. XEND OF TIME CRITICAL SECTION
  327. X
  328. X*/
  329. X
  330. Xexit(0);
  331. X
  332. X}
  333. EOF
  334. chars=`wc -c < 'gc1000.c'`
  335. if test $chars !=     8123; then echo 'gc1000.c' is $chars characters, should be     8123 characters!; fi
  336. fi
  337. exit 0
  338. -- 
  339. Nick Sayer               |  Disclaimer:
  340. N6QQQ [44.2.1.17 soon]   |    "Just because you're reading my post doesn't
  341. mrapple@quack.sac.ca.us  |     mean we're gonna take long showers together."
  342. 209-952-5347 (Telebit)   |                      -- Gunnery Sgt. Thomas Highway
  343.  
  344.