home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / nistchk / part02 < prev    next >
Encoding:
Text File  |  1992-09-03  |  34.2 KB  |  1,296 lines

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