home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume6 / sysvdial / part2 < prev    next >
Text File  |  1986-11-30  |  29KB  |  1,252 lines

  1. Subject: v06i087:  System V generic dial routines (sysVdial), Part2/3
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: ihnp4!quest!gene
  6. Mod.sources: Volume 6, Issue 87
  7. Archive-name: sysVdial/Part2
  8.  
  9. [  I did not try to compile this, as we run BSD exlusively.  It appears
  10.    that the hardest part of doing the port will be emulating the timed-
  11.    out reads (c_cc[VTIME]) in dial.c  --r$  ]
  12.  
  13. #    Generic Modem Dialer subroutine and support programs for system V.
  14. #    
  15. #    Modem configuration is done in the user configured file
  16. #    dialinfo.  Should be able to dial any modem (eg Vadic, Hayes)
  17. #    with a built-in auto dialer.   Replaces ATT dial(3C).
  18. #    Works with CU, uucico, lp, etc.
  19. #    
  20. #    This is part 2 of 3.
  21. #    
  22. #    The parts are:
  23. #    
  24. #    1)    README file and all documentation.
  25. #    2)    Makefile, dialinfo, *.h, some *.c files
  26. #    3)    dial.c
  27. #    
  28. #--------CUT---------CUT---------CUT---------CUT--------#
  29. #########################################################
  30. #                                                       #
  31. # This is a shell archive file.  To extract files:      #
  32. #                                                       #
  33. #    1)    Create an empty directory for the files.        #
  34. #    2) Write a file, such as "file.shar", containing   #
  35. #       this archive file into the directory.           #
  36. #    3) Type "sh file.shar".  Do not use csh.           #
  37. #                                                       #
  38. #########################################################
  39. echo Creating: Makefile
  40. sed -e 's/^#//' >Makefile <<'end_Makefile'
  41. ##    Copyright 1986, Gene H. Olson, Quest Research, Burnsville MN.
  42. ##    Permission to copy and distribute for any purpose,
  43. ##    so long as this notice is preserved.
  44. #
  45. #CFLAGS =
  46. #
  47. #PROGS = dialer dialprint
  48. #
  49. #N = @nroff -man
  50. #
  51. #all: $(PROGS)
  52. #
  53. #doc:
  54. #    $N dialer.1
  55. #    $N dialprint.1
  56. #    $N dial.3
  57. #    $N dialinfo.4
  58. #
  59. #dialprint: libdial.a dialprint.o
  60. #    cc dialprint.o libdial.a -o dialprint
  61. #
  62. #dialer: libdial.a dialer.o
  63. #    cc dialer.o libdial.a -o dialer
  64. #
  65. #libdial.a: readinfo.o dialinfo.o dial.o
  66. #    rm -f libdial.a
  67. #    ar cr libdial.a dial.o dialinfo.o readinfo.o
  68. #
  69. #readinfo.o: readinfo.h
  70. #dialinfo.o: readinfo.h dialinfo.h
  71. #dial.o: dialinfo.h readinfo.h dial.h
  72. #dialprint.o: dialinfo.h dial.h
  73. #dialer.o: dial.h
  74. #
  75. #lint:
  76. #    lint readinfo.c dialinfo.c dialprint.c
  77. #    lint readinfo.c dialinfo.c dial.c dialer.c
  78. #
  79. #install: $(PROGS)
  80. #    cp dialinfo /usr/lib/uucp
  81. #    cp $(PROGS) /usr/lbin
  82. #    : cp dial.h /usr/include
  83. #    : cp libdial.a /usr/lib/libdial.a
  84. #    : ar r /lib/libc.a dial.o dialinfo.o readinfo.o
  85. #
  86. #clean:
  87. #    rm -f $(PROGS) libdial.a *.o
  88. end_Makefile
  89. echo Creating: dialinfo
  90. sed -e 's/^#//' >dialinfo <<'end_dialinfo'
  91. ###############################################################
  92. ##       Dialinfo - Dialer procedure definitions              #
  93. ##                                                            #
  94. ##    See dialer.1 dialprint.1 dial.2 dialinfo.7 for          #
  95. ##    more information.   And good luck.                      #
  96. ##                                                            #
  97. ##                                Gene H. Olson (author)      #
  98. ###############################################################
  99. #
  100. ##    Hayes modem dialer.
  101. #
  102. #hayes,
  103. #    star=*, pound=#, flash=H0\,H1,
  104. #    delay=\,, wait=\,, retry=20,
  105. #    s0=P1 M"AT Q0\r" [OK]1 [in:]4 [IN:]4 [rd:]4 [RD:]4 S10 T3,
  106. #    s1=E"dialing %1 %2 %3 %4 %{DIALDEBUG}" M"AT DT%N\r" [CONNECT]10 [NO CARRIER]2 S60 T3,
  107. #    s2=E"no answer ..." D1 R3 G0,
  108. #    s3=E"no modem response ..." D1 R10 G0,
  109. #    s4=E"hung up unix system ..." D1 R5 G0,
  110. #    s6=\$hello \${hello},
  111. #    s10=C1 G+,
  112. #
  113. #
  114. ##    Hayes entry to call another UNIX system.
  115. #
  116. #uhayes,
  117. #    s10=E"looking for login ..." C1 [login:]40 [ssword:]11 H31 S2  T11,
  118. #    s11=R1 M"^M"  [login:]40 [ssword:]11 H31 S5  T12,
  119. #    s12=M"^M"     [login:]40 [ssword:]11 H31 S5  T13,
  120. #    s13=M"^D^D^D" [login:]40 [ssword:]11 H31 S10 T14,
  121. #    s14=B         [login:]40 [ssword:]11 H31 S10 T15,
  122. #    s15=M"^M"     [login:]40 [ssword:]11 H31 S5  T16,
  123. #    s16=B         [login:]40 [ssword:]11 H31 S10 T17,
  124. #    s17=M"^M"     [login:]40 [ssword:]11 H31 S5  T18,
  125. #    s18=B         [login:]40 [ssword:]11 H31 S10 T19,
  126. #    s19=M"^M"     [login:]40 [ssword:]11 H31 S5  T20,
  127. #    s20=B         [login:]40 [ssword:]11 H31 S10 T21,
  128. #    s21=M"^M"     [login:]40 [ssword:]11 H31 S5  T30,
  129. #
  130. #    s30=E"No response from remote ..." R10 G0,
  131. #    s31=E"Remote system hung up ..." R3 G0,
  132. #
  133. #    s40=M"^M"     G+,
  134. #    use=hayes,
  135. #
  136. ##    Vadic 3451
  137. #
  138. #vadic|va3451,
  139. #    delay=K, wait=KK, retry=5,
  140. #    s0=G1,
  141. #    s1=M"^E^M" [Y\n*] S4 T10,
  142. #    s2=M"D^M" [NUMBER]3 [ERROR]11 [*]11 T0,
  143. #    s3=M"%P^M" [%N]4 [ERROR]11 [*]11 T0,
  144. #    s4=M"^M" [ING:],
  145. #    s5=[CONNECT]+ [NO CARRIER]12 T30,
  146. #    s10=E"No response from dialer" R2 G0,
  147. #    s11=E"Comm error with dialer" R2 G0,
  148. #    s12=E"Connect failed" R1 G0,
  149. #    use=prometheus,
  150. end_dialinfo
  151. echo Creating: dial.h
  152. sed -e 's/^#//' >dial.h <<'end_dial.h'
  153. #/****************************************************************
  154. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  155. # *    Minnesota.   Permission to copy and distribute this         *
  156. # *    program, all associated code in source and binary form,     *
  157. # *    for any purpose, so long as this notice is preserved.       *
  158. # ****************************************************************/
  159. #
  160. #/*    Dial(3C) return codes */
  161. #
  162. ##define    INTRPT   (-1)   /* Interrupt during dial */
  163. ##define    D_HUNG   (-2)   /* Dialer hung */
  164. ##define    NO_ANS   (-3)   /* Busy or no answer */
  165. ##define    ILL_BD   (-4)   /* Illegal/unknown baud rate */
  166. ##define    A_PROB   (-5)   /* Dialinfo(4) configuration error */
  167. ##define    L_PROB   (-6)   /* TTY device error */
  168. ##define    NO_Ldv   (-7)   /* L-devices file unreadable */
  169. ##define    DV_NT_A  (-8)   /* Requested device not available */
  170. ##define    DV_NT_K  (-9)   /* Requested device unknown */
  171. ##define    NO_BD_A  (-10)  /* Nothing available at requested speed */
  172. ##define    NO_BD_K  (-11)  /* No device known at requested speed */
  173. #
  174. #/*    Dial(3C) Call structure */
  175. #
  176. #typedef struct {
  177. #    struct termio  *attr;     /* Final terminal attributes */
  178. #    int            baud;      /* Baud rate to use after dialing */
  179. #    int            speed;     /* Baud rate to use during dialing */
  180. #    char           *line;     /* TTY device name */
  181. #    char           *telno;    /* Phone number(s) or system name */
  182. #    int            modem;     /* Modem control for direct lines */
  183. #    char           *device;   /* ACU or dialer name */
  184. #    int            dev_len;   /* Length of device name (not used) */
  185. #} CALL;
  186. #
  187. #/*    External definitions */
  188. #
  189. #extern int nolock ;    /* Don't use the lock file */
  190. #
  191. #extern int dial() ;
  192. #extern void undial() ;
  193. #extern void dialmsg() ;
  194. end_dial.h
  195. echo Creating: dialinfo.h
  196. sed -e 's/^#//' >dialinfo.h <<'end_dialinfo.h'
  197. #/****************************************************************
  198. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  199. # *    Minnesota.   Permission to copy and distribute this         *
  200. # *    program, all associated code in source and binary form,     *
  201. # *    for any purpose, so long as this notice is preserved.       *
  202. # ****************************************************************/
  203. #
  204. #/*********************************************************************
  205. # *           DIALINFO  dialer description header file.               *
  206. # *********************************************************************/
  207. #
  208. #
  209. ##define NSTATE    100                /* Max number of keyboard states */
  210. #
  211. #/*
  212. # *    Dialer Information (dialinfo) structure to define
  213. # *    characteristics of a dialer.
  214. # */
  215. #
  216. #typedef struct dialinfo {
  217. #    char    *di_star ;                /* "*" button push string */
  218. #    char    *di_pound ;                /* "#"    button push string */
  219. #    char    *di_delay ;                /* "-"  delay 4 sec */
  220. #    char    *di_wait ;                /* "="    wait for dial tone */
  221. #    char    *di_flash ;                /* "f"    flash off hook 1 sec */
  222. #    short    di_retry ;                /* Retry count */
  223. #    char    *di_state[NSTATE];        /* State list */
  224. #    } DINFO ;
  225. #
  226. #extern void dialfree() ;
  227. end_dialinfo.h
  228. echo Creating: readinfo.h
  229. sed -e 's/^#//' >readinfo.h <<'end_readinfo.h'
  230. #/****************************************************************
  231. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  232. # *    Minnesota.   Permission to copy and distribute this         *
  233. # *    program, all associated code in source and binary form,     *
  234. # *    for any purpose, so long as this notice is preserved.       *
  235. # ****************************************************************/
  236. #
  237. #/***********************************************************
  238. # *     Header file for common info file string/keyword     *
  239. # *     unpacking routines.                                 *
  240. # ***********************************************************/
  241. #
  242. #
  243. ##define IKEYSIZE    10                /* Max keyword length */
  244. ##define ITEXTSIZE    100                /* Max key value length */
  245. end_readinfo.h
  246. echo Creating: readinfo.c
  247. sed -e 's/^#//' >readinfo.c <<'end_readinfo.c'
  248. #/****************************************************************
  249. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  250. # *    Minnesota.   Permission to copy and distribute this         *
  251. # *    program, all associated code in source and binary form,     *
  252. # *    for any purpose, so long as this notice is preserved.       *
  253. # ****************************************************************/
  254. #
  255. #
  256. #/***************************************************************
  257. # *        Procedures to read "info" files in the style         *
  258. # *        of "terminfo" or "dialinfo".                         *
  259. # ***************************************************************/
  260. #
  261. #
  262. ##include <stdio.h>
  263. ##include <ctype.h>
  264. #
  265. ##include "readinfo.h"
  266. #
  267. ##define loop for(;;)
  268. #
  269. #extern char *strcpy() ;
  270. #extern char *getenv() ;
  271. #
  272. #/******
  273. # *    findinfo - Find entry in info file.
  274. # *
  275. # *    Returns: 0=found, -1=not found.
  276. # */
  277. #
  278. #static int
  279. #findinfo(file, entry)
  280. #register FILE *file ;                /* Open file to search in */
  281. #register char *entry ;                /* Entry to search for */
  282. #{
  283. #    register short ch ;
  284. #    register char *cp ;
  285. #
  286. #    /*
  287. #     *    Always start from the beginning
  288. #     *    of the file.
  289. #     */
  290. #
  291. #    (void) fseek(file, 0L, 0) ;
  292. #
  293. #    /*
  294. #     *    Loop through lines in the file.
  295. #     */
  296. #
  297. #    loop {
  298. #
  299. #        /*
  300. #         *    If the first character of the line is
  301. #         *    alphanumeric,  scan the line for strings
  302. #         *    separated by "|" characters which exactly
  303. #         *    match the entry name.
  304. #         */
  305. #
  306. #        ch = getc(file) ;
  307. #        if (isalnum(ch) || ch == '/') {
  308. #            loop {
  309. #
  310. #                /*
  311. #                 *    Scan for a match terminated by '|' or ','.
  312. #                 *    If found, succeed with the file pointer
  313. #                 *    positioned to the first field entry.
  314. #                 */
  315. #
  316. #                cp = entry ;
  317. #                while (ch == *cp) {
  318. #                    ch = getc(file) ;
  319. #                    cp++ ;
  320. #                    }
  321. #
  322. #                if (*cp == 0 && (ch == '|' || ch == ',')) {
  323. #                    loop {
  324. #                        if (ch == ',') return(0) ;
  325. #                        if (ch == '\n') break ;
  326. #                        if (ch == EOF) return(-1) ;
  327. #                        ch = getc(file) ;
  328. #                        }
  329. #                    }
  330. #
  331. #                /*
  332. #                 *    If no match found, position past any "|"
  333. #                 *    character found and try again.  Otherwise
  334. #                 *    the entry is not on this line.
  335. #                 */
  336. #
  337. #                loop {
  338. #                    if (ch == '|' || ch == ',' || ch == '\n') break ;
  339. #                    ch = getc(file) ;
  340. #                    if (ch == EOF) return(-1) ;
  341. #                    }
  342. #
  343. #                if (ch != '|') break ;
  344. #
  345. #                ch = getc(file) ;
  346. #                }
  347. #            }
  348. #
  349. #        /*
  350. #         *    Skip to end-of-line.
  351. #         */
  352. #
  353. #        loop {
  354. #            if (ch == EOF) return(-1) ;
  355. #            if (ch == '\n') break ;
  356. #            ch = getc(file) ;
  357. #            }
  358. #        }
  359. #    }
  360. #
  361. #
  362. #
  363. #/******
  364. # *    getnext - Get next character from descriptor file, or
  365. # *              embedded environment variable.
  366. # */
  367. #
  368. #int
  369. #getnext(file, cpp)
  370. #register FILE *file ;        /* File to read char from */
  371. #register char **cpp ;        /* Macro string/state pointer */
  372. #{
  373. #    register int ch ;
  374. #    register int i ;
  375. #    char name[21] ;
  376. #    static char defaddr ;
  377. #
  378. #    /*
  379. #     *    Loop until we find a character to return.
  380. #     */
  381. #
  382. #    loop {
  383. #
  384. #        /*
  385. #         *    If reading a default string from the file,
  386. #         *    read until a unescaped "}" character is seen.
  387. #         */
  388. #
  389. #        if (*cpp == &defaddr) {
  390. #            ch = getc(file) ;
  391. #            if (ch == '}') *cpp = 0 ;
  392. #            else if (ch == '\\') {
  393. #                ch = getc(file) ;
  394. #                if (ch == '}') return(ch) ;
  395. #                (void) ungetc(ch, file) ;
  396. #                return('\\') ;
  397. #                }
  398. #            else return(ch) ;
  399. #            }
  400. #
  401. #        /*
  402. #         *    If in a macro string, get the next character.
  403. #         */
  404. #
  405. #        else if (*cpp) {
  406. #            if (**cpp == 0) *cpp = 0 ;
  407. #            else {
  408. #                ch = *(*cpp)++ ;
  409. #                return(ch) ;
  410. #                }
  411. #            }
  412. #
  413. #        /*
  414. #         *    Otherwise, just get the next character from
  415. #         *    the file.   Unless of course it is an unescaped
  416. #         *    "${" sequence which begins an environment variable
  417. #         *    specification.
  418. #         */
  419. #
  420. #        else {
  421. #            ch = getc(file) ;
  422. #
  423. #            if (ch == '\\') {
  424. #                ch = getc(file) ;
  425. #                if (ch != '$') {
  426. #                    (void) ungetc(ch, file) ;
  427. #                    return('\\') ;
  428. #                    }
  429. #                return('$') ;
  430. #                }
  431. #
  432. #            if (ch != '$') return(ch) ;
  433. #
  434. #            ch = getc(file) ;
  435. #            if (ch != '{') {
  436. #                (void) ungetc(ch, file) ;
  437. #                return('$') ;
  438. #                }
  439. #
  440. #            /*
  441. #             *    We saw an unescaped "${".  Get the environment
  442. #             *    variable name and look it up.
  443. #             *
  444. #             *    If the variable is found, set *cpp to return
  445. #             *    its value, and skip over any default string seen.
  446. #             *
  447. #             *    If not found, and a default string is given, set
  448. #             *    *cpp so the default string will be read from the
  449. #             *    file.
  450. #             */
  451. #
  452. #            i = 0 ;
  453. #            loop {
  454. #                ch = getc(file) ;
  455. #                if (ch == EOF) return(EOF) ;
  456. #                if (ch == '-' || ch == '}') break ;
  457. #                if (i < sizeof(name)-1) name[i++] = ch ;
  458. #                }
  459. #            name[i] = 0 ;
  460. #
  461. #            *cpp = getenv(name) ;
  462. #
  463. #            if (ch == '-') {
  464. #                if (*cpp) {
  465. #                    loop {
  466. #                        ch = getc(file) ;
  467. #                        if (ch == EOF) return(EOF) ;
  468. #                        if (ch == '}') break ;
  469. #                        if (ch == '\\') {
  470. #                            ch = getc(file) ;
  471. #                            if (ch == EOF) return(EOF) ;
  472. #                            }
  473. #                        }
  474. #                    }
  475. #                else *cpp = &defaddr ;
  476. #                }
  477. #            }
  478. #        }
  479. #    }
  480. #
  481. #
  482. #
  483. #/******
  484. # *    getinfo - Get next key=text entry in info description.
  485. # *
  486. # *    Returns:    1=found, 0=end of entry, -1=error.
  487. # */
  488. #
  489. #static int
  490. #getinfo(file, cpp, key, text)
  491. #FILE *file ;                    /* Info file pointer */
  492. #char **cpp ;                    /* Macro char pointer */
  493. #char *key ;                        /* Returned key string */
  494. #char *text ;                    /* Returned text string */
  495. #{
  496. #    register short ch ;
  497. #    register char *cp ;
  498. #    register short count ;
  499. #
  500. #    /*
  501. #     *    Scan for the next keyword.
  502. #     */
  503. #
  504. #    ch = getnext(file, cpp) ;
  505. #    loop {
  506. #        if (ch == EOF) return(0) ;
  507. #
  508. #        if (isalpha(ch)) break ;
  509. #
  510. #        if (ch == '\n') {
  511. #            ch = getnext(file, cpp) ;
  512. #            if (isalpha(ch)) return(0) ;
  513. #            }
  514. #
  515. #        else if (ch == '#') {
  516. #            loop {
  517. #                ch = getnext(file, cpp) ;
  518. #                if (ch == EOF) return(-1) ;
  519. #                if (ch == '\n') break ;
  520. #                }
  521. #            }
  522. #
  523. #        else if (ch == ' ' || ch == '\t' || ch == ',')
  524. #            ch = getnext(file, cpp) ;
  525. #
  526. #        else return(-1) ;
  527. #        }
  528. #
  529. #    /*
  530. #     *    Pick up keyword.
  531. #     */
  532. #
  533. #    count = 0 ;
  534. #    cp = key ;
  535. #
  536. #    while (isalnum(ch)) {
  537. #        if (++count > IKEYSIZE) return(-1) ;
  538. #        *cp++ = ch ;
  539. #        ch = getnext(file, cpp) ;
  540. #        }
  541. #
  542. #    *cp = 0 ;
  543. #
  544. #    if (ch != '=') return(-1) ;
  545. #
  546. #    /*
  547. #     *    Pick up associated string text.
  548. #     */
  549. #
  550. #    count = 0 ;
  551. #    cp = text ;
  552. #
  553. #    loop {
  554. #        ch = getnext(file, cpp) ;
  555. #        if (ch == ',') break ;
  556. #
  557. #        if (ch == EOF) return(-1) ;
  558. #
  559. #        if (ch == '\\') {
  560. #            ch = getnext(file, cpp) ;
  561. #            if (ch == EOF) return(-1) ;
  562. #            if (ch != ',') {
  563. #                *cp++ = '\\' ;
  564. #                count++ ;
  565. #                }
  566. #            }
  567. #
  568. #        if (++count > ITEXTSIZE) return(-1) ;
  569. #
  570. #        *cp++ = ch ;
  571. #        }
  572. #
  573. #    *cp = 0 ;
  574. #
  575. #    return(1) ;
  576. #    }
  577. #
  578. #
  579. #
  580. #/******
  581. # *    readinfo - Read info file for data.
  582. # */
  583. #
  584. #int
  585. #readinfo(fname, entry, build, info)
  586. #char *fname ;                    /* Info File name to read */
  587. #char *entry ;                    /* Info entry name to return */
  588. #int (*build)() ;                /* Build entry procedure */
  589. #char *info ;                    /* Info pointer */
  590. #{
  591. #    register FILE *file ;
  592. #    register int i ;
  593. #    register int usecount ;
  594. #
  595. #    char *cp ;
  596. #    char key[IKEYSIZE+1] ;
  597. #    char text[ITEXTSIZE+1] ;
  598. #    char use[ITEXTSIZE+1] ;
  599. #
  600. #    /*
  601. #     *    Open info file.
  602. #     */
  603. #
  604. #    file = fopen(fname,"r") ;
  605. #    if (file == 0) {
  606. #        (void) fprintf(stderr, "Cannot open: %s\n", fname) ;
  607. #        return(-1) ;
  608. #        }
  609. #    
  610. #    /*
  611. #     *    Loop to read all info entries in "use" list.
  612. #     */
  613. #
  614. #    usecount = 20 ;
  615. #    loop {
  616. #
  617. #        /*
  618. #         *    Find entry name in file.
  619. #         */
  620. #
  621. #        if (findinfo(file, entry) < 0) {
  622. #            (void) fprintf(stderr, "File %s, no entry found: %s\n",
  623. #                fname, entry) ;
  624. #            (void) fclose(file) ;
  625. #            return(-1) ;
  626. #            }
  627. #
  628. ##ifdef DEBUG
  629. #        (void) fprintf(stderr,"Found entry: %s\n",entry) ;
  630. ##endif
  631. #
  632. #        /*
  633. #         *    Unpack and process all entries.
  634. #         */
  635. #
  636. #        cp = 0 ;
  637. #        loop {
  638. #            i = getinfo(file,&cp,key,text) ;
  639. #            if (i == 0) {
  640. #                (void) fclose(file) ;
  641. #                return(0) ;
  642. #                }
  643. #
  644. #            if (i < 0) {
  645. #                (void) fprintf(stderr, "File %s, corrupted entry: %s\n",
  646. #                    fname, entry) ;
  647. #                (void) fclose(file) ;
  648. #                return(-1) ;
  649. #                }
  650. #
  651. ##ifdef DEBUG
  652. #            (void) fprintf(stderr,"Got %s=%s\n",key,text) ;
  653. ##endif
  654. #
  655. #            /*
  656. #             *    Follow "use" list chain to next entry.
  657. #             */
  658. #
  659. #            if (strcmp(key, "use") == 0) {
  660. #                (void) strcpy(use, text) ;
  661. #                entry = use ;
  662. #                if (--usecount > 0) break ;
  663. #                (void) fclose(file) ;
  664. #                return(-1) ;
  665. #                }
  666. #
  667. #            /*
  668. #             *    Add data to info entry.
  669. #             */
  670. #
  671. #            if ((*build)(info, key, text) < 0) {
  672. #                (void) fprintf(stderr,
  673. #                    "Error in file %s, entry %s, %s=%s\n",
  674. #                    fname, entry, key, text) ;
  675. #                (void) fclose(file) ;
  676. #                return(-1) ;
  677. #                }
  678. #            }
  679. #        }
  680. #    }
  681. end_readinfo.c
  682. echo Creating: dialinfo.c
  683. sed -e 's/^#//' >dialinfo.c <<'end_dialinfo.c'
  684. #/****************************************************************
  685. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  686. # *    Minnesota.   Permission to copy and distribute this         *
  687. # *    program, all associated code in source and binary form,     *
  688. # *    for any purpose, so long as this notice is preserved.       *
  689. # ****************************************************************/
  690. #
  691. #
  692. #/**************************************************************
  693. # *          Procedures to read and decode dialinfo            *
  694. # *                   dialer entries.                          *
  695. # **************************************************************/
  696. #
  697. ##include <stdio.h>
  698. ##include <ctype.h>
  699. #
  700. ##include "readinfo.h"
  701. ##include "dialinfo.h"
  702. #
  703. ##define loop for (;;)
  704. #
  705. #extern void free() ;
  706. #extern char *malloc() ;
  707. #extern char *strcpy() ;
  708. #extern char *getenv() ;
  709. #
  710. #
  711. #/******
  712. # *    stralloc - Allocate string.
  713. # */
  714. #
  715. #static char *
  716. #stralloc(str)
  717. #char *str ;                            /* String to copy */
  718. #{
  719. #    register char *p ;
  720. #
  721. #    p = malloc((unsigned) (strlen(str)+1)) ;
  722. #    if (p != 0) (void) strcpy(p, str) ;
  723. #    return(p) ;
  724. #    }
  725. #
  726. #
  727. #
  728. #/*****
  729. # *    parseshort - Parse out short.
  730. # *
  731. # *    Returns: advanced ptr=okay, 0=error.
  732. # */
  733. #
  734. #char *
  735. #parseshort(cp, num, low, high)
  736. #register char *cp ;                    /* Start character */
  737. #short *num ;                        /* Short to fetch */
  738. #short low ;                            /* Lowest legal value */
  739. #short high ;                        /* Highest legal value */
  740. #{
  741. #    register short n ;
  742. #
  743. #    if (!isdigit(*cp)) return(0) ;
  744. #
  745. #    n = 0 ;
  746. #
  747. #    do {
  748. #        n = 10 * n + *cp++ - '0' ;
  749. #        } while (isdigit(*cp)) ;
  750. #
  751. #    if (n < low || n > high) return(0) ;
  752. #
  753. #    *num = n ;
  754. #    return(cp) ;
  755. #    }
  756. #
  757. #
  758. #
  759. #/*******
  760. # *    buildinfo - Build information entry for key=text string.
  761. # *
  762. # *    Returns: 0=info built, -1=error.
  763. # */
  764. #
  765. #static int
  766. #buildinfo(dinfo,key,text)
  767. #char *dinfo ;                        /* Dialer info structure */
  768. #char *key ;                            /* Keyword name */
  769. #char *text ;                        /* Associated text */
  770. #{
  771. #    register DINFO *di ;
  772. #    register char *cp ;
  773. #    register char **cpp ;
  774. #    short state ;
  775. #
  776. #    di = (DINFO *) dinfo ;
  777. #
  778. #    /*
  779. #     *    Build phone number character replacement strings.
  780. #     */
  781. #
  782. #    if (strcmp(key,"star") == 0) {
  783. #        if (di->di_star == 0) di->di_star = stralloc(text) ;
  784. #        }
  785. #
  786. #    else if (strcmp(key,"pound") == 0) {
  787. #        if (di->di_pound == 0) di->di_pound = stralloc(text) ;
  788. #        }
  789. #
  790. #    else if (strcmp(key,"delay") == 0) {
  791. #        if (di->di_delay == 0) di->di_delay = stralloc(text) ;
  792. #        }
  793. #
  794. #    else if (strcmp(key, "wait") == 0) {
  795. #        if (di->di_wait == 0) di->di_wait = stralloc(text) ;
  796. #        }
  797. #
  798. #    else if (strcmp(key,"flash") == 0) {
  799. #        if (di->di_flash == 0) di->di_flash = stralloc(text) ;
  800. #        }
  801. #
  802. #    /*
  803. #     *    Build "retry" count.
  804. #     */
  805. #
  806. #    else if (strcmp(key, "retry") == 0) {
  807. #        if (di->di_retry < 0) {
  808. #            cp = parseshort(text, &di->di_retry, 0, 1000) ;
  809. #            if (cp == 0 || *cp != 0) return(-1) ;
  810. #            }
  811. #        }
  812. #
  813. #    /*
  814. #     *    Build dial defintions.
  815. #     */
  816. #
  817. #    else if
  818. #        (    key[0] == 's'
  819. #        &&    (cp = parseshort(key+1, &state, 0, NSTATE-1))
  820. #        &&    *cp == 0
  821. #        )
  822. #    {
  823. #        cpp = &di->di_state[state] ;
  824. #        if (*cpp == 0) *cpp = stralloc(text) ;
  825. #        }
  826. #
  827. #    else return(-1) ;
  828. #
  829. #    return(0) ;
  830. #    }
  831. #
  832. #
  833. #
  834. #/******
  835. # *    dialinfo - Get dial information for entry "dialer".
  836. # */
  837. #
  838. #int
  839. #dialinfo(dinfo, dialer)
  840. #DINFO *dinfo ;                        /* Retrieved dialer info */
  841. #char *dialer ;                        /* Dialer name */
  842. #{
  843. #    register int i ;
  844. #    register char *fname ;
  845. #
  846. #    /*
  847. #     *    Initialize dialinfo entry.
  848. #     */
  849. #
  850. #    dinfo->di_star = 0 ;
  851. #    dinfo->di_pound = 0 ;
  852. #    dinfo->di_delay = 0 ;
  853. #    dinfo->di_wait = 0 ;
  854. #    dinfo->di_flash = 0 ;
  855. #    dinfo->di_retry = -1 ;
  856. #    for (i = 0 ; i < NSTATE ; i++) dinfo->di_state[i] = 0 ;
  857. #
  858. #    /*
  859. #     *    Get dialinfo file name from environment if specified.
  860. #     */
  861. #
  862. #    fname = getenv("DIALINFO") ;
  863. #    if (fname == 0 || *fname == 0) fname = "/usr/lib/uucp/dialinfo" ;
  864. #
  865. #    /*
  866. #     *    Read the file and return status.
  867. #     */
  868. #
  869. #    return( readinfo(fname, dialer, buildinfo, (char *)dinfo) ) ;
  870. #    }
  871. #
  872. #
  873. #/******
  874. # *    dialfree - Free storage associated with dialinfo entry.
  875. # */
  876. #
  877. #void
  878. #dialfree(di)
  879. #register DINFO *di ;            /* Dialinfo entry */
  880. #{
  881. #    register int i ;
  882. #    register char **spp ;
  883. #
  884. #    if (di->di_delay) free(di->di_delay) ;
  885. #    if (di->di_wait) free(di->di_wait) ;
  886. #    if (di->di_star) free(di->di_star) ;
  887. #    if (di->di_pound) free(di->di_pound) ;
  888. #    if (di->di_flash) free(di->di_flash) ;
  889. #
  890. #    i = 0 ;
  891. #    spp = &di->di_state[0] ;
  892. #
  893. #    while (i < NSTATE) {
  894. #        if (*spp) free(*spp) ;
  895. #        i++ ;
  896. #        spp++ ;
  897. #        }
  898. #    }
  899. end_dialinfo.c
  900. echo Creating: dialprint.c
  901. sed -e 's/^#//' >dialprint.c <<'end_dialprint.c'
  902. #/****************************************************************
  903. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  904. # *    Minnesota.   Permission to copy and distribute this         *
  905. # *    program, all associated code in source and binary form,     *
  906. # *    for any purpose, so long as this notice is preserved.       *
  907. # ****************************************************************/
  908. #
  909. #/***************************************************************
  910. # *         Program to print out DIALINFO entries               *
  911. # ***************************************************************/
  912. #
  913. ##include <stdio.h>
  914. #
  915. ##include "readinfo.h"
  916. ##include "dialinfo.h"
  917. #
  918. #
  919. #/******
  920. # *    dialprint - Print dialer info.
  921. # */
  922. #
  923. #dialprint(dinfo, dialer)
  924. #register DINFO *dinfo ;                    /* Entry to print */
  925. #char *dialer ;                            /* Dialer name */
  926. #{
  927. #    register char **cpp ;
  928. #    register int i ;
  929. #    
  930. #    (void) printf("%s,\n", dialer) ;
  931. #
  932. #    if (dinfo->di_star) (void) printf("\tstar=%s,\n", dinfo->di_star) ;
  933. #
  934. #    if (dinfo->di_pound) (void) printf("\tpound=%s,\n", dinfo->di_pound) ;
  935. #
  936. #    if (dinfo->di_delay) (void) printf("\tdelay=%s,\n", dinfo->di_delay) ;
  937. #
  938. #    if (dinfo->di_wait) (void) printf("\twait=%s,\n", dinfo->di_wait) ;
  939. #
  940. #    if (dinfo->di_flash) (void) printf("\tflash=%s,\n", dinfo->di_flash) ;
  941. #
  942. #    if (dinfo->di_retry >= 0) (void) printf("\tretry=%d,\n", dinfo->di_retry) ;
  943. #
  944. #    i = 0 ;
  945. #    cpp = &dinfo->di_state[0] ;
  946. #
  947. #    while (i < NSTATE) {
  948. #        if (*cpp) (void) printf("\ts%d=%s,\n", i, *cpp) ;
  949. #        i++ ;
  950. #        cpp++ ;
  951. #        }
  952. #    }
  953. #
  954. #
  955. #
  956. #main(argc,argv)
  957. #int argc ;                            /* Argument count */
  958. #char **argv ;                        /* Argument vector */
  959. #{
  960. #    DINFO dinfo ;
  961. #
  962. #    if (argc != 2) {
  963. #        (void) fprintf(stderr, "Bad arg count\n") ;
  964. #        return(2) ;
  965. #        }
  966. #
  967. #    (void) dialinfo(&dinfo, argv[1]) ;
  968. #
  969. #    dialprint(&dinfo, argv[1]) ;
  970. #
  971. #    dialfree(&dinfo) ;
  972. #
  973. #    return(0) ;
  974. #    }
  975. end_dialprint.c
  976. echo Creating: dialer.c
  977. sed -e 's/^#//' >dialer.c <<'end_dialer.c'
  978. #/****************************************************************
  979. # *    Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
  980. # *    Minnesota.   Permission to copy and distribute this         *
  981. # *    program, all associated code in source and binary form,     *
  982. # *    for any purpose, so long as this notice is preserved.       *
  983. # ****************************************************************/
  984. #
  985. ##include <stdio.h>
  986. ##include <signal.h>
  987. ##include <termio.h>
  988. #
  989. ##include "dial.h"
  990. #
  991. #extern int nolock ;                    /* See dial(3C) */
  992. #extern int optind ;                    /* See getopt(3) */
  993. #extern char *optarg ;                /* See getopt(3) */
  994. #
  995. #extern unsigned sleep() ;
  996. #extern void perror() ;
  997. #extern void exit() ;
  998. #extern char *malloc() ;
  999. #
  1000. #static struct termio myterm ;        /* My terminal flags */
  1001. #static int dialfd ;                    /* Dial file descriptor */
  1002. #
  1003. #
  1004. #/*****
  1005. # *    quit - exit gracefully.
  1006. # */
  1007. #
  1008. #quit(status)
  1009. #{
  1010. #    (void) signal(SIGHUP, SIG_IGN) ;
  1011. #    (void) signal(SIGINT, SIG_IGN) ;
  1012. #    (void) signal(SIGQUIT, SIG_IGN) ;
  1013. #    (void) signal(SIGPIPE, SIG_IGN) ;
  1014. #    (void) signal(SIGTERM, SIG_IGN) ;
  1015. #
  1016. #    if (dialfd >= 0) undial(dialfd) ;
  1017. #    (void) ioctl(0, TCSETA, &myterm) ;
  1018. #
  1019. #    exit(status) ;
  1020. #    }
  1021. #
  1022. #
  1023. #/*****
  1024. # *    catch - catch interrupt.
  1025. # */
  1026. #
  1027. #catch()
  1028. #{
  1029. #    quit(INTRPT) ;
  1030. #    }
  1031. #
  1032. #
  1033. #
  1034. #/*****
  1035. # *    main - Main program.
  1036. # */
  1037. #
  1038. #main(argc,argv)
  1039. #int argc ;
  1040. #char **argv ;
  1041. #{
  1042. #    register short opt ;
  1043. #    register FILE *dialfile ;
  1044. #    register short ch ;
  1045. #    register int err ;
  1046. #    register int i ;
  1047. #    unsigned waitfree ;
  1048. #    unsigned redial ;
  1049. #    short copy ;
  1050. #    struct termio tio ;
  1051. #    CALL call ;
  1052. #
  1053. #    waitfree = 0 ;
  1054. #    redial = 0 ;
  1055. #    copy = 0 ;
  1056. #
  1057. #    /*
  1058. #     *    Set up tty options to be used when
  1059. #     *    modem control is enabled.
  1060. #     */
  1061. #
  1062. #    tio.c_iflag = IGNPAR | IGNBRK | ISTRIP | IXON ;
  1063. #    tio.c_oflag = 0 ;
  1064. #    tio.c_cflag = CS8 | CREAD | HUPCL | CLOCAL ;
  1065. #    tio.c_lflag = NOFLSH ;
  1066. #
  1067. #    tio.c_cc[VMIN] = 10 ;
  1068. #    tio.c_cc[VTIME] = 1 ;
  1069. #
  1070. #    /*
  1071. #     *    Initialize call structure.
  1072. #     */
  1073. #
  1074. #    call.attr = &tio ;
  1075. #    call.baud = 0 ;
  1076. #    call.speed = 0 ;
  1077. #    call.line = 0 ;
  1078. #    call.telno = 0 ;
  1079. #    call.modem = 0 ;
  1080. #    call.device = 0 ;
  1081. #
  1082. #    /*
  1083. #     *    Decode options.
  1084. #     */
  1085. #
  1086. #    while ((opt = getopt(argc,argv,"ceonrwb:l:s:")) != EOF) {
  1087. #        switch (opt) {
  1088. #
  1089. #            /*
  1090. #             *    Copy standard input to remote.
  1091. #             */
  1092. #
  1093. #            case 'c':
  1094. #                copy = 1 ;
  1095. #                break ;
  1096. #
  1097. #            /*
  1098. #             *    Even parity after carrier detect.
  1099. #             */
  1100. #
  1101. #            case 'e':
  1102. #                tio.c_cflag &= ~(CSIZE | PARENB | PARODD) ;
  1103. #                tio.c_cflag |= CS7 | PARENB ;
  1104. #                break ;
  1105. #
  1106. #            /*
  1107. #             *    Odd parity after carrier detect.
  1108. #             */
  1109. #
  1110. #            case 'o':
  1111. #                tio.c_cflag &= ~(CSIZE | PARENB | PARODD) ;
  1112. #                tio.c_cflag |= CS7 | PARENB | PARODD ;
  1113. #                break ;
  1114. #
  1115. #            /*
  1116. #             *    No lock file.  Caller allocates it for us.
  1117. #             */
  1118. #
  1119. #            case 'n':
  1120. #                nolock = 1 ;
  1121. #                break ;
  1122. #
  1123. #            /*
  1124. #             *    Redial if no answer.
  1125. #             */
  1126. #
  1127. #            case 'r':
  1128. #                redial = 60 ;
  1129. #                break ;
  1130. #
  1131. #            /*
  1132. #             *    Wait for free outgoing line.
  1133. #             */
  1134. #
  1135. #            case 'w':
  1136. #                waitfree = 30 ;
  1137. #                break ;
  1138. #
  1139. #            /*
  1140. #             *    Device name for outgoing line.
  1141. #             */
  1142. #
  1143. #            case 'l':
  1144. #                call.line = optarg ;
  1145. #                break ;
  1146. #
  1147. #            /*
  1148. #             *    Baud rate for initial dial.
  1149. #             */
  1150. #
  1151. #            case 'b':
  1152. #                call.baud = atoi(optarg) ;
  1153. #                break ;
  1154. #
  1155. #            /*
  1156. #             *    Baud rate after connect.
  1157. #             */
  1158. #
  1159. #            case 's':
  1160. #                call.speed = atoi(optarg) ;
  1161. #                break ;
  1162. #                    
  1163. #            /*
  1164. #             *    Bad parameter.
  1165. #             */
  1166. #
  1167. #            default:
  1168. #                exit(2) ;
  1169. #            }
  1170. #        }
  1171. #
  1172. #    /*
  1173. #     *    Get phone number.
  1174. #     */
  1175. #
  1176. #    if (optind != argc) call.telno = argv[optind] ;
  1177. #
  1178. #    /*
  1179. #     *    Setup signal catching stuff.
  1180. #     */
  1181. #
  1182. #    dialfd = -1 ;
  1183. #
  1184. #    (void) ioctl(0, TCGETA, &myterm) ;
  1185. #
  1186. #    if (signal(SIGHUP, SIG_IGN) == SIG_DFL) (void) signal(SIGHUP, catch) ;
  1187. #    if (signal(SIGINT, SIG_IGN) == SIG_DFL) (void) signal(SIGINT, catch) ;
  1188. #    if (signal(SIGQUIT, SIG_IGN) == SIG_DFL) (void) signal(SIGQUIT, catch) ;
  1189. #    if (signal(SIGPIPE, SIG_IGN) == SIG_DFL) (void) signal(SIGPIPE, catch) ;
  1190. #    if (signal(SIGTERM, SIG_IGN) == SIG_DFL) (void) signal(SIGTERM, catch) ;
  1191. #
  1192. #    /*
  1193. #     *    Attempt the dial.
  1194. #     */
  1195. #
  1196. #    for (;;) {
  1197. #        dialfd = dial(call) ;
  1198. #
  1199. #        if (dialfd == NO_ANS && redial) {
  1200. #            dialmsg("No answer, redial in %d seconds.\n", redial) ;
  1201. #            (void) sleep(redial) ;
  1202. #            }
  1203. #
  1204. #        else if ((dialfd == DV_NT_A || dialfd == NO_BD_A) && waitfree) {
  1205. #            dialmsg("No outgoing line, will retry in %d seconds.\n", waitfree) ;
  1206. #            (void) sleep(waitfree) ;
  1207. #            }
  1208. #
  1209. #        else break ;
  1210. #        }
  1211. #
  1212. #    if (dialfd < 0) quit(-dialfd) ;
  1213. #
  1214. #    /*
  1215. #     *    If a copy operation is selected, copy standard
  1216. #     *    input to the dialed-up device.
  1217. #     */
  1218. #
  1219. #    if (copy) {
  1220. #
  1221. #        dialfile = fdopen(dialfd, "w") ;
  1222. #        if (dialfile == 0) {
  1223. #            perror("fdopen") ;
  1224. #            quit(-L_PROB) ;
  1225. #            }
  1226. #
  1227. #        (void) setvbuf(dialfile, malloc(BUFSIZ), _IONBF, BUFSIZ) ;
  1228. #
  1229. #        err = 0 ;
  1230. #
  1231. #        while (err >= 0 && (ch = getchar()) != EOF)
  1232. #            err = putc(ch, dialfile) ;
  1233. #
  1234. #        for (i = 0 ; i < 10 ; i++)
  1235. #            err = putc('\000',dialfile) ;
  1236. #
  1237. #        if (err >= 0) err = fflush(dialfile) ;
  1238. #
  1239. #        if (err < 0) {
  1240. #            perror("copy write error") ;
  1241. #            quit(-L_PROB) ;
  1242. #            }
  1243. #        }
  1244. #
  1245. #    quit(0) ;
  1246. #    return(0) ;
  1247. #    }
  1248. end_dialer.c
  1249.  
  1250.  
  1251.  
  1252.