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

Defined functions

Acuopn defined in line 472; used 8 times
busyloop defined in line 1197; used 1 times
df2cls defined in line 800; used 2 times
df2opn defined in line 677; used 2 times
dircls defined in line 203; used 3 times
diropn defined in line 155; used 4 times
dkopn defined in line 225; used 2 times
dncls defined in line 650; used 2 times
dnopn defined in line 531; used 2 times
ftimedelay defined in line 1183; used 1 times
hyscls defined in line 878; used 3 times
hysopn defined in line 825; used 2 times
hysqcls defined in line 1021; used 2 times
hysqopn defined in line 949; used 2 times
miccls defined in line 450; used 2 times
micopn defined in line 363; used 2 times
nap defined in line 1161; used 1 times
nodev defined in line 132; used 1 times
  • in line 44
nulldev defined in line 124; used 12 times
pnetopn defined in line 262; used 2 times
rvmacscls defined in line 1475; used 2 times
rvmacsopn defined in line 1369; used 2 times
slowrite defined in line 1203; used 4 times
unetcls defined in line 340; used 4 times
unetopn defined in line 307; used 2 times
vadcls defined in line 1338; used 2 times
vadopn defined in line 1238; used 2 times
ventcls defined in line 1217; used 2 times
ventopn defined in line 1064; used 2 times

Defined variables

condevs defined in line 82; used 2 times
devSel declared in line 40; defined in line 470; used 32 times
itimerval defined in line 1155; used 4 times
sccsid defined in line 2; never used

Defined macros

CPUSPEED defined in line 1195; used 1 times
DELAY defined in line 1196; used 1 times
DFLTPORT defined in line 305; used 1 times
DKTRIES defined in line 215; used 1 times
ETX defined in line 1365; used 1 times
SI defined in line 1366; used 1 times
SOH defined in line 1367; used 1 times
STX defined in line 1364; used 1 times
uucpdelay defined in line 1194; used 1 times
Last modified: 1983-07-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3224
Valid CSS Valid XHTML 1.0 Strict