133581Srick #ifndef lint 2*33948Srick static char sccsid[] = "@(#)conn.c 5.13 (Berkeley) 04/05/88"; 333581Srick #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 6433562Srick #define PCP_CITY 14 6533562Srick #define PCP_PASSWORD 16 6633562Srick #define PCP_RPHONE 20 6733562Srick #define NPCFIELDS 23 6825705Sbloom 6925705Sbloom static char *PCFlds[] = { 7025705Sbloom "PC-PURSUIT", 7125705Sbloom "Any", 7225705Sbloom "ACU", 7325705Sbloom "1200", 7433562Srick CNULL, 7533562Srick CNULL, 7633562Srick "P_ZERO", /* Telenet insists on zero parity */ 7725705Sbloom "ABORT", 7833562Srick "BUSY", /* Abort on Busy Signal */ 7933562Srick CNULL, 8033562Srick "\\d\\d\\r\\d\\r", /* Get telenet's attention */ 8133562Srick "TERMINAL=~3-\r-TERM~3-\r-TERM~5", /* Terminal type ? */ 8233562Srick "\\r", 8333562Srick "@", /* telenet's prompt */ 8433562Srick "D/DCWAS/21,telenetloginstring", /* overwritten later */ 8533562Srick "PASSWORD", 8633562Srick CNULL, /* telenet password */ 8733562Srick "CONNECTED", /* We're now talking to a Hayes in the remote city */ 8833562Srick "ATZ", /* Reset it */ 8933562Srick "OK", 9033562Srick "ATDT6907171", /* overwritten */ 9133562Srick "CONNECT", 9233562Srick "\\d\\r", /* We're in !*/ 9333562Srick CNULL, 9425705Sbloom }; 9525705Sbloom 9633562Srick static char PCP_brand[25]; 9725705Sbloom 9818619Sralph /* 9918619Sralph * place a telephone call to system and login, etc. 10013642Ssam * 10113642Ssam * return codes: 10213642Ssam * CF_SYSTEM: don't know system 10313642Ssam * CF_TIME: wrong time to call 10413642Ssam * CF_DIAL: call failed 10513642Ssam * CF_NODEV: no devices available to place call 10613642Ssam * CF_LOGIN: login/password dialog failed 10713642Ssam * 10813642Ssam * >0 - file no. - connect ok 10913642Ssam */ 11013642Ssam 11113642Ssam int Dcf = -1; 11217834Sralph char *Flds[MAXC/10]; 11325966Sbloom char LineType[10]; 11417834Sralph extern int LocalOnly; 11513642Ssam 11613642Ssam conn(system) 11713642Ssam char *system; 11813642Ssam { 11925705Sbloom int nf; 12018619Sralph char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE]; 12113642Ssam register FILE *fsys; 12213642Ssam int fcode = 0; 12313642Ssam 12413642Ssam nf = 0; 12513642Ssam 12613642Ssam fsys = fopen(SYSFILE, "r"); 127*33948Srick if (fsys == NULL) { 128*33948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", SYSFILE); 129*33948Srick cleanup(FAIL); 130*33948Srick } 13113642Ssam 13217834Sralph DEBUG(4, "finds (%s) called\n", system); 13325127Sbloom keeplooking: 13417834Sralph while((nf = finds(fsys, system, info, Flds)) > 0) { 13525966Sbloom strncpy(LineType, Flds[F_LINE], 10); 13617834Sralph if (LocalOnly) { 13725966Sbloom if (strcmp("TCP", LineType) 13825966Sbloom && strcmp("DIR", LineType) 13925966Sbloom && strcmp("LOCAL", LineType) ) { 14025705Sbloom fcode = CF_TIME; 14125705Sbloom continue; 14225705Sbloom } 14317834Sralph } 14423596Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 14518619Sralph if (!onesys && MaxGrade != DefMaxGrade && 14625705Sbloom !iswrk(file, "chk", Spool, wkpre)) { 14725705Sbloom fcode = CF_TIME; 14825705Sbloom continue; 14925705Sbloom } 15025705Sbloom /* For GTE's PC Pursuit */ 15125966Sbloom if (snccmp(LineType, PCP) == SAME) { 15225705Sbloom FILE *dfp; 15325705Sbloom int status; 15425705Sbloom static struct Devices dev; 15533562Srick 15625705Sbloom dfp = fopen(DEVFILE, "r"); 157*33948Srick if (dfp == NULL) { 158*33948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 159*33948Srick DEVFILE); 160*33948Srick cleanup(FAIL); 161*33948Srick } 16225705Sbloom while ((status=rddev(dfp, &dev)) != FAIL 16325705Sbloom && strcmp(PCP, dev.D_type) != SAME) 16425705Sbloom ; 16525705Sbloom fclose(dfp); 16625705Sbloom if (status == FAIL) 16725705Sbloom continue; 16825705Sbloom if (mlock(PCP) == FAIL) { 16925705Sbloom fcode = CF_NODEV; 17025705Sbloom logent("DEVICE", "NO"); 17125705Sbloom continue; 17225705Sbloom } 17325705Sbloom PCFlds[PCP_BAUD] = dev.D_class; 17425705Sbloom PCFlds[PCP_PHONE] = dev.D_calldev; 17533562Srick sprintf(PCFlds[PCP_CITY], "c d/%s%s,%s", 17633562Srick Flds[F_CLASS], 17733562Srick index(Flds[F_CLASS], '/') == NULL ? "/12" : "", 17833562Srick dev.D_arg[D_CHAT]); 17933562Srick PCFlds[PCP_PASSWORD] = dev.D_line; 18033562Srick strncpy(&PCFlds[PCP_RPHONE][4], Flds[F_PHONE], 7); 18125705Sbloom strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand)); 18233562Srick if ((fcode = getto(PCFlds)) < 0) { 18333562Srick rmlock(PCP); 18425705Sbloom continue; 18533562Srick } 18625705Sbloom Dcf = fcode; 18725705Sbloom fcode = login(NPCFIELDS, PCFlds, Dcf); 18833562Srick if (fcode == SUCCESS) 18933562Srick break; 19033562Srick fcode = CF_DIAL; 19133562Srick rmlock(PCP); 19233562Srick /* end PC Pursuit */ 19333562Srick } else if ((fcode = getto(Flds)) > 0) { 19433562Srick Dcf = fcode; 19513642Ssam break; 19633562Srick } 19713642Ssam } 19813642Ssam 19925127Sbloom if (nf <= 0) { 20025127Sbloom fclose(fsys); 20117834Sralph return fcode ? fcode : nf; 20225127Sbloom } 20313642Ssam 20425705Sbloom 20525705Sbloom if (fcode >= 0) { 20625705Sbloom DEBUG(4, "login %s\n", "called"); 20733562Srick fcode = login(nf, Flds, Dcf); } 20825705Sbloom if (fcode < 0) { 20913642Ssam clsacu(); 21025705Sbloom if (fcode == ABORT) { 21125127Sbloom fcode = CF_DIAL; 21225127Sbloom goto keeplooking; 21325127Sbloom } else { 21425127Sbloom fclose(fsys); 21523596Sbloom return CF_LOGIN; 21625127Sbloom } 21713642Ssam } 21825127Sbloom fclose(fsys); 21925705Sbloom fioclex(Dcf); 22025705Sbloom return Dcf; 22113642Ssam } 22213642Ssam 22325127Sbloom /* 22425127Sbloom * connect to remote machine 22513642Ssam * 22613642Ssam * return codes: 22713642Ssam * >0 - file number - ok 22813642Ssam * FAIL - failed 22913642Ssam */ 23013642Ssam 23113642Ssam getto(flds) 23213642Ssam register char *flds[]; 23313642Ssam { 23413642Ssam register struct condev *cd; 23513642Ssam int nulldev(), diropn(); 23625127Sbloom char *line; 23713642Ssam 23817834Sralph DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); 23913642Ssam DEBUG(4, "for sys %s\n", flds[F_NAME]); 24013642Ssam 24125127Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME) 24225127Sbloom line = "ACU"; 24325127Sbloom else 24425127Sbloom line = flds[F_LINE]; 24525127Sbloom #ifdef DIALINOUT 24625127Sbloom if (snccmp(line, "ACU") != SAME) 24725127Sbloom reenable(); 24825127Sbloom #endif DIALINOUT 24913642Ssam CU_end = nulldev; 25025705Sbloom if (snccmp(line, PCP) == SAME) { 25125705Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) { 25225705Sbloom if (snccmp(PCP_brand, cd->CU_brand) == SAME) { 25325705Sbloom CU_end = cd->CU_clos; 25425705Sbloom return diropn(flds); 25525705Sbloom } 25613642Ssam } 25725705Sbloom logent(PCP_brand, "UNSUPPORTED ACU TYPE"); 25825705Sbloom } else { 25925705Sbloom for (cd = condevs; cd->CU_meth != NULL; cd++) { 26025705Sbloom if (snccmp(cd->CU_meth, line) == SAME) { 26125705Sbloom DEBUG(4, "Using %s to call\n", cd->CU_meth); 26225705Sbloom return (*(cd->CU_gen))(flds); 26325705Sbloom } 26425705Sbloom } 26525705Sbloom DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); 26613642Ssam } 26717834Sralph return diropn(flds); /* search failed, so use direct */ 26817834Sralph } 26913642Ssam 27025127Sbloom /* 27125127Sbloom * close call unit 27213642Ssam * 27313642Ssam * return codes: none 27413642Ssam */ 27513642Ssam 27613642Ssam int (*CU_end)() = nulldev; 27713642Ssam clsacu() 27813642Ssam { 27917834Sralph /* make *sure* Dcf is no longer exclusive. 28017834Sralph * Otherwise dual call-in/call-out modems could get stuck. 28117834Sralph * Unfortunately, doing this here is not ideal, but it is the 28217834Sralph * easiest place to put the call. 28317834Sralph * Hopefully everyone honors the LCK protocol, of course 28417834Sralph */ 28525705Sbloom #ifdef TIOCNXCL 28623596Sbloom if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) 28723596Sbloom DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); 28817834Sralph #endif 28917834Sralph if (setjmp(Sjbuf)) 29017834Sralph logent(Rmtname, "CLOSE TIMEOUT"); 29117834Sralph else { 29217834Sralph signal(SIGALRM, alarmtr); 29317834Sralph alarm(20); 29417834Sralph (*(CU_end))(Dcf); 29517834Sralph alarm(0); 29617834Sralph } 29713642Ssam if (close(Dcf) == 0) { 29813642Ssam DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); 29913642Ssam logent("clsacu", "NOT CLOSED by CU_clos"); 30013642Ssam } 30113642Ssam Dcf = -1; 30213642Ssam CU_end = nulldev; 30313642Ssam } 30413642Ssam 30525127Sbloom /* 30625127Sbloom * expand phone number for given prefix and number 30713642Ssam */ 30813642Ssam 30913642Ssam exphone(in, out) 31013642Ssam register char *in, *out; 31113642Ssam { 31213642Ssam FILE *fn; 31313642Ssam char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; 31413642Ssam char buf[BUFSIZ]; 31513642Ssam register char *s1; 31613642Ssam 31717834Sralph if (!isascii(*in) || !isalpha(*in)) { 31813642Ssam strcpy(out, in); 31913642Ssam return; 32013642Ssam } 32113642Ssam 32213642Ssam s1=pre; 32317834Sralph while (isascii(*in) && isalpha(*in)) 32413642Ssam *s1++ = *in++; 32513642Ssam *s1 = '\0'; 32613642Ssam s1 = npart; 32713642Ssam while (*in != '\0') 32813642Ssam *s1++ = *in++; 32913642Ssam *s1 = '\0'; 33013642Ssam 33113642Ssam tpre[0] = '\0'; 33213642Ssam if ((fn = fopen(DIALFILE, "r")) == NULL) 33313642Ssam DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); 33413642Ssam else { 33513642Ssam while (cfgets(buf, BUFSIZ, fn)) { 33617834Sralph if (sscanf(buf, "%s%s", p, tpre) != 2) 33717834Sralph continue; 33813642Ssam if (strcmp(p, pre) == SAME) 33913642Ssam goto found; 34013642Ssam tpre[0] = '\0'; 34113642Ssam } 34213642Ssam DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); 34313642Ssam found:; 34413642Ssam fclose(fn); 34513642Ssam } 34613642Ssam 34713642Ssam strcpy(out, tpre); 34813642Ssam strcat(out, npart); 34913642Ssam } 35013642Ssam 35118619Sralph /* 35218619Sralph * read and decode a line from device file 35313642Ssam * 35413642Ssam * return code - FAIL at end-of file; 0 otherwise 35513642Ssam */ 35613642Ssam 35713642Ssam rddev(fp, dev) 35813642Ssam register struct Devices *dev; 35913642Ssam FILE *fp; 36013642Ssam { 36117834Sralph register int na; 36213642Ssam 36317834Sralph if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) 36417834Sralph return FAIL; 36517834Sralph na = getargs(dev->D_argbfr, dev->D_arg, 20); 366*33948Srick if (na < 4) { 367*33948Srick syslog(LOG_ERR, "%s: invalid device entry", dev->D_argbfr); 368*33948Srick cleanup(FAIL); 369*33948Srick } 37017834Sralph if (na == 4) { 37117834Sralph dev->D_brand = ""; 37217834Sralph na++; 37317834Sralph } 37413642Ssam dev->D_speed = atoi(fdig(dev->D_class)); 37517834Sralph dev->D_numargs = na; 37617834Sralph return 0; 37713642Ssam } 37813642Ssam 37918619Sralph /* 38018619Sralph * set system attribute vector 38113642Ssam * 38213642Ssam * return codes: 38313642Ssam * >0 - number of arguments in vector - succeeded 38413642Ssam * CF_SYSTEM - system name not found 38513642Ssam * CF_TIME - wrong time to call 38613642Ssam */ 38713642Ssam 38813642Ssam finds(fsys, sysnam, info, flds) 38913642Ssam char *sysnam, info[], *flds[]; 39013642Ssam FILE *fsys; 39113642Ssam { 39213642Ssam int na; 39313642Ssam int fcode = 0; 39413642Ssam 39513642Ssam /* format of fields 39613642Ssam * 0 name; 39713642Ssam * 1 time 39813642Ssam * 2 acu/hardwired 39913642Ssam * 3 speed 40013642Ssam * etc 40113642Ssam */ 40213642Ssam while (cfgets(info, MAXC, fsys) != NULL) { 40317834Sralph na = getargs(info, flds, MAXC/10); 40423596Sbloom if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) 40513642Ssam continue; 40618619Sralph if (ifdate(flds[F_TIME]) != FAIL) 40713642Ssam /* found a good entry */ 40817834Sralph return na; 40913642Ssam DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); 41013642Ssam fcode = CF_TIME; 41113642Ssam } 41217834Sralph return fcode ? fcode : CF_SYSTEM; 41313642Ssam } 41413642Ssam 41518619Sralph /* 41618619Sralph * do login conversation 41713642Ssam * 41823596Sbloom * return codes: SUCCESS | FAIL 41913642Ssam */ 42013642Ssam 42113642Ssam login(nf, flds, fn) 42213642Ssam register char *flds[]; 42313642Ssam int nf, fn; 42413642Ssam { 42513642Ssam register char *want, *altern; 42613642Ssam int k, ok; 42713642Ssam 428*33948Srick if (nf < 4) { 429*33948Srick syslog(LOG_ERR, "Too few log fields: %d", nf); 430*33948Srick cleanup(FAIL); 431*33948Srick } 43217834Sralph if (setjmp(Cjbuf)) 43317834Sralph return FAIL; 43417834Sralph AbortOn = NULL; 43513642Ssam for (k = F_LOGIN; k < nf; k += 2) { 43613642Ssam want = flds[k]; 43733562Srick if (want == NULL) 43833562Srick want = ""; 43913642Ssam ok = FAIL; 44017834Sralph while (ok != SUCCESS) { 44113642Ssam altern = index(want, '-'); 44213642Ssam if (altern != NULL) 44313642Ssam *altern++ = '\0'; 44417834Sralph if (strcmp(want, "ABORT") == 0) { 44517834Sralph AbortOn = flds[k+1]; 44617834Sralph DEBUG(4, "ABORT ON: %s\n", AbortOn); 44717834Sralph goto nextfield; 44817834Sralph } 44925705Sbloom DEBUG(4, "wanted \"%s\"\n", want); 45013642Ssam ok = expect(want, fn); 45117834Sralph DEBUG(4, "got: %s\n", ok ? "?" : "that"); 45217834Sralph if (ok == FAIL) { 45317834Sralph if (altern == NULL) { 45417834Sralph logent("LOGIN", _FAILED); 45517834Sralph return FAIL; 45617834Sralph } 45717834Sralph want = index(altern, '-'); 45817834Sralph if (want != NULL) 45917834Sralph *want++ = '\0'; 46017834Sralph sendthem(altern, fn); 46117834Sralph } else 46217834Sralph if (ok == ABORT) { 46333562Srick char sbuf[MAXFULLNAME]; 46433562Srick sprintf(sbuf, "LOGIN ABORTED on \"%s\"", AbortOn); 46533562Srick logent(sbuf, _FAILED); 46623596Sbloom return ABORT; 46717834Sralph } 46813642Ssam } 46917834Sralph sleep(1); 47013642Ssam if (k+1 < nf) 47113642Ssam sendthem(flds[k+1], fn); 47217834Sralph nextfield: ; 47313642Ssam } 47417834Sralph return SUCCESS; 47513642Ssam } 47613642Ssam 47713642Ssam 47817834Sralph /* conditional table generation to support odd speeds */ 47913642Ssam struct sg_spds {int sp_val, sp_name;} spds[] = { 48013642Ssam #ifdef B50 48113642Ssam { 50, B50}, 48213642Ssam #endif 48313642Ssam #ifdef B75 48413642Ssam { 75, B75}, 48513642Ssam #endif 48613642Ssam #ifdef B110 48713642Ssam { 110, B110}, 48813642Ssam #endif 48913642Ssam #ifdef B150 49013642Ssam { 150, B150}, 49113642Ssam #endif 49213642Ssam #ifdef B200 49313642Ssam { 200, B200}, 49413642Ssam #endif 49513642Ssam #ifdef B300 49613642Ssam { 300, B300}, 49713642Ssam #endif 49813642Ssam #ifdef B600 49913642Ssam {600, B600}, 50013642Ssam #endif 50113642Ssam #ifdef B1200 50213642Ssam {1200, B1200}, 50313642Ssam #endif 50413642Ssam #ifdef B1800 50513642Ssam {1800, B1800}, 50613642Ssam #endif 50713642Ssam #ifdef B2000 50813642Ssam {2000, B2000}, 50913642Ssam #endif 51013642Ssam #ifdef B2400 51113642Ssam {2400, B2400}, 51213642Ssam #endif 51313642Ssam #ifdef B3600 51413642Ssam {3600, B3600}, 51513642Ssam #endif 51613642Ssam #ifdef B4800 51713642Ssam {4800, B4800}, 51813642Ssam #endif 51913642Ssam #ifdef B7200 52013642Ssam {7200, B7200}, 52113642Ssam #endif 52213642Ssam #ifdef B9600 52313642Ssam {9600, B9600}, 52413642Ssam #endif 52513642Ssam #ifdef B19200 52617834Sralph {19200, B19200}, 52713642Ssam #endif 52817834Sralph #ifdef EXTA 52917834Sralph {19200, EXTA}, 53017834Sralph #endif 53113642Ssam {0, 0} 53213642Ssam }; 53313642Ssam 53418619Sralph /* 53518619Sralph * set speed/echo/mode... 53613642Ssam * 53713642Ssam * return codes: none 53813642Ssam */ 53913642Ssam 54013642Ssam fixline(tty, spwant) 54113642Ssam int tty, spwant; 54213642Ssam { 54317834Sralph #ifdef USG 54413642Ssam struct termio ttbuf; 54517834Sralph #else !USG 54613642Ssam struct sgttyb ttbuf; 54717834Sralph #endif !USG 54813642Ssam register struct sg_spds *ps; 54913642Ssam int speed = -1; 55013642Ssam 55113642Ssam for (ps = spds; ps->sp_val; ps++) 55213642Ssam if (ps->sp_val == spwant) 55313642Ssam speed = ps->sp_name; 554*33948Srick if (speed < 0) { 555*33948Srick syslog(LOG_ERR, "unrecognized speed: %d", speed); 556*33948Srick cleanup(FAIL); 557*33948Srick } 55817834Sralph #ifdef USG 55923596Sbloom if (ioctl(tty, TCGETA, &ttbuf) < 0) 56023596Sbloom return FAIL; 56113642Ssam /* ttbuf.sg_flags = (ANYP|RAW); 56213642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ 56313642Ssam ttbuf.c_iflag = (ushort)0; 56413642Ssam ttbuf.c_oflag = (ushort)0; 56513642Ssam ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); 56613642Ssam ttbuf.c_lflag = (ushort)0; 56713642Ssam ttbuf.c_cc[VMIN] = 6; 56813642Ssam ttbuf.c_cc[VTIME] = 1; 56923596Sbloom if (ioctl(tty, TCSETA, &ttbuf) < 0) 57023596Sbloom return FAIL; 57117834Sralph #else !USG 57223596Sbloom if (ioctl(tty, TIOCGETP, &ttbuf) < 0) 57323596Sbloom return FAIL; 57413642Ssam ttbuf.sg_flags = (ANYP|RAW); 57513642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; 57623596Sbloom if (ioctl(tty, TIOCSETP, &ttbuf) < 0) 57723596Sbloom return FAIL; 57813642Ssam #endif 57917834Sralph #ifndef USG 58023596Sbloom if (ioctl(tty, TIOCHPCL, STBNULL) < 0) 58123596Sbloom return FAIL; 58223596Sbloom if (ioctl(tty, TIOCEXCL, STBNULL) < 0) 58323596Sbloom return FAIL; 58413642Ssam #endif 58517834Sralph linebaudrate = spwant; 58623596Sbloom return SUCCESS; 58713642Ssam } 58813642Ssam 58917834Sralph #define MR 100 59013642Ssam 59118619Sralph /* 59218619Sralph * look for expected string 59313642Ssam * 59413642Ssam * return codes: 59513642Ssam * 0 - found 59613642Ssam * FAIL - lost line or too many characters read 59713642Ssam * some character - timed out 59813642Ssam */ 59913642Ssam 60013642Ssam expect(str, fn) 60113642Ssam register char *str; 60213642Ssam int fn; 60313642Ssam { 60414592Skarels char rdvec[MR]; 60517834Sralph register char *rp = rdvec, *strptr; 60617834Sralph int kr, cnt_char; 60713642Ssam char nextch; 60825127Sbloom int timo = MAXMSGTIME; 60913642Ssam 61017834Sralph if (*str == '\0' || strcmp(str, "\"\"") == SAME) 61117834Sralph return SUCCESS; 61217834Sralph /* Cleanup str, convert \0xx strings to one char */ 61317834Sralph for (strptr = str; *strptr; strptr++) { 61417834Sralph if (*strptr == '\\') 61517834Sralph switch(*++strptr) { 61617834Sralph case 's': 61717834Sralph DEBUG(5, "BLANK\n", CNULL); 61817834Sralph *strptr = ' '; 61917834Sralph break; 62017834Sralph default: 62117834Sralph strptr--; /* back up to backslash */ 62217834Sralph sscanf(strptr + 1,"%o", &cnt_char); 62317834Sralph DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); 62417834Sralph *strptr = (char) (cnt_char); 62517834Sralph strcpy(&strptr[1], &strptr[4]); 62617834Sralph } 62717834Sralph } 62817834Sralph 62925127Sbloom strptr = index(str, '~'); 63025127Sbloom if (strptr != NULL) { 63125127Sbloom *strptr++ = '\0'; 63225127Sbloom timo = atoi(strptr); 63325127Sbloom if (timo <= 0) 63425127Sbloom timo = MAXMSGTIME; 63525127Sbloom } 63625127Sbloom 63717834Sralph if (setjmp(Sjbuf)) 63817834Sralph return FAIL; 63913642Ssam signal(SIGALRM, alarmtr); 64025127Sbloom alarm(timo); 64125127Sbloom *rp = 0; 64213642Ssam while (notin(str, rdvec)) { 64325705Sbloom int c; 64417834Sralph if(AbortOn != NULL && !notin(AbortOn, rdvec)) { 64517834Sralph DEBUG(1, "Call aborted on '%s'\n", AbortOn); 64617834Sralph alarm(0); 64717834Sralph return ABORT; 64817834Sralph } 64913642Ssam kr = read(fn, &nextch, 1); 65013642Ssam if (kr <= 0) { 65113642Ssam alarm(0); 65213642Ssam DEBUG(4, "lost line kr - %d\n, ", kr); 65313642Ssam logent("LOGIN", "LOST LINE"); 65417834Sralph return FAIL; 65513642Ssam } 65613642Ssam c = nextch & 0177; 65725705Sbloom if (c == '\0') 65825705Sbloom continue; 65925705Sbloom DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); 66025705Sbloom *rp++ = c; 66113642Ssam if (rp >= rdvec + MR) { 66217834Sralph register char *p; 66317834Sralph for (p = rdvec+MR/2; p < rp; p++) 66417834Sralph *(p-MR/2) = *p; 66517834Sralph rp -= MR/2; 66613642Ssam } 66713642Ssam *rp = '\0'; 66813642Ssam } 66913642Ssam alarm(0); 67017834Sralph return SUCCESS; 67113642Ssam } 67213642Ssam 67313642Ssam 67413642Ssam /* 67513642Ssam * Determine next file descriptor that would be allocated. 67613642Ssam * This permits later closing of a file whose open was interrupted. 67713642Ssam * It is a UNIX kernel problem, but it has to be handled. 67813642Ssam * unc!smb (Steve Bellovin) probably first discovered it. 67913642Ssam */ 68013642Ssam getnextfd() 68113642Ssam { 68213642Ssam close(next_fd = open("/", 0)); 68313642Ssam } 68413642Ssam 68517834Sralph /* 68617834Sralph * send line of login sequence 68713642Ssam * 68813642Ssam * return codes: none 68913642Ssam */ 69013642Ssam sendthem(str, fn) 69113642Ssam register char *str; 69213642Ssam int fn; 69313642Ssam { 69413642Ssam register char *strptr; 69513642Ssam int i, n, cr = 1; 69617834Sralph register char c; 69713642Ssam static int p_init = 0; 69813642Ssam 69925705Sbloom DEBUG(5, "send \"%s\"\n", str); 70013642Ssam 70113642Ssam if (!p_init) { 70213642Ssam p_init++; 703*33948Srick bld_partab(P_ZERO); 70413642Ssam } 70513642Ssam 70613642Ssam if (prefix("BREAK", str)) { 70713642Ssam sscanf(&str[5], "%1d", &i); 70813642Ssam if (i <= 0 || i > 10) 70913642Ssam i = 3; 71013642Ssam /* send break */ 71113642Ssam genbrk(fn, i); 71213642Ssam return; 71313642Ssam } 71413642Ssam 71513642Ssam if (prefix("PAUSE", str)) { 71613642Ssam sscanf(&str[5], "%1d", &i); 71713642Ssam if (i <= 0 || i > 10) 71813642Ssam i = 3; 71913642Ssam /* pause for a while */ 72013642Ssam sleep((unsigned)i); 72113642Ssam return; 72213642Ssam } 72313642Ssam 72413642Ssam if (strcmp(str, "EOT") == SAME) { 72513642Ssam p_chwrite(fn, '\04'); 72613642Ssam return; 72713642Ssam } 72813642Ssam 72913642Ssam /* Send a '\n' */ 73025705Sbloom if (strcmp(str, "LF") == SAME) { 73125705Sbloom p_chwrite(fn, '\n'); 73225705Sbloom return; 73325705Sbloom } 73413642Ssam 73513642Ssam /* Send a '\r' */ 73625705Sbloom if (strcmp(str, "CR") == SAME) { 73725705Sbloom p_chwrite(fn, '\r'); 73825705Sbloom return; 73925705Sbloom } 74013642Ssam 74113642Ssam /* Set parity as needed */ 74213642Ssam if (strcmp(str, "P_ZERO") == SAME) { 74313642Ssam bld_partab(P_ZERO); 74413642Ssam return; 74513642Ssam } 74613642Ssam if (strcmp(str, "P_ONE") == SAME) { 74713642Ssam bld_partab(P_ONE); 74813642Ssam return; 74913642Ssam } 75013642Ssam if (strcmp(str, "P_EVEN") == SAME) { 75113642Ssam bld_partab(P_EVEN); 75213642Ssam return; 75313642Ssam } 75413642Ssam if (strcmp(str, "P_ODD") == SAME) { 75513642Ssam bld_partab(P_ODD); 75613642Ssam return; 75713642Ssam } 75813642Ssam 75913642Ssam /* If "", just send '\r' */ 76017834Sralph if (strcmp(str, "\"\"") == SAME) { 76117834Sralph p_chwrite(fn, '\r'); 76217834Sralph return; 76317834Sralph } 76417834Sralph 76525705Sbloom strptr = str; 76625705Sbloom while ((c = *strptr++) != '\0') { 76717834Sralph if (c == '\\') { 76817834Sralph switch(*strptr++) { 76925705Sbloom case '\0': 77025705Sbloom DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); 77125705Sbloom --strptr; 77225705Sbloom continue; 77317834Sralph case 's': 77417834Sralph DEBUG(5, "BLANK\n", CNULL); 77525705Sbloom c = ' '; 77617834Sralph break; 77717834Sralph case 'd': 77817834Sralph DEBUG(5, "DELAY\n", CNULL); 77917834Sralph sleep(1); 78017834Sralph continue; 78125705Sbloom case 'n': 78225705Sbloom DEBUG(5, "NEW LINE\n", CNULL); 78325705Sbloom c = '\n'; 78425705Sbloom break; 78517834Sralph case 'r': 78617834Sralph DEBUG(5, "RETURN\n", CNULL); 78725705Sbloom c = '\r'; 78817834Sralph break; 78917834Sralph case 'b': 79017834Sralph if (isdigit(*strptr)) { 79117834Sralph i = (*strptr++ - '0'); 79217834Sralph if (i <= 0 || i > 10) 79317834Sralph i = 3; 79417834Sralph } else 79513642Ssam i = 3; 79617834Sralph /* send break */ 79717834Sralph genbrk(fn, i); 79817834Sralph if (*strptr == '\0') 79917834Sralph cr = 0; 80013642Ssam continue; 80117834Sralph case 'c': 80217834Sralph if (*strptr == '\0') { 80317834Sralph DEBUG(5, "NO CR\n", CNULL); 80417834Sralph cr = 0; 80525705Sbloom } else 80625705Sbloom DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); 80713642Ssam continue; 80825705Sbloom #define isoctal(x) ((x >= '0') && (x <= '7')) 80917834Sralph default: 81025705Sbloom if (isoctal(strptr[-1])) { 81117834Sralph i = 0; 81217834Sralph n = 0; 81325705Sbloom --strptr; 81425705Sbloom while (isoctal(*strptr) && ++n <= 3) 81525705Sbloom i = i * 8 + (*strptr++ - '0'); 81625705Sbloom DEBUG(5, "\\%o\n", i); 81717834Sralph p_chwrite(fn, (char)i); 81817834Sralph continue; 81917834Sralph } 82013642Ssam } 82125705Sbloom } 82225705Sbloom p_chwrite(fn, c); 82313642Ssam } 82413642Ssam 82513642Ssam if (cr) 82613642Ssam p_chwrite(fn, '\r'); 82713642Ssam return; 82813642Ssam } 82913642Ssam 83013642Ssam p_chwrite(fd, c) 83113642Ssam int fd; 83217834Sralph char c; 83313642Ssam { 83417834Sralph c = par_tab[c&0177]; 83517834Sralph if (write(fd, &c, 1) != 1) { 83617834Sralph logent(sys_errlist[errno], "BAD WRITE"); 83717834Sralph longjmp(Cjbuf, 2); 83817834Sralph } 83913642Ssam } 84013642Ssam 84113642Ssam /* 84213642Ssam * generate parity table for use by p_chwrite. 84313642Ssam */ 84413642Ssam bld_partab(type) 84513642Ssam int type; 84613642Ssam { 84713642Ssam register int i, j, n; 84813642Ssam 84913642Ssam for (i = 0; i < sizeof(par_tab); i++) { 85013642Ssam n = 0; 85113642Ssam for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) 85213642Ssam n++; 85313642Ssam par_tab[i] = i; 85413642Ssam if (type == P_ONE 85513642Ssam || (type == P_EVEN && (n&01) != 0) 85613642Ssam || (type == P_ODD && (n&01) == 0)) 85713642Ssam par_tab[i] |= sizeof(par_tab); 85813642Ssam } 85913642Ssam } 86013642Ssam 86118619Sralph /* 86218619Sralph * check for occurrence of substring "sh" 86313642Ssam * 86413642Ssam * return codes: 86513642Ssam * 0 - found the string 86613642Ssam * 1 - not in the string 86713642Ssam */ 86813642Ssam notin(sh, lg) 86913642Ssam register char *sh, *lg; 87013642Ssam { 87113642Ssam while (*lg != '\0') { 87213642Ssam if (wprefix(sh, lg)) 87318619Sralph return 0; 87413642Ssam else 87513642Ssam lg++; 87613642Ssam } 87718619Sralph return 1; 87813642Ssam } 87913642Ssam 88018619Sralph /* 88123596Sbloom * Allow multiple date specifications separated by ','. 88213642Ssam */ 88318619Sralph ifdate(p) 88418619Sralph register char *p; 88513642Ssam { 88625705Sbloom register char *np; 88718619Sralph register int ret, g; 88823596Sbloom int rtime, i; 88913642Ssam 89023596Sbloom /* pick up retry time for failures */ 89123596Sbloom /* global variable Retrytime is set here */ 89223596Sbloom if ((np = index(p, ';')) == NULL) { 89323596Sbloom Retrytime = RETRYTIME; 89423596Sbloom } else { 89523596Sbloom i = sscanf(np+1, "%d", &rtime); 89623596Sbloom if (i < 1 || rtime < 0) 89723596Sbloom rtime = 5; 89823596Sbloom Retrytime = rtime * 60; 89923596Sbloom } 90023596Sbloom 90118619Sralph ret = FAIL; 90218619Sralph MaxGrade = '\0'; 90318619Sralph do { 90423596Sbloom np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ 90523596Sbloom if (np) 90623596Sbloom *np = '\0'; 90718619Sralph g = ifadate(p); 90818619Sralph DEBUG(11,"ifadate returns %o\n", g); 90918619Sralph if (g != FAIL) { 91018619Sralph ret = SUCCESS; 91118619Sralph if (g > MaxGrade) 91218619Sralph MaxGrade = g; 91318619Sralph } 91423596Sbloom if (np) 91523596Sbloom *np = ','; 91623596Sbloom p = np + 1; 91723596Sbloom } while (np); 91823596Sbloom if (MaxGrade == '\0') 91923596Sbloom MaxGrade = DefMaxGrade; 92018619Sralph return ret; 92113642Ssam } 92213642Ssam 92318619Sralph /* 92418619Sralph * this routine will check a string (string) 92513642Ssam * like "MoTu0800-1730" to see if the present 92613642Ssam * time is within the given limits. 92713642Ssam * SIDE EFFECT - Retrytime is set 92813642Ssam * 92913642Ssam * return codes: 93013642Ssam * 0 - not within limits 93113642Ssam * 1 - within limits 93213642Ssam */ 93313642Ssam 93418619Sralph ifadate(string) 93518619Sralph char *string; 93613642Ssam { 93713642Ssam static char *days[]={ 93813642Ssam "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 93913642Ssam }; 94013642Ssam time_t clock; 94118619Sralph register char *s = string; 94217834Sralph int i, tl, th, tn, dayok=0; 94313642Ssam struct tm *localtime(); 94413642Ssam struct tm *tp; 94518619Sralph char *p, MGrade; 94613642Ssam 94723596Sbloom if ((p = index(s, '/')) == NULL) 94818619Sralph MGrade = DefMaxGrade; 94918619Sralph else 95018619Sralph MGrade = p[1]; 95118619Sralph 95213642Ssam time(&clock); 95313642Ssam tp = localtime(&clock); 95417834Sralph while (isascii(*s) && isalpha(*s)) { 95513642Ssam for (i = 0; days[i]; i++) { 95613642Ssam if (prefix(days[i], s)) 95713642Ssam if (tp->tm_wday == i) 95813642Ssam dayok = 1; 95913642Ssam } 96013642Ssam 96113642Ssam if (prefix("Wk", s)) 96213642Ssam if (tp->tm_wday >= 1 && tp->tm_wday <= 5) 96313642Ssam dayok = 1; 96413642Ssam if (prefix("Any", s)) 96513642Ssam dayok = 1; 96617834Sralph if (prefix("Evening", s)) { 96717834Sralph /* Sat or Sun */ 96817834Sralph if (tp->tm_wday == 6 || tp->tm_wday == 0 96917834Sralph || tp->tm_hour >= 17 || tp->tm_hour < 8) 97017834Sralph dayok = 1; 97117834Sralph } 97217834Sralph if (prefix("Night", s)) { 97317834Sralph if (tp->tm_wday == 6 /* Sat */ 97418619Sralph || tp->tm_hour >= 23 || tp->tm_hour < 8 97518619Sralph /* Sunday before 5pm */ 97618619Sralph || (tp->tm_wday == 0 && tp->tm_hour < 17)) 97717834Sralph dayok = 1; 97817834Sralph } 97925705Sbloom if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ 98025705Sbloom /* Sat or Sun */ 98125705Sbloom if (tp->tm_wday == 6 || tp->tm_wday == 0 98225705Sbloom || tp->tm_hour >= 18 || tp->tm_hour < 7) 98325705Sbloom dayok = 1; 98425705Sbloom } 98513642Ssam s++; 98613642Ssam } 98713642Ssam 98818619Sralph if (dayok == 0 && s != string) 98918619Sralph return FAIL; 99013642Ssam i = sscanf(s, "%d-%d", &tl, &th); 99118619Sralph if (i < 2) 99218619Sralph return MGrade; 99318619Sralph tn = tp->tm_hour * 100 + tp->tm_min; 99418619Sralph if (th < tl) { /* crosses midnight */ 99518619Sralph if (tl <= tn || tn < th) 99618619Sralph return MGrade; 99725966Sbloom } else { 99817834Sralph if (tl <= tn && tn < th) 99918619Sralph return MGrade; 100025966Sbloom } 100118619Sralph return FAIL; 100213642Ssam } 100313642Ssam 100418619Sralph /* 100518619Sralph * find first digit in string 100613642Ssam * 100713642Ssam * return - pointer to first digit in string or end of string 100813642Ssam */ 100913642Ssam char * 101013642Ssam fdig(cp) 101113642Ssam register char *cp; 101213642Ssam { 101313642Ssam register char *c; 101413642Ssam 101513642Ssam for (c = cp; *c; c++) 101613642Ssam if (*c >= '0' && *c <= '9') 101713642Ssam break; 101817834Sralph return c; 101913642Ssam } 102013642Ssam 102113642Ssam /* 102213642Ssam * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 102313642Ssam * Strings are compared as if they contain all capital letters. 102413642Ssam */ 102513642Ssam snccmp(s1, s2) 102613642Ssam register char *s1, *s2; 102713642Ssam { 102813642Ssam char c1, c2; 102913642Ssam 103025127Sbloom if (islower(*s1)) 103125127Sbloom c1 = toupper(*s1); 103225127Sbloom else 103325127Sbloom c1 = *s1; 103425127Sbloom if (islower(*s2)) 103525127Sbloom c2 = toupper(*s2); 103625127Sbloom else 103725127Sbloom c2 = *s2; 103813642Ssam 103913642Ssam while (c1 == c2) { 104025127Sbloom if (*s1++ == '\0') 104117834Sralph return 0; 104213642Ssam s2++; 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; 105113642Ssam } 105217834Sralph return c1 - c2; 105313642Ssam } 105425127Sbloom 105517834Sralph /* 105625127Sbloom * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 105725127Sbloom * Strings are compared as if they contain all capital letters. 105825127Sbloom */ 105925127Sbloom sncncmp(s1, s2, n) 106025127Sbloom register char *s1, *s2; 106125127Sbloom register int n; 106225127Sbloom { 106325127Sbloom char c1, c2; 106425127Sbloom 106525127Sbloom if (islower(*s1)) 106625127Sbloom c1 = toupper(*s1); 106725127Sbloom else 106825127Sbloom c1 = *s1; 106925127Sbloom if (islower(*s2)) 107025127Sbloom c2 = toupper(*s2); 107125127Sbloom else 107225127Sbloom c2 = *s2; 107325127Sbloom 107425127Sbloom while ( --n >= 0 && c1 == c2) { 107525127Sbloom if (*s1++ == '\0') 107625127Sbloom return 0; 107725127Sbloom s2++; 107825127Sbloom if (islower(*s1)) 107925127Sbloom c1 = toupper(*s1); 108025127Sbloom else 108125127Sbloom c1 = *s1; 108225127Sbloom if (islower(*s2)) 108325127Sbloom c2 = toupper(*s2); 108425127Sbloom else 108525127Sbloom c2 = *s2; 108625127Sbloom } 108725127Sbloom return n<0 ? 0 : (c1 - c2); 108825127Sbloom } 108925127Sbloom /* 109017834Sralph * do chat script 109117834Sralph * occurs after local port is opened, 109217834Sralph * before 'dialing' the other machine. 109317834Sralph */ 109417834Sralph dochat(dev, flds, fd) 109517834Sralph register struct Devices *dev; 109617834Sralph char *flds[]; 109717834Sralph int fd; 109817834Sralph { 109917834Sralph register int i; 110017834Sralph register char *p; 110117834Sralph char bfr[sizeof(dev->D_argbfr)]; 110217834Sralph 110317834Sralph if (dev->D_numargs <= 5) 110417834Sralph return(0); 110517834Sralph DEBUG(4, "dochat called %d\n", dev->D_numargs); 110617834Sralph for (i = 0; i < dev->D_numargs-5; i++) { 110717834Sralph sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); 110817834Sralph if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { 110917834Sralph p = malloc((unsigned)strlen(bfr)+1); 111017834Sralph if (p != NULL) { 111117834Sralph strcpy(p, bfr); 111217834Sralph dev->D_arg[D_CHAT+i] = p; 111317834Sralph } 111417834Sralph } 111517834Sralph } 111617834Sralph /* following is a kludge because login() arglist is a kludge */ 111717834Sralph i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); 111817834Sralph /* 111917834Sralph * If login() last did a sendthem(), must pause so things can settle. 112017834Sralph * But don't bother if chat failed. 112117834Sralph */ 112217834Sralph if (i == 0 && (dev->D_numargs&01)) 112317834Sralph sleep(2); 112417834Sralph return(i); 112517834Sralph } 112625705Sbloom 112725705Sbloom /* 112825705Sbloom * fix kill/echo/raw on line 112925705Sbloom * 113025705Sbloom * return codes: none 113125705Sbloom */ 113225705Sbloom fixmode(tty) 113325705Sbloom register int tty; 113425705Sbloom { 113525705Sbloom #ifdef USG 113625705Sbloom struct termio ttbuf; 113725705Sbloom #else !USG 113825705Sbloom struct sgttyb ttbuf; 113925705Sbloom #endif !USG 114025705Sbloom register struct sg_spds *ps; 114125705Sbloom int speed; 114225705Sbloom 114325705Sbloom if (IsTcpIp) 114425705Sbloom return; 114525705Sbloom #ifdef USG 114625705Sbloom ioctl(tty, TCGETA, &ttbuf); 114725705Sbloom ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 114825705Sbloom speed = ttbuf.c_cflag &= (CBAUD); 114925705Sbloom ttbuf.c_cflag |= (CS8|CREAD); 115025705Sbloom ttbuf.c_cc[VMIN] = 6; 115125705Sbloom ttbuf.c_cc[VTIME] = 1; 115225705Sbloom ioctl(tty, TCSETA, &ttbuf); 115325705Sbloom #else !USG 115425705Sbloom ioctl(tty, TIOCGETP, &ttbuf); 115525705Sbloom ttbuf.sg_flags = (ANYP | RAW); 115625705Sbloom ioctl(tty, TIOCSETP, &ttbuf); 115725705Sbloom speed = ttbuf.sg_ispeed; 115825705Sbloom ioctl(tty, TIOCEXCL, STBNULL); 115925705Sbloom #endif !USG 116025705Sbloom 116125705Sbloom for (ps = spds; ps->sp_val; ps++) 116225705Sbloom if (ps->sp_name == speed) { 116325705Sbloom linebaudrate = ps->sp_val; 116425705Sbloom DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); 116525705Sbloom return; 116625705Sbloom } 1167*33948Srick if (linebaudrate < 0) { 1168*33948Srick syslog(LOG_ERR, "unrecognized speed: %d", linebaudrate); 1169*33948Srick cleanup(FAIL); 1170*33948Srick } 117125705Sbloom } 1172