133581Srick #ifndef lint 2*34094Sbostic static char sccsid[] = "@(#)conn.c 5.14 (Berkeley) 04/24/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"); 12733948Srick if (fsys == NULL) { 12833948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", SYSFILE); 12933948Srick cleanup(FAIL); 13033948Srick } 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"); 15733948Srick if (dfp == NULL) { 15833948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 15933948Srick DEVFILE); 16033948Srick cleanup(FAIL); 16133948Srick } 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 231*34094Sbostic int nulldev(); 232*34094Sbostic 23313642Ssam getto(flds) 23413642Ssam register char *flds[]; 23513642Ssam { 23613642Ssam register struct condev *cd; 237*34094Sbostic int diropn(); 23825127Sbloom char *line; 23913642Ssam 24017834Sralph DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); 24113642Ssam DEBUG(4, "for sys %s\n", flds[F_NAME]); 24213642Ssam 24325127Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME) 24425127Sbloom line = "ACU"; 24525127Sbloom else 24625127Sbloom line = flds[F_LINE]; 24725127Sbloom #ifdef DIALINOUT 24825127Sbloom if (snccmp(line, "ACU") != SAME) 24925127Sbloom reenable(); 25025127Sbloom #endif DIALINOUT 25113642Ssam CU_end = nulldev; 25225705Sbloom if (snccmp(line, PCP) == SAME) { 25325705Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) { 25425705Sbloom if (snccmp(PCP_brand, cd->CU_brand) == SAME) { 25525705Sbloom CU_end = cd->CU_clos; 25625705Sbloom return diropn(flds); 25725705Sbloom } 25813642Ssam } 25925705Sbloom logent(PCP_brand, "UNSUPPORTED ACU TYPE"); 26025705Sbloom } else { 26125705Sbloom for (cd = condevs; cd->CU_meth != NULL; cd++) { 26225705Sbloom if (snccmp(cd->CU_meth, line) == SAME) { 26325705Sbloom DEBUG(4, "Using %s to call\n", cd->CU_meth); 26425705Sbloom return (*(cd->CU_gen))(flds); 26525705Sbloom } 26625705Sbloom } 26725705Sbloom DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); 26813642Ssam } 26917834Sralph return diropn(flds); /* search failed, so use direct */ 27017834Sralph } 27113642Ssam 27225127Sbloom /* 27325127Sbloom * close call unit 27413642Ssam * 27513642Ssam * return codes: none 27613642Ssam */ 27713642Ssam 27813642Ssam int (*CU_end)() = nulldev; 27913642Ssam clsacu() 28013642Ssam { 28117834Sralph /* make *sure* Dcf is no longer exclusive. 28217834Sralph * Otherwise dual call-in/call-out modems could get stuck. 28317834Sralph * Unfortunately, doing this here is not ideal, but it is the 28417834Sralph * easiest place to put the call. 28517834Sralph * Hopefully everyone honors the LCK protocol, of course 28617834Sralph */ 28725705Sbloom #ifdef TIOCNXCL 28823596Sbloom if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) 28923596Sbloom DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); 29017834Sralph #endif 29117834Sralph if (setjmp(Sjbuf)) 29217834Sralph logent(Rmtname, "CLOSE TIMEOUT"); 29317834Sralph else { 29417834Sralph signal(SIGALRM, alarmtr); 29517834Sralph alarm(20); 29617834Sralph (*(CU_end))(Dcf); 29717834Sralph alarm(0); 29817834Sralph } 29913642Ssam if (close(Dcf) == 0) { 30013642Ssam DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); 30113642Ssam logent("clsacu", "NOT CLOSED by CU_clos"); 30213642Ssam } 30313642Ssam Dcf = -1; 30413642Ssam CU_end = nulldev; 30513642Ssam } 30613642Ssam 30725127Sbloom /* 30825127Sbloom * expand phone number for given prefix and number 30913642Ssam */ 31013642Ssam 31113642Ssam exphone(in, out) 31213642Ssam register char *in, *out; 31313642Ssam { 31413642Ssam FILE *fn; 31513642Ssam char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; 31613642Ssam char buf[BUFSIZ]; 31713642Ssam register char *s1; 31813642Ssam 31917834Sralph if (!isascii(*in) || !isalpha(*in)) { 32013642Ssam strcpy(out, in); 32113642Ssam return; 32213642Ssam } 32313642Ssam 32413642Ssam s1=pre; 32517834Sralph while (isascii(*in) && isalpha(*in)) 32613642Ssam *s1++ = *in++; 32713642Ssam *s1 = '\0'; 32813642Ssam s1 = npart; 32913642Ssam while (*in != '\0') 33013642Ssam *s1++ = *in++; 33113642Ssam *s1 = '\0'; 33213642Ssam 33313642Ssam tpre[0] = '\0'; 33413642Ssam if ((fn = fopen(DIALFILE, "r")) == NULL) 33513642Ssam DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); 33613642Ssam else { 33713642Ssam while (cfgets(buf, BUFSIZ, fn)) { 33817834Sralph if (sscanf(buf, "%s%s", p, tpre) != 2) 33917834Sralph continue; 34013642Ssam if (strcmp(p, pre) == SAME) 34113642Ssam goto found; 34213642Ssam tpre[0] = '\0'; 34313642Ssam } 34413642Ssam DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); 34513642Ssam found:; 34613642Ssam fclose(fn); 34713642Ssam } 34813642Ssam 34913642Ssam strcpy(out, tpre); 35013642Ssam strcat(out, npart); 35113642Ssam } 35213642Ssam 35318619Sralph /* 35418619Sralph * read and decode a line from device file 35513642Ssam * 35613642Ssam * return code - FAIL at end-of file; 0 otherwise 35713642Ssam */ 35813642Ssam 35913642Ssam rddev(fp, dev) 36013642Ssam register struct Devices *dev; 36113642Ssam FILE *fp; 36213642Ssam { 36317834Sralph register int na; 36413642Ssam 36517834Sralph if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) 36617834Sralph return FAIL; 36717834Sralph na = getargs(dev->D_argbfr, dev->D_arg, 20); 36833948Srick if (na < 4) { 36933948Srick syslog(LOG_ERR, "%s: invalid device entry", dev->D_argbfr); 37033948Srick cleanup(FAIL); 37133948Srick } 37217834Sralph if (na == 4) { 37317834Sralph dev->D_brand = ""; 37417834Sralph na++; 37517834Sralph } 37613642Ssam dev->D_speed = atoi(fdig(dev->D_class)); 37717834Sralph dev->D_numargs = na; 37817834Sralph return 0; 37913642Ssam } 38013642Ssam 38118619Sralph /* 38218619Sralph * set system attribute vector 38313642Ssam * 38413642Ssam * return codes: 38513642Ssam * >0 - number of arguments in vector - succeeded 38613642Ssam * CF_SYSTEM - system name not found 38713642Ssam * CF_TIME - wrong time to call 38813642Ssam */ 38913642Ssam 39013642Ssam finds(fsys, sysnam, info, flds) 39113642Ssam char *sysnam, info[], *flds[]; 39213642Ssam FILE *fsys; 39313642Ssam { 39413642Ssam int na; 39513642Ssam int fcode = 0; 39613642Ssam 39713642Ssam /* format of fields 39813642Ssam * 0 name; 39913642Ssam * 1 time 40013642Ssam * 2 acu/hardwired 40113642Ssam * 3 speed 40213642Ssam * etc 40313642Ssam */ 40413642Ssam while (cfgets(info, MAXC, fsys) != NULL) { 40517834Sralph na = getargs(info, flds, MAXC/10); 40623596Sbloom if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) 40713642Ssam continue; 40818619Sralph if (ifdate(flds[F_TIME]) != FAIL) 40913642Ssam /* found a good entry */ 41017834Sralph return na; 41113642Ssam DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); 41213642Ssam fcode = CF_TIME; 41313642Ssam } 41417834Sralph return fcode ? fcode : CF_SYSTEM; 41513642Ssam } 41613642Ssam 41718619Sralph /* 41818619Sralph * do login conversation 41913642Ssam * 42023596Sbloom * return codes: SUCCESS | FAIL 42113642Ssam */ 42213642Ssam 42313642Ssam login(nf, flds, fn) 42413642Ssam register char *flds[]; 42513642Ssam int nf, fn; 42613642Ssam { 42713642Ssam register char *want, *altern; 42813642Ssam int k, ok; 42913642Ssam 43033948Srick if (nf < 4) { 43133948Srick syslog(LOG_ERR, "Too few log fields: %d", nf); 43233948Srick cleanup(FAIL); 43333948Srick } 43417834Sralph if (setjmp(Cjbuf)) 43517834Sralph return FAIL; 43617834Sralph AbortOn = NULL; 43713642Ssam for (k = F_LOGIN; k < nf; k += 2) { 43813642Ssam want = flds[k]; 43933562Srick if (want == NULL) 44033562Srick want = ""; 44113642Ssam ok = FAIL; 44217834Sralph while (ok != SUCCESS) { 44313642Ssam altern = index(want, '-'); 44413642Ssam if (altern != NULL) 44513642Ssam *altern++ = '\0'; 44617834Sralph if (strcmp(want, "ABORT") == 0) { 44717834Sralph AbortOn = flds[k+1]; 44817834Sralph DEBUG(4, "ABORT ON: %s\n", AbortOn); 44917834Sralph goto nextfield; 45017834Sralph } 45125705Sbloom DEBUG(4, "wanted \"%s\"\n", want); 45213642Ssam ok = expect(want, fn); 45317834Sralph DEBUG(4, "got: %s\n", ok ? "?" : "that"); 45417834Sralph if (ok == FAIL) { 45517834Sralph if (altern == NULL) { 45617834Sralph logent("LOGIN", _FAILED); 45717834Sralph return FAIL; 45817834Sralph } 45917834Sralph want = index(altern, '-'); 46017834Sralph if (want != NULL) 46117834Sralph *want++ = '\0'; 46217834Sralph sendthem(altern, fn); 46317834Sralph } else 46417834Sralph if (ok == ABORT) { 46533562Srick char sbuf[MAXFULLNAME]; 46633562Srick sprintf(sbuf, "LOGIN ABORTED on \"%s\"", AbortOn); 46733562Srick logent(sbuf, _FAILED); 46823596Sbloom return ABORT; 46917834Sralph } 47013642Ssam } 47117834Sralph sleep(1); 47213642Ssam if (k+1 < nf) 47313642Ssam sendthem(flds[k+1], fn); 47417834Sralph nextfield: ; 47513642Ssam } 47617834Sralph return SUCCESS; 47713642Ssam } 47813642Ssam 47913642Ssam 48017834Sralph /* conditional table generation to support odd speeds */ 48113642Ssam struct sg_spds {int sp_val, sp_name;} spds[] = { 48213642Ssam #ifdef B50 48313642Ssam { 50, B50}, 48413642Ssam #endif 48513642Ssam #ifdef B75 48613642Ssam { 75, B75}, 48713642Ssam #endif 48813642Ssam #ifdef B110 48913642Ssam { 110, B110}, 49013642Ssam #endif 49113642Ssam #ifdef B150 49213642Ssam { 150, B150}, 49313642Ssam #endif 49413642Ssam #ifdef B200 49513642Ssam { 200, B200}, 49613642Ssam #endif 49713642Ssam #ifdef B300 49813642Ssam { 300, B300}, 49913642Ssam #endif 50013642Ssam #ifdef B600 50113642Ssam {600, B600}, 50213642Ssam #endif 50313642Ssam #ifdef B1200 50413642Ssam {1200, B1200}, 50513642Ssam #endif 50613642Ssam #ifdef B1800 50713642Ssam {1800, B1800}, 50813642Ssam #endif 50913642Ssam #ifdef B2000 51013642Ssam {2000, B2000}, 51113642Ssam #endif 51213642Ssam #ifdef B2400 51313642Ssam {2400, B2400}, 51413642Ssam #endif 51513642Ssam #ifdef B3600 51613642Ssam {3600, B3600}, 51713642Ssam #endif 51813642Ssam #ifdef B4800 51913642Ssam {4800, B4800}, 52013642Ssam #endif 52113642Ssam #ifdef B7200 52213642Ssam {7200, B7200}, 52313642Ssam #endif 52413642Ssam #ifdef B9600 52513642Ssam {9600, B9600}, 52613642Ssam #endif 52713642Ssam #ifdef B19200 52817834Sralph {19200, B19200}, 52913642Ssam #endif 53017834Sralph #ifdef EXTA 53117834Sralph {19200, EXTA}, 53217834Sralph #endif 53313642Ssam {0, 0} 53413642Ssam }; 53513642Ssam 53618619Sralph /* 53718619Sralph * set speed/echo/mode... 53813642Ssam * 53913642Ssam * return codes: none 54013642Ssam */ 54113642Ssam 54213642Ssam fixline(tty, spwant) 54313642Ssam int tty, spwant; 54413642Ssam { 54517834Sralph #ifdef USG 54613642Ssam struct termio ttbuf; 54717834Sralph #else !USG 54813642Ssam struct sgttyb ttbuf; 54917834Sralph #endif !USG 55013642Ssam register struct sg_spds *ps; 55113642Ssam int speed = -1; 55213642Ssam 55313642Ssam for (ps = spds; ps->sp_val; ps++) 55413642Ssam if (ps->sp_val == spwant) 55513642Ssam speed = ps->sp_name; 55633948Srick if (speed < 0) { 55733948Srick syslog(LOG_ERR, "unrecognized speed: %d", speed); 55833948Srick cleanup(FAIL); 55933948Srick } 56017834Sralph #ifdef USG 56123596Sbloom if (ioctl(tty, TCGETA, &ttbuf) < 0) 56223596Sbloom return FAIL; 56313642Ssam /* ttbuf.sg_flags = (ANYP|RAW); 56413642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ 56513642Ssam ttbuf.c_iflag = (ushort)0; 56613642Ssam ttbuf.c_oflag = (ushort)0; 56713642Ssam ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); 56813642Ssam ttbuf.c_lflag = (ushort)0; 56913642Ssam ttbuf.c_cc[VMIN] = 6; 57013642Ssam ttbuf.c_cc[VTIME] = 1; 57123596Sbloom if (ioctl(tty, TCSETA, &ttbuf) < 0) 57223596Sbloom return FAIL; 57317834Sralph #else !USG 57423596Sbloom if (ioctl(tty, TIOCGETP, &ttbuf) < 0) 57523596Sbloom return FAIL; 57613642Ssam ttbuf.sg_flags = (ANYP|RAW); 57713642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; 57823596Sbloom if (ioctl(tty, TIOCSETP, &ttbuf) < 0) 57923596Sbloom return FAIL; 58013642Ssam #endif 58117834Sralph #ifndef USG 58223596Sbloom if (ioctl(tty, TIOCHPCL, STBNULL) < 0) 58323596Sbloom return FAIL; 58423596Sbloom if (ioctl(tty, TIOCEXCL, STBNULL) < 0) 58523596Sbloom return FAIL; 58613642Ssam #endif 58717834Sralph linebaudrate = spwant; 58823596Sbloom return SUCCESS; 58913642Ssam } 59013642Ssam 59117834Sralph #define MR 100 59213642Ssam 59318619Sralph /* 59418619Sralph * look for expected string 59513642Ssam * 59613642Ssam * return codes: 59713642Ssam * 0 - found 59813642Ssam * FAIL - lost line or too many characters read 59913642Ssam * some character - timed out 60013642Ssam */ 60113642Ssam 60213642Ssam expect(str, fn) 60313642Ssam register char *str; 60413642Ssam int fn; 60513642Ssam { 60614592Skarels char rdvec[MR]; 60717834Sralph register char *rp = rdvec, *strptr; 60817834Sralph int kr, cnt_char; 60913642Ssam char nextch; 61025127Sbloom int timo = MAXMSGTIME; 61113642Ssam 61217834Sralph if (*str == '\0' || strcmp(str, "\"\"") == SAME) 61317834Sralph return SUCCESS; 61417834Sralph /* Cleanup str, convert \0xx strings to one char */ 61517834Sralph for (strptr = str; *strptr; strptr++) { 61617834Sralph if (*strptr == '\\') 61717834Sralph switch(*++strptr) { 61817834Sralph case 's': 61917834Sralph DEBUG(5, "BLANK\n", CNULL); 62017834Sralph *strptr = ' '; 62117834Sralph break; 62217834Sralph default: 62317834Sralph strptr--; /* back up to backslash */ 62417834Sralph sscanf(strptr + 1,"%o", &cnt_char); 62517834Sralph DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); 62617834Sralph *strptr = (char) (cnt_char); 62717834Sralph strcpy(&strptr[1], &strptr[4]); 62817834Sralph } 62917834Sralph } 63017834Sralph 63125127Sbloom strptr = index(str, '~'); 63225127Sbloom if (strptr != NULL) { 63325127Sbloom *strptr++ = '\0'; 63425127Sbloom timo = atoi(strptr); 63525127Sbloom if (timo <= 0) 63625127Sbloom timo = MAXMSGTIME; 63725127Sbloom } 63825127Sbloom 63917834Sralph if (setjmp(Sjbuf)) 64017834Sralph return FAIL; 64113642Ssam signal(SIGALRM, alarmtr); 64225127Sbloom alarm(timo); 64325127Sbloom *rp = 0; 64413642Ssam while (notin(str, rdvec)) { 64525705Sbloom int c; 64617834Sralph if(AbortOn != NULL && !notin(AbortOn, rdvec)) { 64717834Sralph DEBUG(1, "Call aborted on '%s'\n", AbortOn); 64817834Sralph alarm(0); 64917834Sralph return ABORT; 65017834Sralph } 65113642Ssam kr = read(fn, &nextch, 1); 65213642Ssam if (kr <= 0) { 65313642Ssam alarm(0); 65413642Ssam DEBUG(4, "lost line kr - %d\n, ", kr); 65513642Ssam logent("LOGIN", "LOST LINE"); 65617834Sralph return FAIL; 65713642Ssam } 65813642Ssam c = nextch & 0177; 65925705Sbloom if (c == '\0') 66025705Sbloom continue; 66125705Sbloom DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); 66225705Sbloom *rp++ = c; 66313642Ssam if (rp >= rdvec + MR) { 66417834Sralph register char *p; 66517834Sralph for (p = rdvec+MR/2; p < rp; p++) 66617834Sralph *(p-MR/2) = *p; 66717834Sralph rp -= MR/2; 66813642Ssam } 66913642Ssam *rp = '\0'; 67013642Ssam } 67113642Ssam alarm(0); 67217834Sralph return SUCCESS; 67313642Ssam } 67413642Ssam 67513642Ssam 67613642Ssam /* 67713642Ssam * Determine next file descriptor that would be allocated. 67813642Ssam * This permits later closing of a file whose open was interrupted. 67913642Ssam * It is a UNIX kernel problem, but it has to be handled. 68013642Ssam * unc!smb (Steve Bellovin) probably first discovered it. 68113642Ssam */ 68213642Ssam getnextfd() 68313642Ssam { 68413642Ssam close(next_fd = open("/", 0)); 68513642Ssam } 68613642Ssam 68717834Sralph /* 68817834Sralph * send line of login sequence 68913642Ssam * 69013642Ssam * return codes: none 69113642Ssam */ 69213642Ssam sendthem(str, fn) 69313642Ssam register char *str; 69413642Ssam int fn; 69513642Ssam { 69613642Ssam register char *strptr; 69713642Ssam int i, n, cr = 1; 69817834Sralph register char c; 69913642Ssam static int p_init = 0; 70013642Ssam 70125705Sbloom DEBUG(5, "send \"%s\"\n", str); 70213642Ssam 70313642Ssam if (!p_init) { 70413642Ssam p_init++; 70533948Srick bld_partab(P_ZERO); 70613642Ssam } 70713642Ssam 70813642Ssam if (prefix("BREAK", str)) { 70913642Ssam sscanf(&str[5], "%1d", &i); 71013642Ssam if (i <= 0 || i > 10) 71113642Ssam i = 3; 71213642Ssam /* send break */ 71313642Ssam genbrk(fn, i); 71413642Ssam return; 71513642Ssam } 71613642Ssam 71713642Ssam if (prefix("PAUSE", str)) { 71813642Ssam sscanf(&str[5], "%1d", &i); 71913642Ssam if (i <= 0 || i > 10) 72013642Ssam i = 3; 72113642Ssam /* pause for a while */ 72213642Ssam sleep((unsigned)i); 72313642Ssam return; 72413642Ssam } 72513642Ssam 72613642Ssam if (strcmp(str, "EOT") == SAME) { 72713642Ssam p_chwrite(fn, '\04'); 72813642Ssam return; 72913642Ssam } 73013642Ssam 73113642Ssam /* Send a '\n' */ 73225705Sbloom if (strcmp(str, "LF") == SAME) { 73325705Sbloom p_chwrite(fn, '\n'); 73425705Sbloom return; 73525705Sbloom } 73613642Ssam 73713642Ssam /* Send a '\r' */ 73825705Sbloom if (strcmp(str, "CR") == SAME) { 73925705Sbloom p_chwrite(fn, '\r'); 74025705Sbloom return; 74125705Sbloom } 74213642Ssam 74313642Ssam /* Set parity as needed */ 74413642Ssam if (strcmp(str, "P_ZERO") == SAME) { 74513642Ssam bld_partab(P_ZERO); 74613642Ssam return; 74713642Ssam } 74813642Ssam if (strcmp(str, "P_ONE") == SAME) { 74913642Ssam bld_partab(P_ONE); 75013642Ssam return; 75113642Ssam } 75213642Ssam if (strcmp(str, "P_EVEN") == SAME) { 75313642Ssam bld_partab(P_EVEN); 75413642Ssam return; 75513642Ssam } 75613642Ssam if (strcmp(str, "P_ODD") == SAME) { 75713642Ssam bld_partab(P_ODD); 75813642Ssam return; 75913642Ssam } 76013642Ssam 76113642Ssam /* If "", just send '\r' */ 76217834Sralph if (strcmp(str, "\"\"") == SAME) { 76317834Sralph p_chwrite(fn, '\r'); 76417834Sralph return; 76517834Sralph } 76617834Sralph 76725705Sbloom strptr = str; 76825705Sbloom while ((c = *strptr++) != '\0') { 76917834Sralph if (c == '\\') { 77017834Sralph switch(*strptr++) { 77125705Sbloom case '\0': 77225705Sbloom DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); 77325705Sbloom --strptr; 77425705Sbloom continue; 77517834Sralph case 's': 77617834Sralph DEBUG(5, "BLANK\n", CNULL); 77725705Sbloom c = ' '; 77817834Sralph break; 77917834Sralph case 'd': 78017834Sralph DEBUG(5, "DELAY\n", CNULL); 78117834Sralph sleep(1); 78217834Sralph continue; 78325705Sbloom case 'n': 78425705Sbloom DEBUG(5, "NEW LINE\n", CNULL); 78525705Sbloom c = '\n'; 78625705Sbloom break; 78717834Sralph case 'r': 78817834Sralph DEBUG(5, "RETURN\n", CNULL); 78925705Sbloom c = '\r'; 79017834Sralph break; 79117834Sralph case 'b': 79217834Sralph if (isdigit(*strptr)) { 79317834Sralph i = (*strptr++ - '0'); 79417834Sralph if (i <= 0 || i > 10) 79517834Sralph i = 3; 79617834Sralph } else 79713642Ssam i = 3; 79817834Sralph /* send break */ 79917834Sralph genbrk(fn, i); 80017834Sralph if (*strptr == '\0') 80117834Sralph cr = 0; 80213642Ssam continue; 80317834Sralph case 'c': 80417834Sralph if (*strptr == '\0') { 80517834Sralph DEBUG(5, "NO CR\n", CNULL); 80617834Sralph cr = 0; 80725705Sbloom } else 80825705Sbloom DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); 80913642Ssam continue; 81025705Sbloom #define isoctal(x) ((x >= '0') && (x <= '7')) 81117834Sralph default: 81225705Sbloom if (isoctal(strptr[-1])) { 81317834Sralph i = 0; 81417834Sralph n = 0; 81525705Sbloom --strptr; 81625705Sbloom while (isoctal(*strptr) && ++n <= 3) 81725705Sbloom i = i * 8 + (*strptr++ - '0'); 81825705Sbloom DEBUG(5, "\\%o\n", i); 81917834Sralph p_chwrite(fn, (char)i); 82017834Sralph continue; 82117834Sralph } 82213642Ssam } 82325705Sbloom } 82425705Sbloom p_chwrite(fn, c); 82513642Ssam } 82613642Ssam 82713642Ssam if (cr) 82813642Ssam p_chwrite(fn, '\r'); 82913642Ssam return; 83013642Ssam } 83113642Ssam 83213642Ssam p_chwrite(fd, c) 83313642Ssam int fd; 83417834Sralph char c; 83513642Ssam { 83617834Sralph c = par_tab[c&0177]; 83717834Sralph if (write(fd, &c, 1) != 1) { 83817834Sralph logent(sys_errlist[errno], "BAD WRITE"); 83917834Sralph longjmp(Cjbuf, 2); 84017834Sralph } 84113642Ssam } 84213642Ssam 84313642Ssam /* 84413642Ssam * generate parity table for use by p_chwrite. 84513642Ssam */ 84613642Ssam bld_partab(type) 84713642Ssam int type; 84813642Ssam { 84913642Ssam register int i, j, n; 85013642Ssam 85113642Ssam for (i = 0; i < sizeof(par_tab); i++) { 85213642Ssam n = 0; 85313642Ssam for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) 85413642Ssam n++; 85513642Ssam par_tab[i] = i; 85613642Ssam if (type == P_ONE 85713642Ssam || (type == P_EVEN && (n&01) != 0) 85813642Ssam || (type == P_ODD && (n&01) == 0)) 85913642Ssam par_tab[i] |= sizeof(par_tab); 86013642Ssam } 86113642Ssam } 86213642Ssam 86318619Sralph /* 86418619Sralph * check for occurrence of substring "sh" 86513642Ssam * 86613642Ssam * return codes: 86713642Ssam * 0 - found the string 86813642Ssam * 1 - not in the string 86913642Ssam */ 87013642Ssam notin(sh, lg) 87113642Ssam register char *sh, *lg; 87213642Ssam { 87313642Ssam while (*lg != '\0') { 87413642Ssam if (wprefix(sh, lg)) 87518619Sralph return 0; 87613642Ssam else 87713642Ssam lg++; 87813642Ssam } 87918619Sralph return 1; 88013642Ssam } 88113642Ssam 88218619Sralph /* 88323596Sbloom * Allow multiple date specifications separated by ','. 88413642Ssam */ 88518619Sralph ifdate(p) 88618619Sralph register char *p; 88713642Ssam { 88825705Sbloom register char *np; 88918619Sralph register int ret, g; 89023596Sbloom int rtime, i; 89113642Ssam 89223596Sbloom /* pick up retry time for failures */ 89323596Sbloom /* global variable Retrytime is set here */ 89423596Sbloom if ((np = index(p, ';')) == NULL) { 89523596Sbloom Retrytime = RETRYTIME; 89623596Sbloom } else { 89723596Sbloom i = sscanf(np+1, "%d", &rtime); 89823596Sbloom if (i < 1 || rtime < 0) 89923596Sbloom rtime = 5; 90023596Sbloom Retrytime = rtime * 60; 90123596Sbloom } 90223596Sbloom 90318619Sralph ret = FAIL; 90418619Sralph MaxGrade = '\0'; 90518619Sralph do { 90623596Sbloom np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ 90723596Sbloom if (np) 90823596Sbloom *np = '\0'; 90918619Sralph g = ifadate(p); 91018619Sralph DEBUG(11,"ifadate returns %o\n", g); 91118619Sralph if (g != FAIL) { 91218619Sralph ret = SUCCESS; 91318619Sralph if (g > MaxGrade) 91418619Sralph MaxGrade = g; 91518619Sralph } 91623596Sbloom if (np) 91723596Sbloom *np = ','; 91823596Sbloom p = np + 1; 91923596Sbloom } while (np); 92023596Sbloom if (MaxGrade == '\0') 92123596Sbloom MaxGrade = DefMaxGrade; 92218619Sralph return ret; 92313642Ssam } 92413642Ssam 92518619Sralph /* 92618619Sralph * this routine will check a string (string) 92713642Ssam * like "MoTu0800-1730" to see if the present 92813642Ssam * time is within the given limits. 92913642Ssam * SIDE EFFECT - Retrytime is set 93013642Ssam * 93113642Ssam * return codes: 93213642Ssam * 0 - not within limits 93313642Ssam * 1 - within limits 93413642Ssam */ 93513642Ssam 93618619Sralph ifadate(string) 93718619Sralph char *string; 93813642Ssam { 93913642Ssam static char *days[]={ 94013642Ssam "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 94113642Ssam }; 94213642Ssam time_t clock; 94318619Sralph register char *s = string; 94417834Sralph int i, tl, th, tn, dayok=0; 94513642Ssam struct tm *localtime(); 94613642Ssam struct tm *tp; 94718619Sralph char *p, MGrade; 94813642Ssam 94923596Sbloom if ((p = index(s, '/')) == NULL) 95018619Sralph MGrade = DefMaxGrade; 95118619Sralph else 95218619Sralph MGrade = p[1]; 95318619Sralph 95413642Ssam time(&clock); 95513642Ssam tp = localtime(&clock); 95617834Sralph while (isascii(*s) && isalpha(*s)) { 95713642Ssam for (i = 0; days[i]; i++) { 95813642Ssam if (prefix(days[i], s)) 95913642Ssam if (tp->tm_wday == i) 96013642Ssam dayok = 1; 96113642Ssam } 96213642Ssam 96313642Ssam if (prefix("Wk", s)) 96413642Ssam if (tp->tm_wday >= 1 && tp->tm_wday <= 5) 96513642Ssam dayok = 1; 96613642Ssam if (prefix("Any", s)) 96713642Ssam dayok = 1; 96817834Sralph if (prefix("Evening", s)) { 96917834Sralph /* Sat or Sun */ 97017834Sralph if (tp->tm_wday == 6 || tp->tm_wday == 0 97117834Sralph || tp->tm_hour >= 17 || tp->tm_hour < 8) 97217834Sralph dayok = 1; 97317834Sralph } 97417834Sralph if (prefix("Night", s)) { 97517834Sralph if (tp->tm_wday == 6 /* Sat */ 97618619Sralph || tp->tm_hour >= 23 || tp->tm_hour < 8 97718619Sralph /* Sunday before 5pm */ 97818619Sralph || (tp->tm_wday == 0 && tp->tm_hour < 17)) 97917834Sralph dayok = 1; 98017834Sralph } 98125705Sbloom if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ 98225705Sbloom /* Sat or Sun */ 98325705Sbloom if (tp->tm_wday == 6 || tp->tm_wday == 0 98425705Sbloom || tp->tm_hour >= 18 || tp->tm_hour < 7) 98525705Sbloom dayok = 1; 98625705Sbloom } 98713642Ssam s++; 98813642Ssam } 98913642Ssam 99018619Sralph if (dayok == 0 && s != string) 99118619Sralph return FAIL; 99213642Ssam i = sscanf(s, "%d-%d", &tl, &th); 99318619Sralph if (i < 2) 99418619Sralph return MGrade; 99518619Sralph tn = tp->tm_hour * 100 + tp->tm_min; 99618619Sralph if (th < tl) { /* crosses midnight */ 99718619Sralph if (tl <= tn || tn < th) 99818619Sralph return MGrade; 99925966Sbloom } else { 100017834Sralph if (tl <= tn && tn < th) 100118619Sralph return MGrade; 100225966Sbloom } 100318619Sralph return FAIL; 100413642Ssam } 100513642Ssam 100618619Sralph /* 100718619Sralph * find first digit in string 100813642Ssam * 100913642Ssam * return - pointer to first digit in string or end of string 101013642Ssam */ 101113642Ssam char * 101213642Ssam fdig(cp) 101313642Ssam register char *cp; 101413642Ssam { 101513642Ssam register char *c; 101613642Ssam 101713642Ssam for (c = cp; *c; c++) 101813642Ssam if (*c >= '0' && *c <= '9') 101913642Ssam break; 102017834Sralph return c; 102113642Ssam } 102213642Ssam 102313642Ssam /* 102413642Ssam * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 102513642Ssam * Strings are compared as if they contain all capital letters. 102613642Ssam */ 102713642Ssam snccmp(s1, s2) 102813642Ssam register char *s1, *s2; 102913642Ssam { 103013642Ssam char c1, c2; 103113642Ssam 103225127Sbloom if (islower(*s1)) 103325127Sbloom c1 = toupper(*s1); 103425127Sbloom else 103525127Sbloom c1 = *s1; 103625127Sbloom if (islower(*s2)) 103725127Sbloom c2 = toupper(*s2); 103825127Sbloom else 103925127Sbloom c2 = *s2; 104013642Ssam 104113642Ssam while (c1 == c2) { 104225127Sbloom if (*s1++ == '\0') 104317834Sralph return 0; 104413642Ssam s2++; 104525127Sbloom if (islower(*s1)) 104625127Sbloom c1 = toupper(*s1); 104725127Sbloom else 104825127Sbloom c1 = *s1; 104925127Sbloom if (islower(*s2)) 105025127Sbloom c2 = toupper(*s2); 105125127Sbloom else 105225127Sbloom c2 = *s2; 105313642Ssam } 105417834Sralph return c1 - c2; 105513642Ssam } 105625127Sbloom 105717834Sralph /* 105825127Sbloom * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 105925127Sbloom * Strings are compared as if they contain all capital letters. 106025127Sbloom */ 106125127Sbloom sncncmp(s1, s2, n) 106225127Sbloom register char *s1, *s2; 106325127Sbloom register int n; 106425127Sbloom { 106525127Sbloom char c1, c2; 106625127Sbloom 106725127Sbloom if (islower(*s1)) 106825127Sbloom c1 = toupper(*s1); 106925127Sbloom else 107025127Sbloom c1 = *s1; 107125127Sbloom if (islower(*s2)) 107225127Sbloom c2 = toupper(*s2); 107325127Sbloom else 107425127Sbloom c2 = *s2; 107525127Sbloom 107625127Sbloom while ( --n >= 0 && c1 == c2) { 107725127Sbloom if (*s1++ == '\0') 107825127Sbloom return 0; 107925127Sbloom s2++; 108025127Sbloom if (islower(*s1)) 108125127Sbloom c1 = toupper(*s1); 108225127Sbloom else 108325127Sbloom c1 = *s1; 108425127Sbloom if (islower(*s2)) 108525127Sbloom c2 = toupper(*s2); 108625127Sbloom else 108725127Sbloom c2 = *s2; 108825127Sbloom } 108925127Sbloom return n<0 ? 0 : (c1 - c2); 109025127Sbloom } 109125127Sbloom /* 109217834Sralph * do chat script 109317834Sralph * occurs after local port is opened, 109417834Sralph * before 'dialing' the other machine. 109517834Sralph */ 109617834Sralph dochat(dev, flds, fd) 109717834Sralph register struct Devices *dev; 109817834Sralph char *flds[]; 109917834Sralph int fd; 110017834Sralph { 110117834Sralph register int i; 110217834Sralph register char *p; 110317834Sralph char bfr[sizeof(dev->D_argbfr)]; 110417834Sralph 110517834Sralph if (dev->D_numargs <= 5) 110617834Sralph return(0); 110717834Sralph DEBUG(4, "dochat called %d\n", dev->D_numargs); 110817834Sralph for (i = 0; i < dev->D_numargs-5; i++) { 110917834Sralph sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); 111017834Sralph if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { 111117834Sralph p = malloc((unsigned)strlen(bfr)+1); 111217834Sralph if (p != NULL) { 111317834Sralph strcpy(p, bfr); 111417834Sralph dev->D_arg[D_CHAT+i] = p; 111517834Sralph } 111617834Sralph } 111717834Sralph } 111817834Sralph /* following is a kludge because login() arglist is a kludge */ 111917834Sralph i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); 112017834Sralph /* 112117834Sralph * If login() last did a sendthem(), must pause so things can settle. 112217834Sralph * But don't bother if chat failed. 112317834Sralph */ 112417834Sralph if (i == 0 && (dev->D_numargs&01)) 112517834Sralph sleep(2); 112617834Sralph return(i); 112717834Sralph } 112825705Sbloom 112925705Sbloom /* 113025705Sbloom * fix kill/echo/raw on line 113125705Sbloom * 113225705Sbloom * return codes: none 113325705Sbloom */ 113425705Sbloom fixmode(tty) 113525705Sbloom register int tty; 113625705Sbloom { 113725705Sbloom #ifdef USG 113825705Sbloom struct termio ttbuf; 113925705Sbloom #else !USG 114025705Sbloom struct sgttyb ttbuf; 114125705Sbloom #endif !USG 114225705Sbloom register struct sg_spds *ps; 114325705Sbloom int speed; 114425705Sbloom 114525705Sbloom if (IsTcpIp) 114625705Sbloom return; 114725705Sbloom #ifdef USG 114825705Sbloom ioctl(tty, TCGETA, &ttbuf); 114925705Sbloom ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 115025705Sbloom speed = ttbuf.c_cflag &= (CBAUD); 115125705Sbloom ttbuf.c_cflag |= (CS8|CREAD); 115225705Sbloom ttbuf.c_cc[VMIN] = 6; 115325705Sbloom ttbuf.c_cc[VTIME] = 1; 115425705Sbloom ioctl(tty, TCSETA, &ttbuf); 115525705Sbloom #else !USG 115625705Sbloom ioctl(tty, TIOCGETP, &ttbuf); 115725705Sbloom ttbuf.sg_flags = (ANYP | RAW); 115825705Sbloom ioctl(tty, TIOCSETP, &ttbuf); 115925705Sbloom speed = ttbuf.sg_ispeed; 116025705Sbloom ioctl(tty, TIOCEXCL, STBNULL); 116125705Sbloom #endif !USG 116225705Sbloom 116325705Sbloom for (ps = spds; ps->sp_val; ps++) 116425705Sbloom if (ps->sp_name == speed) { 116525705Sbloom linebaudrate = ps->sp_val; 116625705Sbloom DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); 116725705Sbloom return; 116825705Sbloom } 116933948Srick if (linebaudrate < 0) { 117033948Srick syslog(LOG_ERR, "unrecognized speed: %d", linebaudrate); 117133948Srick cleanup(FAIL); 117233948Srick } 117325705Sbloom } 1174