callers.c

Upload User: acmefrp
Upload Date: 2010-03-06
Package Size: 23768k
Code Size: 25k
Category: OS Develop
Development Platform: C/C++
  1. /* Copyright (c) 1984 AT&T */
  2. /*   All Rights Reserved   */
  3. /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
  4. /* The copyright notice above does not evidence any    */
  5. /* actual or intended publication of such source code. */
  6. #ident  "@(#)callers.c 1.1 92/07/30" /* from SVR3.2 uucp:callers.c 2.23 */
  7. #include "uucp.h"
  8. #ifdef BSD4_2
  9. #include <netdb.h>
  10. #include <netinet/in.h>
  11. #include <sys/socket.h>
  12. #endif
  13. #ifdef UNET
  14. #include  "UNET/unetio.h"
  15. #include  "UNET/tcp.h"
  16. #endif
  17. int alarmtr();
  18. extern jmp_buf Sjbuf;
  19. extern char *fdig();
  20. extern int Modemctrl;
  21. /*
  22.  * to add a new caller:
  23.  * declare the function that knows how to call on the device,
  24.  * add a line to the callers table giving the name of the device
  25.  * (from Devices file) and the name of the function
  26.  * add the function to the end of this file
  27.  */
  28. #ifdef DIAL801
  29. int dial801();
  30. #endif
  31. #ifdef DATAKIT
  32. int dkcall();
  33. #endif /* DATAKIT */
  34. #ifdef V8
  35. int Dialout();
  36. #endif
  37. #ifdef TCP
  38. int unetcall();
  39. int tcpcall();
  40. #endif /* TCP */
  41. #ifdef SYTEK
  42. int sytcall();
  43. #endif /* SYTEK */
  44. #ifdef TLI
  45. int tlicall();
  46. #endif /* TLI */
  47. struct caller Caller[] = {
  48. #ifdef DIAL801
  49. {"801", dial801},
  50. {"212", dial801},
  51. #endif /* DIAL801 */
  52. #ifdef V8
  53. {"Dialout", Dialout}, /* ditto but using dialout(III) */
  54. #endif
  55. #ifdef TCP
  56. #ifdef BSD4_2
  57. {"TCP", tcpcall}, /* 4.2BSD sockets */
  58. #else /* !BSD4_2 */
  59. #ifdef UNET
  60. {"TCP", unetcall}, /* 3com implementation of tcp */
  61. {"Unetserver", unetcall},
  62. #endif /* UNET */
  63. #endif /* BSD4_2 */
  64. #endif /* TCP */
  65. #ifdef DATAKIT
  66. {"DK", dkcall}, /* standard AT&T DATAKIT VCS caller */
  67. #endif /* DATAKIT */
  68. #ifdef SYTEK
  69. {"Sytek", sytcall}, /* untested but should work */
  70. #endif /* SYTEK */
  71. #ifdef TLI
  72. {"TLI", tlicall}, /* AT&T Transport Layer Interface */
  73. #ifdef TLIS
  74. {"TLIS", tlicall}, /* AT&T Transport Layer Interface */
  75. #endif /*  TLIS  */
  76. #endif /* TLI */
  77. {NULL,  NULL} /* this line must be last */
  78. };
  79. /***
  80.  * exphone - expand phone number for given prefix and number
  81.  *
  82.  * return code - none
  83.  */
  84. static void
  85. exphone(in, out)
  86. char *in, *out;
  87. {
  88. FILE *fn;
  89. char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH];
  90. char buf[BUFSIZ];
  91. char *s1;
  92. if (!isalpha(*in)) {
  93. (void) strcpy(out, in);
  94. return;
  95. }
  96. s1=pre;
  97. while (isalpha(*in))
  98. *s1++ = *in++;
  99. *s1 = NULLCHAR;
  100. s1 = npart;
  101. while (*in != NULLCHAR)
  102. *s1++ = *in++;
  103. *s1 = NULLCHAR;
  104. tpre[0] = NULLCHAR;
  105. fn = fopen(DIALCODES, "r");
  106. if (fn != NULL) {
  107. while (fgets(buf, BUFSIZ, fn)) {
  108. if ( sscanf(buf, "%s%s", p, tpre) < 1)
  109. continue;
  110. if (EQUALS(p, pre))
  111. break;
  112. tpre[0] = NULLCHAR;
  113. }
  114. fclose(fn);
  115. }
  116. (void) strcpy(out, tpre);
  117. (void) strcat(out, npart);
  118. return;
  119. }
  120. /*
  121.  * repphone - Replace D and T sequences in arg with phone
  122.  * expanding and translating as appropriate.
  123.  */
  124. static char *
  125. repphone(arg, phone, trstr)
  126. register char *arg, *phone, *trstr;
  127. {
  128. extern void translate();
  129. static char pbuf[2*(MAXPH+2)];
  130. register char *fp, *tp;
  131. for (tp=pbuf; *arg; arg++) {
  132. if (*arg != '\') {
  133. *tp++ = *arg;
  134. continue;
  135. } else {
  136. switch (*(arg+1)) {
  137. case 'T':
  138. exphone(phone, tp);
  139. translate(trstr, tp);
  140. for(; *tp; tp++)
  141.     ;
  142. arg++;
  143. break;
  144. case 'D':
  145. for(fp=phone; *tp = *fp++; tp++)
  146.     ;
  147. arg++;
  148. break;
  149. default:
  150. *tp++ = *arg;
  151. break;
  152. }
  153. }
  154. }
  155. *tp = '';
  156. return(pbuf);
  157. }
  158. /*
  159.  * processdev - Process a line from the Devices file
  160.  *
  161.  * return codes:
  162.  * file descriptor  -  succeeded
  163.  * FAIL  -  failed
  164.  */
  165. processdev(flds, dev)
  166. register char *flds[], *dev[];
  167. {
  168. int dcf = -1;
  169. register struct caller *ca;
  170. char *args[D_MAX+1], dcname[20];
  171. register char **sdev;
  172. extern int (*Setup)();
  173. extern void translate(), setdevcfg();
  174. register nullfd;
  175. char *phonecl; /* clear phone string */
  176. char phoneex[2*(MAXPH+2)]; /* expanded phone string */
  177. extern ttygenbrk();
  178. sdev = dev;
  179. /* set up default "break" routine */
  180. genbrk = ttygenbrk;
  181. for (ca = Caller; ca->CA_type != NULL; ca++) {
  182. /* This will find built-in caller functions */
  183. if (EQUALS(ca->CA_type, dev[D_CALLER])) {
  184. DEBUG(5, "Internal caller type %sn", dev[D_CALLER]);
  185. if (dev[D_ARG] == NULL) {
  186. /* if NULL - assume translate */
  187. dev[D_ARG+1] = NULL; /* needed for for loop later to mark the end */
  188. dev[D_ARG] = "\T";
  189. }
  190. dev[D_ARG] = repphone(dev[D_ARG], flds[F_PHONE], "");
  191. if ((dcf = (*(ca->CA_caller))(flds, dev)) < 0)
  192. return(dcf) ;
  193. if ( interface( ca->CA_type ) ) {
  194. DEBUG(5, "interface(%s) failed", ca->CA_type);
  195. Uerror = SS_DEVICE_FAILED;
  196. /* restore vanilla unix interface */
  197. (void)interface("UNIX");
  198. return(FAIL);
  199. }
  200. dev += 2; /* Skip to next CALLER and ARG */
  201. break;
  202. }
  203. }
  204. if (dcf == -1) {
  205. /* Here if not a built-in caller function */
  206. /* If "DIAL" is defined, the mlock will probably fail */
  207. /* (/usr/spool/locks is usually 755 owned by uucp), but */
  208. /* since are using advisory file locks anyway let it */
  209. /* slide. */
  210. if (mlock(dev[D_LINE]) == FAIL) { /* Lock the line */
  211. #ifdef DIAL
  212. ;
  213. }
  214. #else /* !DIAL */
  215. DEBUG(5, "mlock %s failedn", dev[D_LINE]);
  216. Uerror = SS_LOCKED_DEVICE;
  217. return(FAIL);
  218. }
  219. DEBUG(5, "mlock %s succeededn", dev[D_LINE]);
  220. #endif /* DIAL */
  221. /*
  222.  * Open the line
  223.  */
  224. if ( *dev[D_LINE] != '/' ) {
  225. (void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
  226. } else {
  227. (void) strcpy(dcname, dev[D_LINE] );
  228. }
  229. /* take care of the possible partial open fd */
  230. (void) close(nullfd = open("/", 0));
  231. if (setjmp(Sjbuf)) {
  232. (void) close(nullfd);
  233. DEBUG(1, "generic open timeoutn", 0);
  234. logent("generic open", "TIMEOUT");
  235. Uerror = SS_CANT_ACCESS_DEVICE;
  236. goto bad;
  237. }
  238. (void) signal(SIGALRM, alarmtr);
  239. (void) alarm(10);
  240. if ( Modemctrl ) {
  241. DEBUG(7, "opening with O_NDELAY setn", 0);
  242. dcf = open(dcname, (O_RDWR | O_NDELAY) );
  243. } else
  244. dcf = open(dcname, O_RDWR );
  245. (void) alarm(0);
  246. if (dcf < 0) {
  247. DEBUG(1, "generic open failed, errno = %dn", errno);
  248. logent("generic open", "FAILED");
  249. Uerror = SS_CANT_ACCESS_DEVICE;
  250. (void) close(nullfd);
  251. goto bad;
  252. }
  253. if ( Modemctrl ) {
  254. DEBUG(7, "clear O_NDELAYn", 0);
  255. if ( fcntl(dcf, F_SETFL,
  256. (fcntl(dcf, F_GETFL, 0) & ~O_NDELAY)) < 0 ) {
  257. DEBUG( 7, "clear O_NDELAY failed, errno %dn", errno);
  258. (void)close(dcf);
  259. Uerror = SS_DEVICE_FAILED;
  260. goto bad;
  261. }
  262. }
  263. #ifdef ATTSV
  264. if ( filelock(dcf) != SUCCESS ) {
  265. (void)close(dcf);
  266. DEBUG(1, "failed to lock device %sn", dcname);
  267. Uerror = SS_LOCKED_DEVICE;
  268. goto bad;
  269. }
  270. #endif /* ATTSV */
  271. fixline(dcf, atoi(fdig(dev[D_CLASS])), D_DIRECT);
  272. }
  273. /* init device config info */
  274. DEBUG(5, "processdev: calling setdevcfg(%s, ", Progname);
  275. DEBUG(5, "%s)n", flds[F_TYPE]);
  276. setdevcfg(Progname, flds[F_TYPE]);
  277. if ( (*Setup)( MASTER, &dcf, &dcf ) ) {
  278. /* any device|system lock files we should remove? */
  279. DEBUG(5, "MASTER Setup failed", 0);
  280. Uerror = SS_DEVICE_FAILED;
  281. goto bad;
  282. }
  283. /*
  284.  * Now loop through the remaining callers and chat
  285.  * according to scripts in dialers file.
  286.  */
  287. for (; dev[D_CALLER] != NULL; dev += 2) {
  288. register int w;
  289. /*
  290.  * Scan Dialers file to find an entry
  291.  */
  292. if ((w = gdial(dev[D_CALLER], args, D_MAX)) < 1) {
  293. DEBUG(1, "%s not found in Dialers filen", dev[D_CALLER]);
  294. logent("generic call to gdial", "FAILED");
  295. Uerror = SS_CANT_ACCESS_DEVICE;
  296. goto bad;
  297. }
  298. if (w <= 2) /* do nothing - no chat */
  299. break;
  300. /*
  301.  * Translate the phone number
  302.  */
  303. if (dev[D_ARG] == NULL) {
  304. /* if NULL - assume no translation */
  305. dev[D_ARG+1] = NULL; /* needed for for loop to mark the end */
  306. dev[D_ARG] = "\D";
  307. }
  308. phonecl = repphone(dev[D_ARG], flds[F_PHONE], args[1]);
  309. exphone(phonecl, phoneex);
  310. translate(args[1], phoneex);
  311. /*
  312.  * Chat
  313.  */
  314. if (chat(w-2, &args[2], dcf, phonecl, phoneex) != SUCCESS) {
  315. Uerror = SS_CHAT_FAILED;
  316. goto bad;
  317. }
  318. }
  319. /*
  320.  * Success at last!
  321.  */
  322. strcpy(Dc, sdev[D_LINE]);
  323. return(dcf);
  324. bad:
  325. if ( dcf >= 0 )
  326. (void)close(dcf);
  327. delock(sdev[D_LINE]);
  328. /* restore vanilla unix interface */
  329. (void)interface("UNIX");
  330. return(FAIL);
  331. }
  332. /*
  333.  * translate the pairs of characters present in the first
  334.  * string whenever the first of the pair appears in the second
  335.  * string.
  336.  */
  337. static void
  338. translate(ttab, str)
  339. register char *ttab, *str;
  340. {
  341. register char *s;
  342. for(;*ttab && *(ttab+1); ttab += 2)
  343. for(s=str;*s;s++)
  344. if(*ttab == *s)
  345. *s = *(ttab+1);
  346. }
  347. #define MAXLINE 512
  348. /*
  349.  * Get the information about the dialer.
  350.  * gdial(type, arps, narps)
  351.  * type -> type of dialer (e.g., penril)
  352.  * arps -> array of pointers returned by gdial
  353.  * narps -> number of elements in array returned by gdial
  354.  * Return value:
  355.  * -1 -> Can't open DIALERFILE
  356.  * 0 -> requested type not found
  357.  * >0 -> success - number of fields filled in
  358.  */
  359. static
  360. gdial(type, arps, narps)
  361. register char *type, *arps[];
  362. register int narps;
  363. {
  364. static char info[MAXLINE];
  365. register na;
  366. extern void dialreset();
  367. DEBUG(2, "gdial(%s) calledn", type);
  368. while (getdialline(info, sizeof(info))) {
  369. if ((info[0] == '#') || (info[0] == ' ') ||
  370.     (info[0] == 't') || (info[0] == 'n'))
  371. continue;
  372. if ((na = getargs(info, arps, narps)) == 0)
  373. continue;
  374. if (EQUALS(arps[0], type)) {
  375. dialreset();
  376. bsfix(arps);
  377. return(na);
  378. }
  379. }
  380. dialreset();
  381. return(0);
  382. }
  383. #ifdef DATAKIT
  384. /***
  385.  * dkcall(flds, dev) make a DATAKIT VCS connection
  386.  *   DATAKIT VCS is a trademark of AT&T
  387.  *
  388.  * return codes:
  389.  * >0 - file number - ok
  390.  * FAIL - failed
  391.  */
  392. #include "dk.h"
  393. dkcall(flds, dev)
  394. char *flds[], *dev[];
  395. {
  396. register fd;
  397. #ifdef V8
  398. extern int cdkp_ld;
  399. #endif
  400. char dialstring[64];
  401. extern  dkbreak();
  402. strcpy(dialstring, dev[D_ARG]);
  403. #ifndef STANDALONE
  404. if(*flds[F_CLASS] < '0' || *flds[F_CLASS] > '9')
  405. sprintf(dialstring, "%s.%s", dev[D_ARG], flds[F_CLASS]);
  406. #endif
  407. DEBUG(4, "dkcall(%s)n", dialstring);
  408. #ifdef V8
  409. if (setjmp(Sjbuf)) {
  410. Uerror = SS_DIAL_FAILED;
  411. return(FAIL);
  412. }
  413. (void) signal(SIGALRM, alarmtr);
  414. (void) alarm(15);
  415. DEBUG(4, "tdkdial(%s", flds[F_PHONE]);
  416. DEBUG(4, ", %d)n", atoi(dev[D_CLASS]));
  417.      if ((fd = tdkdial(flds[F_PHONE], atoi(dev[D_CLASS]))) >= 0)
  418.     if (dkproto(fd, cdkp_ld) < 0)
  419.        {
  420.      close(fd);
  421.      fd = -1;
  422.        }
  423. (void) alarm(0);
  424. #else
  425. fd = dkdial(dialstring);
  426. #endif
  427. (void) strcpy(Dc, "DK");
  428. if (fd < 0) {
  429. Uerror = SS_DIAL_FAILED;
  430. return(FAIL);
  431. }
  432. else {
  433. genbrk = dkbreak;
  434. return(fd);
  435. }
  436. }
  437. #endif /* DATAKIT */
  438. #ifdef TCP
  439. /***
  440.  * tcpcall(flds, dev) make ethernet/socket connection
  441.  *
  442.  * return codes:
  443.  * >0 - file number - ok
  444.  * FAIL - failed
  445.  */
  446. #ifndef BSD4_2
  447. /*ARGSUSED*/
  448. tcpcall(flds, dev)
  449. char *flds[], *dev[];
  450. {
  451. Uerror = SS_NO_DEVICE;
  452. return(FAIL);
  453. }
  454. #else /* BSD4_2 */
  455. tcpcall(flds, dev)
  456. char *flds[], *dev[];
  457. {
  458. int ret;
  459. short port;
  460. extern int errno, sys_nerr;
  461. extern char *sys_errlist[];
  462. struct servent *sp;
  463. struct hostent *hp;
  464. struct sockaddr_in sin;
  465. if (EQUALS(flds[F_CLASS], "-")) {
  466. /*
  467.  * Use standard UUCP port number.
  468.  */
  469. sp = getservbyname("uucp", "tcp");
  470. endservent();
  471. ASSERT(sp != NULL, "No uucp service number", 0, 0);
  472. port = sp->s_port;
  473. } else {
  474. /*
  475.  * Systems file specifies a port number.
  476.  */
  477. sp = getservbyname(flds[F_CLASS], "tcp");
  478. endservent();
  479. if (sp == NULL) {
  480. port = htons(atoi(flds[F_CLASS]));
  481. if (port == 0) {
  482. logent("tcpopen", "unknown port number");
  483. Uerror = SS_NO_DEVICE;
  484. return(FAIL);
  485. }
  486. } else
  487. port = sp->s_port;
  488. }
  489. if (EQUALS(flds[F_PHONE], "-")) {
  490. /*
  491.  * Use UUCP name as host name.
  492.  */
  493. hp = gethostbyname(flds[F_NAME]);
  494. } else {
  495. /*
  496.  * Systems file specifies a host name different from the UUCP
  497.  * host name.
  498.  */
  499. hp = gethostbyname(flds[F_PHONE]);
  500. }
  501. endhostent();
  502. if (hp == NULL) {
  503. logent("tcpopen", "no such host");
  504. Uerror = SS_NO_DEVICE;
  505. return(FAIL);
  506. }
  507. DEBUG(4, "tcpdial host %s, ", hp->h_name);
  508. DEBUG(4, "port %dn", ntohs(port));
  509. ret = socket(AF_INET, SOCK_STREAM, 0);
  510. if (ret < 0) {
  511. if (errno < sys_nerr) {
  512. DEBUG(5, "no socket: %sn", sys_errlist[errno]);
  513. logent("no socket", sys_errlist[errno]);
  514. }
  515. else {
  516. DEBUG(5, "no socket, errno %dn", errno);
  517. logent("tcpopen", "NO SOCKET");
  518. }
  519. Uerror = SS_NO_DEVICE;
  520. return(FAIL);
  521. }
  522. sin.sin_family = hp->h_addrtype;
  523. bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
  524. sin.sin_port = port;
  525. if (setjmp(Sjbuf)) {
  526. DEBUG(4, "timeout tcpopenn", 0);
  527. logent("tcpopen", "TIMEOUT");
  528. Uerror = SS_NO_DEVICE;
  529. return(FAIL);
  530. }
  531. (void) signal(SIGALRM, alarmtr);
  532. (void) alarm(30);
  533. DEBUG(7, "family: %dn", sin.sin_family);
  534. DEBUG(7, "port: %dn", sin.sin_port);
  535. DEBUG(7, "addr: %08xn",*((int *) &sin.sin_addr));
  536. if (connect(ret, (caddr_t)&sin, sizeof (sin)) < 0) {
  537. (void) alarm(0);
  538. (void) close(ret);
  539. if (errno < sys_nerr) {
  540. DEBUG(5, "connect failed: %sn", sys_errlist[errno]);
  541. logent("connect failed", sys_errlist[errno]);
  542. }
  543. else {
  544. DEBUG(5, "connect failed, errno %dn", errno);
  545. logent("tcpopen", "CONNECT FAILED");
  546. }
  547. Uerror = SS_NO_DEVICE;
  548. return(FAIL);
  549. }
  550. (void) signal(SIGPIPE, SIG_IGN);  /* watch out for broken ipc link...*/
  551. (void) alarm(0);
  552. (void) strcpy(Dc, "IPC");
  553. return(ret);
  554. }
  555. #endif /* BSD4_2 */
  556. /***
  557.  * unetcall(flds, dev) make ethernet connection
  558.  *
  559.  * return codes:
  560.  * >0 - file number - ok
  561.  * FAIL - failed
  562.  */
  563. #ifndef UNET
  564. unetcall(flds, dev)
  565. char *flds[], *dev[];
  566. {
  567. Uerror = SS_NO_DEVICE;
  568. return(FAIL);
  569. }
  570. #else /* UNET */
  571. unetcall(flds, dev)
  572. char *flds[], *dev[];
  573. {
  574. int ret;
  575. int port;
  576. extern int errno;
  577. port = atoi(dev[D_ARG]);
  578. DEBUG(4, "unetdial host %s, ", flds[F_PHONE]);
  579. DEBUG(4, "port %dn", port);
  580. (void) alarm(30);
  581. ret = tcpopen(flds[F_PHONE], port, 0, TO_ACTIVE, "rw");
  582. (void) alarm(0);
  583. endhnent();
  584. if (ret < 0) {
  585. DEBUG(5, "tcpopen failed: errno %dn", errno);
  586. Uerror = SS_DIAL_FAILED;
  587. return(FAIL);
  588. }
  589. (void) strcpy(Dc, "UNET");
  590. return(ret);
  591. }
  592. #endif /* UNET */
  593. #endif /* TCP */
  594. #ifdef SYTEK
  595. /****
  596.  * sytcall(flds, dev) make a sytek connection
  597.  *
  598.  * return codes:
  599.  * >0 - file number - ok
  600.  * FAIL - failed
  601.  */
  602. /*ARGSUSED*/
  603. sytcall(flds, dev)
  604. char *flds[], *dev[];
  605. {
  606. extern int errno;
  607. int dcr, dcr2, nullfd, ret;
  608. char dcname[20], command[BUFSIZ];
  609. (void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
  610. DEBUG(4, "dc - %s, ", dcname);
  611. if (mlock(dev[D_LINE]) == FAIL) { /* Lock the line */
  612. DEBUG(5, "mlock %s failedn", dev[D_LINE]);
  613. Uerror = SS_LOCKED_DEVICE;
  614. return(FAIL);
  615. }
  616. dcr = open(dcname, O_WRONLY|O_NDELAY);
  617. if (dcr < 0) {
  618. Uerror = SS_DIAL_FAILED;
  619. DEBUG(4, "OPEN FAILED %sn", dcname);
  620. delock(dev[D_LINE]);
  621. return(FAIL);
  622. }
  623. if ( filelock(dcr) != SUCCESS ) {
  624. (void)close(dcr);
  625. DEBUG(1, "failed to lock device %sn", dcname);
  626. Uerror = SS_LOCKED_DEVICE;
  627. }
  628. sytfixline(dcr, atoi(fdig(dev[D_CLASS])), D_DIRECT);
  629. (void) sleep(2);
  630. DEBUG(4, "Calling Sytek unit %sn", dev[D_ARG]);
  631. (void) sprintf(command,"rrcall %sr", dev[D_ARG]);
  632. ret = (*Write)(dcr, command, strlen(command));
  633. (void) sleep(1);
  634. DEBUG(4, "COM1 return = %dn", ret);
  635. sytfix2line(dcr);
  636. (void) close(nullfd = open("/", 0));
  637. (void) signal(SIGALRM, alarmtr);
  638. if (setjmp(Sjbuf)) {
  639. DEBUG(4, "timeout sytek openn", 0);
  640. (void) close(nullfd);
  641. (void) close(dcr2);
  642. (void) close(dcr);
  643. Uerror = SS_DIAL_FAILED;
  644. delock(dev[D_LINE]);
  645. return(FAIL);
  646. }
  647. (void) alarm(10);
  648. dcr2 = open(dcname,O_RDWR);
  649. (void) alarm(0);
  650. (void) close(dcr);
  651. if (dcr2 < 0) {
  652. DEBUG(4, "OPEN 2 FAILED %sn", dcname);
  653. Uerror = SS_DIAL_FAILED;
  654. (void) close(nullfd); /* kernel might think dc2 is open */
  655. delock(dev[D_LINE]);
  656. return(FAIL);
  657. }
  658. return(dcr2);
  659. }
  660. #endif /* SYTEK */
  661. #ifdef DIAL801
  662. /***
  663.  * dial801(flds, dev) dial remote machine on 801/801
  664.  * char *flds[], *dev[];
  665.  *
  666.  * return codes:
  667.  * file descriptor  -  succeeded
  668.  * FAIL  -  failed
  669.  *
  670.  * unfortunately, open801() is different for usg and non-usg
  671.  */
  672. /*ARGSUSED*/
  673. dial801(flds, dev)
  674. char *flds[], *dev[];
  675. {
  676. char dcname[20], dnname[20], phone[MAXPH+2], *fdig();
  677. int dcf = -1, speed;
  678. if (mlock(dev[D_LINE]) == FAIL) {
  679. DEBUG(5, "mlock %s failedn", dev[D_LINE]);
  680. Uerror = SS_LOCKED_DEVICE;
  681. return(FAIL);
  682. }
  683. (void) sprintf(dnname, "/dev/%s", dev[D_CALLDEV]);
  684. (void) sprintf(phone, "%s%s", dev[D_ARG]   , ACULAST);
  685. (void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
  686. CDEBUG(1, "Use Port %s, ", dcname);
  687. DEBUG(4, "acu - %s, ", dnname);
  688. CDEBUG(1, "Phone Number  %sn", phone);
  689. VERBOSE("Trying modem - %s, ", dcname); /* for cu */
  690. VERBOSE("acu - %s, ", dnname); /* for cu */
  691. VERBOSE("calling  %s:  ", phone); /* for cu */
  692. speed = atoi(fdig(dev[D_CLASS]));
  693. dcf = open801(dcname, dnname, phone, speed);
  694. if (dcf >= 0) {
  695. fixline(dcf, speed, D_ACU);
  696. (void) strcpy(Dc, dev[D_LINE]); /* for later unlock() */
  697. VERBOSE("SUCCEEDEDn", 0);
  698. } else {
  699. delock(dev[D_LINE]);
  700. VERBOSE("FAILEDn", 0);
  701. }
  702. return(dcf);
  703. }
  704. #ifndef ATTSV
  705. /*ARGSUSED*/
  706. open801(dcname, dnname, phone, speed)
  707. char *dcname, *dnname, *phone;
  708. {
  709. int nw, lt, pid = -1, dcf = -1, nullfd, dnf = -1;
  710. unsigned timelim;
  711. if ((dnf = open(dnname, 1)) < 0) {
  712. DEBUG(5, "can't open %sn", dnname);
  713. Uerror = SS_CANT_ACCESS_DEVICE;
  714. return(FAIL);
  715. }
  716. DEBUG(5, "%s is openn", dnname);
  717. (void) close(nullfd = open("/dev/null", 0)); /* partial open hack */
  718. if (setjmp(Sjbuf)) {
  719. DEBUG(4, "timeout modem openn", 0);
  720. logent("801 open", "TIMEOUT");
  721. (void) close(nullfd);
  722. (void) close(dcf);
  723. (void) close(dnf);
  724. if (pid > 0) {
  725. kill(pid, 9);
  726. wait((int *) 0);
  727. }
  728. Uerror = SS_DIAL_FAILED;
  729. return(FAIL);
  730. }
  731. (void) signal(SIGALRM, alarmtr);
  732. timelim = 5 * strlen(phone);
  733. (void) alarm(timelim < 30 ? 30 : timelim);
  734. if ((pid = fork()) == 0) {
  735. sleep(2);
  736. nw = (*Write)(dnf, phone, lt = strlen(phone));
  737. if (nw != lt) {
  738. DEBUG(4, "ACU write error %dn", errno);
  739. logent("ACU write", "FAILED");
  740. exit(1);
  741. }
  742. DEBUG(4, "ACU write okn", 0);
  743. exit(0);
  744. }
  745. /*  open line - will return on carrier */
  746. dcf = open(dcname, 2);
  747. DEBUG(4, "dcf is %dn", dcf);
  748. if (dcf < 0) { /* handle like a timeout */
  749. (void) alarm(0);
  750. longjmp(Sjbuf, 1);
  751. }
  752. /* modem is open */
  753. while ((nw = wait(&lt)) != pid && nw != -1)
  754. ;
  755. (void) alarm(0);
  756. (void) close(dnf); /* no reason to keep the 801 open */
  757. if (lt != 0) {
  758. DEBUG(4, "Fork Stat %on", lt);
  759. (void) close(dcf);
  760. Uerror = SS_DIAL_FAILED;
  761. return(FAIL);
  762. }
  763. return(dcf);
  764. }
  765. #else /* ATTSV */
  766. open801(dcname, dnname, phone, speed)
  767. char *dcname, *dnname, *phone;
  768. {
  769. int nw, lt, dcf = -1, nullfd, dnf = -1, ret;
  770. unsigned timelim;
  771. (void) close(nullfd = open("/", 0)); /* partial open hack */
  772. if (setjmp(Sjbuf)) {
  773. DEBUG(4, "DN write %sn", "timeout");
  774. (void) close(dnf);
  775. (void) close(dcf);
  776. (void) close(nullfd);
  777. Uerror = SS_DIAL_FAILED;
  778. return(FAIL);
  779. }
  780. (void) signal(SIGALRM, alarmtr);
  781. timelim = 5 * strlen(phone);
  782. (void) alarm(timelim < 30 ? 30 : timelim);
  783. if ((dnf = open(dnname, O_WRONLY)) < 0 ) {
  784. DEBUG(5, "can't open %sn", dnname);
  785. Uerror = SS_CANT_ACCESS_DEVICE;
  786. return(FAIL);
  787. }
  788. DEBUG(5, "%s is openn", dnname);
  789. if ( filelock(dnf) != SUCCESS ) {
  790. (void)close(dnf);
  791. DEBUG(1, "failed to lock device %sn", dnname);
  792. Uerror = SS_LOCKED_DEVICE;
  793. }
  794. if (  (dcf = open(dcname, O_RDWR | O_NDELAY)) < 0 ) {
  795. DEBUG(5, "can't open %sn", dcname);
  796. Uerror = SS_CANT_ACCESS_DEVICE;
  797. return(FAIL);
  798. }
  799. if ( filelock(dcf) != SUCCESS ) {
  800. (void)close(dcf);
  801. DEBUG(1, "failed to lock device %sn", dcname);
  802. Uerror = SS_LOCKED_DEVICE;
  803. }
  804. DEBUG(4, "dcf is %dn", dcf);
  805. fixline(dcf, speed, D_ACU);
  806. nw = (*Write)(dnf, phone, lt = strlen(phone));
  807. if (nw != lt) {
  808. (void) alarm(0);
  809. DEBUG(4, "ACU write error %dn", errno);
  810. (void) close(dnf);
  811. (void) close(dcf);
  812. Uerror = SS_DIAL_FAILED;
  813. return(FAIL);
  814. } else 
  815. DEBUG(4, "ACU write okn", 0);
  816. (void) close(dnf);
  817. (void) close(nullfd = open("/", 0)); /* partial open hack */
  818. ret = open(dcname, 2);  /* wait for carrier  */
  819. (void) alarm(0);
  820. (void) close(ret); /* close 2nd modem open() */
  821. if (ret < 0) { /* open() interrupted by alarm */
  822. DEBUG(4, "Line open %sn", "failed");
  823. Uerror = SS_DIAL_FAILED;
  824. (void) close(nullfd); /* close partially opened modem */
  825. return(FAIL);
  826. }
  827. (void) fcntl(dcf,F_SETFL, fcntl(dcf, F_GETFL, 0) & ~O_NDELAY);
  828. return(dcf);
  829. }
  830. #endif /* ATTSV */
  831. #endif /* DIAL801 */
  832. #ifdef V8
  833. Dialout(flds)
  834. char *flds[];
  835. {
  836.     int fd;
  837.     char phone[MAXPH+2];
  838.     exphone(flds[F_PHONE], phone);
  839.     DEBUG(4, "call dialout(%s", phone);
  840.     DEBUG(4, ", %s)n", dev[D_CLASS]);
  841.     fd = dialout(phone, dev[D_CLASS]);
  842.     if (fd == -1)
  843. Uerror = SS_NO_DEVICE;
  844.     if (fd == -3)
  845. Uerror = SS_DIAL_FAILED;
  846.     if (fd == -9)
  847. Uerror = SS_DEVICE_FAILED;
  848.     (void) strcpy(Dc, "Dialout");
  849.     return(fd);
  850. }
  851. #endif /* V8 */
  852. #ifdef TLI
  853. /*
  854.  *
  855.  * AT&T Transport Layer Interface
  856.  *
  857.  * expected in Devices
  858.  * TLI line1 - - TLI 
  859.  * or
  860.  * TLIS line1 - - TLIS
  861.  *
  862.  */
  863. #include <sys/tiuser.h>
  864. #define CONNECT_ATTEMPTS 3
  865. #define TFREE(p) if ( (p) ) t_free( (p) )
  866. /*
  867.  * returns fd to remote uucp daemon
  868.  */
  869. int
  870. tlicall(flds, dev)
  871. char *flds[];
  872. char *dev[];
  873. {
  874. char addrbuf[ BUFSIZ ];
  875. char devname[MAXNAMESIZE];
  876. int fd, service;
  877. register int i, j;
  878. struct t_bind *bind_ret = 0;
  879. struct t_info tinfo;
  880. struct t_call *sndcall = 0, *rcvcall = 0;
  881. extern int errno, t_errno;
  882. extern char *sys_errlist[], *t_errlist[];
  883. extern struct netbuf *stoa();
  884. if ( dev[D_LINE][0] != '/' ) {
  885. /* dev holds device name relative to /dev */
  886. sprintf(devname, "/dev/%s", dev[D_LINE]);
  887. } else {
  888. /* dev holds full path name of device */
  889. strcpy(devname, dev[D_LINE]);
  890. }
  891. /* gimme local transport endpoint */
  892. errno = t_errno = 0;
  893. if (setjmp(Sjbuf)) {
  894. DEBUG(1, "t_open timeoutn", 0);
  895. logent("t_open", "TIMEOUT");
  896. Uerror = SS_NO_DEVICE;
  897. return(FAIL);
  898. }
  899. (void) signal(SIGALRM, alarmtr);
  900. (void) alarm(5);
  901. fd = t_open(devname, O_RDWR, &tinfo);
  902. (void) alarm(0);
  903. if (fd < 0) {
  904. tfaillog(fd, "t_open" );
  905. Uerror = SS_NO_DEVICE;
  906. return(FAIL);
  907. }
  908. if ( filelock(fd) != SUCCESS ) {
  909. (void)t_close(fd);
  910. DEBUG(1, "tlicall: failed to lock device %sn", devname);
  911. Uerror = SS_LOCKED_DEVICE;
  912. return(FAIL);
  913. }
  914. /* allocate tli structures */
  915. errno = t_errno = 0;
  916. if ( (bind_ret = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL)) == 
  917.     (struct t_bind *)NULL
  918. || (sndcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL)) == 
  919.     (struct t_call *)NULL
  920. || (rcvcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL)) ==
  921.     (struct t_call *)NULL ) {
  922. tfaillog(fd, "t_alloc" );
  923. TFREE(bind_ret);TFREE(sndcall);TFREE(rcvcall);
  924. Uerror = SS_NO_DEVICE;
  925. return(FAIL);
  926. }
  927. /* bind */
  928. errno = t_errno = 0;
  929. if (t_bind(fd, (struct t_bind *) 0, bind_ret ) < 0) {
  930. tfaillog(fd, "t_bind" );
  931. TFREE(bind_ret);TFREE(sndcall);TFREE(rcvcall);
  932. Uerror = SS_NO_DEVICE;
  933. (void) t_close(fd);
  934. return(FAIL);
  935. }
  936. DEBUG(5, "tlicall: bound to %sn", bind_ret->addr.buf);
  937. /*
  938.  * Prepare to connect.
  939.  *
  940.  * If address begins with "x", "X", "o", or "O",
  941.  * assume is hexadecimal or octal address and use stoa()
  942.  * to convert it.
  943.  *
  944.  * Else is usual uucico address -- only N's left to process.
  945.  * Walk thru connection address, changing N's to NULLCHARs.
  946.  * Note:  If a NULLCHAR must be part of the connection address,
  947.  * it must be overtly included in the address.  One recommended
  948.  * way is to do it in the Devices file, thusly:
  949.  * Netname /dev/netport - - TLI D00
  950.  * bsfix() turns 00 into N and then the loop below makes it a
  951.  * real, included-in-the-length null-byte.
  952.  *
  953.  * The DEBUG must print the strecpy'd address (so that
  954.  * non-printables will have been replaced with C escapes).
  955.  */
  956. DEBUG(5, "t_connect to addr "%s"n",
  957. strecpy( addrbuf, dev[D_ARG], "\" ) );
  958. if ( dev[D_ARG][0] == '\' &&
  959. ( dev[D_ARG][1] == 'x' || dev[D_ARG][1] == 'X'
  960. || dev[D_ARG][1] == 'o' || dev[D_ARG][1] == 'O' ) ) {
  961. if ( stoa(dev[D_ARG], &(sndcall->addr)) == (struct netbuf *)NULL ) {
  962. DEBUG(5, "tlicall: stoa failedn","");
  963. logent("tlicall", "string-to-address failed");
  964. Uerror = SS_NO_DEVICE;
  965. (void) t_close(fd);
  966. return(FAIL);
  967. }
  968. } else {
  969. for( i = j = 0; i < BUFSIZ && dev[D_ARG][i] != NULLCHAR;
  970. ++i, ++j ) {
  971. if( dev[D_ARG][i] == '\'  &&  dev[D_ARG][i+1] == 'N' ) {
  972. addrbuf[j] = NULLCHAR;
  973. ++i;
  974. }
  975. else {
  976. addrbuf[j] = dev[D_ARG][i];
  977. }
  978. }
  979. sndcall->addr.buf = addrbuf;
  980. sndcall->addr.len = j;
  981. }
  982. if (setjmp(Sjbuf)) {
  983. DEBUG(4, "timeout tlicalln", 0);
  984. logent("tlicall", "TIMEOUT");
  985. TFREE(bind_ret);TFREE(sndcall);TFREE(rcvcall);
  986. Uerror = SS_NO_DEVICE;
  987. (void) t_close(fd);
  988. return(FAIL);
  989. }
  990. (void) signal(SIGALRM, alarmtr);
  991. (void) alarm(30);
  992. /* connect to the service -- some listeners can't handle */
  993. /* multiple connect requests, so try it a few times */
  994. errno = t_errno = 0;
  995. for ( i = 0; i < CONNECT_ATTEMPTS; ++i ) {
  996. if (t_connect(fd, sndcall, rcvcall) == 0)
  997. break;
  998. if ( (t_errno == TLOOK) && (t_look(fd) == T_DISCONNECT)) {
  999. t_rcvdis(fd,NULL);
  1000. (void) alarm(0);
  1001. } else {
  1002. (void) alarm(0);
  1003. tfaillog(fd, "t_connect");
  1004. TFREE(bind_ret);TFREE(sndcall);TFREE(rcvcall);
  1005. Uerror = SS_DIAL_FAILED;
  1006. (void) t_close(fd);
  1007. return(FAIL);
  1008. }
  1009. }
  1010. (void) alarm(0);
  1011. TFREE(bind_ret);TFREE(sndcall);TFREE(rcvcall);
  1012. if ( i == CONNECT_ATTEMPTS ) {
  1013. tfaillog(fd, "t_connect");
  1014. Uerror = SS_DIAL_FAILED;
  1015. (void) t_close(fd);
  1016. return(FAIL);
  1017. }
  1018. errno = t_errno = 0;
  1019. return(fd);
  1020. }
  1021. #endif /* TLI */