113642Ssam #ifndef lint 2*25966Sbloom static char sccsid[] = "@(#)conn.c 5.10 (Berkeley) 01/24/86"; 313642Ssam #endif 413642Ssam 523596Sbloom #include <signal.h> 613642Ssam #include "uucp.h" 713642Ssam #include <setjmp.h> 813642Ssam #include <ctype.h> 913642Ssam #include <errno.h> 1017834Sralph #ifdef USG 1113642Ssam #include <termio.h> 1213642Ssam #include <fcntl.h> 1313642Ssam #endif 1417834Sralph #ifndef USG 1513642Ssam #include <sgtty.h> 1613642Ssam #endif 1717834Sralph #ifdef BSD4_2 1817834Sralph #include <sys/time.h> 1917834Sralph #else 2017834Sralph #include <time.h> 2117834Sralph #endif 2213642Ssam 2313642Ssam #define MAXC 1000 2413642Ssam 2513642Ssam extern jmp_buf Sjbuf; 2617834Sralph jmp_buf Cjbuf; 2718619Sralph extern int errno, onesys; 2817834Sralph extern char *sys_errlist[]; 2918619Sralph extern char MaxGrade, DefMaxGrade; 3013642Ssam 3113642Ssam /* Parity control during login procedure */ 3213642Ssam #define P_ZERO 0 3313642Ssam #define P_ONE 1 3413642Ssam #define P_EVEN 2 3513642Ssam #define P_ODD 3 3617834Sralph 3717834Sralph #define ABORT -2 3817834Sralph 3917834Sralph char *AbortOn = NULL; 4013642Ssam char par_tab[128]; /* must be power of two */ 4117834Sralph int linebaudrate; /* used for the sleep test in pk1.c */ 4213642Ssam int next_fd = -1; /* predicted fd to close interrupted opens */ 4325705Sbloom 4425705Sbloom char *PCP = "PCP"; /* PC Pursuit device type */ 4525127Sbloom /* 4625127Sbloom * catch alarm routine for "expect". 4713642Ssam */ 4813642Ssam alarmtr() 4913642Ssam { 5013642Ssam signal(SIGALRM, alarmtr); 5113642Ssam if (next_fd >= 0) { 5213642Ssam if (close(next_fd)) 5313642Ssam logent("FAIL", "ACU LINE CLOSE"); 5413642Ssam next_fd = -1; 5513642Ssam } 5613642Ssam longjmp(Sjbuf, 1); 5713642Ssam } 5813642Ssam 5925705Sbloom /* This template is for seismo to call ihnp4 6025705Sbloom * the 3 lines marked ---> will be overwritten for the appropriate city 6125705Sbloom */ 6225705Sbloom #define PCP_BAUD 3 6325705Sbloom #define PCP_PHONE 4 6425705Sbloom #define PCP_CALLBACK 8 6525705Sbloom #define PCP_CITY 10 6625705Sbloom #define PCP_RPHONE 12 6725705Sbloom #define NPCFIELDS 15 6825705Sbloom 6925705Sbloom static char *PCFlds[] = { 7025705Sbloom "PC-PURSUIT", 7125705Sbloom "Any", 7225705Sbloom "ACU", 7325705Sbloom "1200", 7425705Sbloom CNULL, /* <--- **** Welcome to Telenet PC Pursuit ***** */ 7525705Sbloom "ABORT", 7625705Sbloom "Good", /* Abort of Good bye! */ 7725705Sbloom ")", /* <--- Enter your 7-digit phone number (xxx-xxxx) */ 7825705Sbloom CNULL, /* ---> 528-1234 */ 7925705Sbloom "call?", /* <--- Which city do you wish to call? */ 8025705Sbloom CNULL, /* ---> CHICAGO */ 8125705Sbloom ")", /* <--- Enter the phone number you wish to call (xxx-xxxx) */ 8225705Sbloom CNULL, /* ---> 690-7171 */ 8325705Sbloom "R)?", /* <--- You are #1 in the queue. Do you want to wait, or Restart (Y/N/R)? */ 8425705Sbloom "Y", 8525705Sbloom CNULL /* <--- .....Good Bye! */ 8625705Sbloom }; 8725705Sbloom 8825705Sbloom static char PCP_brand[20]; 8925705Sbloom 9018619Sralph /* 9118619Sralph * place a telephone call to system and login, etc. 9213642Ssam * 9313642Ssam * return codes: 9413642Ssam * CF_SYSTEM: don't know system 9513642Ssam * CF_TIME: wrong time to call 9613642Ssam * CF_DIAL: call failed 9713642Ssam * CF_NODEV: no devices available to place call 9813642Ssam * CF_LOGIN: login/password dialog failed 9913642Ssam * 10013642Ssam * >0 - file no. - connect ok 10113642Ssam */ 10213642Ssam 10313642Ssam int Dcf = -1; 10417834Sralph char *Flds[MAXC/10]; 105*25966Sbloom char LineType[10]; 10617834Sralph extern int LocalOnly; 10713642Ssam 10813642Ssam conn(system) 10913642Ssam char *system; 11013642Ssam { 11125705Sbloom int nf; 11218619Sralph char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE]; 11313642Ssam register FILE *fsys; 11413642Ssam int fcode = 0; 11513642Ssam 11613642Ssam nf = 0; 11713642Ssam 11813642Ssam fsys = fopen(SYSFILE, "r"); 11913642Ssam ASSERT(fsys != NULL, "CAN'T OPEN", SYSFILE, 0); 12013642Ssam 12117834Sralph DEBUG(4, "finds (%s) called\n", system); 12225127Sbloom keeplooking: 12317834Sralph while((nf = finds(fsys, system, info, Flds)) > 0) { 124*25966Sbloom strncpy(LineType, Flds[F_LINE], 10); 12517834Sralph if (LocalOnly) { 126*25966Sbloom if (strcmp("TCP", LineType) 127*25966Sbloom && strcmp("DIR", LineType) 128*25966Sbloom && strcmp("LOCAL", LineType) ) { 12925705Sbloom fcode = CF_TIME; 13025705Sbloom continue; 13125705Sbloom } 13217834Sralph } 13323596Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 13418619Sralph if (!onesys && MaxGrade != DefMaxGrade && 13525705Sbloom !iswrk(file, "chk", Spool, wkpre)) { 13625705Sbloom fcode = CF_TIME; 13725705Sbloom continue; 13825705Sbloom } 13925705Sbloom /* For GTE's PC Pursuit */ 140*25966Sbloom if (snccmp(LineType, PCP) == SAME) { 14125705Sbloom FILE *dfp; 14225705Sbloom int status; 14325705Sbloom static struct Devices dev; 14425705Sbloom dfp = fopen(DEVFILE, "r"); 14525705Sbloom ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); 14625705Sbloom while ((status=rddev(dfp, &dev)) != FAIL 14725705Sbloom && strcmp(PCP, dev.D_type) != SAME) 14825705Sbloom ; 14925705Sbloom fclose(dfp); 15025705Sbloom if (status == FAIL) 15125705Sbloom continue; 15225705Sbloom if (mlock(PCP) == FAIL) { 15325705Sbloom fcode = CF_NODEV; 15425705Sbloom logent("DEVICE", "NO"); 15525705Sbloom continue; 15625705Sbloom } 15725705Sbloom PCFlds[PCP_BAUD] = dev.D_class; 15825705Sbloom PCFlds[PCP_PHONE] = dev.D_calldev; 15925705Sbloom PCFlds[PCP_CALLBACK] = dev.D_arg[D_CHAT]; 16025705Sbloom PCFlds[PCP_CITY] = Flds[F_CLASS]; 16125705Sbloom PCFlds[PCP_RPHONE] = Flds[F_PHONE]; 16225705Sbloom strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand)); 16325705Sbloom if ((fcode = getto(PCFlds)) < 0) 16425705Sbloom continue; 16525705Sbloom Dcf = fcode; 16625705Sbloom fcode = login(NPCFIELDS, PCFlds, Dcf); 16725705Sbloom clsacu(); /* Hang up, they'll call back */ 16825705Sbloom if (fcode != SUCCESS) { 16925705Sbloom fcode = CF_DIAL; 17025705Sbloom continue; 17125705Sbloom } 17225705Sbloom Flds[F_CLASS] = dev.D_class; 17325705Sbloom Flds[F_PHONE] = dev.D_line; 17425705Sbloom 17525705Sbloom } /* end PC Pursuit */ 17625705Sbloom if ((fcode = getto(Flds)) > 0) 17713642Ssam break; 17813642Ssam } 17913642Ssam 18025127Sbloom if (nf <= 0) { 18125127Sbloom fclose(fsys); 18217834Sralph return fcode ? fcode : nf; 18325127Sbloom } 18413642Ssam 18525705Sbloom Dcf = fcode; 18625705Sbloom 187*25966Sbloom if (fcode >= 0 && snccmp(LineType, PCP) == SAME) { 18825705Sbloom AbortOn = "Good"; /* .... Good Bye */ 18925705Sbloom fcode = expect("****~300", Dcf); 19025705Sbloom if (fcode != SUCCESS) { 19125705Sbloom DEBUG(4, "\nexpect timed out\n", CNULL); 19225705Sbloom fcode = CF_DIAL; 19325705Sbloom } 19425705Sbloom } 19525705Sbloom if (fcode >= 0) { 19625705Sbloom DEBUG(4, "login %s\n", "called"); 19725705Sbloom fcode = login(nf, Flds, Dcf); 19825705Sbloom } 19925705Sbloom if (fcode < 0) { 20013642Ssam clsacu(); 20125705Sbloom if (fcode == ABORT) { 20225127Sbloom fcode = CF_DIAL; 20325127Sbloom goto keeplooking; 20425127Sbloom } else { 20525127Sbloom fclose(fsys); 20623596Sbloom return CF_LOGIN; 20725127Sbloom } 20813642Ssam } 20925127Sbloom fclose(fsys); 21025705Sbloom fioclex(Dcf); 21125705Sbloom return Dcf; 21213642Ssam } 21313642Ssam 21425127Sbloom /* 21525127Sbloom * connect to remote machine 21613642Ssam * 21713642Ssam * return codes: 21813642Ssam * >0 - file number - ok 21913642Ssam * FAIL - failed 22013642Ssam */ 22113642Ssam 22213642Ssam getto(flds) 22313642Ssam register char *flds[]; 22413642Ssam { 22513642Ssam register struct condev *cd; 22613642Ssam int nulldev(), diropn(); 22725127Sbloom char *line; 22813642Ssam 22917834Sralph DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); 23013642Ssam DEBUG(4, "for sys %s\n", flds[F_NAME]); 23113642Ssam 23225127Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME) 23325127Sbloom line = "ACU"; 23425127Sbloom else 23525127Sbloom line = flds[F_LINE]; 23625127Sbloom #ifdef DIALINOUT 23725127Sbloom if (snccmp(line, "ACU") != SAME) 23825127Sbloom reenable(); 23925127Sbloom #endif DIALINOUT 24013642Ssam CU_end = nulldev; 24125705Sbloom if (snccmp(line, PCP) == SAME) { 24225705Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) { 24325705Sbloom if (snccmp(PCP_brand, cd->CU_brand) == SAME) { 24425705Sbloom CU_end = cd->CU_clos; 24525705Sbloom return diropn(flds); 24625705Sbloom } 24713642Ssam } 24825705Sbloom logent(PCP_brand, "UNSUPPORTED ACU TYPE"); 24925705Sbloom } else { 25025705Sbloom for (cd = condevs; cd->CU_meth != NULL; cd++) { 25125705Sbloom if (snccmp(cd->CU_meth, line) == SAME) { 25225705Sbloom DEBUG(4, "Using %s to call\n", cd->CU_meth); 25325705Sbloom return (*(cd->CU_gen))(flds); 25425705Sbloom } 25525705Sbloom } 25625705Sbloom DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); 25713642Ssam } 25817834Sralph return diropn(flds); /* search failed, so use direct */ 25917834Sralph } 26013642Ssam 26125127Sbloom /* 26225127Sbloom * close call unit 26313642Ssam * 26413642Ssam * return codes: none 26513642Ssam */ 26613642Ssam 26713642Ssam int (*CU_end)() = nulldev; 26813642Ssam clsacu() 26913642Ssam { 27017834Sralph /* make *sure* Dcf is no longer exclusive. 27117834Sralph * Otherwise dual call-in/call-out modems could get stuck. 27217834Sralph * Unfortunately, doing this here is not ideal, but it is the 27317834Sralph * easiest place to put the call. 27417834Sralph * Hopefully everyone honors the LCK protocol, of course 27517834Sralph */ 27625705Sbloom #ifdef TIOCNXCL 27723596Sbloom if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) 27823596Sbloom DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); 27917834Sralph #endif 28017834Sralph if (setjmp(Sjbuf)) 28117834Sralph logent(Rmtname, "CLOSE TIMEOUT"); 28217834Sralph else { 28317834Sralph signal(SIGALRM, alarmtr); 28417834Sralph alarm(20); 28517834Sralph (*(CU_end))(Dcf); 28617834Sralph alarm(0); 28717834Sralph } 28813642Ssam if (close(Dcf) == 0) { 28913642Ssam DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); 29013642Ssam logent("clsacu", "NOT CLOSED by CU_clos"); 29113642Ssam } 29213642Ssam Dcf = -1; 29313642Ssam CU_end = nulldev; 29413642Ssam } 29513642Ssam 29625127Sbloom /* 29725127Sbloom * expand phone number for given prefix and number 29813642Ssam */ 29913642Ssam 30013642Ssam exphone(in, out) 30113642Ssam register char *in, *out; 30213642Ssam { 30313642Ssam FILE *fn; 30413642Ssam char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; 30513642Ssam char buf[BUFSIZ]; 30613642Ssam register char *s1; 30713642Ssam 30817834Sralph if (!isascii(*in) || !isalpha(*in)) { 30913642Ssam strcpy(out, in); 31013642Ssam return; 31113642Ssam } 31213642Ssam 31313642Ssam s1=pre; 31417834Sralph while (isascii(*in) && isalpha(*in)) 31513642Ssam *s1++ = *in++; 31613642Ssam *s1 = '\0'; 31713642Ssam s1 = npart; 31813642Ssam while (*in != '\0') 31913642Ssam *s1++ = *in++; 32013642Ssam *s1 = '\0'; 32113642Ssam 32213642Ssam tpre[0] = '\0'; 32313642Ssam if ((fn = fopen(DIALFILE, "r")) == NULL) 32413642Ssam DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); 32513642Ssam else { 32613642Ssam while (cfgets(buf, BUFSIZ, fn)) { 32717834Sralph if (sscanf(buf, "%s%s", p, tpre) != 2) 32817834Sralph continue; 32913642Ssam if (strcmp(p, pre) == SAME) 33013642Ssam goto found; 33113642Ssam tpre[0] = '\0'; 33213642Ssam } 33313642Ssam DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); 33413642Ssam found:; 33513642Ssam fclose(fn); 33613642Ssam } 33713642Ssam 33813642Ssam strcpy(out, tpre); 33913642Ssam strcat(out, npart); 34013642Ssam } 34113642Ssam 34218619Sralph /* 34318619Sralph * read and decode a line from device file 34413642Ssam * 34513642Ssam * return code - FAIL at end-of file; 0 otherwise 34613642Ssam */ 34713642Ssam 34813642Ssam rddev(fp, dev) 34913642Ssam register struct Devices *dev; 35013642Ssam FILE *fp; 35113642Ssam { 35217834Sralph register int na; 35313642Ssam 35417834Sralph if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) 35517834Sralph return FAIL; 35617834Sralph na = getargs(dev->D_argbfr, dev->D_arg, 20); 35717834Sralph ASSERT(na >= 4, "BAD DEVICE ENTRY", dev->D_argbfr, 0); 35817834Sralph if (na == 4) { 35917834Sralph dev->D_brand = ""; 36017834Sralph na++; 36117834Sralph } 36213642Ssam dev->D_speed = atoi(fdig(dev->D_class)); 36317834Sralph dev->D_numargs = na; 36417834Sralph return 0; 36513642Ssam } 36613642Ssam 36718619Sralph /* 36818619Sralph * set system attribute vector 36913642Ssam * 37013642Ssam * return codes: 37113642Ssam * >0 - number of arguments in vector - succeeded 37213642Ssam * CF_SYSTEM - system name not found 37313642Ssam * CF_TIME - wrong time to call 37413642Ssam */ 37513642Ssam 37613642Ssam finds(fsys, sysnam, info, flds) 37713642Ssam char *sysnam, info[], *flds[]; 37813642Ssam FILE *fsys; 37913642Ssam { 38013642Ssam int na; 38113642Ssam int fcode = 0; 38213642Ssam 38313642Ssam /* format of fields 38413642Ssam * 0 name; 38513642Ssam * 1 time 38613642Ssam * 2 acu/hardwired 38713642Ssam * 3 speed 38813642Ssam * etc 38913642Ssam */ 39013642Ssam while (cfgets(info, MAXC, fsys) != NULL) { 39117834Sralph na = getargs(info, flds, MAXC/10); 39223596Sbloom if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) 39313642Ssam continue; 39418619Sralph if (ifdate(flds[F_TIME]) != FAIL) 39513642Ssam /* found a good entry */ 39617834Sralph return na; 39713642Ssam DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); 39813642Ssam fcode = CF_TIME; 39913642Ssam } 40017834Sralph return fcode ? fcode : CF_SYSTEM; 40113642Ssam } 40213642Ssam 40318619Sralph /* 40418619Sralph * do login conversation 40513642Ssam * 40623596Sbloom * return codes: SUCCESS | FAIL 40713642Ssam */ 40813642Ssam 40913642Ssam login(nf, flds, fn) 41013642Ssam register char *flds[]; 41113642Ssam int nf, fn; 41213642Ssam { 41313642Ssam register char *want, *altern; 41413642Ssam int k, ok; 41513642Ssam 41617834Sralph ASSERT(nf > 4, "TOO FEW LOG FIELDS", CNULL, nf); 41717834Sralph if (setjmp(Cjbuf)) 41817834Sralph return FAIL; 41917834Sralph AbortOn = NULL; 42013642Ssam for (k = F_LOGIN; k < nf; k += 2) { 42113642Ssam want = flds[k]; 42213642Ssam ok = FAIL; 42317834Sralph while (ok != SUCCESS) { 42413642Ssam altern = index(want, '-'); 42513642Ssam if (altern != NULL) 42613642Ssam *altern++ = '\0'; 42717834Sralph if (strcmp(want, "ABORT") == 0) { 42817834Sralph AbortOn = flds[k+1]; 42917834Sralph DEBUG(4, "ABORT ON: %s\n", AbortOn); 43017834Sralph goto nextfield; 43117834Sralph } 43225705Sbloom DEBUG(4, "wanted \"%s\"\n", want); 43313642Ssam ok = expect(want, fn); 43417834Sralph DEBUG(4, "got: %s\n", ok ? "?" : "that"); 43517834Sralph if (ok == FAIL) { 43617834Sralph if (altern == NULL) { 43717834Sralph logent("LOGIN", _FAILED); 43817834Sralph return FAIL; 43917834Sralph } 44017834Sralph want = index(altern, '-'); 44117834Sralph if (want != NULL) 44217834Sralph *want++ = '\0'; 44317834Sralph sendthem(altern, fn); 44417834Sralph } else 44517834Sralph if (ok == ABORT) { 44617834Sralph logent("LOGIN ABORTED", _FAILED); 44723596Sbloom return ABORT; 44817834Sralph } 44913642Ssam } 45017834Sralph sleep(1); 45113642Ssam if (k+1 < nf) 45213642Ssam sendthem(flds[k+1], fn); 45317834Sralph nextfield: ; 45413642Ssam } 45517834Sralph return SUCCESS; 45613642Ssam } 45713642Ssam 45813642Ssam 45917834Sralph /* conditional table generation to support odd speeds */ 46013642Ssam struct sg_spds {int sp_val, sp_name;} spds[] = { 46113642Ssam #ifdef B50 46213642Ssam { 50, B50}, 46313642Ssam #endif 46413642Ssam #ifdef B75 46513642Ssam { 75, B75}, 46613642Ssam #endif 46713642Ssam #ifdef B110 46813642Ssam { 110, B110}, 46913642Ssam #endif 47013642Ssam #ifdef B150 47113642Ssam { 150, B150}, 47213642Ssam #endif 47313642Ssam #ifdef B200 47413642Ssam { 200, B200}, 47513642Ssam #endif 47613642Ssam #ifdef B300 47713642Ssam { 300, B300}, 47813642Ssam #endif 47913642Ssam #ifdef B600 48013642Ssam {600, B600}, 48113642Ssam #endif 48213642Ssam #ifdef B1200 48313642Ssam {1200, B1200}, 48413642Ssam #endif 48513642Ssam #ifdef B1800 48613642Ssam {1800, B1800}, 48713642Ssam #endif 48813642Ssam #ifdef B2000 48913642Ssam {2000, B2000}, 49013642Ssam #endif 49113642Ssam #ifdef B2400 49213642Ssam {2400, B2400}, 49313642Ssam #endif 49413642Ssam #ifdef B3600 49513642Ssam {3600, B3600}, 49613642Ssam #endif 49713642Ssam #ifdef B4800 49813642Ssam {4800, B4800}, 49913642Ssam #endif 50013642Ssam #ifdef B7200 50113642Ssam {7200, B7200}, 50213642Ssam #endif 50313642Ssam #ifdef B9600 50413642Ssam {9600, B9600}, 50513642Ssam #endif 50613642Ssam #ifdef B19200 50717834Sralph {19200, B19200}, 50813642Ssam #endif 50917834Sralph #ifdef EXTA 51017834Sralph {19200, EXTA}, 51117834Sralph #endif 51213642Ssam {0, 0} 51313642Ssam }; 51413642Ssam 51518619Sralph /* 51618619Sralph * set speed/echo/mode... 51713642Ssam * 51813642Ssam * return codes: none 51913642Ssam */ 52013642Ssam 52113642Ssam fixline(tty, spwant) 52213642Ssam int tty, spwant; 52313642Ssam { 52417834Sralph #ifdef USG 52513642Ssam struct termio ttbuf; 52617834Sralph #else !USG 52713642Ssam struct sgttyb ttbuf; 52817834Sralph #endif !USG 52913642Ssam register struct sg_spds *ps; 53013642Ssam int speed = -1; 53113642Ssam 53213642Ssam for (ps = spds; ps->sp_val; ps++) 53313642Ssam if (ps->sp_val == spwant) 53413642Ssam speed = ps->sp_name; 53517834Sralph ASSERT(speed >= 0, "BAD SPEED", CNULL, speed); 53617834Sralph #ifdef USG 53723596Sbloom if (ioctl(tty, TCGETA, &ttbuf) < 0) 53823596Sbloom return FAIL; 53913642Ssam /* ttbuf.sg_flags = (ANYP|RAW); 54013642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ 54113642Ssam ttbuf.c_iflag = (ushort)0; 54213642Ssam ttbuf.c_oflag = (ushort)0; 54313642Ssam ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); 54413642Ssam ttbuf.c_lflag = (ushort)0; 54513642Ssam ttbuf.c_cc[VMIN] = 6; 54613642Ssam ttbuf.c_cc[VTIME] = 1; 54723596Sbloom if (ioctl(tty, TCSETA, &ttbuf) < 0) 54823596Sbloom return FAIL; 54917834Sralph #else !USG 55023596Sbloom if (ioctl(tty, TIOCGETP, &ttbuf) < 0) 55123596Sbloom return FAIL; 55213642Ssam ttbuf.sg_flags = (ANYP|RAW); 55313642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; 55423596Sbloom if (ioctl(tty, TIOCSETP, &ttbuf) < 0) 55523596Sbloom return FAIL; 55613642Ssam #endif 55717834Sralph #ifndef USG 55823596Sbloom if (ioctl(tty, TIOCHPCL, STBNULL) < 0) 55923596Sbloom return FAIL; 56023596Sbloom if (ioctl(tty, TIOCEXCL, STBNULL) < 0) 56123596Sbloom return FAIL; 56213642Ssam #endif 56317834Sralph linebaudrate = spwant; 56423596Sbloom return SUCCESS; 56513642Ssam } 56613642Ssam 56717834Sralph #define MR 100 56813642Ssam 56918619Sralph /* 57018619Sralph * look for expected string 57113642Ssam * 57213642Ssam * return codes: 57313642Ssam * 0 - found 57413642Ssam * FAIL - lost line or too many characters read 57513642Ssam * some character - timed out 57613642Ssam */ 57713642Ssam 57813642Ssam expect(str, fn) 57913642Ssam register char *str; 58013642Ssam int fn; 58113642Ssam { 58214592Skarels char rdvec[MR]; 58317834Sralph register char *rp = rdvec, *strptr; 58417834Sralph int kr, cnt_char; 58513642Ssam char nextch; 58625127Sbloom int timo = MAXMSGTIME; 58713642Ssam 58817834Sralph if (*str == '\0' || strcmp(str, "\"\"") == SAME) 58917834Sralph return SUCCESS; 59017834Sralph /* Cleanup str, convert \0xx strings to one char */ 59117834Sralph for (strptr = str; *strptr; strptr++) { 59217834Sralph if (*strptr == '\\') 59317834Sralph switch(*++strptr) { 59417834Sralph case 's': 59517834Sralph DEBUG(5, "BLANK\n", CNULL); 59617834Sralph *strptr = ' '; 59717834Sralph break; 59817834Sralph default: 59917834Sralph strptr--; /* back up to backslash */ 60017834Sralph sscanf(strptr + 1,"%o", &cnt_char); 60117834Sralph DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); 60217834Sralph *strptr = (char) (cnt_char); 60317834Sralph strcpy(&strptr[1], &strptr[4]); 60417834Sralph } 60517834Sralph } 60617834Sralph 60725127Sbloom strptr = index(str, '~'); 60825127Sbloom if (strptr != NULL) { 60925127Sbloom *strptr++ = '\0'; 61025127Sbloom timo = atoi(strptr); 61125127Sbloom if (timo <= 0) 61225127Sbloom timo = MAXMSGTIME; 61325127Sbloom } 61425127Sbloom 61517834Sralph if (setjmp(Sjbuf)) 61617834Sralph return FAIL; 61713642Ssam signal(SIGALRM, alarmtr); 61825127Sbloom alarm(timo); 61925127Sbloom *rp = 0; 62013642Ssam while (notin(str, rdvec)) { 62125705Sbloom int c; 62217834Sralph if(AbortOn != NULL && !notin(AbortOn, rdvec)) { 62317834Sralph DEBUG(1, "Call aborted on '%s'\n", AbortOn); 62417834Sralph alarm(0); 62517834Sralph return ABORT; 62617834Sralph } 62713642Ssam kr = read(fn, &nextch, 1); 62813642Ssam if (kr <= 0) { 62913642Ssam alarm(0); 63013642Ssam DEBUG(4, "lost line kr - %d\n, ", kr); 63113642Ssam logent("LOGIN", "LOST LINE"); 63217834Sralph return FAIL; 63313642Ssam } 63413642Ssam c = nextch & 0177; 63525705Sbloom if (c == '\0') 63625705Sbloom continue; 63725705Sbloom DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); 63825705Sbloom *rp++ = c; 63913642Ssam if (rp >= rdvec + MR) { 64017834Sralph register char *p; 64117834Sralph for (p = rdvec+MR/2; p < rp; p++) 64217834Sralph *(p-MR/2) = *p; 64317834Sralph rp -= MR/2; 64413642Ssam } 64513642Ssam *rp = '\0'; 64613642Ssam } 64713642Ssam alarm(0); 64817834Sralph return SUCCESS; 64913642Ssam } 65013642Ssam 65113642Ssam 65213642Ssam /* 65313642Ssam * Determine next file descriptor that would be allocated. 65413642Ssam * This permits later closing of a file whose open was interrupted. 65513642Ssam * It is a UNIX kernel problem, but it has to be handled. 65613642Ssam * unc!smb (Steve Bellovin) probably first discovered it. 65713642Ssam */ 65813642Ssam getnextfd() 65913642Ssam { 66013642Ssam close(next_fd = open("/", 0)); 66113642Ssam } 66213642Ssam 66317834Sralph /* 66417834Sralph * send line of login sequence 66513642Ssam * 66613642Ssam * return codes: none 66713642Ssam */ 66813642Ssam sendthem(str, fn) 66913642Ssam register char *str; 67013642Ssam int fn; 67113642Ssam { 67213642Ssam register char *strptr; 67313642Ssam int i, n, cr = 1; 67417834Sralph register char c; 67513642Ssam static int p_init = 0; 67613642Ssam 67725705Sbloom DEBUG(5, "send \"%s\"\n", str); 67813642Ssam 67913642Ssam if (!p_init) { 68013642Ssam p_init++; 68113642Ssam bld_partab(P_EVEN); 68213642Ssam } 68313642Ssam 68413642Ssam if (prefix("BREAK", str)) { 68513642Ssam sscanf(&str[5], "%1d", &i); 68613642Ssam if (i <= 0 || i > 10) 68713642Ssam i = 3; 68813642Ssam /* send break */ 68913642Ssam genbrk(fn, i); 69013642Ssam return; 69113642Ssam } 69213642Ssam 69313642Ssam if (prefix("PAUSE", str)) { 69413642Ssam sscanf(&str[5], "%1d", &i); 69513642Ssam if (i <= 0 || i > 10) 69613642Ssam i = 3; 69713642Ssam /* pause for a while */ 69813642Ssam sleep((unsigned)i); 69913642Ssam return; 70013642Ssam } 70113642Ssam 70213642Ssam if (strcmp(str, "EOT") == SAME) { 70313642Ssam p_chwrite(fn, '\04'); 70413642Ssam return; 70513642Ssam } 70613642Ssam 70713642Ssam /* Send a '\n' */ 70825705Sbloom if (strcmp(str, "LF") == SAME) { 70925705Sbloom p_chwrite(fn, '\n'); 71025705Sbloom return; 71125705Sbloom } 71213642Ssam 71313642Ssam /* Send a '\r' */ 71425705Sbloom if (strcmp(str, "CR") == SAME) { 71525705Sbloom p_chwrite(fn, '\r'); 71625705Sbloom return; 71725705Sbloom } 71813642Ssam 71913642Ssam /* Set parity as needed */ 72013642Ssam if (strcmp(str, "P_ZERO") == SAME) { 72113642Ssam bld_partab(P_ZERO); 72213642Ssam return; 72313642Ssam } 72413642Ssam if (strcmp(str, "P_ONE") == SAME) { 72513642Ssam bld_partab(P_ONE); 72613642Ssam return; 72713642Ssam } 72813642Ssam if (strcmp(str, "P_EVEN") == SAME) { 72913642Ssam bld_partab(P_EVEN); 73013642Ssam return; 73113642Ssam } 73213642Ssam if (strcmp(str, "P_ODD") == SAME) { 73313642Ssam bld_partab(P_ODD); 73413642Ssam return; 73513642Ssam } 73613642Ssam 73713642Ssam /* If "", just send '\r' */ 73817834Sralph if (strcmp(str, "\"\"") == SAME) { 73917834Sralph p_chwrite(fn, '\r'); 74017834Sralph return; 74117834Sralph } 74217834Sralph 74325705Sbloom strptr = str; 74425705Sbloom while ((c = *strptr++) != '\0') { 74517834Sralph if (c == '\\') { 74617834Sralph switch(*strptr++) { 74725705Sbloom case '\0': 74825705Sbloom DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); 74925705Sbloom --strptr; 75025705Sbloom continue; 75117834Sralph case 's': 75217834Sralph DEBUG(5, "BLANK\n", CNULL); 75325705Sbloom c = ' '; 75417834Sralph break; 75517834Sralph case 'd': 75617834Sralph DEBUG(5, "DELAY\n", CNULL); 75717834Sralph sleep(1); 75817834Sralph continue; 75925705Sbloom case 'n': 76025705Sbloom DEBUG(5, "NEW LINE\n", CNULL); 76125705Sbloom c = '\n'; 76225705Sbloom break; 76317834Sralph case 'r': 76417834Sralph DEBUG(5, "RETURN\n", CNULL); 76525705Sbloom c = '\r'; 76617834Sralph break; 76717834Sralph case 'b': 76817834Sralph if (isdigit(*strptr)) { 76917834Sralph i = (*strptr++ - '0'); 77017834Sralph if (i <= 0 || i > 10) 77117834Sralph i = 3; 77217834Sralph } else 77313642Ssam i = 3; 77417834Sralph /* send break */ 77517834Sralph genbrk(fn, i); 77617834Sralph if (*strptr == '\0') 77717834Sralph cr = 0; 77813642Ssam continue; 77917834Sralph case 'c': 78017834Sralph if (*strptr == '\0') { 78117834Sralph DEBUG(5, "NO CR\n", CNULL); 78217834Sralph cr = 0; 78325705Sbloom } else 78425705Sbloom DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); 78513642Ssam continue; 78625705Sbloom #define isoctal(x) ((x >= '0') && (x <= '7')) 78717834Sralph default: 78825705Sbloom if (isoctal(strptr[-1])) { 78917834Sralph i = 0; 79017834Sralph n = 0; 79125705Sbloom --strptr; 79225705Sbloom while (isoctal(*strptr) && ++n <= 3) 79325705Sbloom i = i * 8 + (*strptr++ - '0'); 79425705Sbloom DEBUG(5, "\\%o\n", i); 79517834Sralph p_chwrite(fn, (char)i); 79617834Sralph continue; 79717834Sralph } 79813642Ssam } 79925705Sbloom } 80025705Sbloom p_chwrite(fn, c); 80113642Ssam } 80213642Ssam 80313642Ssam if (cr) 80413642Ssam p_chwrite(fn, '\r'); 80513642Ssam return; 80613642Ssam } 80713642Ssam 80813642Ssam p_chwrite(fd, c) 80913642Ssam int fd; 81017834Sralph char c; 81113642Ssam { 81217834Sralph c = par_tab[c&0177]; 81317834Sralph if (write(fd, &c, 1) != 1) { 81417834Sralph logent(sys_errlist[errno], "BAD WRITE"); 81517834Sralph longjmp(Cjbuf, 2); 81617834Sralph } 81713642Ssam } 81813642Ssam 81913642Ssam /* 82013642Ssam * generate parity table for use by p_chwrite. 82113642Ssam */ 82213642Ssam bld_partab(type) 82313642Ssam int type; 82413642Ssam { 82513642Ssam register int i, j, n; 82613642Ssam 82713642Ssam for (i = 0; i < sizeof(par_tab); i++) { 82813642Ssam n = 0; 82913642Ssam for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) 83013642Ssam n++; 83113642Ssam par_tab[i] = i; 83213642Ssam if (type == P_ONE 83313642Ssam || (type == P_EVEN && (n&01) != 0) 83413642Ssam || (type == P_ODD && (n&01) == 0)) 83513642Ssam par_tab[i] |= sizeof(par_tab); 83613642Ssam } 83713642Ssam } 83813642Ssam 83918619Sralph /* 84018619Sralph * check for occurrence of substring "sh" 84113642Ssam * 84213642Ssam * return codes: 84313642Ssam * 0 - found the string 84413642Ssam * 1 - not in the string 84513642Ssam */ 84613642Ssam notin(sh, lg) 84713642Ssam register char *sh, *lg; 84813642Ssam { 84913642Ssam while (*lg != '\0') { 85013642Ssam if (wprefix(sh, lg)) 85118619Sralph return 0; 85213642Ssam else 85313642Ssam lg++; 85413642Ssam } 85518619Sralph return 1; 85613642Ssam } 85713642Ssam 85818619Sralph /* 85923596Sbloom * Allow multiple date specifications separated by ','. 86013642Ssam */ 86118619Sralph ifdate(p) 86218619Sralph register char *p; 86313642Ssam { 86425705Sbloom register char *np; 86518619Sralph register int ret, g; 86623596Sbloom int rtime, i; 86713642Ssam 86823596Sbloom /* pick up retry time for failures */ 86923596Sbloom /* global variable Retrytime is set here */ 87023596Sbloom if ((np = index(p, ';')) == NULL) { 87123596Sbloom Retrytime = RETRYTIME; 87223596Sbloom } else { 87323596Sbloom i = sscanf(np+1, "%d", &rtime); 87423596Sbloom if (i < 1 || rtime < 0) 87523596Sbloom rtime = 5; 87623596Sbloom Retrytime = rtime * 60; 87723596Sbloom } 87823596Sbloom 87918619Sralph ret = FAIL; 88018619Sralph MaxGrade = '\0'; 88118619Sralph do { 88223596Sbloom np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ 88323596Sbloom if (np) 88423596Sbloom *np = '\0'; 88518619Sralph g = ifadate(p); 88618619Sralph DEBUG(11,"ifadate returns %o\n", g); 88718619Sralph if (g != FAIL) { 88818619Sralph ret = SUCCESS; 88918619Sralph if (g > MaxGrade) 89018619Sralph MaxGrade = g; 89118619Sralph } 89223596Sbloom if (np) 89323596Sbloom *np = ','; 89423596Sbloom p = np + 1; 89523596Sbloom } while (np); 89623596Sbloom if (MaxGrade == '\0') 89723596Sbloom MaxGrade = DefMaxGrade; 89818619Sralph return ret; 89913642Ssam } 90013642Ssam 90118619Sralph /* 90218619Sralph * this routine will check a string (string) 90313642Ssam * like "MoTu0800-1730" to see if the present 90413642Ssam * time is within the given limits. 90513642Ssam * SIDE EFFECT - Retrytime is set 90613642Ssam * 90713642Ssam * return codes: 90813642Ssam * 0 - not within limits 90913642Ssam * 1 - within limits 91013642Ssam */ 91113642Ssam 91218619Sralph ifadate(string) 91318619Sralph char *string; 91413642Ssam { 91513642Ssam static char *days[]={ 91613642Ssam "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 91713642Ssam }; 91813642Ssam time_t clock; 91918619Sralph register char *s = string; 92017834Sralph int i, tl, th, tn, dayok=0; 92113642Ssam struct tm *localtime(); 92213642Ssam struct tm *tp; 92318619Sralph char *p, MGrade; 92413642Ssam 92523596Sbloom if ((p = index(s, '/')) == NULL) 92618619Sralph MGrade = DefMaxGrade; 92718619Sralph else 92818619Sralph MGrade = p[1]; 92918619Sralph 93013642Ssam time(&clock); 93113642Ssam tp = localtime(&clock); 93217834Sralph while (isascii(*s) && isalpha(*s)) { 93313642Ssam for (i = 0; days[i]; i++) { 93413642Ssam if (prefix(days[i], s)) 93513642Ssam if (tp->tm_wday == i) 93613642Ssam dayok = 1; 93713642Ssam } 93813642Ssam 93913642Ssam if (prefix("Wk", s)) 94013642Ssam if (tp->tm_wday >= 1 && tp->tm_wday <= 5) 94113642Ssam dayok = 1; 94213642Ssam if (prefix("Any", s)) 94313642Ssam dayok = 1; 94417834Sralph if (prefix("Evening", s)) { 94517834Sralph /* Sat or Sun */ 94617834Sralph if (tp->tm_wday == 6 || tp->tm_wday == 0 94717834Sralph || tp->tm_hour >= 17 || tp->tm_hour < 8) 94817834Sralph dayok = 1; 94917834Sralph } 95017834Sralph if (prefix("Night", s)) { 95117834Sralph if (tp->tm_wday == 6 /* Sat */ 95218619Sralph || tp->tm_hour >= 23 || tp->tm_hour < 8 95318619Sralph /* Sunday before 5pm */ 95418619Sralph || (tp->tm_wday == 0 && tp->tm_hour < 17)) 95517834Sralph dayok = 1; 95617834Sralph } 95725705Sbloom if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ 95825705Sbloom /* Sat or Sun */ 95925705Sbloom if (tp->tm_wday == 6 || tp->tm_wday == 0 96025705Sbloom || tp->tm_hour >= 18 || tp->tm_hour < 7) 96125705Sbloom dayok = 1; 96225705Sbloom } 96313642Ssam s++; 96413642Ssam } 96513642Ssam 96618619Sralph if (dayok == 0 && s != string) 96718619Sralph return FAIL; 96813642Ssam i = sscanf(s, "%d-%d", &tl, &th); 96918619Sralph if (i < 2) 97018619Sralph return MGrade; 97118619Sralph tn = tp->tm_hour * 100 + tp->tm_min; 97218619Sralph if (th < tl) { /* crosses midnight */ 97318619Sralph if (tl <= tn || tn < th) 97418619Sralph return MGrade; 975*25966Sbloom } else { 97617834Sralph if (tl <= tn && tn < th) 97718619Sralph return MGrade; 978*25966Sbloom } 97918619Sralph return FAIL; 98013642Ssam } 98113642Ssam 98218619Sralph /* 98318619Sralph * find first digit in string 98413642Ssam * 98513642Ssam * return - pointer to first digit in string or end of string 98613642Ssam */ 98713642Ssam char * 98813642Ssam fdig(cp) 98913642Ssam register char *cp; 99013642Ssam { 99113642Ssam register char *c; 99213642Ssam 99313642Ssam for (c = cp; *c; c++) 99413642Ssam if (*c >= '0' && *c <= '9') 99513642Ssam break; 99617834Sralph return c; 99713642Ssam } 99813642Ssam 99913642Ssam /* 100013642Ssam * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 100113642Ssam * Strings are compared as if they contain all capital letters. 100213642Ssam */ 100313642Ssam snccmp(s1, s2) 100413642Ssam register char *s1, *s2; 100513642Ssam { 100613642Ssam char c1, c2; 100713642Ssam 100825127Sbloom if (islower(*s1)) 100925127Sbloom c1 = toupper(*s1); 101025127Sbloom else 101125127Sbloom c1 = *s1; 101225127Sbloom if (islower(*s2)) 101325127Sbloom c2 = toupper(*s2); 101425127Sbloom else 101525127Sbloom c2 = *s2; 101613642Ssam 101713642Ssam while (c1 == c2) { 101825127Sbloom if (*s1++ == '\0') 101917834Sralph return 0; 102013642Ssam s2++; 102125127Sbloom if (islower(*s1)) 102225127Sbloom c1 = toupper(*s1); 102325127Sbloom else 102425127Sbloom c1 = *s1; 102525127Sbloom if (islower(*s2)) 102625127Sbloom c2 = toupper(*s2); 102725127Sbloom else 102825127Sbloom c2 = *s2; 102913642Ssam } 103017834Sralph return c1 - c2; 103113642Ssam } 103225127Sbloom 103317834Sralph /* 103425127Sbloom * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 103525127Sbloom * Strings are compared as if they contain all capital letters. 103625127Sbloom */ 103725127Sbloom sncncmp(s1, s2, n) 103825127Sbloom register char *s1, *s2; 103925127Sbloom register int n; 104025127Sbloom { 104125127Sbloom char c1, c2; 104225127Sbloom 104325127Sbloom if (islower(*s1)) 104425127Sbloom c1 = toupper(*s1); 104525127Sbloom else 104625127Sbloom c1 = *s1; 104725127Sbloom if (islower(*s2)) 104825127Sbloom c2 = toupper(*s2); 104925127Sbloom else 105025127Sbloom c2 = *s2; 105125127Sbloom 105225127Sbloom while ( --n >= 0 && c1 == c2) { 105325127Sbloom if (*s1++ == '\0') 105425127Sbloom return 0; 105525127Sbloom s2++; 105625127Sbloom if (islower(*s1)) 105725127Sbloom c1 = toupper(*s1); 105825127Sbloom else 105925127Sbloom c1 = *s1; 106025127Sbloom if (islower(*s2)) 106125127Sbloom c2 = toupper(*s2); 106225127Sbloom else 106325127Sbloom c2 = *s2; 106425127Sbloom } 106525127Sbloom return n<0 ? 0 : (c1 - c2); 106625127Sbloom } 106725127Sbloom /* 106817834Sralph * do chat script 106917834Sralph * occurs after local port is opened, 107017834Sralph * before 'dialing' the other machine. 107117834Sralph */ 107217834Sralph dochat(dev, flds, fd) 107317834Sralph register struct Devices *dev; 107417834Sralph char *flds[]; 107517834Sralph int fd; 107617834Sralph { 107717834Sralph register int i; 107817834Sralph register char *p; 107917834Sralph char bfr[sizeof(dev->D_argbfr)]; 108017834Sralph 108117834Sralph if (dev->D_numargs <= 5) 108217834Sralph return(0); 108317834Sralph DEBUG(4, "dochat called %d\n", dev->D_numargs); 108417834Sralph for (i = 0; i < dev->D_numargs-5; i++) { 108517834Sralph sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); 108617834Sralph if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { 108717834Sralph p = malloc((unsigned)strlen(bfr)+1); 108817834Sralph if (p != NULL) { 108917834Sralph strcpy(p, bfr); 109017834Sralph dev->D_arg[D_CHAT+i] = p; 109117834Sralph } 109217834Sralph } 109317834Sralph } 109417834Sralph /* following is a kludge because login() arglist is a kludge */ 109517834Sralph i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); 109617834Sralph /* 109717834Sralph * If login() last did a sendthem(), must pause so things can settle. 109817834Sralph * But don't bother if chat failed. 109917834Sralph */ 110017834Sralph if (i == 0 && (dev->D_numargs&01)) 110117834Sralph sleep(2); 110217834Sralph return(i); 110317834Sralph } 110425705Sbloom 110525705Sbloom /* 110625705Sbloom * fix kill/echo/raw on line 110725705Sbloom * 110825705Sbloom * return codes: none 110925705Sbloom */ 111025705Sbloom fixmode(tty) 111125705Sbloom register int tty; 111225705Sbloom { 111325705Sbloom #ifdef USG 111425705Sbloom struct termio ttbuf; 111525705Sbloom #else !USG 111625705Sbloom struct sgttyb ttbuf; 111725705Sbloom #endif !USG 111825705Sbloom register struct sg_spds *ps; 111925705Sbloom int speed; 112025705Sbloom 112125705Sbloom if (IsTcpIp) 112225705Sbloom return; 112325705Sbloom #ifdef USG 112425705Sbloom ioctl(tty, TCGETA, &ttbuf); 112525705Sbloom ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 112625705Sbloom speed = ttbuf.c_cflag &= (CBAUD); 112725705Sbloom ttbuf.c_cflag |= (CS8|CREAD); 112825705Sbloom ttbuf.c_cc[VMIN] = 6; 112925705Sbloom ttbuf.c_cc[VTIME] = 1; 113025705Sbloom ioctl(tty, TCSETA, &ttbuf); 113125705Sbloom #else !USG 113225705Sbloom ioctl(tty, TIOCGETP, &ttbuf); 113325705Sbloom ttbuf.sg_flags = (ANYP | RAW); 113425705Sbloom ioctl(tty, TIOCSETP, &ttbuf); 113525705Sbloom speed = ttbuf.sg_ispeed; 113625705Sbloom ioctl(tty, TIOCEXCL, STBNULL); 113725705Sbloom #endif !USG 113825705Sbloom 113925705Sbloom for (ps = spds; ps->sp_val; ps++) 114025705Sbloom if (ps->sp_name == speed) { 114125705Sbloom linebaudrate = ps->sp_val; 114225705Sbloom DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); 114325705Sbloom return; 114425705Sbloom } 114525705Sbloom ASSERT(linebaudrate >= 0, "BAD SPEED", CNULL, speed); 114625705Sbloom } 114725705Sbloom 1148