1: /*
   2:  * static char sccsid[]="@(#)condevs.c	4.6  7/1/83  uucp-4.2BSD";
   3:  */
   4: /*
   5:  * Here are various dialers to establish the machine-machine connection.
   6:  * conn.c/condevs.c was glued together by Mike Mitchell.
   7:  * The dialers were supplied by many people, to whom we are grateful.
   8:  *
   9:  * ---------------------------------------------------------------------
  10:  * NOTE:
  11:  * There is a bug that occurs at least on PDP11s due to a limitation of
  12:  * setjmp/longjmp.   If the routine that does a setjmp is interrupted
  13:  * and longjmp-ed to,  it loses its register variables (on a pdp11).
  14:  * What works is if the routine that does the setjmp
  15:  * calls a routine and it is the *subroutine* that is interrupted.
  16:  *
  17:  * Anyway, in conclusion, condevs.c is plagued with register variables
  18:  * that are used inside
  19:  * 	if (setjmp(...)) {
  20:  * 		....
  21:  * 	}
  22:  *
  23:  * THE FIX: In dnopn(), for example, delete the 'register' Devices *dev.
  24:  * (That was causing a core dump; deleting register fixed it.)
  25:  * Also for dnopn delete 'register' int dnf... .
  26:  * In pkopn, delete 'register' flds... .
  27:  * There may be others, especially mcm's version of hysopen.
  28:  * You could just delete all references to register, that is safest.
  29:  * This problem might not occur on 4.1bsd, I am not sure.
  30:  * 	Tom Truscott
  31:  */
  32: #include <sys/types.h>
  33: #include <errno.h>
  34: #include <setjmp.h>
  35: #include <signal.h>
  36: #include <sgtty.h>
  37: #include "uucp.h"
  38: 
  39: extern char devSel[];   /* name to pass to delock() in close */
  40: extern int errno, next_fd;
  41: extern jmp_buf Sjbuf;
  42: extern int alarmtr();
  43: int nulldev(), nodev(), Acuopn(), diropn(), dircls();
  44: 
  45: #ifdef DATAKIT
  46: int dkopn();
  47: #endif
  48: #ifdef DN11
  49: int dnopn(), dncls();
  50: #endif
  51: #ifdef HAYES
  52: int hysopn(), hyscls();
  53: #endif
  54: #ifdef HAYESQ
  55: int hysqopn(), hysqcls();  /* a version of hayes that doesn't use ret codes */
  56: #endif
  57: #ifdef DF02
  58: int df2opn(), df2cls();
  59: #endif
  60: #ifdef PNET
  61: int pnetopn();
  62: #endif
  63: #ifdef VENTEL
  64: int ventopn(), ventcls();
  65: #endif
  66: #ifdef  UNET
  67: #include <UNET/unetio.h>
  68: #include <UNET/tcp.h>
  69: int unetopn(), unetcls();
  70: #endif UNET
  71: #ifdef VADIC
  72: int vadopn(), vadcls();
  73: #endif VADIC
  74: #ifdef  RVMACS
  75: int rvmacsopn(), rvmacscls();
  76: #endif
  77: #ifdef MICOM
  78: int micopn(), miccls();
  79: #endif MICOM
  80: 
  81: struct condev condevs[] = {
  82: { "DIR", "direct", diropn, nulldev, dircls },
  83: #ifdef DATAKIT
  84: { "DK", "datakit", dkopn, nulldev, nulldev },
  85: #endif
  86: #ifdef PNET
  87: { "PNET", "pnet", pnetopn, nulldev, nulldev },
  88: #endif
  89: #ifdef  UNET
  90: { "UNET", "UNET", unetopn, nulldev, unetcls },
  91: #endif UNET
  92: #ifdef MICOM
  93: { "MICOM", "micom", micopn, nulldev, miccls },
  94: #endif MICOM
  95: #ifdef DN11
  96: { "ACU", "dn11", Acuopn, dnopn, dncls },
  97: #endif
  98: #ifdef HAYES
  99: { "ACU", "hayes", Acuopn, hysopn, hyscls },
 100: #endif HAYES
 101: #ifdef HAYESQ   /* a version of hayes that doesn't use result codes */
 102: { "ACU", "hayesq", Acuopn, hysqopn, hysqcls },
 103: #endif HATESQ
 104: #ifdef DF02
 105: { "ACU", "DF02", Acuopn, df2opn, df2cls },
 106: #endif
 107: #ifdef VENTEL
 108: { "ACU", "ventel", Acuopn, ventopn, ventcls },
 109: #endif VENTEL
 110: #ifdef VADIC
 111: { "ACU", "vadic", Acuopn, vadopn, vadcls },
 112: #endif VADIC
 113: #ifdef RVMACS
 114: { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls },
 115: #endif RVMACS
 116: 
 117: /* Insert new entries before this line */
 118: { NULL, NULL, NULL, NULL, NULL } };
 119: 
 120: /***
 121:  *	nulldev		a null device (returns CF_DIAL)
 122:  */
 123: int nulldev()
 124: {
 125:     return(CF_DIAL);
 126: }
 127: 
 128: /***
 129:  *	nodev		a null device (returns CF_NODEV)
 130:  */
 131: int nodev()
 132: {
 133:     return(CF_NODEV);
 134: }
 135: 
 136: 
 137: /*
 138:  * The first things in this file are the generic devices.
 139:  * Generic devices look through L-devices and call the CU_open routines for
 140:  * appropriate devices.  Some things, like the Unet interface, or direct
 141:  * connect, do not use the CU_open entry.  ACUs must search to find the'
 142:  * right routine to call.
 143:  */
 144: 
 145: /***
 146:  *	diropn(flds)	connect to hardware line
 147:  *	char *flds[];
 148:  *
 149:  *	return codes:
 150:  *		>0  -  file number  -  ok
 151:  *		FAIL  -  failed
 152:  */
 153: 
 154: diropn(flds)
 155: register char *flds[];
 156: {
 157:     register int dcr, status;
 158:     struct Devices dev;
 159:     char dcname[20];
 160:     FILE *dfp;
 161:     dfp = fopen(DEVFILE, "r");
 162:     ASSERT(dfp != NULL, "CAN'T OPEN", DEVFILE, 0);
 163:     while ((status = rddev(dfp, &dev)) != FAIL) {
 164:         if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
 165:             continue;
 166:         if (strcmp(flds[F_PHONE], dev.D_line) != SAME)
 167:             continue;
 168:         if (mlock(dev.D_line) != FAIL)
 169:             break;
 170:     }
 171:     fclose(dfp);
 172:     if (status == FAIL) {
 173:         logent("DEVICE", "NO");
 174:         return(CF_NODEV);
 175:     }
 176: 
 177:     sprintf(dcname, "/dev/%s", dev.D_line);
 178:     if (setjmp(Sjbuf)) {
 179:         delock(dev.D_line);
 180:         return(FAIL);
 181:     }
 182:     signal(SIGALRM, alarmtr);
 183:     alarm(10);
 184:     getnextfd();
 185:     errno = 0;
 186:     dcr = open(dcname, 2); /* read/write */
 187:     next_fd = -1;
 188:     if (dcr < 0 && errno == EACCES)
 189:         logent(dcname, "CAN'T OPEN");
 190:     alarm(0);
 191:     if (dcr < 0) {
 192:         delock(dev.D_line);
 193:         return(FAIL);
 194:     }
 195:     fflush(stdout);
 196:     fixline(dcr, dev.D_speed);
 197:     strcpy(devSel, dev.D_line); /* for latter unlock */
 198:     CU_end = dircls;
 199:     return(dcr);
 200: }
 201: 
 202: dircls(fd)
 203: register int fd;
 204: {
 205:     if (fd > 0) {
 206:         close(fd);
 207:         delock(devSel);
 208:         }
 209:     }
 210: 
 211: #ifdef DATAKIT
 212: 
 213: #include <dk.h>
 214: #define DKTRIES 2
 215: 
 216: /***
 217:  *	dkopn(flds)	make datakit connection
 218:  *
 219:  *	return codes:
 220:  *		>0 - file number - ok
 221:  *		FAIL - failed
 222:  */
 223: 
 224: dkopn(flds)
 225: char *flds[];
 226: {
 227:     int dkphone;
 228:     register char *cp;
 229:     register ret, i;
 230: 
 231:     if (setjmp(Sjbuf))
 232:         return(FAIL);
 233: 
 234:     signal(SIGALRM, alarmtr);
 235:     dkphone = 0;
 236:     cp = flds[F_PHONE];
 237:     while(*cp)
 238:         dkphone = 10 * dkphone + (*cp++ - '0');
 239:     DEBUG(4, "dkphone (%d) ", dkphone);
 240:     for (i = 0; i < DKTRIES; i++) {
 241:         getnextfd();
 242:         ret = dkdial(D_SH, dkphone, 0);
 243:         next_fd = -1;
 244:         DEBUG(4, "dkdial (%d)\n", ret);
 245:         if (ret > -1)
 246:             break;
 247:     }
 248:     return(ret);
 249: }
 250: #endif
 251: 
 252: #ifdef PNET
 253: /***
 254:  *	pnetopn(flds)
 255:  *
 256:  *	call remote machine via Purdue network
 257:  *	use dial string as host name, speed as socket number
 258:  * Author: Steve Bellovin
 259:  */
 260: 
 261: pnetopn(flds)
 262: char *flds[];
 263: {
 264:     int fd;
 265:     int socket;
 266:     register char *cp;
 267: 
 268:     fd = pnetfile();
 269:     DEBUG(4, "pnet fd - %d\n", fd);
 270:     if (fd < 0) {
 271:         logent("AVAILABLE DEVICE", "NO");
 272:         return(CF_NODEV);
 273:     }
 274:     socket = 0;
 275:     for (cp = flds[F_CLASS]; *cp; cp++)
 276:         socket = 10*socket + (*cp - '0');
 277:     DEBUG(4, "socket - %d\n", socket);
 278:     if (setjmp(Sjbuf)) {
 279:         DEBUG(4, "pnet timeout  - %s\n", flds[F_PHONE]);
 280:         return(FAIL);
 281:     }
 282:     signal(SIGALRM, alarmtr);
 283:     DEBUG(4, "host - %s\n", flds[F_PHONE]);
 284:     alarm(15);
 285:     if (pnetscon(fd, flds[F_PHONE], socket) < 0) {
 286:         DEBUG(4, "pnet connect failed - %s\n", flds[F_PHONE]);
 287:         return(FAIL);
 288:     }
 289:     alarm(0);
 290:     return(fd);
 291: }
 292: #endif	PNET
 293: 
 294: #ifdef UNET
 295: /***
 296:  *	unetopn -- make UNET (tcp-ip) connection
 297:  *
 298:  *	return codes:
 299:  *		>0 - file number - ok
 300:  *		FAIL - failed
 301:  */
 302: 
 303: /* Default port of uucico server */
 304: #define DFLTPORT    33
 305: 
 306: unetopn(flds)
 307: register char *flds[];
 308: {
 309:     register int ret, port;
 310:     int unetcls();
 311: 
 312:     port = atoi(flds[F_PHONE]);
 313:     if (port <= 0 || port > 255)
 314:         port = DFLTPORT;
 315:     DEBUG(4, "unetopn host %s, ", flds[F_NAME]);
 316:     DEBUG(4, "port %d\n", port);
 317:     if (setjmp(Sjbuf)) {
 318:         logent("tcpopen", "TIMEOUT");
 319:         endhnent(); /* see below */
 320:         return(CF_DIAL);
 321:     }
 322:     signal(SIGALRM, alarmtr);
 323:     alarm(30);
 324:     ret = tcpopen(flds[F_NAME], port, 0, TO_ACTIVE, "rw");
 325:     alarm(0);
 326:     endhnent(); /* wave magic wand at 3com and incant "eat it, bruce" */
 327:     if (ret < 0) {
 328:         DEBUG(5, "tcpopen failed: errno %d\n", errno);
 329:         logent("tcpopen", "FAILED");
 330:         return(CF_DIAL);
 331:     }
 332:     CU_end = unetcls;
 333:     return(ret);
 334: }
 335: 
 336: /*
 337:  * unetcls -- close UNET connection.
 338:  */
 339: unetcls(fd)
 340: register int fd;
 341: {
 342:     DEBUG(4, "UNET CLOSE called\n", 0);
 343:     if (fd > 0) {
 344:         /* disable this until a timeout is put in
 345: 		if (ioctl(fd, UIOCCLOSE, STBNULL))
 346: 			logent("UNET CLOSE", "FAILED");
 347: 		 */
 348:         close(fd);
 349:         DEBUG(4, "closed fd %d\n", fd);
 350:     }
 351: }
 352: #endif UNET
 353: 
 354: #ifdef MICOM
 355: 
 356: /*
 357:  *	micopn: establish connection through a micom.
 358:  *	Returns descriptor open to tty for reading and writing.
 359:  *	Negative values (-1...-7) denote errors in connmsg.
 360:  *	Be sure to disconnect tty when done, via HUPCL or stty 0.
 361:  */
 362: micopn(flds)
 363: register char *flds[];
 364: {
 365:     extern errno;
 366:     char *rindex(), *fdig(), dcname[20];
 367:     int dh, ok = 0, speed;
 368:     register struct condev *cd;
 369:     register FILE *dfp;
 370:     struct Devices dev;
 371: 
 372:     dfp = fopen(DEVFILE, "r");
 373:     ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
 374: 
 375:     signal(SIGALRM, alarmtr);
 376:     dh = -1;
 377:     for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) {
 378:         if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
 379:             fseek(dfp, (off_t)0, 0);
 380:             while(rddev(dfp, &dev) != FAIL) {
 381:                 if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
 382:                     continue;
 383:                 if (snccmp(flds[F_LINE], dev.D_type) != SAME)
 384:                     continue;
 385:                 if (mlock(dev.D_line) == FAIL)
 386:                     continue;
 387: 
 388:                 sprintf(dcname, "/dev/%s", dev.D_line);
 389:                 getnextfd();
 390:                 alarm(10);
 391:                 if (setjmp(Sjbuf)) {
 392:                     delock(dev.D_line);
 393:                     logent(dev.D_line,"micom open TIMEOUT");
 394:                     dh = -1;
 395:                     break;
 396:                     }
 397:                 dh = open(dcname, 2);
 398:                 alarm(0);
 399:                 next_fd = -1;
 400:                 if (dh > 0) {
 401:                     break;
 402:                     }
 403:                 devSel[0] = '\0';
 404:                 delock(dev.D_line);
 405:                 }
 406:             }
 407:         }
 408:     fclose(dfp);
 409:     if (dh < 0)
 410:         return(CF_NODEV);
 411: 
 412:     speed = atoi(fdig(flds[F_CLASS]));
 413:     fixline(dh, speed);
 414:     sleep(1);
 415: 
 416:     /* negotiate with micom */
 417:     if (speed != 4800)  /* damn their eyes! */
 418:         write(dh, "\r", 1);
 419:     else
 420:         write(dh, " ", 1);
 421: 
 422:     DEBUG(4, "wanted %s ", "NAME");
 423:     ok = expect("NAME", dh);
 424:     DEBUG(4, "got %s\n", ok ? "?" : "that");
 425:     if (ok == 0) {
 426:         write(dh, flds[F_PHONE], strlen(flds[F_PHONE]));
 427:         sleep(1);
 428:         write(dh, "\r", 1);
 429:         DEBUG(4, "wanted %s ", "GO");
 430:         ok = expect("GO", dh);
 431:         DEBUG(4, "got %s\n", ok ? "?" : "that");
 432:     }
 433: 
 434:     if (ok != 0) {
 435:         if (dh > 2)
 436:             close(dh);
 437:         DEBUG(4, "micom failed\n", "");
 438:         delock(dev.D_line);
 439:         return(CF_DIAL);
 440:     } else
 441:         DEBUG(4, "micom ok\n", "");
 442: 
 443:     CU_end = cd->CU_clos;
 444:     strcat(devSel, dev.D_line); /* for later unlock */
 445:     return(dh);
 446: 
 447: }
 448: 
 449: miccls(fd)
 450: register int fd;
 451: {
 452: 
 453:     if (fd > 0) {
 454:         close(fd);
 455:         delock(devSel);
 456:         }
 457:     }
 458: #endif MICOM
 459: 
 460: /***
 461:  *	Acuopn - open an ACU and dial the number.  The condevs table
 462:  *		will be searched until a dialing unit is found that is
 463:  *		free.
 464:  *
 465:  *	return codes:	>0 - file number - o.k.
 466:  *			FAIL - failed
 467:  */
 468: 
 469: char devSel[20];    /* used for later unlock() */
 470: 
 471: Acuopn(flds)
 472: register char *flds[];
 473: {
 474:     char phone[MAXPH+1];
 475:     register struct condev *cd;
 476:     register int fd;
 477:     register FILE *dfp;
 478:     struct Devices dev;
 479: 
 480:     exphone(flds[F_PHONE], phone);
 481:     devSel[0] = '\0';
 482:     DEBUG(4, "Dialing %s\n", phone);
 483:     dfp = fopen(DEVFILE, "r");
 484:     ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
 485: 
 486:     for(cd = condevs; cd->CU_meth != NULL; cd++) {
 487:     if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
 488:         fseek(dfp, (off_t)0, 0);
 489:         while(rddev(dfp, &dev) != FAIL) {
 490:         if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
 491:             continue;
 492:         if (snccmp(flds[F_LINE], dev.D_type) != SAME)
 493:             continue;
 494:         if (dev.D_brand[0] == '\0')
 495:             logent("Acuopn","No 'brand' name on ACU");
 496:         else if (snccmp(dev.D_brand, cd->CU_brand) != SAME)
 497:             continue;
 498:         if (mlock(dev.D_line) == FAIL)
 499:             continue;
 500: 
 501:         DEBUG(4, "Using %s\n", cd->CU_brand);
 502:         fd = (*(cd->CU_open))(phone, flds, &dev);
 503:         if (fd > 0) {
 504:             CU_end = cd->CU_clos;   /* point CU_end at close func */
 505:             fclose(dfp);
 506:             strcpy(devSel, dev.D_line);   /* save for later unlock() */
 507:             return(fd);
 508:             }
 509:         delock(dev.D_line);
 510:         }
 511:         }
 512:     }
 513:     fclose(dfp);
 514:     return(FAIL);
 515:     }
 516: 
 517: #ifdef DN11
 518: 
 519: /***
 520:  *	dnopn(ph, flds, dev)	dial remote machine
 521:  *	char *ph;
 522:  *	char *flds[];
 523:  *	struct Devices *dev;
 524:  *
 525:  *	return codes:
 526:  *		file descriptor  -  succeeded
 527:  *		FAIL  -  failed
 528:  */
 529: 
 530: dnopn(ph, flds, dev)
 531: char *ph;
 532: char *flds[];
 533: struct Devices *dev;
 534: {
 535:     char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
 536: #ifdef  SYSIII
 537:     struct termio ttbuf;
 538: #endif
 539:     int dnf, dcf;
 540:     int nw, lt, pid, status;
 541:     unsigned timelim;
 542: 
 543:     sprintf(dnname, "/dev/%s", dev->D_calldev);
 544:     errno = 0;
 545: 
 546:     if (setjmp(Sjbuf)) {
 547:         logent(dnname, "CAN'T OPEN");
 548:         DEBUG(4, "%s Open timed out\n", dnname);
 549:         return(CF_NODEV);
 550:     }
 551:     signal(SIGALRM, alarmtr);
 552:     getnextfd();
 553:     alarm(10);
 554:     dnf = open(dnname, 1);
 555:     alarm(0);
 556:     next_fd = -1;
 557:     if (dnf < 0 && errno == EACCES) {
 558:         logent(dnname, "CAN'T OPEN");
 559:         logent("DEVICE", "NO");
 560:         return(CF_NODEV);
 561:         }
 562:     /* rti!trt: avoid passing acu file descriptor to children */
 563:     fioclex(dnf);
 564: 
 565:     sprintf(dcname, "/dev/%s", dev->D_line);
 566:     sprintf(phone, "%s%s", ph, ACULAST);
 567:     DEBUG(4, "dc - %s, ", dcname);
 568:     DEBUG(4, "acu - %s\n", dnname);
 569:     pid = 0;
 570:     if (setjmp(Sjbuf)) {
 571:         logent("DIALUP DN write", "TIMEOUT");
 572:         if (pid)
 573:             kill(pid, 9);
 574:         delock(dev->D_line);
 575:         if (dnf)
 576:             close(dnf);
 577:         return(FAIL);
 578:     }
 579:     signal(SIGALRM, alarmtr);
 580:     timelim = 5 * strlen(phone);
 581:     alarm(timelim < 30 ? 30 : timelim);
 582:     if ((pid = fork()) == 0) {
 583:         sleep(2);
 584:         fclose(stdin);
 585:         fclose(stdout);
 586: #ifdef  TIOCFLUSH
 587:         ioctl(dnf, TIOCFLUSH, STBNULL);
 588: #endif
 589:         nw = write(dnf, phone, lt = strlen(phone));
 590:         if (nw != lt) {
 591:             logent("DIALUP ACU write", "FAILED");
 592:             exit(1);
 593:         }
 594:         DEBUG(4, "ACU write ok%s\n", "");
 595:         exit(0);
 596:     }
 597:     /*  open line - will return on carrier */
 598:     /* RT needs a sleep here because it returns immediately from open */
 599: 
 600: #if RT
 601:     sleep(15);
 602: #endif
 603: 
 604:     getnextfd();
 605:     errno = 0;
 606:     dcf = open(dcname, 2);
 607:     next_fd = -1;
 608:     if (dcf < 0 && errno == EACCES)
 609:         logent(dcname, "CAN'T OPEN");
 610:     DEBUG(4, "dcf is %d\n", dcf);
 611:     if (dcf < 0) {
 612:         logent("DIALUP LINE open", "FAILED");
 613:         alarm(0);
 614:         kill(pid, 9);
 615:         close(dnf);
 616:         delock(dev->D_line);
 617:         return(FAIL);
 618:     }
 619:     /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
 620: /*	ioctl(dcf, TIOCHPCL, STBNULL);*/
 621:     while ((nw = wait(&lt)) != pid && nw != -1)
 622:         ;
 623: #ifdef  SYSIII
 624:     ioctl(dcf, TCGETA, &ttbuf);
 625:     if(!(ttbuf.c_cflag & HUPCL)) {
 626:         ttbuf.c_cflag |= HUPCL;
 627:         ioctl(dcf, TCSETA, &ttbuf);
 628:     }
 629: #endif
 630:     alarm(0);
 631:     fflush(stdout);
 632:     fixline(dcf, dev->D_speed);
 633:     DEBUG(4, "Fork Stat %o\n", lt);
 634:     if (lt != 0) {
 635:         close(dcf);
 636:         if (dnf)
 637:             close(dnf);
 638:         delock(dev->D_line);
 639:         return(FAIL);
 640:     }
 641:     return(dcf);
 642: }
 643: 
 644: /***
 645:  *	dncls()		close dn type call unit
 646:  *
 647:  *	return codes:	None
 648:  */
 649: dncls(fd)
 650: register int fd;
 651: {
 652:     if (fd > 0) {
 653:         close(fd);
 654:         sleep(5);
 655:         delock(devSel);
 656:         }
 657: }
 658: #endif DN11
 659: 
 660: #ifdef DF02
 661: /***
 662:  *	df2opn(ph, flds, dev)	dial remote machine
 663:  *	char *ph;
 664:  *	char *flds[];
 665:  *	struct Devices *dev;
 666:  *
 667:  *	return codes:
 668:  *		file descriptor  -  succeeded
 669:  *		FAIL  -  failed
 670:  *
 671:  *	Modified 9/28/81 by Bill Shannon (DEC)
 672:  *	Changed to use DEC DF02 or DF03 ACU
 673:  */
 674: 
 675: 
 676: df2opn(ph, flds, dev)
 677: char *ph;
 678: char *flds[];
 679: struct Devices *dev;
 680: {
 681:     char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
 682: #ifdef  SYSIII
 683:     struct termio ttbuf;
 684: #endif
 685:     int dcf, dnf;
 686:     int nw, lt, pid, st, status;
 687:     unsigned timelim;
 688: 
 689:     sprintf(dnname, "/dev/%s", dev->D_calldev);
 690:     if (setjmp(Sjbuf)) {
 691:         logent(dnname, "CAN'T OPEN");
 692:         DEBUG(4, "%s Open timed out\n", dnname);
 693:         return(CF_NODEV);
 694:     }
 695:     signal(SIGALRM, alarmtr);
 696:     getnextfd();
 697:     errno = 0;
 698:     alarm(10);
 699:     dnf = open(dnname, 2 );
 700:     alarm(0);
 701:     next_fd = -1;
 702:     if (dnf < 0 && errno == EACCES) {
 703:         logent(dnname, "CAN'T OPEN");
 704:         delock(dev->D_line);
 705:         logent("DEVICE", "NO");
 706:         return(CF_NODEV);
 707:         }
 708:     /* rti!trt: avoid passing acu file descriptor to children */
 709:     fioclex(dnf);
 710: 
 711:     sprintf(dcname, "/dev/%s", dev->D_line);
 712:     fixline(dnf, dev->D_speed);
 713:     sprintf(phone, "\02%s", ph);
 714:     DEBUG(4, "dc - %s, ", dcname);
 715:     DEBUG(4, "acu - %s\n", dnname);
 716:     pid = 0;
 717:     if (setjmp(Sjbuf)) {
 718:         logent("DIALUP DN write", "TIMEOUT");
 719:         if (pid)
 720:             kill(pid, 9);
 721:         delock(dev->D_line);
 722:         if (dnf)
 723:             close(dnf);
 724:         return(FAIL);
 725:     }
 726:     signal(SIGALRM, alarmtr);
 727:     timelim = 5 * strlen(phone);
 728:     alarm(timelim < 30 ? 30 : timelim);
 729:     if ((pid = fork()) == 0) {
 730:         sleep(2);
 731:         fclose(stdin);
 732:         fclose(stdout);
 733: #ifdef  TIOCFLUSH
 734:         ioctl(dnf, TIOCFLUSH, STBNULL);
 735: #endif
 736:         write(dnf, "\01", 1);
 737:         sleep(1);
 738:         nw = write(dnf, phone, lt = strlen(phone));
 739:         if (nw != lt) {
 740:             logent("DIALUP ACU write", "FAILED");
 741:             exit(1);
 742:         }
 743:         DEBUG(4, "ACU write ok%s\n", "");
 744:         exit(0);
 745:     }
 746:     /*  open line - will return on carrier */
 747:     /* RT needs a sleep here because it returns immediately from open */
 748: 
 749: #if RT
 750:     sleep(15);
 751: #endif
 752: 
 753:     if (read(dnf, &c, 1) != 1 || c != 'A')
 754:         dcf = -1;
 755:     else
 756:         dcf = 0;
 757:     DEBUG(4, "dcf is %d\n", dcf);
 758:     if (dcf < 0) {
 759:         logent("DIALUP LINE open", "FAILED");
 760:         alarm(0);
 761:         kill(pid, 9);
 762:         close(dnf);
 763:         delock(dev->D_line);
 764:         return(FAIL);
 765:     }
 766:     dcf = dnf;
 767:     dnf = 0;
 768:     /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
 769: /*	ioctl(dcf, TIOCHPCL, STBNULL);*/
 770:     while ((nw = wait(&lt)) != pid && nw != -1)
 771:         ;
 772: #ifdef  SYSIII
 773:     ioctl(dcf, TCGETA, &ttbuf);
 774:     if(!(ttbuf.c_cflag & HUPCL)) {
 775:         ttbuf.c_cflag |= HUPCL;
 776:         ioctl(dcf, TCSETA, &ttbuf);
 777:     }
 778: #endif
 779:     alarm(0);
 780:     fflush(stdout);
 781:     fixline(dcf, dev->D_speed);
 782:     DEBUG(4, "Fork Stat %o\n", lt);
 783:     if (lt != 0) {
 784:         close(dcf);
 785:         if (dnf)
 786:             close(dnf);
 787:         delock(dev->D_line);
 788:         return(FAIL);
 789:     }
 790:     return(dcf);
 791: }
 792: 
 793: /*
 794:  * df2cls()	close the DF02/DF03 call unit
 795:  *
 796:  *	return codes: none
 797:  */
 798: 
 799: df2cls(fd)
 800: register int fd;
 801: {
 802:     if (fd > 0) {
 803:         close(fd);
 804:         sleep(5);
 805:         delock(devSel);
 806:         }
 807: }
 808: #endif DF02
 809: 
 810: #ifdef HAYES
 811: /***
 812:  *	hysopn(telno, flds, dev) connect to hayes smartmodem
 813:  *	char *flds[], *dev[];
 814:  *
 815:  *	return codes:
 816:  *		>0  -  file number  -  ok
 817:  *		CF_DIAL,CF_DEVICE  -  failed
 818:  */
 819: /*
 820:  * Define HAYSTONE if you have touch tone dialing.
 821:  */
 822: /*#define HAYSTONE	*/
 823: 
 824: hysopn(telno, flds, dev)
 825: char *telno;
 826: char *flds[];
 827: struct Devices *dev;
 828: {
 829:     int dh = -1;
 830:     extern errno;
 831:     char dcname[20];
 832: 
 833:     sprintf(dcname, "/dev/%s", dev->D_line);
 834:     DEBUG(4, "dc - %s\n", dcname);
 835:     if (setjmp(Sjbuf)) {
 836:         DEBUG(1, "timeout hayes open %s\n", dcname);
 837:         logent("hayes open", "TIMEOUT");
 838:         if (dh >= 0)
 839:             close(dh);
 840:         delock(dev->D_line);
 841:         return(CF_DIAL);
 842:     }
 843:     signal(SIGALRM, alarmtr);
 844:     getnextfd();
 845:     alarm(10);
 846:     dh = open(dcname, 2); /* read/write */
 847:     alarm(0);
 848: 
 849:     /* modem is open */
 850:     next_fd = -1;
 851:     if (dh >= 0) {
 852:         fixline(dh, dev->D_speed);
 853: #ifdef HAYSTONE
 854:         write(dh, "\rATDT", 5);
 855: #else
 856:         write(dh, "\rATDP", 5);
 857: #endif
 858:         write(dh, telno, strlen(telno));
 859:         write(dh, "\r", 1);
 860: 
 861:         if (expect("CONNECT", dh) != 0) {
 862:             logent("HSM no carrier", "FAILED");
 863:             strcpy(devSel, dev->D_line);
 864:             hyscls(dh);
 865:             return(CF_DIAL);
 866:         }
 867: 
 868:     }
 869:     if (dh < 0) {
 870:         DEBUG(4, "hayes failed\n", "");
 871:         delock(dev->D_line);
 872:     }
 873:     DEBUG(4, "hayes ok\n", "");
 874:     return(dh);
 875: }
 876: 
 877: hyscls(fd)
 878: int fd;
 879: {
 880:     char dcname[20];
 881:     struct sgttyb hup, sav;
 882: 
 883:     if (fd > 0) {
 884:         sprintf(dcname, "/dev/%s", devSel);
 885:         DEBUG(4, "Hanging up fd = %d\n", fd);
 886: /*
 887:  * code to drop DTR -- change to 0 baud then back to default.
 888:  */
 889:         gtty(fd, &hup);
 890:         gtty(fd, &sav);
 891:         hup.sg_ispeed = B0;
 892:         hup.sg_ospeed = B0;
 893:         stty(fd, &hup);
 894:         sleep(2);
 895:         stty(fd, &sav);
 896: /*
 897:  * now raise DTR -- close the device & open it again.
 898:  */
 899:         sleep(2);
 900:         close(fd);
 901:         sleep(2);
 902:         fd = open(dcname, 2);
 903: /*
 904:  * Since we have a getty sleeping on this line, when it wakes up it sends
 905:  * all kinds of garbage to the modem.  Unfortunatly, the modem likes to
 906:  * execute the previous command when it sees the garbage.  The previous
 907:  * command was to dial the phone, so let's make the last command reset
 908:  * the modem.
 909:  */
 910:         sleep(2);
 911:         write(fd, "\rATZ\r", 5);
 912:         close(fd);
 913:         delock(devSel);
 914:         }
 915:     }
 916: 
 917: #endif HAYES
 918: 
 919: #ifdef HAYESQ
 920: /*
 921:  * New dialout routine to work with Hayes' SMART MODEM
 922:  * 13-JUL-82, Mike Mitchell
 923:  * Modified 23-MAR-83 to work with Tom Truscott's (rti!trt)
 924:  * version of UUCP	(ncsu!mcm)
 925:  *
 926:  * The modem should be set to NOT send any result codes to
 927:  * the system (switch 3 up, 4 down). This end will figure out
 928:  * what is wrong.
 929:  *
 930:  * I had lots of problems with the modem sending
 931:  * result codes since I am using the same modem for both incomming and
 932:  * outgoing calls.  I'd occasionally miss the result code (getty would
 933:  * grab it), and the connect would fail.  Worse yet, the getty would
 934:  * think the result code was a user name, and send garbage to it while
 935:  * it was in the command state.  I turned off ALL result codes, and hope
 936:  * for the best.  99% of the time the modem is in the correct state.
 937:  * Occassionally it doesn't connect, or the phone was busy, etc., and
 938:  * uucico sits there trying to log in.  It eventually times out, calling
 939:  * clsacu() in the process, so it resets itself for the next attempt.
 940:  */
 941: 
 942: /*
 943:  * Define HAYSTONE if touch-tone dialing is to be used.  If it is not defined,
 944:  * Pulse dialing is assumed.
 945:  */
 946: /*#define HAYSTONE*/
 947: 
 948: hysqopn(telno, flds, dev)
 949: register char *telno, *flds[];
 950: struct Devices *dev;
 951: {
 952:     char dcname[20], phone[MAXPH+10], c = 0;
 953: #ifdef  SYSIII
 954:     struct termio ttbuf;
 955: #endif
 956:     int status, dnf;
 957:     unsigned timelim;
 958: 
 959:     signal(SIGALRM, alarmtr);
 960:     sprintf(dcname, "/dev/%s", dev->D_line);
 961: 
 962:     getnextfd();
 963:     if (setjmp(Sjbuf)) {
 964:         delock(dev->D_line);
 965:         logent("DEVICE", "NO");
 966:         DEBUG(4, "Open timed out %s", dcname);
 967:         return(CF_NODEV);
 968:         }
 969:     alarm(10);
 970: 
 971:     if ((dnf = open(dcname, 2)) <= 0) {
 972:         delock(dev->D_line);
 973:         logent("DEVICE", "NO");
 974:         DEBUG(4, "Can't open %s", dcname);
 975:         return(CF_NODEV);
 976:         }
 977: 
 978:     alarm(0);
 979:     next_fd = -1;
 980:     fixline(dnf, dev->D_speed);
 981:     DEBUG(4, "Hayes port - %s, ", dcname);
 982: 
 983: #ifdef HAYSTONE
 984:     sprintf(phone, "\rATDT%s\r", telno);
 985: #else
 986:     sprintf(phone, "\rATDP%s\r", telno);
 987: #endif
 988: 
 989:     write(dnf, phone, strlen(phone));
 990: 
 991: /* calculate delay time for the other system to answer the phone.
 992:  * Default is 15 seconds, add 2 seconds for each comma in the phone
 993:  * number.
 994:  */
 995:     timelim = 150;
 996:     while(*telno) {
 997:         c = *telno++;
 998:         if (c == ',')
 999:             timelim += 20;
1000:         else {
1001: #ifdef HAYSTONE
1002:             timelim += 2;   /* .2 seconds per tone */
1003:             }
1004: #else
1005:             if (c == '0') timelim += 10;   /* .1 second per digit */
1006:             else if (c > '0' && c <= '9')
1007:                 timelim += (c - '0');
1008:             }
1009: #endif
1010:         }
1011:     alarm(timelim/10);
1012:     if (setjmp(Sjbuf) == 0) {
1013:         read(dnf, &c, 1);
1014:         alarm(0);
1015:         }
1016: 
1017:     return(dnf);
1018:     }
1019: 
1020: hysqcls(fd)
1021: int fd;
1022: {
1023:     char dcname[20];
1024:     struct sgttyb hup, sav;
1025: 
1026:     if (fd > 0) {
1027:         sprintf(dcname, "/dev/%s", devSel);
1028:         DEBUG(4, "Hanging up fd = %d\n", fd);
1029: /*
1030:  * code to drop DTR -- change to 0 baud then back to default.
1031:  */
1032:         gtty(fd, &hup);
1033:         gtty(fd, &sav);
1034:         hup.sg_ispeed = B0;
1035:         hup.sg_ospeed = B0;
1036:         stty(fd, &hup);
1037:         sleep(2);
1038:         stty(fd, &sav);
1039: /*
1040:  * now raise DTR -- close the device & open it again.
1041:  */
1042:         sleep(2);
1043:         close(fd);
1044:         sleep(2);
1045:         fd = open(dcname, 2);
1046: /*
1047:  * Since we have a getty sleeping on this line, when it wakes up it sends
1048:  * all kinds of garbage to the modem.  Unfortunatly, the modem likes to
1049:  * execute the previous command when it sees the garbage.  The previous
1050:  * command was to dial the phone, so let's make the last command reset
1051:  * the modem.
1052:  */
1053:         sleep(2);
1054:         write(fd, "\rATZ\r", 5);
1055:         close(fd);
1056:         delock(devSel);
1057:         }
1058:     }
1059: 
1060: #endif HAYESQ
1061: 
1062: #ifdef  VENTEL
1063: ventopn(telno, flds, dev)
1064: char *flds[], *telno;
1065: struct Devices *dev;
1066: {
1067:     int dh;
1068:     int i, ok = -1;
1069:     char dcname[20];
1070: 
1071:     sprintf(dcname, "/dev/%s", dev->D_line);
1072:     if (setjmp(Sjbuf)) {
1073:         DEBUG(1, "timeout ventel open\n", "");
1074:         logent("ventel open", "TIMEOUT");
1075:         if (dh >= 0)
1076:             close(dh);
1077:         delock(dev->D_line);
1078:         return(CF_NODEV);
1079:     }
1080:     signal(SIGALRM, alarmtr);
1081:     getnextfd();
1082:     alarm(10);
1083:     dh = open(dcname, 2);
1084:     next_fd = -1;
1085:     if (dh < 0) {
1086:         DEBUG(4,"%s\n", errno == 4 ? "no carrier" : "can't open modem");
1087:         delock(dev->D_line);
1088:         return(errno == 4 ? CF_DIAL : CF_NODEV);
1089:     }
1090: 
1091:     /* modem is open */
1092:     fixline(dh, dev->D_speed);
1093: 
1094:     /* translate - to % and = to & for VenTel */
1095:     DEBUG(4, "calling %s -> ", telno);
1096:     for (i = 0; i < strlen(telno); ++i) {
1097:         switch(telno[i]) {
1098:         case '-':   /* delay */
1099:             telno[i] = '%';
1100:             break;
1101:         case '=':   /* await dial tone */
1102:             telno[i] = '&';
1103:             break;
1104:         case '<':
1105:             telno[i] = '%';
1106:             break;
1107:         }
1108:     }
1109:     DEBUG(4, "%s\n", telno);
1110:     sleep(1);
1111:     for(i = 0; i < 5; ++i) {    /* make up to 5 tries */
1112:         slowrite(dh, "\r\r");/* awake, thou lowly VenTel! */
1113: 
1114:         DEBUG(4, "wanted %s ", "$");
1115:         ok = expect("$", dh);
1116:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1117:         if (ok != 0)
1118:             continue;
1119:         slowrite(dh, "K");  /* "K" (enter number) command */
1120:         DEBUG(4, "wanted %s ", "DIAL: ");
1121:         ok = expect("DIAL: ", dh);
1122:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1123:         if (ok == 0)
1124:             break;
1125:     }
1126: 
1127:     if (ok == 0) {
1128:         slowrite(dh, telno); /* send telno, send \r */
1129:         slowrite(dh, "\r");
1130:         DEBUG(4, "wanted %s ", "ONLINE");
1131:         ok = expect("ONLINE!", dh);
1132:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1133:     }
1134:     if (ok != 0) {
1135:         if (dh > 2)
1136:             close(dh);
1137:         DEBUG(4, "venDial failed\n", "");
1138:         return(CF_DIAL);
1139:     } else
1140:         DEBUG(4, "venDial ok\n", "");
1141:     return(dh);
1142: }
1143: 
1144: 
1145: /*
1146:  * uucpdelay:  delay execution for numerator/denominator seconds.
1147:  */
1148: 
1149: #ifdef INTERVALTIMER
1150: #define uucpdelay(num,denom) intervaldelay(1000000*num/denom)
1151: #include <time.h>
1152: catch alarm sig
1153: SIGALRM
1154: struct itimerval itimerval;
1155: itimerval.itimer_reload =
1156: itimerval.rtime.itimer_interval =
1157: itimerval.rtime.itimer_value =
1158: settimer(ITIMER_REAL, &itimerval);
1159: pause();
1160: alarm comes in
1161: turn off timer.
1162: #endif INTERVALTIMER
1163: 
1164: #ifdef FASTTIMER
1165: #define uucpdelay(num,denom) nap(60*num/denom)
1166: /*	Sleep in increments of 60ths of second.	*/
1167: nap (time)
1168:     register int time;
1169: {
1170:     static int fd;
1171: 
1172:     if (fd == 0)
1173:         fd = open (FASTTIMER, 0);
1174: 
1175:     read (fd, 0, time);
1176: }
1177: #endif FASTTIMER
1178: 
1179: #ifdef FTIME
1180: #define uucpdelay(num,denom) ftimedelay(1000*num/denom)
1181: #include <sys/timeb.h>
1182: ftimedelay(n)
1183: {
1184:     static struct timeb loctime;
1185:     ftime(&loctime);
1186:     {register i = loctime.millitm;
1187:        while (abs((int)(loctime.millitm - i))<n) ftime(&loctime);
1188:     }
1189: }
1190: #endif FTIME
1191: 
1192: #ifdef BUSYLOOP
1193: #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom)
1194: #define CPUSPEED 1000000    /* VAX 780 is 1MIPS */
1195: #define DELAY(n)    { register long N = (n); while (--N > 0); }
1196: busyloop(n)
1197:     {
1198:     DELAY(n);
1199:     }
1200: #endif BUSYLOOP
1201: 
1202: slowrite(fd, str)
1203: register char *str;
1204: {
1205:     DEBUG(6, "slowrite ", "");
1206:     while (*str) {
1207:         DEBUG(6, "%c", *str);
1208:         uucpdelay(1,10);    /* delay 1/10 second */
1209:         write(fd, str, 1);
1210:         str++;
1211:         }
1212:     DEBUG(6, "\n", "");
1213: }
1214: 
1215: 
1216: ventcls(fd)
1217: int fd;
1218: {
1219: 
1220:     if (fd > 0) {
1221:         close(fd);
1222:         sleep(5);
1223:         delock(devSel);
1224:         }
1225: }
1226: #endif VENTEL
1227: 
1228: #ifdef VADIC
1229: 
1230: /*
1231:  *	vadopn: establish dial-out connection through a Racal-Vadic 3450.
1232:  *	Returns descriptor open to tty for reading and writing.
1233:  *	Negative values (-1...-7) denote errors in connmsg.
1234:  *	Be sure to disconnect tty when done, via HUPCL or stty 0.
1235:  */
1236: 
1237: vadopn(telno, flds, dev)
1238: char *telno;
1239: char *flds[];
1240: struct Devices *dev;
1241: {
1242:     int dh = -1;
1243:     int i, ok, er = 0;
1244:     extern errno;
1245:     char dcname[20];
1246: 
1247:     sprintf(dcname, "/dev/%s", dev->D_line);
1248:     if (setjmp(Sjbuf)) {
1249:         DEBUG(1, "timeout vadic open\n", "");
1250:         logent("vadic open", "TIMEOUT");
1251:         if (dh >= 0)
1252:             close(dh);
1253:         delock(dev->D_line);
1254:         return(CF_NODEV);
1255:     }
1256:     signal(SIGALRM, alarmtr);
1257:     getnextfd();
1258:     alarm(10);
1259:     dh = open(dcname, 2);
1260:     alarm(0);
1261: 
1262:     /* modem is open */
1263:     next_fd = -1;
1264:     if (dh < 0) {
1265:         delock(dev->D_line);
1266:         return(CF_NODEV);
1267:         }
1268:     fixline(dh, dev->D_speed);
1269: 
1270: /* translate - to % and = to & for VenTel */
1271:     DEBUG(4, "calling %s -> ", telno);
1272:     for (i = 0; i < strlen(telno); ++i) {
1273:         switch(telno[i]) {
1274:         case '=':   /* await dial tone */
1275:         case '<':
1276:             telno[i] = 'K';
1277:             break;
1278:         }
1279:     }
1280:     DEBUG(4, "%s\n", telno);
1281:     sleep(1);
1282:     for(i = 0; i < 5; ++i) {    /* make 5 tries */
1283:         /* wake up Vadic */
1284:         write(dh, "\005\r", 2);
1285:         DEBUG(4, "wanted %s ", "*");
1286:         ok = expect("*", dh);
1287:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1288:         if (ok != 0)
1289:             continue;
1290: 
1291:         write(dh, "D\r", 2); /* "D" (enter number) command */
1292:         DEBUG(4, "wanted %s ", "NUMBER?");
1293:         ok = expect("NUMBER?", dh);
1294:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1295:         if (ok != 0)
1296:             continue;
1297: 
1298:     /* send telno, send \r */
1299:         write(dh, telno, strlen(telno));
1300:         sleep(1);
1301:         write(dh, "\r", 1);
1302:         ok = expect(telno, dh);
1303:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1304:         if (ok != 0)
1305:             continue;
1306: 
1307:         write(dh, "\r", 1); /* confirm number */
1308:         DEBUG(4, "wanted %s ", "DIALING: ");
1309:         ok = expect("DIALING: ", dh);
1310:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1311:         if (ok == 0)
1312:             break;
1313:     }
1314: 
1315:     if (ok == 0) {
1316:         /* send telno, send \r */
1317:         write(dh, telno, strlen(telno));
1318:         write(dh, "\r", 1);
1319:         DEBUG(4, "wanted %s ", "ON LINE");
1320:         ok = expect("ON LINE", dh);
1321:         DEBUG(4, "got %s\n", ok ? "?" : "that");
1322:     }
1323: 
1324:     if (ok != 0) {
1325:         if (dh > 2)
1326:             close(dh);
1327:         DEBUG(4, "vadDial failed\n", "");
1328:         delock(dev->D_line);
1329:         return(CF_DIAL);
1330:     }
1331:     DEBUG(4, "vadic ok\n", "");
1332:     return(dh);
1333: }
1334: 
1335: vadcls(fd) {
1336: 
1337:     if (fd > 0) {
1338:         close(fd);
1339:         sleep(5);
1340:         delock(devSel);
1341:         }
1342:     }
1343: 
1344: #endif VADIC
1345: 
1346: #ifdef  RVMACS
1347: /*
1348:  * Racal-Vadic 'RV820' MACS system with 831 adaptor.
1349:  * A typical 300 baud L-devices entry is
1350:  *	ACU /dev/tty10 /dev/tty11,48 300 rvmacs
1351:  * where tty10 is the communication line (D_Line),
1352:  * tty11 is the dialer line (D_calldev),
1353:  * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
1354:  * and the '8' is the communication port (they are 1-indexed).
1355:  * BUGS:
1356:  * Only tested with one dialer, one modem
1357:  * uses common speed for dialer and communication line.
1358:  * UNTESTED
1359:  */
1360: 
1361: #define STX 02  /* Access Adaptor */
1362: #define ETX 03  /* Transfer to Dialer */
1363: #define SI  017 /* Buffer Empty (end of phone number) */
1364: #define SOH 01  /* Abort */
1365: 
1366: rvmacsopn(ph, flds, dev)
1367: char *ph, *flds[];
1368: struct Devices *dev;
1369: {
1370:     register int va, i, child;
1371:     register char *p;
1372:     char c, acu[20], com[20];
1373: 
1374:     child = -1;
1375:     if ((p = index(dev->D_calldev, ',')) == NULL) {
1376:         DEBUG(2, "No dialer/modem specification\n", 0);
1377:         goto failret;
1378:     }
1379:     *p++ = '\0';
1380:     if (setjmp(Sjbuf)) {
1381:         logent("rvmacsopn", "TIMEOUT");
1382:         i = CF_DIAL;
1383:         goto ret;
1384:     }
1385:     DEBUG(4, "STARTING CALL\n", 0);
1386:     sprintf(acu, "/dev/%s", dev->D_calldev);
1387:     getnextfd();
1388:     signal(SIGALRM, alarmtr);
1389:     alarm(30);
1390:     if ((va = open(acu, 2)) < 0) {
1391:         logent(acu, "CAN'T OPEN");
1392:         i = CF_NODEV;
1393:         goto ret;
1394:     }
1395:     fixline(va, dev->D_speed);
1396: 
1397:     p_chwrite(va, STX); /* access adaptor */
1398:     i = *p++ - '0';
1399:     if (i < 0 || i > 7) {
1400:         logent(p-1, "Bad dialer address/modem type\n");
1401:         goto failret;
1402:     }
1403:     p_chwrite(va, i);       /* Send Dialer Address Digit */
1404:     i = *p - '0';
1405:     if (i <= 0 || i > 14) {
1406:         logent(p-1, "Bad modem address\n");
1407:         goto failret;
1408:     }
1409:     p_chwrite(va, i-1); /* Send Modem Address Digit */
1410:     write(va, ph, strlen(ph));  /* Send Phone Number */
1411:     p_chwrite(va, SI);  /* Send Buffer Empty */
1412:     p_chwrite(va, ETX); /* Initiate Call */
1413:     sprintf(com, "/dev/%s", dev->D_line);
1414: 
1415:     /* create child to open comm line */
1416:     if ((child = fork()) == 0) {
1417:         signal(SIGINT, SIG_DFL);
1418:         open(com, 0);
1419:         sleep(5);
1420:         exit(1);
1421:     }
1422: 
1423:     if (read(va, &c, 1) != 1) {
1424:         logent("ACU READ", "FAILED");
1425:         goto failret;
1426:     }
1427:     switch(c) {
1428:     case 'A':
1429:         /* Fine! */
1430:         break;
1431:     case 'B':
1432:         DEBUG(2, "CALL ABORTED\n", 0);
1433:         goto failret;
1434:     case 'D':
1435:         DEBUG(2, "Dialer format error\n", 0);
1436:         goto failret;
1437:     case 'E':
1438:         DEBUG(2, "Dialer parity error\n", 0);
1439:         goto failret;
1440:     case 'F':
1441:         DEBUG(2, "Phone number too long\n", 0);
1442:         goto failret;
1443:     case 'G':
1444:         DEBUG(2, "Busy signal\n", 0);
1445:         goto failret;
1446:     default:
1447:         DEBUG(2, "Unknown MACS return code '%c'\n", i);
1448:         goto failret;
1449:     }
1450:     /*
1451: 	 * open line - will return on carrier
1452: 	 */
1453:     if ((i = open(com, 2)) < 0) {
1454:         if (errno == EIO)
1455:             logent("carrier", "LOST");
1456:         else
1457:             logent("dialup open", "FAILED");
1458:         goto failret;
1459:     }
1460:     fixline(i, dev->D_speed);
1461:     goto ret;
1462: failret:
1463:     i = CF_DIAL;
1464: ret:
1465:     alarm(0);
1466:     if (child != -1)
1467:         kill(child, SIGKILL);
1468:     close(va);
1469:     return(i);
1470: }
1471: 
1472: rvmacscls(fd)
1473: register int fd;
1474: {
1475:     DEBUG(2, "MACS close %d\n", fd);
1476:     p_chwrite(fd, SOH);
1477: /*	ioctl(fd, TIOCCDTR, NULL);*/
1478:     close(fd);
1479: }
1480: #endif

