home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Mac⁄gnuucp 6.14 / source / fio.c < prev    next >
Encoding:
Internet Message Format  |  1990-10-29  |  17.5 KB  |  [TEXT/R*ch]

  1. From: samsung!apple.com!blob
  2. To: fpr.com!jim
  3. Date: Mon, 29 Oct 90 08:04:09 -0800
  4. Subject: Re: 7 bit GNUUCP transfers 
  5. From mitech!blob@apple.com Mon, 29 Oct 90 19:40:19 EDT remote from fpr
  6. Received: by fpr (Mac/gnuucp v3.5) Mon, 29 Oct 90 19:40:19 EDT
  7. Received: from samsung by mitech.com (DECUS UUCP w/Smail);
  8.           Mon, 29 Oct 90 18:22:26 EDT
  9. Received: by schizo from APPLE.COM via SMTP (vers 5.61+)
  10.           for fpr.com!jim (from samsung!apple.com!blob)
  11.           id <AA18898@schizo>; Mon, 29 Oct 90 11:03:47 -0500
  12. Received: by apple.com with SMTP (5.61/25-eef)
  13.           id AA01296; Mon, 29 Oct 90 08:04:11 -0800
  14.           for jim@fpr.com
  15. Message-Id: <9010291604.AA01296@apple.com>
  16. Cc: apple.com!blob
  17. In-Reply-To: Your message of 10 Saturday 90 00:00:00 -0800.
  18.           <9010291055.AA09339@schizo> 
  19.  
  20.  
  21. I got this from Tim Pozar (pozar@kumr.uucp)
  22. ]>Do you have a description of the uucp F protocol?
  23. ]   This is what I found so far.  Drop me a line if you need more
  24. ]info and I can rummage around some other places...
  25.  
  26. ---
  27. READMEfio
  28. ---
  29. F protocol (X.25 PAD)
  30. Installation hints
  31.  
  32. "F" protocol is a UUCP protocol used to communicate over X.25 networks.
  33. The PAD dialer is a "real" dialer that can be used to set up connections
  34. to remote X.25 destinations using MICOM or Motorola PADS - and will probably
  35. work with most other PADS.  fio.c was originally distributed with various 
  36. "alpha-test" versions of the UUCP in BSD4.3 and has been posted several
  37. times.  I wrote the PAD dialer.  This readme gives some pointers on how 
  38. to install this into your UUCP.
  39.  
  40. Applicability: if you already have "f" protocol (eg: you already have BSD4.3 
  41. UUCP), fio.c is likely to be a little older than the one you have, so don't 
  42. bother using it.  However, Rick Adams has told me that the PAD dialer 
  43. didn't make it into real BSD4.3, so the dialer should be really useful to you
  44. without any changes.  If you have an older UUCP (eg: BSD4.2 or previous, 
  45. System V, XENIX) you may be able to install both of these files.
  46.  
  47. Note: I have never tried to install either of these into non-4.3 UUCP,
  48. so your mileage may vary - greatly.  The pad dialer in particular makes use
  49. of "generic" facilities (ABORT sequences, chat scripts etc.) that are not
  50. likely to be accessible in older UUCPs.  So you may have to do some carving
  51. just to get your new UUCP to compile and link.  I'm afraid you're on your
  52. own in that case.
  53.  
  54. Installation:
  55. 1) Make copies of cntrl.c and condevs.c
  56. 2) Insert into cntrl.c, near the beginning:
  57.     #ifdef PAD
  58.     extern int fturnon(), fturnoff();
  59.     extern int frdmsg(), frddata();
  60.     extern int fwrmsg(), fwrdata();
  61.     #endif PAD
  62. 3) in cntrl.c, inside the "struct Proto Ptbl[] =" initialization,
  63.    insert the following just before the "g" proto definition:
  64.     #ifdef PAD
  65. 'f', fturnon, frdmsg, fwrmsg, frddata, fwrdata, fturnoff,
  66.     #endif PAD
  67. 4) In cntrl.c, inside the fptcl(str) function,
  68.    you will see something like:
  69.     for (p = Ptbl; p->P_id != '\0'; p++) {
  70.     ...
  71. if (index(str, p->P_id) != NULL) {
  72. return p->P_id;
  73. }
  74.     }
  75.    Insert the following code just before the "index" line:
  76.     #ifdef PAD
  77. /* only use 'f' protocol on PAD */
  78. if (p->P_id == 'f' && strcmp("PAD", Flds[F_LINE]))
  79. continue;
  80.     #endif PAD
  81.  
  82. 5) in condevs.c, insert the following into the 
  83.    "struct condev condevs[]=" initialization:
  84.     #ifdef PAD
  85. { "PAD", "PAD", padopn, nulldev, padcls },
  86.     #endif
  87. 6) insert "#define PAD 1" into your uucp.h
  88. 7) copy pad.c into the directory containing the rest of the dialers
  89.    and modify the makefile to compile it.
  90. 8) copy fio.c into the main UUCP directory and modify the makefile
  91.    to compile it.
  92. 9) run your UUCP make.
  93.  
  94. You may encounter a number of undefined things.  If "dochat" is undefined,
  95. remove it from pad.c.  Ditto the stuff about ABORT sequences.
  96.  
  97. Typical L.sys entry:
  98.  
  99. <system> Any PAD <speed> <seq> 
  100.  
  101. Where <speed> is the baud rate between your computer and your pad.  <seq>
  102. is the "dial number" to dial the destination.  Eg: if you have to type
  103. "c 12345555" to reach that destination, place "12345555" here.  You may
  104. encounter length restrictions when talking to the PAD, so you may have to
  105. set up "2-character aliases" in the PAD configuration.
  106.  
  107. Typical L-devices entry:
  108.  
  109. PAD <tty> ignored <baud> <chat sequence>
  110.  
  111. The <baud> must be the same as in the L.sys entry.  <tty> is the ttyname
  112. that the PAD is connected to.  Eg: "tty44".  Chat sequence (alternatively
  113. protocol specification in some versions of SV UUCP) is probably not
  114. of any use unless you have the rest of 4.3BSD UUCP.  Duplicate this line
  115. with "DIR" instead of "PAD" so that you can "cu" to the line.
  116.  
  117. Other setup: on dialer out-going line: disable getty, and connect the line
  118. to the PAD.  Initialize the PAD line parameters so that it is a "outgoing"
  119. port, and that you can get at X.28 command mode.  Eg: you should be able
  120. to "cu" to the line and dial out using X.28 commands.  Do not worry about
  121. any other parameters because the dialer will initialize all of the parameters
  122. on the line every time it starts up, and when the link is broken, the parameters
  123. revert.  Thus, the best thing to do is initialize the line for outgoing
  124. cu.
  125. ---
  126. fio.c
  127. ---
  128. /* $Header: fio.c,v 1.20 85/04/30 12:57:32 rick Exp $ */
  129. /*%M%%I%%E%(Mathematisch Centrum)*/
  130.  
  131. /*
  132.  * flow control protocol.
  133.  *
  134.  * This protocol relies on flow control of the data stream.
  135.  * It is meant for working over links that can (almost) be
  136.  * guaranteed to be errorfree, specifically X.25/PAD links.
  137.  * A sumcheck is carried out over a whole file only. If a
  138.  * transport fails the receiver can request retransmission(s).
  139.  * This protocol uses a 7-bit datapath only, so it can be
  140.  * used on links that are not 8-bit transparent.
  141.  *
  142.  * When using this protocol with an X.25 PAD:
  143.  * Although this protocol uses no control chars except CR,
  144.  * control chars NULL and ^P are used before this protocol
  145.  * is started; since ^P is the default char for accessing
  146.  * PAD X.28 command mode, be sure to disable that access
  147.  * (PAD par 1). Also make sure both flow control pars
  148.  * (5 and 12) are set. The CR used in this proto is meant
  149.  * to trigger packet transmission, hence par 3 should be 
  150.  * set to 2; a good value for the Idle Timer (par 4) is 10.
  151.  * All other pars should be set to 0.
  152.  * Normally a calling site will take care of setting the
  153.  * local PAD pars via an X.28 command and those of the remote
  154.  * PAD via an X.29 command, unless the remote site has a
  155.  * special channel assigned for this protocol with the proper
  156.  * par settings.
  157.  *
  158.  * Author: Piet Beertema, CWI, Amsterdam, Sep 1984
  159.  */
  160.  
  161. #include "uucp.h"
  162. #include <signal.h>
  163. #ifdef USG
  164. #include <termio.h>
  165. #else !USG
  166. #include <sgtty.h>
  167. #endif !USG
  168. #include <setjmp.h>
  169.  
  170. #define FBUFSIZ256
  171.  
  172. #ifndef MAXMSGLEN
  173. #define MAXMSGLENBUFSIZ
  174. #endif MAXMSGLEN
  175.  
  176. static int chksum;
  177. static jmp_buf Ffailbuf;
  178.  
  179. static
  180. falarm()
  181. {
  182. signal(SIGALRM, falarm);
  183. longjmp(Ffailbuf, 1);
  184. }
  185.  
  186. static int (*fsig)();
  187.  
  188. #ifndef USG
  189. #define TCGETATIOCGETP
  190. #define TCSETAFTIOCSETP
  191. #define termiosgttyb
  192. #else
  193. #endif USG
  194.  
  195. fturnon()
  196. {
  197. int ret;
  198. struct termio ttbuf;
  199.  
  200. ioctl(Ifn, TCGETA, &ttbuf);
  201. #ifdef USG
  202. ttbuf.c_iflag = IXOFF|IXON|ISTRIP;
  203. ttbuf.c_cc[VMIN] = FBUFSIZ > 64 ? 64 : FBUFSIZ;
  204. ttbuf.c_cc[VTIME] = 5;
  205. #else
  206. ttbuf.sg_flags = ANYP|CBREAK|TANDEM;
  207. #endif USG
  208. ret = ioctl(Ifn, TCSETAF, &ttbuf);
  209. ASSERT(ret >= 0, "STTY FAILED", "", ret);
  210. #ifndefUSG
  211. {
  212.     intlocalmodeword;
  213.     ioctl(Ifn, TIOCLGET, &localmodeword);
  214.     DEBUG(8, "local mode word: %o\n", localmodeword);
  215.     localmodeword &= ~LNOHANG;
  216.     ioctl(Ifn, TIOCLSET, &localmodeword);
  217. }
  218. #endif
  219. fsig = signal(SIGALRM, falarm);
  220. /* give the other side time to perform its ioctl;
  221.  * otherwise it may flush out the first data this
  222.  * side is about to send.
  223.  */
  224. sleep(2);
  225. return SUCCESS;
  226. }
  227.  
  228. fturnoff()
  229. {
  230. (void) signal(SIGALRM, fsig);
  231. return SUCCESS;
  232. }
  233.  
  234. fwrmsg(type, str, fn)
  235. register char *str;
  236. int fn;
  237. char type;
  238. {
  239. register char *s;
  240. char bufr[MAXMSGLEN];
  241.  
  242. s = bufr;
  243. *s++ = type;
  244. while (*str)
  245. *s++ = *str++;
  246. if (*(s-1) == '\n')
  247. s--;
  248. *s++ = '\r';
  249. (void) write(fn, bufr, s - bufr);
  250. return SUCCESS;
  251. }
  252.  
  253. frdmsg(str, fn)
  254. register char *str;
  255. register int fn;
  256. {
  257. register char *smax;
  258.  
  259. if (setjmp(Ffailbuf))
  260. return FAIL;
  261. smax = str + MAXMSGLEN - 1;
  262. (void) alarm(2*MAXMSGTIME);
  263. for (;;) {
  264. if (read(fn, str, 1) <= 0)
  265. goto msgerr;
  266. if (*str == '\r')
  267. break;
  268. if (*str < ' ')
  269. continue;
  270. if (str++ >= smax)
  271. goto msgerr;
  272. }
  273. *str = '\0';
  274. (void) alarm(0);
  275. return SUCCESS;
  276. msgerr:
  277. (void) alarm(0);
  278. return FAIL;
  279. }
  280.  
  281. fwrdata(fp1, fn)
  282. FILE *fp1;
  283. int fn;
  284. {
  285. register int flen, alen, ret;
  286. register char *obp;
  287. char ibuf[FBUFSIZ];
  288. char ack;
  289. long abytes, fbytes;
  290. struct timeb t1, t2;
  291. int mil, retries = 0;
  292.  
  293. ret = FAIL;
  294. retry:
  295. chksum = 0xffff;
  296. abytes = fbytes = 0L;
  297. ack = '\0';
  298. #ifdef USG
  299. time(&t1.time);
  300. t1.millitm = 0;
  301. #else !USG
  302. ftime(&t1);
  303. #endif !USG
  304. while ((flen = fread(ibuf, sizeof (char), FBUFSIZ, fp1)) > 0) {
  305. alen = fwrblk(fn, ibuf, flen);
  306. abytes += alen >= 0 ? alen : -alen;
  307. if (alen <= 0)
  308. goto acct;
  309. fbytes += flen;
  310. }
  311. sprintf(ibuf, "\176\176%04x\r", chksum);
  312. abytes += alen = strlen(ibuf);
  313. if (write(fn, ibuf, alen) == alen) {
  314. DEBUG(8, "wrdata: checksum length: %d\n", alen);
  315. DEBUG(8, "checksum: %04x\n", chksum);
  316. if (frdmsg(ibuf, fn) != FAIL) {
  317. if ((ack = ibuf[0]) == 'G')
  318. ret = 0;
  319. DEBUG(4, "ack - '%c'\n", ack);
  320. }
  321. }
  322. acct:
  323. if (ack == 'R') {
  324. DEBUG(4, "RETRY:\n", 0);
  325. fseek(fp1, 0L, 0);
  326. retries++;
  327. goto retry;
  328. }
  329. #ifdef USG
  330. time(&t2.time);
  331. t2.millitm = 0;
  332. #else !USG
  333. ftime(&t2);
  334. #endif !USG
  335. Now = t2;
  336. t2.time -= t1.time;
  337. mil = t2.millitm - t1.millitm;
  338. if (mil < 0) {
  339. --t2.time;
  340. mil += 1000;
  341. }
  342. sprintf(ibuf, "sent data %ld bytes %ld.%02d secs",
  343. fbytes, (long)t2.time, mil/10);
  344. sysacct(abytes, t2.time - t1.time);
  345. if (retries > 0) 
  346. sprintf((char *)ibuf+strlen(ibuf)," %d retries", retries);
  347. DEBUG(1, "%s\n", ibuf);
  348. syslog(ibuf);
  349. #ifdef SYSACCT
  350. if (ret)
  351. sysaccf(NULL);/* force accounting */
  352. #endif SYSACCT
  353. return ret;
  354. }
  355.  
  356. /* max. attempts to retransmit a file: */
  357. #define MAXRETRIES(fbytes < 10000L ? 2 : 1)
  358.  
  359. frddata(fn, fp2)
  360. register int fn;
  361. register FILE *fp2;
  362. {
  363. register int flen;
  364. register char eof;
  365. char ibuf[FBUFSIZ];
  366. int ret, retries = 0;
  367. long alen, abytes, fbytes;
  368. struct timeb t1, t2;
  369. int mil;
  370.  
  371. ret = FAIL;
  372. retry:
  373. chksum = 0xffff;
  374. abytes = fbytes = 0L;
  375. #ifdef USG
  376. time(&t1.time);
  377. t1.millitm = 0;
  378. #else !USG
  379. ftime(&t1);
  380. #endif !USG
  381. do {
  382. flen = frdblk(ibuf, fn, &alen);
  383. abytes += alen;
  384. if (flen < 0)
  385. goto acct;
  386. if (eof = flen > FBUFSIZ)
  387. flen -= FBUFSIZ + 1;
  388. fbytes += flen;
  389. if (fwrite(ibuf, sizeof (char), flen, fp2) != flen)
  390. goto acct;
  391. } while (!eof);
  392. ret = 0;
  393. acct:
  394. if (ret) {
  395. if (retries++ < MAXRETRIES) {
  396. DEBUG(8, "send ack: 'R'\n", 0);
  397. fwrmsg('R', "", fn);
  398. fseek(fp2, 0L, 0);
  399. DEBUG(4, "RETRY:\n", 0);
  400. goto retry;
  401. }
  402. DEBUG(8, "send ack: 'Q'\n", 0);
  403. fwrmsg('Q', "", fn);
  404. #ifdef SYSACCT
  405. sysaccf(NULL);/* force accounting */
  406. #endif SYSACCT
  407. } else {
  408. DEBUG(8, "send ack: 'G'\n", 0);
  409. fwrmsg('G', "", fn);
  410. }
  411. #ifdef USG
  412. time(&t2.time);
  413. t2.millitm = 0;
  414. #else !USG
  415. ftime(&t2);
  416. #endif !USG
  417. Now = t2;
  418. t2.time -= t1.time;
  419. mil = t2.millitm - t1.millitm;
  420. if (mil < 0) {
  421. --t2.time;
  422. mil += 1000;
  423. }
  424. sprintf(ibuf, "received data %ld bytes %ld.%02d secs",
  425. fbytes, (long)t2.time, mil/10);
  426. sysacct(abytes, t2.time - t1.time);
  427. if (retries > 0) 
  428. sprintf((char *)ibuf+strlen(ibuf)," %d retries", retries);
  429. DEBUG(1, "%s\n", ibuf);
  430. syslog(ibuf);
  431. return ret;
  432. }
  433.  
  434. static
  435. frdbuf(blk, len, fn)
  436. register char *blk;
  437. register int len;
  438. register int fn;
  439. {
  440. static int ret = FBUFSIZ / 2;
  441. #ifndef Not080
  442. extern int linebaudrate;
  443. #endif Not080
  444.  
  445. if (setjmp(Ffailbuf))
  446. return FAIL;
  447. #ifndef Not080
  448. if (len == FBUFSIZ && ret < FBUFSIZ / 2 &&
  449.     linebaudrate > 0 && linebaudrate < 4800)
  450. sleep(1);
  451. #endif Not080
  452. (void) alarm(MAXMSGTIME);
  453. ret = read(fn, blk, len);
  454. alarm(0);
  455. return ret <= 0 ? FAIL : ret;
  456. }
  457.  
  458. /* call ultouch every TC calls to either frdblk or fwrblk  */
  459.  
  460. #defineTC20
  461. staticint tc = TC;
  462.  
  463. /* Byte conversion:
  464.  *
  465.  *   from        pre       to
  466.  * 000-037       172     100-137
  467.  * 040-171               040-171
  468.  * 172-177       173     072-077
  469.  * 200-237       174     100-137
  470.  * 240-371       175     040-171
  471.  * 372-377       176     072-077
  472.  */
  473.  
  474. static
  475. fwrblk(fn, ip, len)
  476. int fn;
  477. register char *ip;
  478. register int len;
  479. {
  480. register char *op;
  481. register int sum, nl;
  482. int ret;
  483. char obuf[FBUFSIZ * 2];
  484.  
  485. /* call ultouch occasionally */
  486. if (--tc < 0) {
  487. tc = TC;
  488. ultouch();
  489. }
  490. DEBUG(8, "fwrblk: %d/", len);
  491. op = obuf;
  492. nl = 0;
  493. sum = chksum;
  494. do {
  495. if (sum & 0x8000) {
  496. sum <<= 1;
  497. sum++;
  498. } else
  499. sum <<= 1;
  500. sum += *ip & 0377;
  501. sum &= 0xffff;
  502. if (*ip & 0200) {
  503. *ip &= 0177;
  504. if (*ip < 040) {
  505. *op++ = '\174';
  506. *op++ = *ip++ + 0100;
  507. } else
  508. if (*ip <= 0171) {
  509. *op++ = '\175';
  510. *op++ = *ip++;
  511. }
  512. else {
  513. *op++ = '\176';
  514. *op++ = *ip++ - 0100;
  515. }
  516. nl += 2;
  517. } else {
  518. if (*ip < 040) {
  519. *op++ = '\172';
  520. *op++ = *ip++ + 0100;
  521. nl += 2;
  522. } else
  523. if (*ip <= 0171) {
  524. *op++ = *ip++;
  525. nl++;
  526. } else {
  527. *op++ = '\173';
  528. *op++ = *ip++ - 0100;
  529. nl += 2;
  530. }
  531. }
  532. } while (--len);
  533. chksum = sum;
  534. DEBUG(8, "%d\n", nl);
  535. ret = write(fn, obuf, nl);
  536. return ret == nl ? nl : ret < 0 ? 0 : -ret;
  537. }
  538.  
  539. static
  540. frdblk(ip, fn, rlen)
  541. register char *ip;
  542. int fn;
  543. long *rlen;
  544. {
  545. register char *op, c;
  546. register int sum, len, nl;
  547. char buf[5], *erbp = ip;
  548. int i;
  549. static char special = 0;
  550.  
  551. /* call ultouch occasionally */
  552. if (--tc < 0) {
  553. tc = TC;
  554. ultouch();
  555. }
  556.  
  557. if ((len = frdbuf(ip, FBUFSIZ, fn)) == FAIL) {
  558. *rlen = 0;
  559. goto dcorr;
  560. }
  561. *rlen = len;
  562. DEBUG(8, "%d/", len);
  563. op = ip;
  564. nl = 0;
  565. sum = chksum;
  566. do {
  567. if ((*ip &= 0177) >= '\172') {
  568. if (special) {
  569. DEBUG(8, "%d", nl);
  570. special = 0;
  571. op = buf;
  572. if (*ip++ != '\176' || (i = --len) > 5)
  573. goto dcorr;
  574. while (i--)
  575. *op++ = *ip++;
  576. while (len < 5) {
  577. i = frdbuf(&buf[len], 5 - len, fn);
  578. if (i == FAIL) {
  579. len = FAIL;
  580. goto dcorr;
  581. }
  582. DEBUG(8, ",%d", i);
  583. len += i;
  584. *rlen += i;
  585. }
  586. if (buf[4] != '\r')
  587. goto dcorr;
  588. sscanf(buf, "%4x", &chksum);
  589. DEBUG(8, "\nchecksum: %04x\n", sum);
  590. if (chksum == sum)
  591. return FBUFSIZ + 1 + nl;
  592. else {
  593. DEBUG(8, "\n", 0);
  594. DEBUG(4, "Bad checksum\n", 0);
  595. return FAIL;
  596. }
  597. }
  598. special = *ip++;
  599. } else {
  600. if (*ip < '\040') {
  601. /* error: shouldn't get control chars */
  602. goto dcorr;
  603. }
  604. switch (special) {
  605. case 0:
  606. c = *ip++;
  607. break;
  608. case '\172':
  609. c = *ip++ - 0100;
  610. break;
  611. case '\173':
  612. c = *ip++ + 0100;
  613. break;
  614. case '\174':
  615. c = *ip++ + 0100;
  616. break;
  617. case '\175':
  618. c = *ip++ + 0200;
  619. break;
  620. case '\176':
  621. c = *ip++ + 0300;
  622. break;
  623. }
  624. *op++ = c;
  625. if (sum & 0x8000) {
  626. sum <<= 1;
  627. sum++;
  628. } else
  629. sum <<= 1;
  630. sum += c & 0377;
  631. sum &= 0xffff;
  632. special = 0;
  633. nl++;
  634. }
  635. } while (--len);
  636. chksum = sum;
  637. DEBUG(8, "%d,", nl);
  638. return nl;
  639. dcorr:
  640. DEBUG(8, "\n", 0);
  641. DEBUG(4, "Data corrupted\n", 0);
  642. while (len != FAIL) {
  643. if ((len = frdbuf(erbp, FBUFSIZ, fn)) != FAIL)
  644. *rlen += len;
  645. }
  646. return FAIL;
  647. }
  648. ---
  649. pad.c
  650. ---
  651.  
  652. #ifndef lint
  653. static char*RcsId = "$Header: pad.c,v 1.1 85/01/08 19:58:45 rick Exp $";
  654. #endif !lint
  655.  
  656. #include "../condevs.h"
  657. #ifdef PAD
  658.  
  659. /*
  660.  *padopn: establish connection through a PAD.
  661.  *Returns descriptor open to tty for reading and writing.
  662.  *Negative values (-1...-7) denote errors in connmsg.
  663.  *Be sure to disconnect tty when done, via HUPCL or stty 0.
  664.  */
  665.  
  666. char *padparms[] = {
  667. "set1:0,2:0,3:2,4:1,5:1,6:5,7:4,9:0,10:0,13:0",
  668. "set14:0,15:0,16:0,17:0,18:0,19:1,20:255",
  669. "set102:0,103:17,104:19,105:0,106:0,107:0,108:0",
  670. "set109:0,110:0,111:0,112:0,113:0,114:0,115:0,116:0",
  671. NULL
  672. };
  673.  
  674. externchar*AbortOn;
  675. intpadcls();
  676. padopn(flds)
  677. register char *flds[];
  678. {
  679. char phone[MAXPH+1];
  680. register char **parmptr;
  681. extern errno;
  682. char *rindex(), *fdig(), dcname[20];
  683. int dh, ok = 0, speed;
  684. register struct condev *cd;
  685. register FILE *dfp;
  686. struct Devices dev;
  687.  
  688. dfp = fopen(DEVFILE, "r");
  689. ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
  690.  
  691. signal(SIGALRM, alarmtr);
  692. dh = -1;
  693. for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) {
  694. if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
  695. fseek(dfp, (off_t)0, 0);
  696. while(rddev(dfp, &dev) != FAIL) {
  697. if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
  698. continue;
  699. if (snccmp(flds[F_LINE], dev.D_type) != SAME)
  700. continue;
  701. DEBUG(4, "Trying line %s\n", dev.D_line);
  702. if (mlock(dev.D_line) == FAIL)
  703. continue;
  704.  
  705. sprintf(dcname, "/dev/%s", dev.D_line);
  706. getnextfd();
  707. alarm(10);
  708. if (setjmp(Sjbuf)) {
  709. delock(dev.D_line);
  710. logent(dev.D_line,"pad open TIMEOUT");
  711. dh = -1;
  712. break;
  713. }
  714. dh = open(dcname, 2);
  715. alarm(0);
  716. next_fd = -1;
  717. if (dh > 0) {
  718. break;
  719. }
  720. DEBUG(4, "Can't open line %s\n", dev.D_line);
  721. devSel[0] = '\0';
  722. delock(dev.D_line);
  723. }
  724. }
  725. }
  726. fclose(dfp);
  727. if (dh < 0)
  728. return CF_NODEV;
  729. DEBUG(4, "Using line %s\n", dev.D_line);
  730.  
  731. speed = atoi(fdig(flds[F_CLASS]));
  732. fixline(dh, speed);
  733. /*Do we need this?  I don't know*/
  734. sleep(1);
  735.  
  736. /* Synchronize with PAD prompt */
  737. write(dh, "\r", 1);
  738. DEBUG(10, "Pad Sync: wanted %s\n", ">");
  739. ok = expect(">", dh);
  740. DEBUG(10, "got %s\n", ok ? "?" : "that");
  741.  
  742. if (ok) {
  743. logent(dev.D_line, "PAD SYNC FAILED");
  744. close(dh);
  745. return CF_DIAL;
  746. }
  747.  
  748. /*Initialization of PAD*/
  749. AbortOn = "err";
  750. for (parmptr = padparms; ok == 0 && *parmptr; parmptr++) {
  751. DEBUG(10, "PAD setup: %s\n", *parmptr);
  752. write(dh, *parmptr, strlen(*parmptr));
  753. write(dh, "\r", 1);
  754. ok = expect(">", dh);
  755. DEBUG(4, "setup %s\n", ok? "failed": "worked");
  756. }
  757. if (Debug > 10) {
  758. DEBUG(10, "PAD %s:\n", "configuration");
  759. write(dh, "par?\r", 6);
  760. ok = expect(">", dh);
  761. }
  762. AbortOn = NULL;/* dochat(login) does this anyways */
  763. if (ok) {
  764. logent(dev.D_line, "PAD SETUP/CONFIG DEBUG FAILED");
  765. close(dh);
  766. return CF_DIAL;
  767. }
  768.  
  769. /*Do chat from L-devices */
  770. if (dochat(&dev, flds, dh)) {
  771. logent(dev.D_line, "CHAT FAILED");
  772. close(dh);
  773. return CF_DIAL;
  774. }
  775.  
  776. if (ok == 0) {
  777. exphone(flds[F_PHONE], phone);
  778. DEBUG(4, "PAD: calling %s\n", phone);
  779. write(dh, "c ", 2);
  780. write(dh, phone, strlen(phone));
  781. write(dh, "\r", 1);
  782. DEBUG(4, "wanted %s ", "com");
  783. AbortOn = "clr";
  784. ok = expect("com", dh);
  785. DEBUG(4, "got %s\n", ok ? "?" : "that");
  786. AbortOn = NULL;
  787. }
  788.  
  789. if (ok != 0) {
  790. if (dh > 2)
  791. close(dh);
  792. DEBUG(4, "pad failed\n", "");
  793. delock(dev.D_line);
  794. return(CF_DIAL);
  795. else
  796. DEBUG(4, "pad ok\n", "");
  797.  
  798. CU_end = padcls;
  799. strcat(devSel, dev.D_line);/* for later unlock */
  800. return dh;
  801. }
  802.  
  803. padcls(fd)
  804. register int fd;
  805. {
  806.  
  807. if (fd > 0) {
  808. DEBUG(4, "Closing %s\n", "PAD");
  809. close(fd);
  810. delock(devSel);
  811. }
  812. }
  813. #endif MICOM
  814. ---
  815. eof
  816. ---
  817.  
  818.  
  819. ======================================================================
  820.  
  821.