148664Sbostic /*- 248664Sbostic * Copyright (c) 1985 The Regents of the University of California. 348664Sbostic * All rights reserved. 448664Sbostic * 548664Sbostic * %sccs.include.proprietary.c% 648664Sbostic */ 748664Sbostic 833581Srick #ifndef lint 9*60116Storek static char sccsid[] = "@(#)conn.c 5.18 (Berkeley) 05/17/93"; 1048664Sbostic #endif /* not lint */ 1113642Ssam 1223596Sbloom #include <signal.h> 1313642Ssam #include "uucp.h" 1413642Ssam #include <setjmp.h> 1513642Ssam #include <ctype.h> 1613642Ssam #include <errno.h> 1717834Sralph #ifdef USG 1813642Ssam #include <termio.h> 1913642Ssam #include <fcntl.h> 2013642Ssam #endif 2117834Sralph #ifndef USG 2213642Ssam #include <sgtty.h> 2313642Ssam #endif 2417834Sralph #ifdef BSD4_2 2517834Sralph #include <sys/time.h> 2617834Sralph #else 2717834Sralph #include <time.h> 2817834Sralph #endif 2913642Ssam 3013642Ssam #define MAXC 1000 3113642Ssam 3213642Ssam extern jmp_buf Sjbuf; 3317834Sralph jmp_buf Cjbuf; 3418619Sralph extern int errno, onesys; 35*60116Storek extern const char *const sys_errlist[]; 3618619Sralph extern char MaxGrade, DefMaxGrade; 3713642Ssam 3813642Ssam /* Parity control during login procedure */ 3913642Ssam #define P_ZERO 0 4013642Ssam #define P_ONE 1 4113642Ssam #define P_EVEN 2 4213642Ssam #define P_ODD 3 4317834Sralph 4417834Sralph #define ABORT -2 4517834Sralph 4617834Sralph char *AbortOn = NULL; 4713642Ssam char par_tab[128]; /* must be power of two */ 4817834Sralph int linebaudrate; /* used for the sleep test in pk1.c */ 4913642Ssam int next_fd = -1; /* predicted fd to close interrupted opens */ 5025705Sbloom 5125705Sbloom char *PCP = "PCP"; /* PC Pursuit device type */ 5225127Sbloom /* 5325127Sbloom * catch alarm routine for "expect". 5413642Ssam */ 5546879Sbostic void 5613642Ssam alarmtr() 5713642Ssam { 5813642Ssam signal(SIGALRM, alarmtr); 5913642Ssam if (next_fd >= 0) { 6013642Ssam if (close(next_fd)) 6113642Ssam logent("FAIL", "ACU LINE CLOSE"); 6213642Ssam next_fd = -1; 6313642Ssam } 6413642Ssam longjmp(Sjbuf, 1); 6513642Ssam } 6613642Ssam 6725705Sbloom /* This template is for seismo to call ihnp4 6825705Sbloom * the 3 lines marked ---> will be overwritten for the appropriate city 6925705Sbloom */ 7025705Sbloom #define PCP_BAUD 3 7125705Sbloom #define PCP_PHONE 4 7233562Srick #define PCP_CITY 14 7333562Srick #define PCP_PASSWORD 16 7433562Srick #define PCP_RPHONE 20 7533562Srick #define NPCFIELDS 23 7625705Sbloom 7725705Sbloom static char *PCFlds[] = { 7825705Sbloom "PC-PURSUIT", 7925705Sbloom "Any", 8025705Sbloom "ACU", 8125705Sbloom "1200", 8233562Srick CNULL, 8333562Srick CNULL, 8433562Srick "P_ZERO", /* Telenet insists on zero parity */ 8525705Sbloom "ABORT", 8633562Srick "BUSY", /* Abort on Busy Signal */ 8733562Srick CNULL, 8833562Srick "\\d\\d\\r\\d\\r", /* Get telenet's attention */ 8933562Srick "TERMINAL=~3-\r-TERM~3-\r-TERM~5", /* Terminal type ? */ 9033562Srick "\\r", 9133562Srick "@", /* telenet's prompt */ 9233562Srick "D/DCWAS/21,telenetloginstring", /* overwritten later */ 9333562Srick "PASSWORD", 9433562Srick CNULL, /* telenet password */ 9533562Srick "CONNECTED", /* We're now talking to a Hayes in the remote city */ 9633562Srick "ATZ", /* Reset it */ 9733562Srick "OK", 9833562Srick "ATDT6907171", /* overwritten */ 9933562Srick "CONNECT", 10033562Srick "\\d\\r", /* We're in !*/ 10133562Srick CNULL, 10225705Sbloom }; 10325705Sbloom 10433562Srick static char PCP_brand[25]; 10534167Srick int Dcf = -1; 10634167Srick char *Flds[MAXC/10]; 10734167Srick char LineType[10]; 10834167Srick extern int LocalOnly; 10925705Sbloom 11018619Sralph /* 11118619Sralph * place a telephone call to system and login, etc. 11213642Ssam * 11313642Ssam * return codes: 11413642Ssam * CF_SYSTEM: don't know system 11513642Ssam * CF_TIME: wrong time to call 11613642Ssam * CF_DIAL: call failed 11713642Ssam * CF_NODEV: no devices available to place call 11813642Ssam * CF_LOGIN: login/password dialog failed 11913642Ssam * 12013642Ssam * >0 - file no. - connect ok 12113642Ssam */ 12213642Ssam conn(system) 12313642Ssam char *system; 12413642Ssam { 12525705Sbloom int nf; 12618619Sralph char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE]; 12713642Ssam register FILE *fsys; 12813642Ssam int fcode = 0; 12913642Ssam 13013642Ssam nf = 0; 13113642Ssam 13213642Ssam fsys = fopen(SYSFILE, "r"); 13333948Srick if (fsys == NULL) { 13433948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", SYSFILE); 13533948Srick cleanup(FAIL); 13633948Srick } 13713642Ssam 13817834Sralph DEBUG(4, "finds (%s) called\n", system); 13925127Sbloom keeplooking: 14017834Sralph while((nf = finds(fsys, system, info, Flds)) > 0) { 14125966Sbloom strncpy(LineType, Flds[F_LINE], 10); 14217834Sralph if (LocalOnly) { 14325966Sbloom if (strcmp("TCP", LineType) 14425966Sbloom && strcmp("DIR", LineType) 14525966Sbloom && strcmp("LOCAL", LineType) ) { 14625705Sbloom fcode = CF_TIME; 14725705Sbloom continue; 14825705Sbloom } 14917834Sralph } 15023596Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 15118619Sralph if (!onesys && MaxGrade != DefMaxGrade && 15225705Sbloom !iswrk(file, "chk", Spool, wkpre)) { 15325705Sbloom fcode = CF_TIME; 15425705Sbloom continue; 15525705Sbloom } 15625705Sbloom /* For GTE's PC Pursuit */ 15725966Sbloom if (snccmp(LineType, PCP) == SAME) { 15825705Sbloom FILE *dfp; 15925705Sbloom int status; 16025705Sbloom static struct Devices dev; 16133562Srick 16225705Sbloom dfp = fopen(DEVFILE, "r"); 16333948Srick if (dfp == NULL) { 16433948Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 16533948Srick DEVFILE); 16633948Srick cleanup(FAIL); 16733948Srick } 16825705Sbloom while ((status=rddev(dfp, &dev)) != FAIL 16925705Sbloom && strcmp(PCP, dev.D_type) != SAME) 17025705Sbloom ; 17125705Sbloom fclose(dfp); 17225705Sbloom if (status == FAIL) 17325705Sbloom continue; 17425705Sbloom if (mlock(PCP) == FAIL) { 17525705Sbloom fcode = CF_NODEV; 17625705Sbloom logent("DEVICE", "NO"); 17725705Sbloom continue; 17825705Sbloom } 17925705Sbloom PCFlds[PCP_BAUD] = dev.D_class; 18025705Sbloom PCFlds[PCP_PHONE] = dev.D_calldev; 18133562Srick sprintf(PCFlds[PCP_CITY], "c d/%s%s,%s", 18233562Srick Flds[F_CLASS], 18333562Srick index(Flds[F_CLASS], '/') == NULL ? "/12" : "", 18433562Srick dev.D_arg[D_CHAT]); 18533562Srick PCFlds[PCP_PASSWORD] = dev.D_line; 18633562Srick strncpy(&PCFlds[PCP_RPHONE][4], Flds[F_PHONE], 7); 18725705Sbloom strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand)); 18833562Srick if ((fcode = getto(PCFlds)) < 0) { 18933562Srick rmlock(PCP); 19025705Sbloom continue; 19133562Srick } 19225705Sbloom Dcf = fcode; 19325705Sbloom fcode = login(NPCFIELDS, PCFlds, Dcf); 19433562Srick if (fcode == SUCCESS) 19533562Srick break; 19633562Srick fcode = CF_DIAL; 19733562Srick rmlock(PCP); 19833562Srick /* end PC Pursuit */ 19933562Srick } else if ((fcode = getto(Flds)) > 0) { 20033562Srick Dcf = fcode; 20113642Ssam break; 20233562Srick } 20313642Ssam } 20413642Ssam 20525127Sbloom if (nf <= 0) { 20625127Sbloom fclose(fsys); 20717834Sralph return fcode ? fcode : nf; 20825127Sbloom } 20913642Ssam 21025705Sbloom 21125705Sbloom if (fcode >= 0) { 21225705Sbloom DEBUG(4, "login %s\n", "called"); 21334167Srick setproctitle("login"); 21433562Srick fcode = login(nf, Flds, Dcf); } 21525705Sbloom if (fcode < 0) { 21613642Ssam clsacu(); 21725705Sbloom if (fcode == ABORT) { 21825127Sbloom fcode = CF_DIAL; 21925127Sbloom goto keeplooking; 22025127Sbloom } else { 22125127Sbloom fclose(fsys); 22223596Sbloom return CF_LOGIN; 22325127Sbloom } 22413642Ssam } 22525127Sbloom fclose(fsys); 22625705Sbloom fioclex(Dcf); 22725705Sbloom return Dcf; 22813642Ssam } 22913642Ssam 23034167Srick int nulldev(); 23134167Srick int (*CU_end)() = nulldev; 23234167Srick 23325127Sbloom /* 23425127Sbloom * connect to remote machine 23513642Ssam * 23613642Ssam * return codes: 23713642Ssam * >0 - file number - ok 23813642Ssam * FAIL - failed 23913642Ssam */ 24013642Ssam getto(flds) 24113642Ssam register char *flds[]; 24213642Ssam { 24313642Ssam register struct condev *cd; 24434094Sbostic int diropn(); 24525127Sbloom char *line; 24613642Ssam 24717834Sralph DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); 24813642Ssam DEBUG(4, "for sys %s\n", flds[F_NAME]); 24913642Ssam 25025127Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME) 25125127Sbloom line = "ACU"; 25225127Sbloom else 25325127Sbloom line = flds[F_LINE]; 25425127Sbloom #ifdef DIALINOUT 25525127Sbloom if (snccmp(line, "ACU") != SAME) 25625127Sbloom reenable(); 25725127Sbloom #endif DIALINOUT 25813642Ssam CU_end = nulldev; 25925705Sbloom if (snccmp(line, PCP) == SAME) { 26025705Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) { 26125705Sbloom if (snccmp(PCP_brand, cd->CU_brand) == SAME) { 26225705Sbloom CU_end = cd->CU_clos; 26325705Sbloom return diropn(flds); 26425705Sbloom } 26513642Ssam } 26625705Sbloom logent(PCP_brand, "UNSUPPORTED ACU TYPE"); 26725705Sbloom } else { 26825705Sbloom for (cd = condevs; cd->CU_meth != NULL; cd++) { 26925705Sbloom if (snccmp(cd->CU_meth, line) == SAME) { 27025705Sbloom DEBUG(4, "Using %s to call\n", cd->CU_meth); 27125705Sbloom return (*(cd->CU_gen))(flds); 27225705Sbloom } 27325705Sbloom } 27425705Sbloom DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); 27513642Ssam } 27617834Sralph return diropn(flds); /* search failed, so use direct */ 27717834Sralph } 27813642Ssam 27925127Sbloom /* 28025127Sbloom * close call unit 28113642Ssam * 28213642Ssam * return codes: none 28313642Ssam */ 28413642Ssam clsacu() 28513642Ssam { 28617834Sralph /* make *sure* Dcf is no longer exclusive. 28717834Sralph * Otherwise dual call-in/call-out modems could get stuck. 28817834Sralph * Unfortunately, doing this here is not ideal, but it is the 28917834Sralph * easiest place to put the call. 29017834Sralph * Hopefully everyone honors the LCK protocol, of course 29117834Sralph */ 29225705Sbloom #ifdef TIOCNXCL 29323596Sbloom if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) 29423596Sbloom DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); 29517834Sralph #endif 29617834Sralph if (setjmp(Sjbuf)) 29717834Sralph logent(Rmtname, "CLOSE TIMEOUT"); 29817834Sralph else { 29917834Sralph signal(SIGALRM, alarmtr); 30017834Sralph alarm(20); 30117834Sralph (*(CU_end))(Dcf); 30217834Sralph alarm(0); 30317834Sralph } 30413642Ssam if (close(Dcf) == 0) { 30513642Ssam DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); 30613642Ssam logent("clsacu", "NOT CLOSED by CU_clos"); 30713642Ssam } 30813642Ssam Dcf = -1; 30913642Ssam CU_end = nulldev; 31013642Ssam } 31113642Ssam 31225127Sbloom /* 31325127Sbloom * expand phone number for given prefix and number 31413642Ssam */ 31513642Ssam exphone(in, out) 31613642Ssam register char *in, *out; 31713642Ssam { 31813642Ssam FILE *fn; 31913642Ssam char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; 32013642Ssam char buf[BUFSIZ]; 32113642Ssam register char *s1; 32213642Ssam 32317834Sralph if (!isascii(*in) || !isalpha(*in)) { 32413642Ssam strcpy(out, in); 32513642Ssam return; 32613642Ssam } 32713642Ssam 32813642Ssam s1=pre; 32917834Sralph while (isascii(*in) && isalpha(*in)) 33013642Ssam *s1++ = *in++; 33113642Ssam *s1 = '\0'; 33213642Ssam s1 = npart; 33313642Ssam while (*in != '\0') 33413642Ssam *s1++ = *in++; 33513642Ssam *s1 = '\0'; 33613642Ssam 33713642Ssam tpre[0] = '\0'; 33813642Ssam if ((fn = fopen(DIALFILE, "r")) == NULL) 33913642Ssam DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); 34013642Ssam else { 34113642Ssam while (cfgets(buf, BUFSIZ, fn)) { 34217834Sralph if (sscanf(buf, "%s%s", p, tpre) != 2) 34317834Sralph continue; 34413642Ssam if (strcmp(p, pre) == SAME) 34513642Ssam goto found; 34613642Ssam tpre[0] = '\0'; 34713642Ssam } 34813642Ssam DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); 34913642Ssam found:; 35013642Ssam fclose(fn); 35113642Ssam } 35213642Ssam 35313642Ssam strcpy(out, tpre); 35413642Ssam strcat(out, npart); 35513642Ssam } 35613642Ssam 35718619Sralph /* 35818619Sralph * read and decode a line from device file 35913642Ssam * 36013642Ssam * return code - FAIL at end-of file; 0 otherwise 36113642Ssam */ 36213642Ssam rddev(fp, dev) 36313642Ssam register struct Devices *dev; 36413642Ssam FILE *fp; 36513642Ssam { 36617834Sralph register int na; 36713642Ssam 36817834Sralph if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) 36917834Sralph return FAIL; 37017834Sralph na = getargs(dev->D_argbfr, dev->D_arg, 20); 37133948Srick if (na < 4) { 37233948Srick syslog(LOG_ERR, "%s: invalid device entry", dev->D_argbfr); 37333948Srick cleanup(FAIL); 37433948Srick } 37517834Sralph if (na == 4) { 37617834Sralph dev->D_brand = ""; 37717834Sralph na++; 37817834Sralph } 37913642Ssam dev->D_speed = atoi(fdig(dev->D_class)); 38017834Sralph dev->D_numargs = na; 38117834Sralph return 0; 38213642Ssam } 38313642Ssam 38418619Sralph /* 38518619Sralph * set system attribute vector 38613642Ssam * 38713642Ssam * return codes: 38813642Ssam * >0 - number of arguments in vector - succeeded 38913642Ssam * CF_SYSTEM - system name not found 39013642Ssam * CF_TIME - wrong time to call 39113642Ssam */ 39213642Ssam finds(fsys, sysnam, info, flds) 39313642Ssam char *sysnam, info[], *flds[]; 39413642Ssam FILE *fsys; 39513642Ssam { 39613642Ssam int na; 39713642Ssam int fcode = 0; 39813642Ssam 39913642Ssam /* format of fields 40013642Ssam * 0 name; 40113642Ssam * 1 time 40213642Ssam * 2 acu/hardwired 40313642Ssam * 3 speed 40413642Ssam * etc 40513642Ssam */ 40613642Ssam while (cfgets(info, MAXC, fsys) != NULL) { 40717834Sralph na = getargs(info, flds, MAXC/10); 40823596Sbloom if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) 40913642Ssam continue; 41018619Sralph if (ifdate(flds[F_TIME]) != FAIL) 41113642Ssam /* found a good entry */ 41217834Sralph return na; 41313642Ssam DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); 41413642Ssam fcode = CF_TIME; 41513642Ssam } 41617834Sralph return fcode ? fcode : CF_SYSTEM; 41713642Ssam } 41813642Ssam 41918619Sralph /* 42018619Sralph * do login conversation 42113642Ssam * 42223596Sbloom * return codes: SUCCESS | FAIL 42313642Ssam */ 42413642Ssam login(nf, flds, fn) 42513642Ssam register char *flds[]; 42613642Ssam int nf, fn; 42713642Ssam { 42813642Ssam register char *want, *altern; 42913642Ssam int k, ok; 43013642Ssam 43133948Srick if (nf < 4) { 43233948Srick syslog(LOG_ERR, "Too few log fields: %d", nf); 43333948Srick cleanup(FAIL); 43433948Srick } 43517834Sralph if (setjmp(Cjbuf)) 43617834Sralph return FAIL; 43717834Sralph AbortOn = NULL; 43813642Ssam for (k = F_LOGIN; k < nf; k += 2) { 43913642Ssam want = flds[k]; 44033562Srick if (want == NULL) 44133562Srick want = ""; 44213642Ssam ok = FAIL; 44317834Sralph while (ok != SUCCESS) { 44413642Ssam altern = index(want, '-'); 44513642Ssam if (altern != NULL) 44613642Ssam *altern++ = '\0'; 44717834Sralph if (strcmp(want, "ABORT") == 0) { 44817834Sralph AbortOn = flds[k+1]; 44917834Sralph DEBUG(4, "ABORT ON: %s\n", AbortOn); 45017834Sralph goto nextfield; 45117834Sralph } 45225705Sbloom DEBUG(4, "wanted \"%s\"\n", want); 45313642Ssam ok = expect(want, fn); 45417834Sralph DEBUG(4, "got: %s\n", ok ? "?" : "that"); 45517834Sralph if (ok == FAIL) { 45617834Sralph if (altern == NULL) { 45717834Sralph logent("LOGIN", _FAILED); 45817834Sralph return FAIL; 45917834Sralph } 46017834Sralph want = index(altern, '-'); 46117834Sralph if (want != NULL) 46217834Sralph *want++ = '\0'; 46317834Sralph sendthem(altern, fn); 46417834Sralph } else 46517834Sralph if (ok == ABORT) { 46633562Srick char sbuf[MAXFULLNAME]; 46733562Srick sprintf(sbuf, "LOGIN ABORTED on \"%s\"", AbortOn); 46833562Srick logent(sbuf, _FAILED); 46923596Sbloom return ABORT; 47017834Sralph } 47113642Ssam } 47217834Sralph sleep(1); 47313642Ssam if (k+1 < nf) 47413642Ssam sendthem(flds[k+1], fn); 47517834Sralph nextfield: ; 47613642Ssam } 47717834Sralph return SUCCESS; 47813642Ssam } 47913642Ssam 48013642Ssam 48117834Sralph /* conditional table generation to support odd speeds */ 48213642Ssam struct sg_spds {int sp_val, sp_name;} spds[] = { 48313642Ssam #ifdef B50 48413642Ssam { 50, B50}, 48513642Ssam #endif 48613642Ssam #ifdef B75 48713642Ssam { 75, B75}, 48813642Ssam #endif 48913642Ssam #ifdef B110 49013642Ssam { 110, B110}, 49113642Ssam #endif 49213642Ssam #ifdef B150 49313642Ssam { 150, B150}, 49413642Ssam #endif 49513642Ssam #ifdef B200 49613642Ssam { 200, B200}, 49713642Ssam #endif 49813642Ssam #ifdef B300 49913642Ssam { 300, B300}, 50013642Ssam #endif 50113642Ssam #ifdef B600 50213642Ssam {600, B600}, 50313642Ssam #endif 50413642Ssam #ifdef B1200 50513642Ssam {1200, B1200}, 50613642Ssam #endif 50713642Ssam #ifdef B1800 50813642Ssam {1800, B1800}, 50913642Ssam #endif 51013642Ssam #ifdef B2000 51113642Ssam {2000, B2000}, 51213642Ssam #endif 51313642Ssam #ifdef B2400 51413642Ssam {2400, B2400}, 51513642Ssam #endif 51613642Ssam #ifdef B3600 51713642Ssam {3600, B3600}, 51813642Ssam #endif 51913642Ssam #ifdef B4800 52013642Ssam {4800, B4800}, 52113642Ssam #endif 52213642Ssam #ifdef B7200 52313642Ssam {7200, B7200}, 52413642Ssam #endif 52513642Ssam #ifdef B9600 52613642Ssam {9600, B9600}, 52713642Ssam #endif 52813642Ssam #ifdef B19200 52917834Sralph {19200, B19200}, 53013642Ssam #endif 53117834Sralph #ifdef EXTA 53217834Sralph {19200, EXTA}, 53317834Sralph #endif 53413642Ssam {0, 0} 53513642Ssam }; 53613642Ssam 53718619Sralph /* 53818619Sralph * set speed/echo/mode... 53913642Ssam * 54013642Ssam * return codes: none 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 expect(str, fn) 60213642Ssam register char *str; 60313642Ssam int fn; 60413642Ssam { 60514592Skarels char rdvec[MR]; 60617834Sralph register char *rp = rdvec, *strptr; 60717834Sralph int kr, cnt_char; 60813642Ssam char nextch; 60925127Sbloom int timo = MAXMSGTIME; 61013642Ssam 61117834Sralph if (*str == '\0' || strcmp(str, "\"\"") == SAME) 61217834Sralph return SUCCESS; 61317834Sralph /* Cleanup str, convert \0xx strings to one char */ 61417834Sralph for (strptr = str; *strptr; strptr++) { 61517834Sralph if (*strptr == '\\') 61617834Sralph switch(*++strptr) { 61717834Sralph case 's': 61817834Sralph DEBUG(5, "BLANK\n", CNULL); 61934167Srick strptr--; 62017834Sralph *strptr = ' '; 62134167Srick strcpy(&strptr[1], &strptr[4]); 62217834Sralph break; 62317834Sralph default: 62417834Sralph strptr--; /* back up to backslash */ 62517834Sralph sscanf(strptr + 1,"%o", &cnt_char); 62617834Sralph DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); 62717834Sralph *strptr = (char) (cnt_char); 62817834Sralph strcpy(&strptr[1], &strptr[4]); 62917834Sralph } 63017834Sralph } 63117834Sralph 63225127Sbloom strptr = index(str, '~'); 63325127Sbloom if (strptr != NULL) { 63425127Sbloom *strptr++ = '\0'; 63525127Sbloom timo = atoi(strptr); 63625127Sbloom if (timo <= 0) 63725127Sbloom timo = MAXMSGTIME; 63825127Sbloom } 63925127Sbloom 64017834Sralph if (setjmp(Sjbuf)) 64117834Sralph return FAIL; 64213642Ssam signal(SIGALRM, alarmtr); 64325127Sbloom alarm(timo); 64425127Sbloom *rp = 0; 64513642Ssam while (notin(str, rdvec)) { 64625705Sbloom int c; 64717834Sralph if(AbortOn != NULL && !notin(AbortOn, rdvec)) { 64817834Sralph DEBUG(1, "Call aborted on '%s'\n", AbortOn); 64917834Sralph alarm(0); 65017834Sralph return ABORT; 65117834Sralph } 65213642Ssam kr = read(fn, &nextch, 1); 65313642Ssam if (kr <= 0) { 65413642Ssam alarm(0); 65513642Ssam DEBUG(4, "lost line kr - %d\n, ", kr); 65613642Ssam logent("LOGIN", "LOST LINE"); 65717834Sralph return FAIL; 65813642Ssam } 65913642Ssam c = nextch & 0177; 66025705Sbloom if (c == '\0') 66125705Sbloom continue; 66225705Sbloom DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); 66325705Sbloom *rp++ = c; 66413642Ssam if (rp >= rdvec + MR) { 66517834Sralph register char *p; 66617834Sralph for (p = rdvec+MR/2; p < rp; p++) 66717834Sralph *(p-MR/2) = *p; 66817834Sralph rp -= MR/2; 66913642Ssam } 67013642Ssam *rp = '\0'; 67113642Ssam } 67213642Ssam alarm(0); 67317834Sralph return SUCCESS; 67413642Ssam } 67513642Ssam 67613642Ssam 67713642Ssam /* 67813642Ssam * Determine next file descriptor that would be allocated. 67913642Ssam * This permits later closing of a file whose open was interrupted. 68013642Ssam * It is a UNIX kernel problem, but it has to be handled. 68113642Ssam * unc!smb (Steve Bellovin) probably first discovered it. 68213642Ssam */ 68313642Ssam getnextfd() 68413642Ssam { 68513642Ssam close(next_fd = open("/", 0)); 68613642Ssam } 68713642Ssam 68817834Sralph /* 68917834Sralph * send line of login sequence 69013642Ssam * 69113642Ssam * return codes: none 69213642Ssam */ 69313642Ssam sendthem(str, fn) 69413642Ssam register char *str; 69513642Ssam int fn; 69613642Ssam { 69713642Ssam register char *strptr; 69813642Ssam int i, n, cr = 1; 69917834Sralph register char c; 70013642Ssam static int p_init = 0; 70113642Ssam 70225705Sbloom DEBUG(5, "send \"%s\"\n", str); 70313642Ssam 70413642Ssam if (!p_init) { 70513642Ssam p_init++; 70633948Srick bld_partab(P_ZERO); 70713642Ssam } 70813642Ssam 70913642Ssam if (prefix("BREAK", str)) { 71013642Ssam sscanf(&str[5], "%1d", &i); 71113642Ssam if (i <= 0 || i > 10) 71213642Ssam i = 3; 71313642Ssam /* send break */ 71413642Ssam genbrk(fn, i); 71513642Ssam return; 71613642Ssam } 71713642Ssam 71813642Ssam if (prefix("PAUSE", str)) { 71913642Ssam sscanf(&str[5], "%1d", &i); 72013642Ssam if (i <= 0 || i > 10) 72113642Ssam i = 3; 72213642Ssam /* pause for a while */ 72313642Ssam sleep((unsigned)i); 72413642Ssam return; 72513642Ssam } 72613642Ssam 72713642Ssam if (strcmp(str, "EOT") == SAME) { 72813642Ssam p_chwrite(fn, '\04'); 72913642Ssam return; 73013642Ssam } 73113642Ssam 73213642Ssam /* Send a '\n' */ 73325705Sbloom if (strcmp(str, "LF") == SAME) { 73425705Sbloom p_chwrite(fn, '\n'); 73525705Sbloom return; 73625705Sbloom } 73713642Ssam 73813642Ssam /* Send a '\r' */ 73925705Sbloom if (strcmp(str, "CR") == SAME) { 74025705Sbloom p_chwrite(fn, '\r'); 74125705Sbloom return; 74225705Sbloom } 74313642Ssam 74413642Ssam /* Set parity as needed */ 74513642Ssam if (strcmp(str, "P_ZERO") == SAME) { 74613642Ssam bld_partab(P_ZERO); 74713642Ssam return; 74813642Ssam } 74913642Ssam if (strcmp(str, "P_ONE") == SAME) { 75013642Ssam bld_partab(P_ONE); 75113642Ssam return; 75213642Ssam } 75313642Ssam if (strcmp(str, "P_EVEN") == SAME) { 75413642Ssam bld_partab(P_EVEN); 75513642Ssam return; 75613642Ssam } 75713642Ssam if (strcmp(str, "P_ODD") == SAME) { 75813642Ssam bld_partab(P_ODD); 75913642Ssam return; 76013642Ssam } 76113642Ssam 76213642Ssam /* If "", just send '\r' */ 76317834Sralph if (strcmp(str, "\"\"") == SAME) { 76417834Sralph p_chwrite(fn, '\r'); 76517834Sralph return; 76617834Sralph } 76717834Sralph 76825705Sbloom strptr = str; 76925705Sbloom while ((c = *strptr++) != '\0') { 77017834Sralph if (c == '\\') { 77117834Sralph switch(*strptr++) { 77225705Sbloom case '\0': 77325705Sbloom DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); 77425705Sbloom --strptr; 77525705Sbloom continue; 77617834Sralph case 's': 77717834Sralph DEBUG(5, "BLANK\n", CNULL); 77825705Sbloom c = ' '; 77917834Sralph break; 78017834Sralph case 'd': 78117834Sralph DEBUG(5, "DELAY\n", CNULL); 78217834Sralph sleep(1); 78317834Sralph continue; 78425705Sbloom case 'n': 78525705Sbloom DEBUG(5, "NEW LINE\n", CNULL); 78625705Sbloom c = '\n'; 78725705Sbloom break; 78817834Sralph case 'r': 78917834Sralph DEBUG(5, "RETURN\n", CNULL); 79025705Sbloom c = '\r'; 79117834Sralph break; 79217834Sralph case 'b': 79317834Sralph if (isdigit(*strptr)) { 79417834Sralph i = (*strptr++ - '0'); 79517834Sralph if (i <= 0 || i > 10) 79617834Sralph i = 3; 79717834Sralph } else 79813642Ssam i = 3; 79917834Sralph /* send break */ 80017834Sralph genbrk(fn, i); 80117834Sralph if (*strptr == '\0') 80217834Sralph cr = 0; 80313642Ssam continue; 80417834Sralph case 'c': 80517834Sralph if (*strptr == '\0') { 80617834Sralph DEBUG(5, "NO CR\n", CNULL); 80717834Sralph cr = 0; 80825705Sbloom } else 80925705Sbloom DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); 81013642Ssam continue; 81125705Sbloom #define isoctal(x) ((x >= '0') && (x <= '7')) 81217834Sralph default: 81325705Sbloom if (isoctal(strptr[-1])) { 81417834Sralph i = 0; 81517834Sralph n = 0; 81625705Sbloom --strptr; 81725705Sbloom while (isoctal(*strptr) && ++n <= 3) 81825705Sbloom i = i * 8 + (*strptr++ - '0'); 81925705Sbloom DEBUG(5, "\\%o\n", i); 82017834Sralph p_chwrite(fn, (char)i); 82117834Sralph continue; 82217834Sralph } 82313642Ssam } 82425705Sbloom } 82525705Sbloom p_chwrite(fn, c); 82613642Ssam } 82713642Ssam 82813642Ssam if (cr) 82913642Ssam p_chwrite(fn, '\r'); 83013642Ssam return; 83113642Ssam } 83213642Ssam 83313642Ssam p_chwrite(fd, c) 83413642Ssam int fd; 83517834Sralph char c; 83613642Ssam { 83717834Sralph c = par_tab[c&0177]; 83817834Sralph if (write(fd, &c, 1) != 1) { 83917834Sralph logent(sys_errlist[errno], "BAD WRITE"); 84017834Sralph longjmp(Cjbuf, 2); 84117834Sralph } 84213642Ssam } 84313642Ssam 84413642Ssam /* 84513642Ssam * generate parity table for use by p_chwrite. 84613642Ssam */ 84713642Ssam bld_partab(type) 84813642Ssam int type; 84913642Ssam { 85013642Ssam register int i, j, n; 85113642Ssam 85213642Ssam for (i = 0; i < sizeof(par_tab); i++) { 85313642Ssam n = 0; 85413642Ssam for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) 85513642Ssam n++; 85613642Ssam par_tab[i] = i; 85713642Ssam if (type == P_ONE 85813642Ssam || (type == P_EVEN && (n&01) != 0) 85913642Ssam || (type == P_ODD && (n&01) == 0)) 86013642Ssam par_tab[i] |= sizeof(par_tab); 86113642Ssam } 86213642Ssam } 86313642Ssam 86418619Sralph /* 86518619Sralph * check for occurrence of substring "sh" 86613642Ssam * 86713642Ssam * return codes: 86813642Ssam * 0 - found the string 86913642Ssam * 1 - not in the string 87013642Ssam */ 87113642Ssam notin(sh, lg) 87213642Ssam register char *sh, *lg; 87313642Ssam { 87413642Ssam while (*lg != '\0') { 87513642Ssam if (wprefix(sh, lg)) 87618619Sralph return 0; 87713642Ssam else 87813642Ssam lg++; 87913642Ssam } 88018619Sralph return 1; 88113642Ssam } 88213642Ssam 88318619Sralph /* 88423596Sbloom * Allow multiple date specifications separated by ','. 88513642Ssam */ 88618619Sralph ifdate(p) 88718619Sralph register char *p; 88813642Ssam { 88925705Sbloom register char *np; 89018619Sralph register int ret, g; 89123596Sbloom int rtime, i; 89213642Ssam 89323596Sbloom /* pick up retry time for failures */ 89423596Sbloom /* global variable Retrytime is set here */ 89523596Sbloom if ((np = index(p, ';')) == NULL) { 89623596Sbloom Retrytime = RETRYTIME; 89723596Sbloom } else { 89823596Sbloom i = sscanf(np+1, "%d", &rtime); 89923596Sbloom if (i < 1 || rtime < 0) 90023596Sbloom rtime = 5; 90123596Sbloom Retrytime = rtime * 60; 90223596Sbloom } 90323596Sbloom 90418619Sralph ret = FAIL; 90518619Sralph MaxGrade = '\0'; 90618619Sralph do { 90723596Sbloom np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ 90823596Sbloom if (np) 90923596Sbloom *np = '\0'; 91018619Sralph g = ifadate(p); 91118619Sralph DEBUG(11,"ifadate returns %o\n", g); 91218619Sralph if (g != FAIL) { 91318619Sralph ret = SUCCESS; 91418619Sralph if (g > MaxGrade) 91518619Sralph MaxGrade = g; 91618619Sralph } 91723596Sbloom if (np) 91823596Sbloom *np = ','; 91923596Sbloom p = np + 1; 92023596Sbloom } while (np); 92123596Sbloom if (MaxGrade == '\0') 92223596Sbloom MaxGrade = DefMaxGrade; 92318619Sralph return ret; 92413642Ssam } 92513642Ssam 92618619Sralph /* 92718619Sralph * this routine will check a string (string) 92813642Ssam * like "MoTu0800-1730" to see if the present 92913642Ssam * time is within the given limits. 93013642Ssam * SIDE EFFECT - Retrytime is set 93113642Ssam * 93213642Ssam * return codes: 93313642Ssam * 0 - not within limits 93413642Ssam * 1 - within limits 93513642Ssam */ 93613642Ssam 93718619Sralph ifadate(string) 93818619Sralph char *string; 93913642Ssam { 94013642Ssam static char *days[]={ 94113642Ssam "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 94213642Ssam }; 94313642Ssam time_t clock; 94418619Sralph register char *s = string; 94517834Sralph int i, tl, th, tn, dayok=0; 94613642Ssam struct tm *localtime(); 94713642Ssam struct tm *tp; 94818619Sralph char *p, MGrade; 94913642Ssam 95023596Sbloom if ((p = index(s, '/')) == NULL) 95118619Sralph MGrade = DefMaxGrade; 95218619Sralph else 95318619Sralph MGrade = p[1]; 95418619Sralph 95513642Ssam time(&clock); 95613642Ssam tp = localtime(&clock); 95717834Sralph while (isascii(*s) && isalpha(*s)) { 95813642Ssam for (i = 0; days[i]; i++) { 95913642Ssam if (prefix(days[i], s)) 96013642Ssam if (tp->tm_wday == i) 96113642Ssam dayok = 1; 96213642Ssam } 96313642Ssam 96413642Ssam if (prefix("Wk", s)) 96513642Ssam if (tp->tm_wday >= 1 && tp->tm_wday <= 5) 96613642Ssam dayok = 1; 96713642Ssam if (prefix("Any", s)) 96813642Ssam dayok = 1; 96917834Sralph if (prefix("Evening", s)) { 97017834Sralph /* Sat or Sun */ 97117834Sralph if (tp->tm_wday == 6 || tp->tm_wday == 0 97217834Sralph || tp->tm_hour >= 17 || tp->tm_hour < 8) 97317834Sralph dayok = 1; 97417834Sralph } 97517834Sralph if (prefix("Night", s)) { 97617834Sralph if (tp->tm_wday == 6 /* Sat */ 97718619Sralph || tp->tm_hour >= 23 || tp->tm_hour < 8 97818619Sralph /* Sunday before 5pm */ 97918619Sralph || (tp->tm_wday == 0 && tp->tm_hour < 17)) 98017834Sralph dayok = 1; 98117834Sralph } 98225705Sbloom if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ 98325705Sbloom /* Sat or Sun */ 98425705Sbloom if (tp->tm_wday == 6 || tp->tm_wday == 0 98525705Sbloom || tp->tm_hour >= 18 || tp->tm_hour < 7) 98625705Sbloom dayok = 1; 98725705Sbloom } 98813642Ssam s++; 98913642Ssam } 99013642Ssam 99118619Sralph if (dayok == 0 && s != string) 99218619Sralph return FAIL; 99313642Ssam i = sscanf(s, "%d-%d", &tl, &th); 99418619Sralph if (i < 2) 99518619Sralph return MGrade; 99618619Sralph tn = tp->tm_hour * 100 + tp->tm_min; 99718619Sralph if (th < tl) { /* crosses midnight */ 99818619Sralph if (tl <= tn || tn < th) 99918619Sralph return MGrade; 100025966Sbloom } else { 100117834Sralph if (tl <= tn && tn < th) 100218619Sralph return MGrade; 100325966Sbloom } 100418619Sralph return FAIL; 100513642Ssam } 100613642Ssam 100718619Sralph /* 100818619Sralph * find first digit in string 100913642Ssam * 101013642Ssam * return - pointer to first digit in string or end of string 101113642Ssam */ 101213642Ssam char * 101313642Ssam fdig(cp) 101413642Ssam register char *cp; 101513642Ssam { 101613642Ssam register char *c; 101713642Ssam 101813642Ssam for (c = cp; *c; c++) 101913642Ssam if (*c >= '0' && *c <= '9') 102013642Ssam break; 102117834Sralph return c; 102213642Ssam } 102313642Ssam 102413642Ssam /* 102513642Ssam * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 102613642Ssam * Strings are compared as if they contain all capital letters. 102713642Ssam */ 102813642Ssam snccmp(s1, s2) 102913642Ssam register char *s1, *s2; 103013642Ssam { 103113642Ssam char c1, c2; 103213642Ssam 103325127Sbloom if (islower(*s1)) 103425127Sbloom c1 = toupper(*s1); 103525127Sbloom else 103625127Sbloom c1 = *s1; 103725127Sbloom if (islower(*s2)) 103825127Sbloom c2 = toupper(*s2); 103925127Sbloom else 104025127Sbloom c2 = *s2; 104113642Ssam 104213642Ssam while (c1 == c2) { 104325127Sbloom if (*s1++ == '\0') 104417834Sralph return 0; 104513642Ssam s2++; 104625127Sbloom if (islower(*s1)) 104725127Sbloom c1 = toupper(*s1); 104825127Sbloom else 104925127Sbloom c1 = *s1; 105025127Sbloom if (islower(*s2)) 105125127Sbloom c2 = toupper(*s2); 105225127Sbloom else 105325127Sbloom c2 = *s2; 105413642Ssam } 105517834Sralph return c1 - c2; 105613642Ssam } 105725127Sbloom 105817834Sralph /* 105925127Sbloom * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 106025127Sbloom * Strings are compared as if they contain all capital letters. 106125127Sbloom */ 106225127Sbloom sncncmp(s1, s2, n) 106325127Sbloom register char *s1, *s2; 106425127Sbloom register int n; 106525127Sbloom { 106625127Sbloom char c1, c2; 106725127Sbloom 106825127Sbloom if (islower(*s1)) 106925127Sbloom c1 = toupper(*s1); 107025127Sbloom else 107125127Sbloom c1 = *s1; 107225127Sbloom if (islower(*s2)) 107325127Sbloom c2 = toupper(*s2); 107425127Sbloom else 107525127Sbloom c2 = *s2; 107625127Sbloom 107725127Sbloom while ( --n >= 0 && c1 == c2) { 107825127Sbloom if (*s1++ == '\0') 107925127Sbloom return 0; 108025127Sbloom s2++; 108125127Sbloom if (islower(*s1)) 108225127Sbloom c1 = toupper(*s1); 108325127Sbloom else 108425127Sbloom c1 = *s1; 108525127Sbloom if (islower(*s2)) 108625127Sbloom c2 = toupper(*s2); 108725127Sbloom else 108825127Sbloom c2 = *s2; 108925127Sbloom } 109025127Sbloom return n<0 ? 0 : (c1 - c2); 109125127Sbloom } 109225127Sbloom /* 109317834Sralph * do chat script 109417834Sralph * occurs after local port is opened, 109517834Sralph * before 'dialing' the other machine. 109617834Sralph */ 109717834Sralph dochat(dev, flds, fd) 109817834Sralph register struct Devices *dev; 109917834Sralph char *flds[]; 110017834Sralph int fd; 110117834Sralph { 110217834Sralph register int i; 110317834Sralph register char *p; 110417834Sralph char bfr[sizeof(dev->D_argbfr)]; 110517834Sralph 110617834Sralph if (dev->D_numargs <= 5) 110717834Sralph return(0); 110817834Sralph DEBUG(4, "dochat called %d\n", dev->D_numargs); 110917834Sralph for (i = 0; i < dev->D_numargs-5; i++) { 111017834Sralph sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); 111117834Sralph if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { 111217834Sralph p = malloc((unsigned)strlen(bfr)+1); 111317834Sralph if (p != NULL) { 111417834Sralph strcpy(p, bfr); 111517834Sralph dev->D_arg[D_CHAT+i] = p; 111617834Sralph } 111717834Sralph } 111817834Sralph } 111917834Sralph /* following is a kludge because login() arglist is a kludge */ 112017834Sralph i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); 112117834Sralph /* 112217834Sralph * If login() last did a sendthem(), must pause so things can settle. 112317834Sralph * But don't bother if chat failed. 112417834Sralph */ 112517834Sralph if (i == 0 && (dev->D_numargs&01)) 112617834Sralph sleep(2); 112717834Sralph return(i); 112817834Sralph } 112925705Sbloom 113025705Sbloom /* 113125705Sbloom * fix kill/echo/raw on line 113225705Sbloom * 113325705Sbloom * return codes: none 113425705Sbloom */ 113525705Sbloom fixmode(tty) 113625705Sbloom register int tty; 113725705Sbloom { 113825705Sbloom #ifdef USG 113925705Sbloom struct termio ttbuf; 114025705Sbloom #else !USG 114125705Sbloom struct sgttyb ttbuf; 114225705Sbloom #endif !USG 114325705Sbloom register struct sg_spds *ps; 114425705Sbloom int speed; 114525705Sbloom 114625705Sbloom if (IsTcpIp) 114725705Sbloom return; 114825705Sbloom #ifdef USG 114925705Sbloom ioctl(tty, TCGETA, &ttbuf); 115025705Sbloom ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 115125705Sbloom speed = ttbuf.c_cflag &= (CBAUD); 115225705Sbloom ttbuf.c_cflag |= (CS8|CREAD); 115325705Sbloom ttbuf.c_cc[VMIN] = 6; 115425705Sbloom ttbuf.c_cc[VTIME] = 1; 115525705Sbloom ioctl(tty, TCSETA, &ttbuf); 115625705Sbloom #else !USG 115725705Sbloom ioctl(tty, TIOCGETP, &ttbuf); 115825705Sbloom ttbuf.sg_flags = (ANYP | RAW); 115925705Sbloom ioctl(tty, TIOCSETP, &ttbuf); 116025705Sbloom speed = ttbuf.sg_ispeed; 116125705Sbloom ioctl(tty, TIOCEXCL, STBNULL); 116225705Sbloom #endif !USG 116325705Sbloom 116425705Sbloom for (ps = spds; ps->sp_val; ps++) 116525705Sbloom if (ps->sp_name == speed) { 116625705Sbloom linebaudrate = ps->sp_val; 116725705Sbloom DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); 116825705Sbloom return; 116925705Sbloom } 117033948Srick if (linebaudrate < 0) { 117133948Srick syslog(LOG_ERR, "unrecognized speed: %d", linebaudrate); 117233948Srick cleanup(FAIL); 117333948Srick } 117425705Sbloom } 1175