Defined functions

Acuopn defined in line 471; used 8 times
busyloop defined in line 1196; used 1 times
df2cls defined in line 799; used 2 times
df2opn defined in line 676; used 2 times
dircls defined in line 202; used 3 times
diropn defined in line 154; used 4 times
dkopn defined in line 224; used 2 times
dncls defined in line 649; used 2 times
dnopn defined in line 530; used 2 times
ftimedelay defined in line 1182; used 1 times
hyscls defined in line 877; used 3 times
hysopn defined in line 824; used 2 times
hysqcls defined in line 1020; used 2 times
hysqopn defined in line 948; used 2 times
miccls defined in line 449; used 2 times
micopn defined in line 362; used 2 times
nap defined in line 1160; used 1 times
nodev defined in line 131; used 1 times
  • in line 43
nulldev defined in line 123; used 12 times
pnetopn defined in line 261; used 2 times
rvmacscls defined in line 1472; used 2 times
rvmacsopn defined in line 1366; used 2 times
slowrite defined in line 1202; used 4 times
unetcls defined in line 339; used 4 times
unetopn defined in line 306; used 2 times
vadcls defined in line 1335; used 2 times
vadopn defined in line 1237; used 2 times
ventcls defined in line 1216; used 2 times
ventopn defined in line 1063; used 2 times

Defined variables

condevs defined in line 81; used 2 times
devSel declared in line 39; defined in line 469; used 32 times
itimerval defined in line 1154; used 4 times

Defined macros

CPUSPEED defined in line 1194; used 1 times
DELAY defined in line 1195; used 1 times
DFLTPORT defined in line 304; used 1 times
DKTRIES defined in line 214; used 1 times
ETX defined in line 1362; used 1 times
SI defined in line 1363; used 1 times
SOH defined in line 1364; used 1 times
STX defined in line 1361; used 1 times
uucpdelay defined in line 1193; used 1 times
Last modified: 1983-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3167
Valid CSS Valid XHTML 1.0 Strict