home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / sources / 3b1 / 83 < prev    next >
Encoding:
Text File  |  1992-09-03  |  34.4 KB  |  1,302 lines

  1. Path: sparky!uunet!comp-sources-3b1
  2. From: zebra!vern (Vernon C. Hoxie)
  3. Newsgroups: comp.sources.3b1
  4. Subject: v02i030:  NIST.timechk, version 2.1, Part02/02
  5. Date: 4 Sep 1992 12:18:16 -0400
  6. Organization: UUNET Communications
  7. Lines: 1288
  8. Sender: dhb@ftp.UU.NET
  9. Approved: dave@galaxia.network23.com
  10. Message-ID: <188288INN7k8@ftp.UU.NET>
  11. NNTP-Posting-Host: ftp.uu.net
  12. X-Checksum-Snefru: 24d5bf74 78e2632a c0948552 6b9f58bc
  13.  
  14. Submitted-by: zebra!vern (Vernon C. Hoxie)
  15. Posting-number: Volume 2, Issue 30
  16. Archive-name: nistchk/part02
  17.  
  18.  
  19. ---------------------------- cut here ------------------------------------
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 2 (of 2)."
  27. # Contents:  NISTtime.c calc.c obm.c
  28. # Wrapped by vern@zebra on Thu Aug 27 11:06:33 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f NISTtime.c -a "${1}" != "-c" ; then 
  31.   echo shar: Will not over-write existing file \"NISTtime.c\"
  32. else
  33. echo shar: Extracting \"NISTtime.c\" \(13458 characters\)
  34. sed "s/^X//" >NISTtime.c <<'END_OF_NISTtime.c'
  35. X#sccs    "@(#)    NIST.time:NISTtime.c    2.1"    8/27/92
  36. X
  37. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  38. X *                                                                     *
  39. X *  Copyright (c) July, 24, 1989, August 8, 1992 by Vernon C. Hoxie    *
  40. X *                                                                     *
  41. X *      This source code may be freely distributed as long as this     *
  42. X *      copyright notice is included.  No monetary charges should      *
  43. X *      be made in excess of the cost of copying and distribution.     *
  44. X *                                                                     *
  45. X *      Any profits which might be derived from the sale of this       *
  46. X *      work must be shared with me.  Other monetary contributions     *
  47. X *      will be gratefully accepted.                                   *
  48. X *                                                                     *
  49. X *         Vernon C. Hoxie, zebra!vern, vern@zebra.alphacdc.com        *
  50. X *                                                                     *
  51. X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  52. X
  53. X
  54. X
  55. X#include "NISTtime.h"
  56. X#include <time.h>
  57. X#include <string.h>
  58. X
  59. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  60. X * Usage: "NIST.time -c tty000" correct clock using "/dev/tty000"    *
  61. X *      "NIST.time -i tty000" reset clock from scratch.                 *
  62. X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  63. X
  64. X#ifndef DVC_LEN
  65. X#define DVC_LEN 30            /* Defined in <dial.h> */
  66. X#endif
  67. X
  68. X/* This is the start up getty used to set-up a smart modem */
  69. X
  70. Xstruct termio my_getty = 
  71. X{
  72. X    IGNBRK | IGNPAR | ICRNL | IXANY,                /* c_iflag   */
  73. X    0,                                              /* c_oflag   */
  74. X     B1200 | CS8 | CREAD | HUPCL | CTSCD | CLOCAL,   /* c_cflag   */
  75. X    ISIG,                                           /* c_lflag   */
  76. X    0,                                              /* c_line    */
  77. X    {                                               /* c_cc[NCC] */
  78. X        CINTR,              /* VINTR  = DEL    */
  79. X        CQUIT,              /* VQUIT  = FS     */
  80. X        CERASE,             /* VERASE = BS     */
  81. X        CKILL,              /* VKILL  = '@'    */
  82. X        1,                  /* VMIN  = 1 char  */
  83. X        0                   /* VTIM  = 0 sec   */
  84. X    }
  85. X};
  86. X
  87. Xextern int run_mod( );
  88. Xextern long sys_delta;
  89. Xextern int dst;
  90. X
  91. Xmain(argc,argv)
  92. Xint argc;
  93. Xchar *argv[];
  94. X
  95. X{
  96. X    void set_time( );
  97. X    void trunc_errs( );
  98. X    int done, high;
  99. X    char cflag, iflag;
  100. X    char *optp;
  101. X    char devname[DVC_LEN];
  102. X    cflag = '\0';
  103. X    iflag = '\0';
  104. X    if ( argc < 2 ) usage( );
  105. X    while (--argc > 0)
  106. X    {
  107. X        done = 0;
  108. X        optp = argv[argc];
  109. X    /* set the option flags from the command line following a '-' */
  110. X
  111. X        if (*optp == '-')
  112. X        {
  113. X            while ( *optp++ && ! done )
  114. X            {
  115. X                switch ( *optp )
  116. X                {
  117. X                    case 'c': cflag = *optp; break;
  118. X                    case 'i': iflag = *optp; break;
  119. X                    default: done = 1;
  120. X                }
  121. X            }
  122. X            --optp;
  123. X        }
  124. X
  125. X        /* devname will be the last entry on the command line. */
  126. X        
  127. X        else if ( ! devname[0] ) strcpy( devname, optp );
  128. X    }
  129. X    if ( ! cflag && ! iflag ) usage( ); 
  130. X
  131. X        /* Put 'stderr' into /tmp/NIST temporarily */
  132. X
  133. X    freopen( TMP_ERRS, "w+", stderr );
  134. X
  135. X    if ( iflag ) boot = 1;
  136. X    else boot = 0;
  137. X
  138. X    if ( cflag || iflag ) set_time( devname );
  139. X
  140. X    /* Check if any errors were recorded */
  141. X    if (( high = ftell( stderr )) > 0 ) trunc_errs( high );
  142. X    unlink( TMP_ERRS );
  143. X
  144. X    exit( 0 );
  145. X}                    /* main() */
  146. X
  147. Xusage( )
  148. X
  149. X{
  150. X    fprintf( stderr,
  151. X     "Usage: NIST.time - [ c ][ i ] ph#/tty###\n" );
  152. X    exit( 0 );
  153. X}
  154. X
  155. Xvoid set_time( name )
  156. Xchar *name;
  157. X
  158. X{
  159. X    extern int run_obm( );
  160. X    extern int run_mod( );
  161. X    void update( );
  162. X    void sig_sleep( );
  163. X    void sign_off( );
  164. X    
  165. X    char *pph, *dev;
  166. X    char *ptty, *pscan;
  167. X    char *tty = "tty";
  168. X    char *ph = "ph";
  169. X    int k, ret;
  170. X    pph = ph;
  171. X    ptty = tty;
  172. X    pscan = name;
  173. X    dev = name;
  174. X
  175. X    /* Scan 'name' for "ph" or "tty".  These pointers will be the */
  176. X    /* flags for selecting the OBM or smart modem routine.        */
  177. X
  178. X    while ( *pscan && *pph && *ptty )
  179. X    {
  180. X        if ( *pph == *pscan) pph++;
  181. X            else pph = ph;
  182. X        if ( *ptty == *pscan ) ptty++;
  183. X        else ptty = tty;
  184. X
  185. X        /* Trim off any path name provided */
  186. X        if ( *pscan  == '/' ) dev = pscan + 1;
  187. X        pscan++;
  188. X    }
  189. X#ifdef DEBUG
  190. X    printf("Device name = %s\n", name);
  191. X#endif
  192. X    if ( ! *pscan ) usage( );
  193. X
  194. X    /* Limit activity to eight attempts then log an error message. */
  195. X
  196. X    for ( k = 8; k; k-- )
  197. X    {
  198. X        sys_delta = 0;        /* Reset delta time accumulator */
  199. X        if ( ! *pph )
  200. X        {
  201. X            ret = run_obm( dev );
  202. X            if ( tiofd > 0 )
  203. X            {
  204. X                if ( ret <= -10 )
  205. X                {
  206. X                    tiofd = 0;
  207. X                    ret += 10;
  208. X                }
  209. X                else sign_off();
  210. X            }
  211. X        }
  212. X        else if ( ! *ptty )
  213. X        {
  214. X            ret = run_mod( dev );
  215. X            sign_off( dev );
  216. X        }
  217. X        alarm( 0 );
  218. X        if ( ret == 0 )
  219. X        {
  220. X            update();
  221. X            return;
  222. X        }
  223. X        if ( ret < 0 )
  224. X        {
  225. X            fprintf(stderr,
  226. X                 "There was a fundamental system error.\n");
  227. X            fprintf(stderr,
  228. X                    "The return code was %d\n", ret);
  229. X            break;
  230. X        }
  231. X        fflush( stderr );
  232. X#ifdef DEBUG
  233. X        printf("Sleep for %d secs. Retries to go, %d\n",
  234. X                ret, k - 1 );
  235. X#endif
  236. X        alarm( ret );
  237. X        signal( SIGALRM, sig_sleep ); 
  238. X        pause( );
  239. X    }
  240. X    fprintf( stderr, "Exceeded eight errors.\n" );
  241. X    return;
  242. X}            /* set_time() */
  243. X
  244. Xvoid trunc_errs( high )
  245. Xint high;
  246. X
  247. X{
  248. X    char *wrk, *buf;
  249. X    int efd, lfd, size1, size2;
  250. X    long now;
  251. X
  252. X            /* Close stderr so that it can be reopened for reading. */
  253. X    fclose( stderr );
  254. X    size1 = ERR_SIZE + high + 10;
  255. X    buf = malloc( size1 );
  256. X
  257. X            /* First enter the time stamp */
  258. X    time( &now );
  259. X    sprintf( buf, "Date: %s", ctime( &now ));
  260. X    wrk = buf + strlen( buf );
  261. X    efd = open( TMP_ERRS, O_RDONLY );
  262. X    wrk += read( efd, wrk, high );
  263. X    close ( efd );
  264. X    *wrk++ = '\n';                            /* Mark the entry boundary */
  265. X
  266. X        /* Open the error log file and transfer */
  267. X        /* the entire file to 'buf' buffer.     */
  268. X    lfd = open( LOG_ERRS, O_RDWR | O_CREAT, 0666 );
  269. X    if ( size2 = ( ERR_SIZE + high + wrk - buf ) > size1 ) {
  270. X        size2 = size1;
  271. X    }
  272. X    wrk += read( lfd, wrk, size2 );
  273. X
  274. X        /* Limit size of error log. */
  275. X    if (( wrk - buf ) >= ERR_SIZE ) {
  276. X        while (( wrk-- - buf ) >= ERR_SIZE );
  277. X        while ( 1 ) {
  278. X            while ( *wrk-- != '\n' );
  279. X            if ( *wrk == '\n' ) break;
  280. X        }
  281. X        wrk++;
  282. X    }
  283. X    close( lfd );
  284. X            /* Reopen to truncate. */
  285. X    lfd = open( LOG_ERRS, O_RDWR | O_TRUNC, 0666 );
  286. X    write( lfd, buf, wrk - buf );
  287. X    close( lfd );
  288. X    return;
  289. X}                    /* trunc_errs() */
  290. X
  291. Xvoid sig_timeout()
  292. X{
  293. X    signal( SIGALRM, sig_timeout );
  294. X    fprintf( stderr, "Timeout. " );
  295. X    longjmp( place, 180 );
  296. X    return;
  297. X}                    /* sig_timeout() */
  298. X
  299. X    /* Used with the 'pause( )' command to catch and reset the      */
  300. X    /* alarm signals.  The same as 'sleep( ) but seems to be safer. */
  301. X
  302. Xvoid sig_sleep( )
  303. X{
  304. X    signal( SIGALRM, sig_sleep );
  305. X#ifdef DEBUG
  306. X    printf("'sig_sleep()' completed.\n");
  307. X#endif
  308. X    return;
  309. X}                    /* sig_sleep() */
  310. X
  311. X#define CLOCK_TICK 1000/HZ        /* HZ = 60 for unix-pc */
  312. X
  313. X/* This routine is "borrowed" from kermit.  Its a handy little    */
  314. X/* routine and if you are building your own library of pets,   */
  315. X/* consider this for inclusion - vch.  m = msec of delay.      */
  316. X
  317. Xint mpause( m )
  318. Xint m;
  319. X
  320. X{
  321. X    extern long times( );
  322. X    long t1, t2, tarray[4];
  323. X    int t3;
  324. X
  325. X    if ( m <= 0 ) return( 0 );
  326. X     if (( t1 = times( tarray )) < 0) return( -1 );
  327. X    while (1)
  328. X    {
  329. X        if (( t2 = times( tarray )) < 0) return( -1 );
  330. X        t3 = (( int )( t2 - t1 )) * CLOCK_TICK;
  331. X        if ( t3 > m ) return( t3 );
  332. X     }
  333. X}                    /* mpause() */
  334. X
  335. Xint open_tty( dev )
  336. Xchar *dev;
  337. X
  338. X{
  339. X    int j;
  340. X    int c_flag, init_baud;
  341. X    char full_name[30];
  342. X
  343. X    strcat( strcpy( full_name, DEVPATH ), dev );
  344. X
  345. X    if (( j = access( full_name, 0 )) < 0 )
  346. X    {
  347. X        fprintf( stderr, "%s doesn't exist!\n", full_name );
  348. X        return( -1 );
  349. X    }
  350. X
  351. X    if (( j = open( full_name, O_RDWR | O_NDELAY ) ) == -1 )
  352. X    {
  353. X        fprintf( stderr, "Opening port %s, %s\n",
  354. X                full_name, sys_errlist[errno] );
  355. X        return( -1 );
  356. X    }
  357. X
  358. X#ifdef DEBUG
  359. X    printf( "The file for %s opened with fildes of %d\n",
  360. X            full_name, j);
  361. X#endif
  362. X
  363. X    if (( ioctl( j, TCGETA, &old_getty ) ) == -1 )
  364. X    {
  365. X        fprintf( stderr, "open_tty(), TCGETA old_getty, %s\n",
  366. X                sys_errlist[errno] );
  367. X        return( -1 );
  368. X    }
  369. X
  370. X    c_flag = my_getty.c_cflag & ~CBAUD;
  371. X#ifdef OBM
  372. X#ifdef EXTERNAL
  373. X    if ( strncmp( dev, "ph", 2 ) == 0 ) init_baud = B1200;
  374. X    else init_baud = INIT_BAUD;
  375. X#else        /* ! EXTERNAL */
  376. X    init_baud = B1200;
  377. X#endif
  378. X#else        /* ! OBM */
  379. X    init_baud = INIT_BAUD;
  380. X#endif
  381. X    my_getty.c_cflag = c_flag | init_baud | CLOCAL | CTSCD ;
  382. X
  383. X    if (( ioctl( j, TCSETA, &my_getty ) ) == -1 )
  384. X    {
  385. X        fprintf( stderr, "open_tty(), TCSETA my_getty, %s\n",
  386. X                sys_errlist[errno] );
  387. X        return( -1 );
  388. X    }
  389. X    return( j );            /* The return will be 'tiofd' */
  390. X}    /* open_tty() */
  391. X
  392. X    /* Open LCK..NIST in /usr/spool/uucp and insert our pid.  */
  393. X    /* Then try linking to a LCK.. file.  If there is an      */
  394. X    /* existing one, 'link()' will fail with errno set to     */
  395. X    /* EEXIST.  See if the process which set the LCK.. file   */
  396. X    /* still active with 'kill( opid, 0 ).  If it is active,  */
  397. X    /* return with a sleep value.  If inactive, commandeer    */
  398. X    /* it by 'unlink()' and then link it to LCK..NIST.        */
  399. X
  400. X    /* This revised sequence was suggested by Karl Swartz.    */
  401. X    /*   Thanks Karl!                                         */
  402. X
  403. Xint lock_it( dev )
  404. Xchar *dev;
  405. X
  406. X{
  407. X    int tfd, lfd;
  408. X    int pid, oldpid = 0;
  409. X
  410. X    strcat( strcpy( lck_file, LCKPATH ), dev );
  411. X    strcat( strcpy( nist_file, LCKPATH ), "NIST" );
  412. X
  413. X#ifdef DEBUG
  414. X    printf("lck_file = >%s<\n", lck_file);
  415. X    printf("nist_file = >%s<\n", nist_file);
  416. X#endif
  417. X
  418. X    if (( tfd = open ( nist_file, O_WRONLY | O_CREAT, 0666 ) ) <= 0 )
  419. X    {
  420. X        fprintf( stderr, "Can't open %s, %s\n",
  421. X                nist_file, sys_errlist[errno] );
  422. X        return( -1 );
  423. X    }
  424. X    pid = getpid();
  425. X    write( tfd, &pid, sizeof( int ));
  426. X    close( tfd );
  427. X    if (( link( nist_file, lck_file )) < 0 )
  428. X    {
  429. X        if ( errno != EEXIST )
  430. X        {
  431. X            fprintf( stderr, "Can't link %s to %s, %s\n",
  432. X                nist_file, lck_file, sys_errlist[errno] );
  433. X            return( -1 );
  434. X        }
  435. X        if (( lfd = open( lck_file, O_RDWR )) < 0 )
  436. X        {
  437. X            fprintf( stderr, "Can't open existing %s file, %s\n",
  438. X                lck_file, sys_errlist[errno] );
  439. X            return( -1 );
  440. X        }
  441. X        if (( read( lfd, &oldpid, sizeof( int ) ) ) < 0 )
  442. X        {    /* Give up if we can't read it */
  443. X            fprintf( stderr, "Can't read %s file, %s\n",
  444. X                lck_file, sys_errlist[errno] );
  445. X            return( -1 );
  446. X        }
  447. X
  448. X        if (pid != oldpid && ( kill( oldpid, 0 )) == 0 )
  449. X        {    /* We can't kill() it if it is in use! */
  450. X            fprintf( stderr, "%s is in use by pid %d\n",
  451. X                    dev, oldpid );
  452. X            return( 300 );
  453. X        }
  454. X        unlink( lck_file );
  455. X        if (( link( nist_file, lck_file )) < 0 )
  456. X        {
  457. X            fprintf( stderr, "Second Link of %s to %s failed, %s\n",
  458. X                nist_file, lck_file, sys_errlist[errno] );
  459. X            return( -1 );
  460. X        }
  461. X    }
  462. X    hasLock = 1;
  463. X    return( 0 );
  464. X}                    /* lock_it() */
  465. X
  466. X#ifdef DUMPGETTY
  467. X
  468. X#define INITTAB "/etc/inittab"
  469. X
  470. X    /* This routine changes the entry in '/etc/inttab' associated */
  471. X    /* with the device from a ' ' to ':' or back again depending  */
  472. X    /* upon the char 'new' which is passed to it.  After changing */
  473. X    /* the init table, it performs 'kill(1,1)' which causes the   */
  474. X    /* inittab to be re-examined.  This is a variation of a       */
  475. X    /* replacement for '/usr/lib/setgetty' on the Unix-pc.  That  */
  476. X    /* replacement was written by John B. Milton.                 */
  477. X
  478. Xint do_getty( dev, new )
  479. Xchar *dev, new;
  480. X
  481. X{
  482. X    int j;
  483. X    int ifd;
  484. X    int this;
  485. X    int last;
  486. X    
  487. X    char old;
  488. X    char test[6];
  489. X    char buf[85];
  490. X    char *pscan;
  491. X    char *ptarg;
  492. X    char *anch;
  493. X    
  494. X    if ( new == ' ') old = ':';
  495. X    else if ( new = ':' ) old = ' ';
  496. X#ifdef DEBUG
  497. X    else
  498. X    {
  499. X        printf("Bad option to 'do_getty()', use ' ' or ':'\n");
  500. X        exit( -1 );
  501. X    }
  502. X    if ( getuid( ) )
  503. X    {
  504. X        printf( 
  505. X           "You must be running as 'su' to dump a 'uugetty'.\n" );
  506. X        return( -1 );
  507. X    }
  508. X#endif
  509. X    
  510. X    if (( ifd = open( INITTAB, O_RDWR ) ) < 0 )
  511. X    {
  512. X        fprintf( stderr, "Can't open %s, %s\n",
  513. X                INITTAB, sys_errlist[errno] );
  514. X        return( -1 );
  515. X    }
  516. X    
  517. X    anch = dev;
  518. X    while ( *++anch );
  519. X    anch -= 3;            /* get last three characters */
  520. X
  521. X    this = 0;
  522. X    ptarg = test;
  523. X    *ptarg++ = '\n';
  524. X    *ptarg++ = old;
  525. X    while ( *ptarg++ = *anch++);
  526. X    ptarg = test;
  527. X    while ( *ptarg )
  528. X    {
  529. X        if (( j = read( ifd, buf, sizeof(buf) - 1 )) < 0 )
  530. X        {
  531. X            fprintf( stderr, "Can't read %s, %s\n",
  532. X                INITTAB, sys_errlist[errno] );
  533. X            close( ifd );
  534. X            return( -1 );
  535. X        }
  536. X        if ( j == 0 )
  537. X        {
  538. X            had_getty = old;
  539. X#ifdef DEBUG
  540. X            printf( "Attempt to switch 'uugetty' failed.\n");
  541. X#endif
  542. X            close( ifd );
  543. X            return( 0 );
  544. X        }
  545. X        last = this;
  546. X        this += j;
  547. X        for ( pscan = buf; j && *ptarg; pscan++, j-- )
  548. X        {
  549. X            if ( *pscan == *ptarg ) ptarg++;
  550. X            else ptarg = test;
  551. X        }
  552. X    }
  553. X#ifdef DEBUG
  554. X    printf( "There was a getty.\n" );
  555. X#endif
  556. X    *(pscan - 4) = new;
  557. X    lseek( ifd, last, 0 );
  558. X    write( ifd, buf, this - last);
  559. X    had_getty = new;
  560. X    close( ifd );
  561. X        /* A sloppy 'telinit(1) q' */
  562. X    j = kill( 1, 1 );
  563. X    sleep( 5 );            /* Give the modem time to reset */
  564. X    return( j );
  565. X}                    /* do_getty() */
  566. X#endif    /* #if DUMPGETTY */
  567. X
  568. X    /* Close up whatever tty files we can after collecting  */
  569. X    /* the data.                                            */
  570. X
  571. X
  572. Xvoid sign_off( dev )
  573. Xchar *dev;
  574. X
  575. X{
  576. X    if ( tiofd > 0 )
  577. X    {
  578. X        if ( ioctl( tiofd, TCSETA, &old_getty ) == -1 )
  579. X        {
  580. X            fprintf( stderr, "sign_off(), TCSETA old_getty, %s\n",
  581. X                sys_errlist[errno] );
  582. X        }
  583. X
  584. X#ifdef OBM
  585. X        if ( strpbrk( dev, "ph" ))
  586. X        {
  587. X             if ( ioctl( tiofd, PIOCDISC, &old_phset ) == -1 )
  588. X                fprintf( stderr, "PIOCDISC old_phset, %s\n",
  589. X                    sys_errlist[errno] );
  590. X        }
  591. X#endif    /* #ifdef OBM */
  592. X        close( tiofd );
  593. X    }
  594. X    tiofd = 0;
  595. X#ifdef DEBUG
  596. X    printf( "The 'sign_off()' device is %s\n", dev );
  597. X#endif
  598. X    if ( hasLock )
  599. X    {
  600. X        unlink( lck_file );
  601. X        hasLock = 0;
  602. X    }
  603. X    if (( access( nist_file, 0 )) == 0 ) unlink( nist_file );
  604. X#ifdef DUMPGETTY
  605. X      if ( had_getty == ':' ) do_getty( dev, ' ' );
  606. X#endif    /* #ifdef DUMPGETTY */
  607. X
  608. X}                    /* sign_off() */
  609. END_OF_NISTtime.c
  610. if test 13458 -ne `wc -c <NISTtime.c`; then
  611.     echo shar: \"NISTtime.c\" unpacked with wrong size!
  612. fi
  613. # end of overwriting check
  614. fi
  615. if test -f calc.c -a "${1}" != "-c" ; then 
  616.   echo shar: Will not over-write existing file \"calc.c\"
  617. else
  618. echo shar: Extracting \"calc.c\" \(9707 characters\)
  619. sed "s/^X//" >calc.c <<'END_OF_calc.c'
  620. X#sccs    "@(#)    NIST.time:calc.c    2.1"    8/27/92
  621. X
  622. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  623. X *                                                                     *
  624. X *  Copyright (c) July, 24, 1989, August 8, 1992 by Vernon C. Hoxie    *
  625. X *                                                                     *
  626. X *      This source code may be freely distributed as long as this     *
  627. X *      copyright notice is included.  No monetary charges should      *
  628. X *      be made in excess of the cost of copying and distribution.     *
  629. X *                                                                     *
  630. X *      Any profits which might be derived from the sale of this       *
  631. X *      work must be shared with me.  Other monetary contributions     *
  632. X *      will be gratefully accepted.                                   *
  633. X *                                                                     *
  634. X *         Vernon C. Hoxie, zebra!vern, vern@zebra.alphacdc.com        *
  635. X *                                                                     *
  636. X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  637. X
  638. X
  639. X
  640. X#include "NISTtime.h"
  641. X#include <sys/rtc.h>
  642. X#include <sys/syslocal.h>
  643. X#include <time.h>
  644. X
  645. Xlong sys_delta;
  646. Xint dst;
  647. X
  648. X    /* Translate the ascii data read in from NIST to a            */
  649. X    /* 'struct tm' for use in time comparison.  This may not be   */
  650. X    /* elegant in the context of the best use of 'C' library      */  
  651. X    /* functions, but it should be fast.  There are also a number */
  652. X    /* of checks to verify that we are converting a valid data    */
  653. X    /* string.                                                    */
  654. X
  655. Xint get_data(line)
  656. Xchar *line;
  657. X
  658. X{
  659. X    struct tm *gmt, nist;
  660. X    int dif[6];
  661. X    long now;
  662. X    int i, j;
  663. X    char *lpt;
  664. X    
  665. X    /* Get the system time as near as possible to the */
  666. X    /* receipt of the end of the NIST data line.      */
  667. X
  668. X    time( &now );
  669. X
  670. X    /* A return of 0 forces an additional data line to be read. */
  671. X
  672. X    lpt = line;
  673. X        /* Skip over the Julian date */
  674. X    while ( *lpt++ != ' ' );
  675. X
  676. X    nist.tm_year = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  677. X    if ( *lpt++ != '-' ) return( 0 );
  678. X    nist.tm_mon  = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  679. X    if ( *lpt++ != '-' ) return( 0 );
  680. X    nist.tm_mday = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  681. X    if ( *lpt++ != ' ' ) return( 0 );
  682. X    nist.tm_hour = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  683. X    if ( *lpt++ != ':' ) return( 0 );
  684. X    nist.tm_min  = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  685. X    if ( *lpt++ != ':' ) return( 0 );
  686. X    nist.tm_sec  = (( *lpt++ & 0x0f ) * 10 ) + ( *lpt++ & 0x0f );
  687. X    if ( *lpt++ != ' ' ) return( 0 );
  688. X
  689. X    /* Save the daylight savings time marker for the dst() readout */
  690. X
  691. X    dst = 0;
  692. X    while ( *lpt != ' ' ) dst = ( dst * 10 ) + ( *lpt++ & 0x0f );
  693. X
  694. X        /* If called with the '-i' option, boot will be TRUE.   */
  695. X        /* We will use the first response from NIST to set date */
  696. X        /* and time.  After it has been set, we will go ahead   */
  697. X        /* and collect eight samples to fine tune the time.     */
  698. X     
  699. X#ifdef DEBUG
  700. X    printf("sys = %d, ", now );
  701. X#endif
  702. X    if ( boot )
  703. X    {
  704. X            /* Adjust for month of year */
  705. X        j = 0;
  706. X        boot = 0;
  707. X        switch ( nist.tm_mon )
  708. X        {
  709. X            case 12:
  710. X            case 11: j++;
  711. X            case 10:
  712. X            case  9: j++;
  713. X            case  8: j++;
  714. X            case  7:
  715. X            case  6: j++;
  716. X            case  5:
  717. X            case  4: j++;
  718. X            case  3: if ( nist.tm_year % 4 ) j -= 2;
  719. X                 else j--;
  720. X            case  2: j++;
  721. X            case  1: break;
  722. X        }
  723. X
  724. X        /* In case this is running past the year 2000 */
  725. X        if ( nist.tm_year < 70 ) nist.tm_year += 30;
  726. X        else nist.tm_year -= 70;
  727. X
  728. X    /* Adjust for leap years and toss in the month adjustment */
  729. X        nist.tm_mday = nist.tm_mday + (( nist.tm_year + 1 ) >> 2 )
  730. X                                + j;
  731. X
  732. X        now = nist.tm_year * 31536000 + ( nist.tm_mon - 1) * 2592000
  733. X            + ( nist.tm_mday - 1 ) * 86400 + nist.tm_hour * 3600
  734. X            + nist.tm_min * 60 + nist.tm_sec - 3;
  735. X        stime( &now );
  736. X        return( 0 );
  737. X    }
  738. X#ifdef DEBUG
  739. X    printf( "NIST = %d.\n", now );
  740. X#endif
  741. X    /* Fill the dif[] array with the time differences. */
  742. X
  743. X    gmt = gmtime( &now );
  744. X    dif[5] = nist.tm_year - gmt->tm_year;
  745. X    dif[4] = nist.tm_mon  - gmt->tm_mon - 1;
  746. X    dif[3] = nist.tm_mday - gmt->tm_mday;
  747. X    dif[2] = nist.tm_hour - gmt->tm_hour;
  748. X    dif[1] = nist.tm_min  - gmt->tm_min;
  749. X    dif[0] = nist.tm_sec  - gmt->tm_sec;
  750. X
  751. X    /* Add up the differences in dates and do an update      */
  752. X    /* only if they have a difference of zero.  That is,     */
  753. X    /* do fine tuning only if we have the same date as NIST. */
  754. X
  755. X    for (i = 3, j = 0; i < 6; j = j + dif[i++]);
  756. X    if (j == 0) sys_delta = sys_delta + dif[0] + (dif[1] * 60)
  757. X                + (dif[2] * 3600) - 1;
  758. X    return(1);
  759. X}        /* get_data() */
  760. X
  761. X    /* Perform the actual clock update from the data collected by  */
  762. X    /* get_data( ).  This runs after the modem has hung up.        */
  763. X
  764. X    /* Since the error in the clock was summed over eight samples, */
  765. X    /* we round off the data by 1/2 sec before dividing by eight.  */
  766. X
  767. X    /* In order to avoid conflicts with crontab entries, the       */
  768. X    /* corrections are parsed in increments of 50 sec.  Plus       */
  769. X    /* increments are made at the fifth second and then a sleep()  */
  770. X    /* of 70 seconds is performed.  Negative increments are made   */
  771. X    /* at the 55th second and then a sleep() of 50 sec. is         */
  772. X    /* performed.                                                  */
  773. X
  774. Xvoid update()
  775. X
  776. X{
  777. X    void log_it();
  778. X    char *bufa[80], bufb[80];
  779. X    int del, dt, nap, fflag;
  780. X    long rtc_delta;
  781. X    long now;
  782. X    struct tm *sys_now;
  783. X    extern dst;
  784. X#ifdef UNIXPC
  785. X    struct rtc rtc_now, rtc_was;
  786. X#endif
  787. X
  788. X    /* The data was summed for eight valid data points.  Now we */
  789. X    /* round off by adding four then divide by eight. */
  790. X
  791. X    sys_delta = sys_delta >= 0 ? ( sys_delta + 4 ) >> 3
  792. X                 : ( sys_delta - 4 ) >> 3;
  793. X    dt = sys_delta;        /* Copy for incremental updates. */
  794. X    
  795. X    time( &now );        /* Get system time for log. */
  796. X    sys_now = gmtime( &now );
  797. X    sprintf( bufa, "%.24s, ", ctime( &now ));
  798. X
  799. X#ifdef NOSET
  800. X     if ( 1 )    /* During testing, we can calculate the    */
  801. X#else            /* corrections we just won't install them. */
  802. X
  803. X        /* Only 'su' can update clock. */
  804. X    if ( getuid( ))
  805. X#endif
  806. X    {
  807. X        sprintf( bufb, "Corr. %3d. Not installed.\n", sys_delta );
  808. X        strcat( bufa, bufb );
  809. X        log_it( bufa );
  810. X        return;
  811. X    }
  812. X    
  813. X#ifdef DEBUG
  814. X    printf( "Correction is %d sec. at %d sec.  Taking a nap .. zzz\n",
  815. X        dt, sys_now->tm_sec );
  816. X#endif
  817. X        /* Loop until full correction is installed. */
  818. X    
  819. X    if ( dt < 0 )
  820. X    {
  821. X        link( "/usr/lib/crontab", "/usr/lib/tmp.cron" );
  822. X        unlink( "/usr/lib/crontab" );
  823. X        fflag = 1;
  824. X    }
  825. X    else fflag = 0;
  826. X
  827. X    while ( dt )
  828. X    {
  829. X        del = ( abs( dt ) > 50 )? 50: abs( dt );
  830. X        if ( dt < 0 ) del = -del;
  831. X        if ( dt < 0 )
  832. X        {
  833. X            if ( del > -50 ) nap = - del;
  834. X            else if ( sys_now->tm_sec > 55 ) nap = 0;
  835. X            else nap = 55 - sys_now->tm_sec;
  836. X        }
  837. X        else if ( dt > 0 ) nap = 125 - sys_now->tm_sec;
  838. X        sleep( nap );
  839. X        (void) nice( -20 );    /* no place to be interrupted */
  840. X        time( &now );
  841. X        now = now + del;
  842. X        stime( &now );        /* This should also work on 3B2 */
  843. X        (void) nice( 20 );        /* reset 'nice' to 20 */
  844. X        dt = dt - del;
  845. X        sys_now = gmtime( &now );
  846. X#ifdef DEBUG
  847. X    printf(    "%d:%d min. after insertion of %d sec, nap was %d sec\n",
  848. X            sys_now->tm_min, sys_now->tm_sec, del, nap );
  849. X#endif
  850. X    }
  851. X    sprintf( bufb, "Sys. Corr: %3d sec.", sys_delta );
  852. X    strcat( bufa, bufb );
  853. X    if ( fflag )
  854. X    {
  855. X        sleep( 59 - nap );
  856. X        link( "/usr/lib/tmp.cron", "/usr/lib/crontab" );
  857. X        unlink( "/usr/lib/tmp.cron" );
  858. X    }
  859. X
  860. X#ifdef UNIXPC
  861. X    nice( -20 );
  862. X    syslocal( SYSL_RDRTC, &rtc_was );
  863. X    time( &now );
  864. X    sys_now = localtime( &now );
  865. X
  866. X    rtc_now.sec1  = ( char )( sys_now->tm_sec  % 10 );
  867. X    rtc_now.sec10 = ( char )( sys_now->tm_sec  / 10 );
  868. X    rtc_now.min1  = ( char )( sys_now->tm_min  % 10 );
  869. X    rtc_now.min10 = ( char )( sys_now->tm_min  / 10 );
  870. X    rtc_now.hr1   = ( char )( sys_now->tm_hour % 10 );
  871. X    rtc_now.hr10  = ( char )( sys_now->tm_hour / 10 );
  872. X    rtc_now.day1  = ( char )( sys_now->tm_mday % 10 );
  873. X    rtc_now.day10 = ( char )( sys_now->tm_mday / 10 );
  874. X    rtc_now.mon1  = ( char )(( sys_now->tm_mon + 1 ) % 10 );
  875. X    rtc_now.mon10 = ( char )(( sys_now->tm_mon + 1 ) / 10 );
  876. X    rtc_now.yr1   = ( char )( sys_now->tm_year % 10 );
  877. X    rtc_now.yr10  = ( char )( sys_now->tm_year / 10 );
  878. X    rtc_now.wkday = ( char )( sys_now->tm_wday );
  879. X
  880. X        /* Now reset the rtc */
  881. X
  882. X#ifndef DEBUG
  883. X     syslocal( SYSL_WRTRTC, &rtc_now );
  884. X#endif
  885. X    nice( 20 );
  886. X#endif    /* UNIXPC */
  887. X
  888. X        /* Calculate error for the log */
  889. X    
  890. X    rtc_delta = rtc_now.sec1  - rtc_was.sec1
  891. X        + ( rtc_now.sec10 - rtc_was.sec10 ) * 10
  892. X        + ( rtc_now.min1  - rtc_was.min1  ) * 60
  893. X        + ( rtc_now.min10 - rtc_was.min10 ) * 600
  894. X        + ( rtc_now.hr1   - rtc_was.hr1   ) * 3600
  895. X        + ( rtc_now.hr10  - rtc_was.hr10  ) * 36000; 
  896. X    sprintf( bufb, " RTC Corr: %3d sec. %3d dst\n", rtc_delta, dst );
  897. X    strcat( bufa, bufb );
  898. X    log_it( bufa );
  899. X    return;
  900. X}                    /* update() */
  901. X
  902. X/* Open the file and check that its size is less than LOG_SIZE */
  903. X/* lines.  Remove the oldest if it is too big.                 */
  904. X
  905. Xvoid log_it( new_data )
  906. Xchar *new_data;
  907. X
  908. X{
  909. X    char *tmp, *buf, *wrk;
  910. X    int lfd, num, was;
  911. X
  912. X        /* Open the correction log file and transfer */
  913. X        /* it to the 'buf' buffer */
  914. X    
  915. X    if (( lfd = open( LOG_NAME, O_RDONLY | O_CREAT, 0666 )) == 0)
  916. X    {
  917. X        fprintf( stderr, "Opening NIST.log, %s\n",
  918. X                sys_errlist[errno] );
  919. X        return;
  920. X    }
  921. X    buf = malloc(( LOG_SIZE + 5 ) * 80 );
  922. X    tmp = buf;
  923. X
  924. X        /* Save the old file in buffer */
  925. X
  926. X    was = read( lfd, tmp, (( LOG_SIZE + 4 ) * 80 ));
  927. X    close( lfd );
  928. X    lfd = open( LOG_NAME, O_WRONLY | O_TRUNC | O_APPEND, 0666 );
  929. X    
  930. X        /* Log the new data at the head of the file */
  931. X
  932. X    write( lfd, new_data, strlen( new_data ));
  933. X
  934. X        /* Now count the newlines to determine the end of file */
  935. X
  936. X    tmp = buf;
  937. X    for ( num = 1; num < LOG_SIZE && was; num++)
  938. X        while( *tmp++ != '\n' && --was );
  939. X
  940. X        /* Then move the old data back into the log file. */
  941. X
  942. X    wrk = buf;
  943. X    write( lfd, wrk, ( int )( tmp - buf ));
  944. X    close( lfd );
  945. X    free( buf );
  946. X    return;
  947. X}
  948. END_OF_calc.c
  949. if test 9707 -ne `wc -c <calc.c`; then
  950.     echo shar: \"calc.c\" unpacked with wrong size!
  951. fi
  952. # end of overwriting check
  953. fi
  954. if test -f obm.c -a "${1}" != "-c" ; then 
  955.   echo shar: Will not over-write existing file \"obm.c\"
  956. else
  957. echo shar: Extracting \"obm.c\" \(7868 characters\)
  958. sed "s/^X//" >obm.c <<'END_OF_obm.c'
  959. X#sccs    "@(#)    NIST.time:obm.c    2.1"    8/27/92
  960. X
  961. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  962. X *                                                                     *
  963. X *  Copyright (c) July, 24, 1989, August 8, 1992 by Vernon C. Hoxie    *
  964. X *                                                                     *
  965. X *      This source code may be freely distributed as long as this     *
  966. X *      copyright notice is included.  No monetary charges should      *
  967. X *      be made in excess of the cost of copying and distribution.     *
  968. X *                                                                     *
  969. X *      Any profits which might be derived from the sale of this       *
  970. X *      work must be shared with me.  Other monetary contributions     *
  971. X *      will be gratefully accepted.                                   *
  972. X *                                                                     *
  973. X *         Vernon C. Hoxie, zebra!vern, vern@zebra.alphacdc.com        *
  974. X *                                                                     *
  975. X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  976. X
  977. X
  978. X
  979. X#include "NISTtime.h"
  980. X
  981. X#ifdef OBM
  982. X
  983. X#include <dial.h>
  984. X
  985. Xextern struct termio my_getty;
  986. X
  987. Xstruct updata our_phset =
  988. X{
  989. X#ifdef TONE
  990. X    DATA | DTMF,            /* c_lineparam    */
  991. X#else
  992. X    DATA | PULSE,            /* c_lineparam    */
  993. X#endif
  994. X    5,                   /* c_waitdialtone */
  995. X    0,                   /* c_linestatus    */
  996. X#ifdef QUIET
  997. X    0,                   /* c_feedback     */
  998. X#else
  999. X    SPEAKERON | NORMSPK, /* c_feedback     */
  1000. X#endif
  1001. X    0                    /* c_waitflash    */
  1002. X};
  1003. X
  1004. Xstatic int was = 0;            /* a flag set if was voice */
  1005. X
  1006. X    /* We first check to see if the line is set to VOICE or DATA. */
  1007. X    /* If VOICE, close everything then call 'phonetoggle(1)' to   */
  1008. X    /* change the status. Go ahead and dial and collect the data. */
  1009. X    /* Afterwards, close up every thing and return.               */
  1010. X
  1011. Xint run_obm( dev )
  1012. Xchar *dev;
  1013. X
  1014. X{
  1015. X    void sign_off( );
  1016. X    extern void sig_sleep( );
  1017. X    extern void sig_timeout( );
  1018. X    extern int lock_it( );
  1019. X    extern int open_tty( );
  1020. X    extern struct termio my_getty;
  1021. X    int sample_status( );
  1022. X    int do_toggle( );
  1023. X    char buf[ 85 ];
  1024. X    char *err_msg;
  1025. X    char *phnum;
  1026. X    int c_flag;
  1027. X    int j, k;
  1028. X
  1029. X    if (( j = do_getty( dev, ':' )) < 0 ) return( -1 );
  1030. X
  1031. X    if (( tiofd = open_tty( dev )) < 0 ) {
  1032. X        fprintf( stderr, "Unable to open OBM.\n" );
  1033. X        return( -1 );
  1034. X    }
  1035. X
  1036. X    if (( ioctl( tiofd, PIOCGETP, &old_phset )) == -1 ) {
  1037. X        fprintf( stderr, "PIOCSETP old_phset failed, %s\n",
  1038. X                sys_errlist[errno] );
  1039. X        return( -1 );
  1040. X    }
  1041. X
  1042. X            /* Check if phone line available */
  1043. X    if (( j = sample_status( 5 )) < 0 ) {
  1044. X        fprintf( stderr, "Unable get OBM status. Return was %d.\n", j);
  1045. X        return( -1 );
  1046. X    }
  1047. X    if ( j == VOICE )     /* VOICE mode */
  1048. X    {
  1049. X        if (( was = do_toggle( dev )) < 0 ) return( -1 );
  1050. X        j = run_obm( dev );
  1051. X        if (( was = do_toggle( dev )) < 0 ) return( -1 );
  1052. X        return( j );
  1053. X    }
  1054. X
  1055. X    err_msg = "Timeout setting up OBM.\n";
  1056. X    alarm( 25 );
  1057. X    signal( SIGALRM, sig_timeout );
  1058. X
  1059. X    if ( ( j = setjmp( place ) ) != 0 )
  1060. X    {
  1061. X        fprintf( stderr, err_msg );
  1062. X        return( j );
  1063. X    }
  1064. X    
  1065. X    /* lock_it() returns 300 if an existing lock file is in use. */
  1066. X    /* otherwise, it returns -1 for system errors.              */
  1067. X
  1068. X    if (( j = lock_it( dev )) != 0 ) return( j );
  1069. X
  1070. X    if (( j = sample_status( 6 )) == 0 ) /* DATA mode */
  1071. X    {
  1072. X        fprintf( stderr, "%s not in DATA mode.  Return was %d.\n", dev, j );
  1073. X        return( -1 );
  1074. X    }
  1075. X
  1076. X        /* If line is not in use, we'll get dialtone. */
  1077. X
  1078. X    k = 0;
  1079. X    while ( 1 ) {
  1080. X        if (( j = ioctl( tiofd, PIOCSETP, &our_phset )) == -1 )
  1081. X        {
  1082. X            fprintf( stderr, "Can't set 'our_phset'.\n" );
  1083. X            return( -1 );
  1084. X        }
  1085. X
  1086. X        if (( j = ioctl( tiofd, PIOCOFFHOOK, &our_phset )) == -1 ) {
  1087. X            fprintf( stderr, "Can't go off hook.\n" );
  1088. X            return( 300 );
  1089. X        }
  1090. X
  1091. X        if ( sample_status( 1 ) ) {
  1092. X            fprintf( stderr, "Phone line not available.\n" );
  1093. X        /* Note: a 300 return causes a retry in 300 seconds. */
  1094. X            return( 300 );
  1095. X        }
  1096. X
  1097. X        if (( j = sample_status( 4 )) == DIALTONE ) break;    /* dialtone */
  1098. X
  1099. X        ioctl( tiofd, PIOCDISC, &our_phset );
  1100. X        if ( k++ > 8 ) { 
  1101. X            fprintf( stderr,
  1102. X        "Unable to reset dialtone flag. Return was %d after %d tries.\n",
  1103. X                                 j, k );
  1104. X            return( -1 );
  1105. X        }
  1106. X        close ( tiofd );
  1107. X        tiofd = open_tty( dev );
  1108. X        sleep( 1 );
  1109. X    }
  1110. X
  1111. X    c_flag = my_getty.c_cflag & ~(CBAUD | CLOCAL | CTSCD );
  1112. X    my_getty.c_cflag = c_flag | B1200;
  1113. X
  1114. X    if (( j = ioctl( tiofd, TCSETA, &my_getty )) == -1 )
  1115. X    {
  1116. X        fprintf( stderr, "obm_run(), Can't set 'my_getty'.\n" );
  1117. X        return( -1 );
  1118. X    }
  1119. X
  1120. X    err_msg = "Dialing OBM.\n";
  1121. X    signal( SIGALRM, sig_timeout );
  1122. X    j = alarm( 25 );
  1123. X
  1124. X#ifdef DEBUG
  1125. X    printf( "The time left after set-up = %d secs.\n", j );
  1126. X#endif
  1127. X
  1128. X    phnum = PHNUM;
  1129. X    while ( *phnum ) ioctl( tiofd, PIOCDIAL, phnum++);
  1130. X    ioctl( tiofd, PIOCDIAL, "@" );
  1131. X
  1132. X                    /* MODEMCONNECTED ? */
  1133. X    while ( sample_status( 2 ) == 0 ) {
  1134. X        if ( sample_status( 7 ) != 0 ) {
  1135. X            fprintf( stderr, "Busy tone detected.\n" );
  1136. X            return( 15 );
  1137. X        }
  1138. X    }
  1139. X    err_msg = "Timeout reading data.\n";
  1140. X    signal( SIGALRM, sig_timeout );
  1141. X    j = alarm( 25 );
  1142. X
  1143. X#ifdef DEBUG
  1144. X    printf( "The time left after dialing = %d secs.\n", j );
  1145. X#endif
  1146. X
  1147. X    for( k = 0; k < 8; ) {
  1148. X        register char *p, *q;
  1149. X
  1150. X        q = buf + sizeof( buf );
  1151. X        for ( p = buf; p < q; *p++ = '\0' );
  1152. X        for ( p = buf; *p != '\n' && p < q; ) {
  1153. X            read( tiofd, p, 1 );
  1154. X            if (( *p >= ' ' && *p <= '~' )) *p++;
  1155. X        }
  1156. X#ifdef DEBUG
  1157. X        if (( j = p - buf ) > 0 )
  1158. X            printf( "%d %d >%c< %s", k, j, *(p-1), buf );
  1159. X#endif
  1160. X
  1161. X        if ( *--p == '*' || *p == '#' ) k += get_data( buf );
  1162. X    }
  1163. X
  1164. X    j = alarm( 0 );
  1165. X#ifdef DEBUG
  1166. X    printf( "Time left after data collection = %d secs.\n" , j );
  1167. X#endif
  1168. X    return( 0 );
  1169. X}
  1170. X
  1171. X    /* Sample selected bits of the 'struct updata' to determine */
  1172. X    /* the current status of the selected phone line.         */
  1173. X
  1174. Xint sample_status( what )
  1175. Xint what;
  1176. X
  1177. X{
  1178. X#ifdef DEBUG
  1179. X    static int old_stat = 0;
  1180. X    static int old_param = 0;
  1181. X#endif
  1182. X    struct updata this_phset;
  1183. X    if ( ioctl( tiofd, PIOCGETP, &this_phset ) == -1)
  1184. X    {
  1185. X        fprintf( stderr, "Sample_status failure, %s\n",
  1186. X                    sys_errlist[errno] );
  1187. X        return( -1 );
  1188. X    }
  1189. X#ifdef DEBUG
  1190. X    if ( old_stat != this_phset.c_linestatus ||
  1191. X        old_param != this_phset.c_lineparam )
  1192. X    {
  1193. X        old_stat = this_phset.c_linestatus;
  1194. X        old_param = this_phset.c_lineparam;
  1195. X        printf("c_linestatus = %o  ", old_stat );
  1196. X        printf("c_lineparam  = %o\n", old_param );
  1197. X    }
  1198. X#endif
  1199. X    switch ( what )
  1200. X    {
  1201. X                /* case 1; line busy */
  1202. X        case 1:  return( this_phset.c_linestatus
  1203. X            & ( SETOFFHOOK | INCOMERING | CALLINCOME ));
  1204. X                /* case 2: modem ready */
  1205. X        case 2:  return( this_phset.c_linestatus
  1206. X            & MODEMCONNECTED );
  1207. X                /* case3: line problem */
  1208. X        case 3:  return( this_phset.c_linestatus & NOTONE );
  1209. X                /* case 4: ready to dial */
  1210. X        case 4:  return( this_phset.c_linestatus & DIALTONE );
  1211. X                /* case 5: set to voice */
  1212. X        case 5:  return( this_phset.c_lineparam & VOICE );
  1213. X                /* case 6: set to data */
  1214. X        case 6:  return( this_phset.c_lineparam & DATA );
  1215. X                /* case 7: busy tone or congestion tone detected */
  1216. X        case 7:  return( this_phset.c_linestatus
  1217. X                & ( BUSYTONE | CONGTONE ));
  1218. X            
  1219. X        default: return( -1 );
  1220. X    }
  1221. X}                    /* sample_status */
  1222. X
  1223. Xint do_toggle( dev )
  1224. Xchar *dev;
  1225. X
  1226. X{
  1227. X    void sign_off( );
  1228. X    int k;
  1229. X
  1230. X    if (( ioctl( tiofd, PIOCSETP, &old_phset )) == -1 )
  1231. X    {
  1232. X        fprintf( stderr, "PIOCSETP old_phset failed, %s\n",
  1233. X                    sys_errlist[errno] );
  1234. X        return( -1 );
  1235. X    }
  1236. X    k = sample_status( 5 );
  1237. X#ifdef DEBUG
  1238. X    if ( k == VOICE )
  1239. X        printf( "Toggling phone to DATA.\n" );
  1240. X    else printf( "Toggling phone to VOICE.\n" );
  1241. X#endif
  1242. X
  1243. X    sign_off( dev );
  1244. X    mpause(200);
  1245. X
  1246. X    if ( system( "/usr/bin/phtoggle" ) == -1 )
  1247. X    {
  1248. X        fprintf( stderr, "Phone toggle, %s\n",
  1249. X                    sys_errlist[errno] );
  1250. X        return ( -1 );
  1251. X    }
  1252. X    sleep( 1 );
  1253. X    return( k );
  1254. X}
  1255. X
  1256. X#else        /* ifdef OBM */
  1257. X    /* Dummy function if compiled for EXTERNAL only */
  1258. Xint run_obm( dev )
  1259. Xchar *dev;
  1260. X
  1261. X{
  1262. X    fprintf( stderr,
  1263. X     "You need  to set the OBM flag in NIST.time.h' and\n );
  1264. X    fprintf( stderr,
  1265. X     "recompile in order to use the UNIXPC On Board Modem.\n" );
  1266. X    return ( 0 );
  1267. X}
  1268. X
  1269. X#endif        /* #ifdef OBM */
  1270. END_OF_obm.c
  1271. if test 7868 -ne `wc -c <obm.c`; then
  1272.     echo shar: \"obm.c\" unpacked with wrong size!
  1273. fi
  1274. # end of overwriting check
  1275. fi
  1276. echo shar: End of archive 2 \(of 2\).
  1277. cp /dev/null ark2isdone
  1278. MISSING=""
  1279. for I in 1 2 ; do
  1280.     if test ! -f ark${I}isdone ; then
  1281.     MISSING="${MISSING} ${I}"
  1282.     fi
  1283. done
  1284. if test "${MISSING}" = "" ; then
  1285.     echo You have unpacked both archives.
  1286.     rm -f ark[1-9]isdone
  1287. else
  1288.     echo You still need to unpack the following archives:
  1289.     echo "        " ${MISSING}
  1290. fi
  1291. ##  End of shell archive.
  1292. exit 0
  1293. -- 
  1294. Vernon C. Hoxie                            {ncar,boulder}!scicom!zebra!vern
  1295. 3975 W. 29th Ave.                                       voice: 303-477-1780
  1296. Denver, Colo., 80212                                     uucp: 303-455-2670
  1297. -- 
  1298. David H. Brierley
  1299. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  1300. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  1301. %% Can I be excused, my brain is full. **
  1302.