113642Ssam #ifndef lint 2*25705Sbloom static char sccsid[] = "@(#)conn.c 5.9 (Berkeley) 01/06/86"; 313642Ssam #endif 413642Ssam 523596Sbloom #include <signal.h> 613642Ssam #include "uucp.h" 713642Ssam #include <setjmp.h> 813642Ssam #include <ctype.h> 913642Ssam #include <errno.h> 1017834Sralph #ifdef USG 1113642Ssam #include <termio.h> 1213642Ssam #include <fcntl.h> 1313642Ssam #endif 1417834Sralph #ifndef USG 1513642Ssam #include <sgtty.h> 1613642Ssam #endif 1717834Sralph #ifdef BSD4_2 1817834Sralph #include <sys/time.h> 1917834Sralph #else 2017834Sralph #include <time.h> 2117834Sralph #endif 2213642Ssam 2313642Ssam #define MAXC 1000 2413642Ssam 2513642Ssam extern jmp_buf Sjbuf; 2617834Sralph jmp_buf Cjbuf; 2718619Sralph extern int errno, onesys; 2817834Sralph extern char *sys_errlist[]; 2918619Sralph extern char MaxGrade, DefMaxGrade; 3013642Ssam 3113642Ssam /* Parity control during login procedure */ 3213642Ssam #define P_ZERO 0 3313642Ssam #define P_ONE 1 3413642Ssam #define P_EVEN 2 3513642Ssam #define P_ODD 3 3617834Sralph 3717834Sralph #define ABORT -2 3817834Sralph 3917834Sralph char *AbortOn = NULL; 4013642Ssam char par_tab[128]; /* must be power of two */ 4117834Sralph int linebaudrate; /* used for the sleep test in pk1.c */ 4213642Ssam int next_fd = -1; /* predicted fd to close interrupted opens */ 43*25705Sbloom 44*25705Sbloom 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 59*25705Sbloom /* This template is for seismo to call ihnp4 60*25705Sbloom * the 3 lines marked ---> will be overwritten for the appropriate city 61*25705Sbloom */ 62*25705Sbloom #define PCP_BAUD 3 63*25705Sbloom #define PCP_PHONE 4 64*25705Sbloom #define PCP_CALLBACK 8 65*25705Sbloom #define PCP_CITY 10 66*25705Sbloom #define PCP_RPHONE 12 67*25705Sbloom #define NPCFIELDS 15 68*25705Sbloom 69*25705Sbloom static char *PCFlds[] = { 70*25705Sbloom "PC-PURSUIT", 71*25705Sbloom "Any", 72*25705Sbloom "ACU", 73*25705Sbloom "1200", 74*25705Sbloom CNULL, /* <--- **** Welcome to Telenet PC Pursuit ***** */ 75*25705Sbloom "ABORT", 76*25705Sbloom "Good", /* Abort of Good bye! */ 77*25705Sbloom ")", /* <--- Enter your 7-digit phone number (xxx-xxxx) */ 78*25705Sbloom CNULL, /* ---> 528-1234 */ 79*25705Sbloom "call?", /* <--- Which city do you wish to call? */ 80*25705Sbloom CNULL, /* ---> CHICAGO */ 81*25705Sbloom ")", /* <--- Enter the phone number you wish to call (xxx-xxxx) */ 82*25705Sbloom CNULL, /* ---> 690-7171 */ 83*25705Sbloom "R)?", /* <--- You are #1 in the queue. Do you want to wait, or Restart (Y/N/R)? */ 84*25705Sbloom "Y", 85*25705Sbloom CNULL /* <--- .....Good Bye! */ 86*25705Sbloom }; 87*25705Sbloom 88*25705Sbloom static char PCP_brand[20]; 89*25705Sbloom 9018619Sralph /* 9118619Sralph * place a telephone call to system and login, etc. 9213642Ssam * 9313642Ssam * return codes: 9413642Ssam * CF_SYSTEM: don't know system 9513642Ssam * CF_TIME: wrong time to call 9613642Ssam * CF_DIAL: call failed 9713642Ssam * CF_NODEV: no devices available to place call 9813642Ssam * CF_LOGIN: login/password dialog failed 9913642Ssam * 10013642Ssam * >0 - file no. - connect ok 10113642Ssam */ 10213642Ssam 10313642Ssam int Dcf = -1; 10417834Sralph char *Flds[MAXC/10]; 10517834Sralph extern int LocalOnly; 10613642Ssam 10713642Ssam conn(system) 10813642Ssam char *system; 10913642Ssam { 110*25705Sbloom int nf; 11118619Sralph char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE]; 11213642Ssam register FILE *fsys; 11313642Ssam int fcode = 0; 11413642Ssam 11513642Ssam nf = 0; 11613642Ssam 11713642Ssam fsys = fopen(SYSFILE, "r"); 11813642Ssam ASSERT(fsys != NULL, "CAN'T OPEN", SYSFILE, 0); 11913642Ssam 12017834Sralph DEBUG(4, "finds (%s) called\n", system); 12125127Sbloom keeplooking: 12217834Sralph while((nf = finds(fsys, system, info, Flds)) > 0) { 12317834Sralph if (LocalOnly) { 12417834Sralph if (strcmp("TCP", Flds[F_LINE]) 12517834Sralph && strcmp("DIR", Flds[F_LINE]) 126*25705Sbloom && strcmp("LOCAL", Flds[F_LINE]) ) { 127*25705Sbloom fcode = CF_TIME; 128*25705Sbloom continue; 129*25705Sbloom } 13017834Sralph } 13123596Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 13218619Sralph if (!onesys && MaxGrade != DefMaxGrade && 133*25705Sbloom !iswrk(file, "chk", Spool, wkpre)) { 134*25705Sbloom fcode = CF_TIME; 135*25705Sbloom continue; 136*25705Sbloom } 137*25705Sbloom /* For GTE's PC Pursuit */ 138*25705Sbloom if (snccmp(Flds[F_LINE], PCP) == SAME) { 139*25705Sbloom FILE *dfp; 140*25705Sbloom int status; 141*25705Sbloom static struct Devices dev; 142*25705Sbloom dfp = fopen(DEVFILE, "r"); 143*25705Sbloom ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); 144*25705Sbloom while ((status=rddev(dfp, &dev)) != FAIL 145*25705Sbloom && strcmp(PCP, dev.D_type) != SAME) 146*25705Sbloom ; 147*25705Sbloom fclose(dfp); 148*25705Sbloom if (status == FAIL) 149*25705Sbloom continue; 150*25705Sbloom if (mlock(PCP) == FAIL) { 151*25705Sbloom fcode = CF_NODEV; 152*25705Sbloom logent("DEVICE", "NO"); 153*25705Sbloom continue; 154*25705Sbloom } 155*25705Sbloom PCFlds[PCP_BAUD] = dev.D_class; 156*25705Sbloom PCFlds[PCP_PHONE] = dev.D_calldev; 157*25705Sbloom PCFlds[PCP_CALLBACK] = dev.D_arg[D_CHAT]; 158*25705Sbloom PCFlds[PCP_CITY] = Flds[F_CLASS]; 159*25705Sbloom PCFlds[PCP_RPHONE] = Flds[F_PHONE]; 160*25705Sbloom strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand)); 161*25705Sbloom if ((fcode = getto(PCFlds)) < 0) 162*25705Sbloom continue; 163*25705Sbloom Dcf = fcode; 164*25705Sbloom fcode = login(NPCFIELDS, PCFlds, Dcf); 165*25705Sbloom clsacu(); /* Hang up, they'll call back */ 166*25705Sbloom if (fcode != SUCCESS) { 167*25705Sbloom fcode = CF_DIAL; 168*25705Sbloom continue; 169*25705Sbloom } 170*25705Sbloom Flds[F_CLASS] = dev.D_class; 171*25705Sbloom Flds[F_PHONE] = dev.D_line; 172*25705Sbloom 173*25705Sbloom } /* end PC Pursuit */ 174*25705Sbloom if ((fcode = getto(Flds)) > 0) 17513642Ssam break; 17613642Ssam } 17713642Ssam 17825127Sbloom if (nf <= 0) { 17925127Sbloom fclose(fsys); 18017834Sralph return fcode ? fcode : nf; 18125127Sbloom } 18213642Ssam 183*25705Sbloom Dcf = fcode; 184*25705Sbloom 185*25705Sbloom if (fcode >= 0 && snccmp(Flds[F_LINE], PCP) == SAME) { 186*25705Sbloom AbortOn = "Good"; /* .... Good Bye */ 187*25705Sbloom fcode = expect("****~300", Dcf); 188*25705Sbloom if (fcode != SUCCESS) { 189*25705Sbloom DEBUG(4, "\nexpect timed out\n", CNULL); 190*25705Sbloom fcode = CF_DIAL; 191*25705Sbloom } 192*25705Sbloom } 193*25705Sbloom if (fcode >= 0) { 194*25705Sbloom DEBUG(4, "login %s\n", "called"); 195*25705Sbloom fcode = login(nf, Flds, Dcf); 196*25705Sbloom } 197*25705Sbloom if (fcode < 0) { 19813642Ssam clsacu(); 199*25705Sbloom if (fcode == ABORT) { 20025127Sbloom fcode = CF_DIAL; 20125127Sbloom goto keeplooking; 20225127Sbloom } else { 20325127Sbloom fclose(fsys); 20423596Sbloom return CF_LOGIN; 20525127Sbloom } 20613642Ssam } 20725127Sbloom fclose(fsys); 208*25705Sbloom fioclex(Dcf); 209*25705Sbloom return Dcf; 21013642Ssam } 21113642Ssam 21225127Sbloom /* 21325127Sbloom * connect to remote machine 21413642Ssam * 21513642Ssam * return codes: 21613642Ssam * >0 - file number - ok 21713642Ssam * FAIL - failed 21813642Ssam */ 21913642Ssam 22013642Ssam getto(flds) 22113642Ssam register char *flds[]; 22213642Ssam { 22313642Ssam register struct condev *cd; 22413642Ssam int nulldev(), diropn(); 22525127Sbloom char *line; 22613642Ssam 22717834Sralph DEBUG(4, "getto: call no. %s ", flds[F_PHONE]); 22813642Ssam DEBUG(4, "for sys %s\n", flds[F_NAME]); 22913642Ssam 23025127Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME) 23125127Sbloom line = "ACU"; 23225127Sbloom else 23325127Sbloom line = flds[F_LINE]; 23425127Sbloom #ifdef DIALINOUT 23525127Sbloom if (snccmp(line, "ACU") != SAME) 23625127Sbloom reenable(); 23725127Sbloom #endif DIALINOUT 23813642Ssam CU_end = nulldev; 239*25705Sbloom if (snccmp(line, PCP) == SAME) { 240*25705Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) { 241*25705Sbloom if (snccmp(PCP_brand, cd->CU_brand) == SAME) { 242*25705Sbloom CU_end = cd->CU_clos; 243*25705Sbloom return diropn(flds); 244*25705Sbloom } 24513642Ssam } 246*25705Sbloom logent(PCP_brand, "UNSUPPORTED ACU TYPE"); 247*25705Sbloom } else { 248*25705Sbloom for (cd = condevs; cd->CU_meth != NULL; cd++) { 249*25705Sbloom if (snccmp(cd->CU_meth, line) == SAME) { 250*25705Sbloom DEBUG(4, "Using %s to call\n", cd->CU_meth); 251*25705Sbloom return (*(cd->CU_gen))(flds); 252*25705Sbloom } 253*25705Sbloom } 254*25705Sbloom DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]); 25513642Ssam } 25617834Sralph return diropn(flds); /* search failed, so use direct */ 25717834Sralph } 25813642Ssam 25925127Sbloom /* 26025127Sbloom * close call unit 26113642Ssam * 26213642Ssam * return codes: none 26313642Ssam */ 26413642Ssam 26513642Ssam int (*CU_end)() = nulldev; 26613642Ssam clsacu() 26713642Ssam { 26817834Sralph /* make *sure* Dcf is no longer exclusive. 26917834Sralph * Otherwise dual call-in/call-out modems could get stuck. 27017834Sralph * Unfortunately, doing this here is not ideal, but it is the 27117834Sralph * easiest place to put the call. 27217834Sralph * Hopefully everyone honors the LCK protocol, of course 27317834Sralph */ 274*25705Sbloom #ifdef TIOCNXCL 27523596Sbloom if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0) 27623596Sbloom DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]); 27717834Sralph #endif 27817834Sralph if (setjmp(Sjbuf)) 27917834Sralph logent(Rmtname, "CLOSE TIMEOUT"); 28017834Sralph else { 28117834Sralph signal(SIGALRM, alarmtr); 28217834Sralph alarm(20); 28317834Sralph (*(CU_end))(Dcf); 28417834Sralph alarm(0); 28517834Sralph } 28613642Ssam if (close(Dcf) == 0) { 28713642Ssam DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); 28813642Ssam logent("clsacu", "NOT CLOSED by CU_clos"); 28913642Ssam } 29013642Ssam Dcf = -1; 29113642Ssam CU_end = nulldev; 29213642Ssam } 29313642Ssam 29425127Sbloom /* 29525127Sbloom * expand phone number for given prefix and number 29613642Ssam */ 29713642Ssam 29813642Ssam exphone(in, out) 29913642Ssam register char *in, *out; 30013642Ssam { 30113642Ssam FILE *fn; 30213642Ssam char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; 30313642Ssam char buf[BUFSIZ]; 30413642Ssam register char *s1; 30513642Ssam 30617834Sralph if (!isascii(*in) || !isalpha(*in)) { 30713642Ssam strcpy(out, in); 30813642Ssam return; 30913642Ssam } 31013642Ssam 31113642Ssam s1=pre; 31217834Sralph while (isascii(*in) && isalpha(*in)) 31313642Ssam *s1++ = *in++; 31413642Ssam *s1 = '\0'; 31513642Ssam s1 = npart; 31613642Ssam while (*in != '\0') 31713642Ssam *s1++ = *in++; 31813642Ssam *s1 = '\0'; 31913642Ssam 32013642Ssam tpre[0] = '\0'; 32113642Ssam if ((fn = fopen(DIALFILE, "r")) == NULL) 32213642Ssam DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); 32313642Ssam else { 32413642Ssam while (cfgets(buf, BUFSIZ, fn)) { 32517834Sralph if (sscanf(buf, "%s%s", p, tpre) != 2) 32617834Sralph continue; 32713642Ssam if (strcmp(p, pre) == SAME) 32813642Ssam goto found; 32913642Ssam tpre[0] = '\0'; 33013642Ssam } 33113642Ssam DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); 33213642Ssam found:; 33313642Ssam fclose(fn); 33413642Ssam } 33513642Ssam 33613642Ssam strcpy(out, tpre); 33713642Ssam strcat(out, npart); 33813642Ssam } 33913642Ssam 34018619Sralph /* 34118619Sralph * read and decode a line from device file 34213642Ssam * 34313642Ssam * return code - FAIL at end-of file; 0 otherwise 34413642Ssam */ 34513642Ssam 34613642Ssam rddev(fp, dev) 34713642Ssam register struct Devices *dev; 34813642Ssam FILE *fp; 34913642Ssam { 35017834Sralph register int na; 35113642Ssam 35217834Sralph if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp)) 35317834Sralph return FAIL; 35417834Sralph na = getargs(dev->D_argbfr, dev->D_arg, 20); 35517834Sralph ASSERT(na >= 4, "BAD DEVICE ENTRY", dev->D_argbfr, 0); 35617834Sralph if (na == 4) { 35717834Sralph dev->D_brand = ""; 35817834Sralph na++; 35917834Sralph } 36013642Ssam dev->D_speed = atoi(fdig(dev->D_class)); 36117834Sralph dev->D_numargs = na; 36217834Sralph return 0; 36313642Ssam } 36413642Ssam 36518619Sralph /* 36618619Sralph * set system attribute vector 36713642Ssam * 36813642Ssam * return codes: 36913642Ssam * >0 - number of arguments in vector - succeeded 37013642Ssam * CF_SYSTEM - system name not found 37113642Ssam * CF_TIME - wrong time to call 37213642Ssam */ 37313642Ssam 37413642Ssam finds(fsys, sysnam, info, flds) 37513642Ssam char *sysnam, info[], *flds[]; 37613642Ssam FILE *fsys; 37713642Ssam { 37813642Ssam int na; 37913642Ssam int fcode = 0; 38013642Ssam 38113642Ssam /* format of fields 38213642Ssam * 0 name; 38313642Ssam * 1 time 38413642Ssam * 2 acu/hardwired 38513642Ssam * 3 speed 38613642Ssam * etc 38713642Ssam */ 38813642Ssam while (cfgets(info, MAXC, fsys) != NULL) { 38917834Sralph na = getargs(info, flds, MAXC/10); 39023596Sbloom if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME) 39113642Ssam continue; 39218619Sralph if (ifdate(flds[F_TIME]) != FAIL) 39313642Ssam /* found a good entry */ 39417834Sralph return na; 39513642Ssam DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); 39613642Ssam fcode = CF_TIME; 39713642Ssam } 39817834Sralph return fcode ? fcode : CF_SYSTEM; 39913642Ssam } 40013642Ssam 40118619Sralph /* 40218619Sralph * do login conversation 40313642Ssam * 40423596Sbloom * return codes: SUCCESS | FAIL 40513642Ssam */ 40613642Ssam 40713642Ssam login(nf, flds, fn) 40813642Ssam register char *flds[]; 40913642Ssam int nf, fn; 41013642Ssam { 41113642Ssam register char *want, *altern; 41213642Ssam int k, ok; 41313642Ssam 41417834Sralph ASSERT(nf > 4, "TOO FEW LOG FIELDS", CNULL, nf); 41517834Sralph if (setjmp(Cjbuf)) 41617834Sralph return FAIL; 41717834Sralph AbortOn = NULL; 41813642Ssam for (k = F_LOGIN; k < nf; k += 2) { 41913642Ssam want = flds[k]; 42013642Ssam ok = FAIL; 42117834Sralph while (ok != SUCCESS) { 42213642Ssam altern = index(want, '-'); 42313642Ssam if (altern != NULL) 42413642Ssam *altern++ = '\0'; 42517834Sralph if (strcmp(want, "ABORT") == 0) { 42617834Sralph AbortOn = flds[k+1]; 42717834Sralph DEBUG(4, "ABORT ON: %s\n", AbortOn); 42817834Sralph goto nextfield; 42917834Sralph } 430*25705Sbloom DEBUG(4, "wanted \"%s\"\n", want); 43113642Ssam ok = expect(want, fn); 43217834Sralph DEBUG(4, "got: %s\n", ok ? "?" : "that"); 43317834Sralph if (ok == FAIL) { 43417834Sralph if (altern == NULL) { 43517834Sralph logent("LOGIN", _FAILED); 43617834Sralph return FAIL; 43717834Sralph } 43817834Sralph want = index(altern, '-'); 43917834Sralph if (want != NULL) 44017834Sralph *want++ = '\0'; 44117834Sralph sendthem(altern, fn); 44217834Sralph } else 44317834Sralph if (ok == ABORT) { 44417834Sralph logent("LOGIN ABORTED", _FAILED); 44523596Sbloom return ABORT; 44617834Sralph } 44713642Ssam } 44817834Sralph sleep(1); 44913642Ssam if (k+1 < nf) 45013642Ssam sendthem(flds[k+1], fn); 45117834Sralph nextfield: ; 45213642Ssam } 45317834Sralph return SUCCESS; 45413642Ssam } 45513642Ssam 45613642Ssam 45717834Sralph /* conditional table generation to support odd speeds */ 45813642Ssam struct sg_spds {int sp_val, sp_name;} spds[] = { 45913642Ssam #ifdef B50 46013642Ssam { 50, B50}, 46113642Ssam #endif 46213642Ssam #ifdef B75 46313642Ssam { 75, B75}, 46413642Ssam #endif 46513642Ssam #ifdef B110 46613642Ssam { 110, B110}, 46713642Ssam #endif 46813642Ssam #ifdef B150 46913642Ssam { 150, B150}, 47013642Ssam #endif 47113642Ssam #ifdef B200 47213642Ssam { 200, B200}, 47313642Ssam #endif 47413642Ssam #ifdef B300 47513642Ssam { 300, B300}, 47613642Ssam #endif 47713642Ssam #ifdef B600 47813642Ssam {600, B600}, 47913642Ssam #endif 48013642Ssam #ifdef B1200 48113642Ssam {1200, B1200}, 48213642Ssam #endif 48313642Ssam #ifdef B1800 48413642Ssam {1800, B1800}, 48513642Ssam #endif 48613642Ssam #ifdef B2000 48713642Ssam {2000, B2000}, 48813642Ssam #endif 48913642Ssam #ifdef B2400 49013642Ssam {2400, B2400}, 49113642Ssam #endif 49213642Ssam #ifdef B3600 49313642Ssam {3600, B3600}, 49413642Ssam #endif 49513642Ssam #ifdef B4800 49613642Ssam {4800, B4800}, 49713642Ssam #endif 49813642Ssam #ifdef B7200 49913642Ssam {7200, B7200}, 50013642Ssam #endif 50113642Ssam #ifdef B9600 50213642Ssam {9600, B9600}, 50313642Ssam #endif 50413642Ssam #ifdef B19200 50517834Sralph {19200, B19200}, 50613642Ssam #endif 50717834Sralph #ifdef EXTA 50817834Sralph {19200, EXTA}, 50917834Sralph #endif 51013642Ssam {0, 0} 51113642Ssam }; 51213642Ssam 51318619Sralph /* 51418619Sralph * set speed/echo/mode... 51513642Ssam * 51613642Ssam * return codes: none 51713642Ssam */ 51813642Ssam 51913642Ssam fixline(tty, spwant) 52013642Ssam int tty, spwant; 52113642Ssam { 52217834Sralph #ifdef USG 52313642Ssam struct termio ttbuf; 52417834Sralph #else !USG 52513642Ssam struct sgttyb ttbuf; 52617834Sralph #endif !USG 52713642Ssam register struct sg_spds *ps; 52813642Ssam int speed = -1; 52913642Ssam 53013642Ssam for (ps = spds; ps->sp_val; ps++) 53113642Ssam if (ps->sp_val == spwant) 53213642Ssam speed = ps->sp_name; 53317834Sralph ASSERT(speed >= 0, "BAD SPEED", CNULL, speed); 53417834Sralph #ifdef USG 53523596Sbloom if (ioctl(tty, TCGETA, &ttbuf) < 0) 53623596Sbloom return FAIL; 53713642Ssam /* ttbuf.sg_flags = (ANYP|RAW); 53813642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ 53913642Ssam ttbuf.c_iflag = (ushort)0; 54013642Ssam ttbuf.c_oflag = (ushort)0; 54113642Ssam ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); 54213642Ssam ttbuf.c_lflag = (ushort)0; 54313642Ssam ttbuf.c_cc[VMIN] = 6; 54413642Ssam ttbuf.c_cc[VTIME] = 1; 54523596Sbloom if (ioctl(tty, TCSETA, &ttbuf) < 0) 54623596Sbloom return FAIL; 54717834Sralph #else !USG 54823596Sbloom if (ioctl(tty, TIOCGETP, &ttbuf) < 0) 54923596Sbloom return FAIL; 55013642Ssam ttbuf.sg_flags = (ANYP|RAW); 55113642Ssam ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; 55223596Sbloom if (ioctl(tty, TIOCSETP, &ttbuf) < 0) 55323596Sbloom return FAIL; 55413642Ssam #endif 55517834Sralph #ifndef USG 55623596Sbloom if (ioctl(tty, TIOCHPCL, STBNULL) < 0) 55723596Sbloom return FAIL; 55823596Sbloom if (ioctl(tty, TIOCEXCL, STBNULL) < 0) 55923596Sbloom return FAIL; 56013642Ssam #endif 56117834Sralph linebaudrate = spwant; 56223596Sbloom return SUCCESS; 56313642Ssam } 56413642Ssam 565*25705Sbloom /* 56625518Stef * getbaud(tty) set linebaudrate variable 56725518Stef * 56825518Stef * return codes: none 56925518Stef */ 57025518Stef 57125518Stef getbaud(tty) 57225518Stef int tty; 57325518Stef { 57425518Stef #ifdef USG 57525518Stef struct termio ttbuf; 57625518Stef #else 57725518Stef struct sgttyb ttbuf; 57825518Stef #endif 57925518Stef register struct sg_spds *ps; 58025518Stef register int name; 58125518Stef 58225518Stef if (IsTcpIp) 58325518Stef return; 58425518Stef #ifdef USG 58525518Stef ioctl(tty, TCGETA, &ttbuf); 58625518Stef name = ttbuf.c_cflag & CBAUD; 58725518Stef #else 58825518Stef ioctl(tty, TIOCGETP, &ttbuf); 58925518Stef name = ttbuf.sg_ispeed; 59025518Stef #endif 59125518Stef for (ps = spds; ps->sp_val; ps++) 59225518Stef if (ps->sp_name == name) { 59325518Stef linebaudrate = ps->sp_val; 59425518Stef break; 59525518Stef } 59625518Stef } 59725518Stef 59817834Sralph #define MR 100 59913642Ssam 60018619Sralph /* 60118619Sralph * look for expected string 60213642Ssam * 60313642Ssam * return codes: 60413642Ssam * 0 - found 60513642Ssam * FAIL - lost line or too many characters read 60613642Ssam * some character - timed out 60713642Ssam */ 60813642Ssam 60913642Ssam expect(str, fn) 61013642Ssam register char *str; 61113642Ssam int fn; 61213642Ssam { 61314592Skarels char rdvec[MR]; 61417834Sralph register char *rp = rdvec, *strptr; 61517834Sralph int kr, cnt_char; 61613642Ssam char nextch; 61725127Sbloom int timo = MAXMSGTIME; 61813642Ssam 61917834Sralph if (*str == '\0' || strcmp(str, "\"\"") == SAME) 62017834Sralph return SUCCESS; 62117834Sralph /* Cleanup str, convert \0xx strings to one char */ 62217834Sralph for (strptr = str; *strptr; strptr++) { 62317834Sralph if (*strptr == '\\') 62417834Sralph switch(*++strptr) { 62517834Sralph case 's': 62617834Sralph DEBUG(5, "BLANK\n", CNULL); 62717834Sralph *strptr = ' '; 62817834Sralph break; 62917834Sralph default: 63017834Sralph strptr--; /* back up to backslash */ 63117834Sralph sscanf(strptr + 1,"%o", &cnt_char); 63217834Sralph DEBUG(6, "BACKSLASHED %02xH\n", cnt_char); 63317834Sralph *strptr = (char) (cnt_char); 63417834Sralph strcpy(&strptr[1], &strptr[4]); 63517834Sralph } 63617834Sralph } 63717834Sralph 63825127Sbloom strptr = index(str, '~'); 63925127Sbloom if (strptr != NULL) { 64025127Sbloom *strptr++ = '\0'; 64125127Sbloom timo = atoi(strptr); 64225127Sbloom if (timo <= 0) 64325127Sbloom timo = MAXMSGTIME; 64425127Sbloom } 64525127Sbloom 64617834Sralph if (setjmp(Sjbuf)) 64717834Sralph return FAIL; 64813642Ssam signal(SIGALRM, alarmtr); 64925127Sbloom alarm(timo); 65025127Sbloom *rp = 0; 65113642Ssam while (notin(str, rdvec)) { 652*25705Sbloom int c; 65317834Sralph if(AbortOn != NULL && !notin(AbortOn, rdvec)) { 65417834Sralph DEBUG(1, "Call aborted on '%s'\n", AbortOn); 65517834Sralph alarm(0); 65617834Sralph return ABORT; 65717834Sralph } 65813642Ssam kr = read(fn, &nextch, 1); 65913642Ssam if (kr <= 0) { 66013642Ssam alarm(0); 66113642Ssam DEBUG(4, "lost line kr - %d\n, ", kr); 66213642Ssam logent("LOGIN", "LOST LINE"); 66317834Sralph return FAIL; 66413642Ssam } 66513642Ssam c = nextch & 0177; 666*25705Sbloom if (c == '\0') 667*25705Sbloom continue; 668*25705Sbloom DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c); 669*25705Sbloom *rp++ = c; 67013642Ssam if (rp >= rdvec + MR) { 67117834Sralph register char *p; 67217834Sralph for (p = rdvec+MR/2; p < rp; p++) 67317834Sralph *(p-MR/2) = *p; 67417834Sralph rp -= MR/2; 67513642Ssam } 67613642Ssam *rp = '\0'; 67713642Ssam } 67813642Ssam alarm(0); 67917834Sralph return SUCCESS; 68013642Ssam } 68113642Ssam 68213642Ssam 68313642Ssam /* 68413642Ssam * Determine next file descriptor that would be allocated. 68513642Ssam * This permits later closing of a file whose open was interrupted. 68613642Ssam * It is a UNIX kernel problem, but it has to be handled. 68713642Ssam * unc!smb (Steve Bellovin) probably first discovered it. 68813642Ssam */ 68913642Ssam getnextfd() 69013642Ssam { 69113642Ssam close(next_fd = open("/", 0)); 69213642Ssam } 69313642Ssam 69417834Sralph /* 69517834Sralph * send line of login sequence 69613642Ssam * 69713642Ssam * return codes: none 69813642Ssam */ 69913642Ssam sendthem(str, fn) 70013642Ssam register char *str; 70113642Ssam int fn; 70213642Ssam { 70313642Ssam register char *strptr; 70413642Ssam int i, n, cr = 1; 70517834Sralph register char c; 70613642Ssam static int p_init = 0; 70713642Ssam 708*25705Sbloom DEBUG(5, "send \"%s\"\n", str); 70913642Ssam 71013642Ssam if (!p_init) { 71113642Ssam p_init++; 71213642Ssam bld_partab(P_EVEN); 71313642Ssam } 71413642Ssam 71513642Ssam if (prefix("BREAK", str)) { 71613642Ssam sscanf(&str[5], "%1d", &i); 71713642Ssam if (i <= 0 || i > 10) 71813642Ssam i = 3; 71913642Ssam /* send break */ 72013642Ssam genbrk(fn, i); 72113642Ssam return; 72213642Ssam } 72313642Ssam 72413642Ssam if (prefix("PAUSE", str)) { 72513642Ssam sscanf(&str[5], "%1d", &i); 72613642Ssam if (i <= 0 || i > 10) 72713642Ssam i = 3; 72813642Ssam /* pause for a while */ 72913642Ssam sleep((unsigned)i); 73013642Ssam return; 73113642Ssam } 73213642Ssam 73313642Ssam if (strcmp(str, "EOT") == SAME) { 73413642Ssam p_chwrite(fn, '\04'); 73513642Ssam return; 73613642Ssam } 73713642Ssam 73813642Ssam /* Send a '\n' */ 739*25705Sbloom if (strcmp(str, "LF") == SAME) { 740*25705Sbloom p_chwrite(fn, '\n'); 741*25705Sbloom return; 742*25705Sbloom } 74313642Ssam 74413642Ssam /* Send a '\r' */ 745*25705Sbloom if (strcmp(str, "CR") == SAME) { 746*25705Sbloom p_chwrite(fn, '\r'); 747*25705Sbloom return; 748*25705Sbloom } 74913642Ssam 75013642Ssam /* Set parity as needed */ 75113642Ssam if (strcmp(str, "P_ZERO") == SAME) { 75213642Ssam bld_partab(P_ZERO); 75313642Ssam return; 75413642Ssam } 75513642Ssam if (strcmp(str, "P_ONE") == SAME) { 75613642Ssam bld_partab(P_ONE); 75713642Ssam return; 75813642Ssam } 75913642Ssam if (strcmp(str, "P_EVEN") == SAME) { 76013642Ssam bld_partab(P_EVEN); 76113642Ssam return; 76213642Ssam } 76313642Ssam if (strcmp(str, "P_ODD") == SAME) { 76413642Ssam bld_partab(P_ODD); 76513642Ssam return; 76613642Ssam } 76713642Ssam 76813642Ssam /* If "", just send '\r' */ 76917834Sralph if (strcmp(str, "\"\"") == SAME) { 77017834Sralph p_chwrite(fn, '\r'); 77117834Sralph return; 77217834Sralph } 77317834Sralph 774*25705Sbloom strptr = str; 775*25705Sbloom while ((c = *strptr++) != '\0') { 77617834Sralph if (c == '\\') { 77717834Sralph switch(*strptr++) { 778*25705Sbloom case '\0': 779*25705Sbloom DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL); 780*25705Sbloom --strptr; 781*25705Sbloom continue; 78217834Sralph case 's': 78317834Sralph DEBUG(5, "BLANK\n", CNULL); 784*25705Sbloom c = ' '; 78517834Sralph break; 78617834Sralph case 'd': 78717834Sralph DEBUG(5, "DELAY\n", CNULL); 78817834Sralph sleep(1); 78917834Sralph continue; 790*25705Sbloom case 'n': 791*25705Sbloom DEBUG(5, "NEW LINE\n", CNULL); 792*25705Sbloom c = '\n'; 793*25705Sbloom break; 79417834Sralph case 'r': 79517834Sralph DEBUG(5, "RETURN\n", CNULL); 796*25705Sbloom c = '\r'; 79717834Sralph break; 79817834Sralph case 'b': 79917834Sralph if (isdigit(*strptr)) { 80017834Sralph i = (*strptr++ - '0'); 80117834Sralph if (i <= 0 || i > 10) 80217834Sralph i = 3; 80317834Sralph } else 80413642Ssam i = 3; 80517834Sralph /* send break */ 80617834Sralph genbrk(fn, i); 80717834Sralph if (*strptr == '\0') 80817834Sralph cr = 0; 80913642Ssam continue; 81017834Sralph case 'c': 81117834Sralph if (*strptr == '\0') { 81217834Sralph DEBUG(5, "NO CR\n", CNULL); 81317834Sralph cr = 0; 814*25705Sbloom } else 815*25705Sbloom DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL); 81613642Ssam continue; 817*25705Sbloom #define isoctal(x) ((x >= '0') && (x <= '7')) 81817834Sralph default: 819*25705Sbloom if (isoctal(strptr[-1])) { 82017834Sralph i = 0; 82117834Sralph n = 0; 822*25705Sbloom --strptr; 823*25705Sbloom while (isoctal(*strptr) && ++n <= 3) 824*25705Sbloom i = i * 8 + (*strptr++ - '0'); 825*25705Sbloom DEBUG(5, "\\%o\n", i); 82617834Sralph p_chwrite(fn, (char)i); 82717834Sralph continue; 82817834Sralph } 82913642Ssam } 830*25705Sbloom } 831*25705Sbloom p_chwrite(fn, c); 83213642Ssam } 83313642Ssam 83413642Ssam if (cr) 83513642Ssam p_chwrite(fn, '\r'); 83613642Ssam return; 83713642Ssam } 83813642Ssam 83913642Ssam p_chwrite(fd, c) 84013642Ssam int fd; 84117834Sralph char c; 84213642Ssam { 84317834Sralph c = par_tab[c&0177]; 84417834Sralph if (write(fd, &c, 1) != 1) { 84517834Sralph logent(sys_errlist[errno], "BAD WRITE"); 84617834Sralph longjmp(Cjbuf, 2); 84717834Sralph } 84813642Ssam } 84913642Ssam 85013642Ssam /* 85113642Ssam * generate parity table for use by p_chwrite. 85213642Ssam */ 85313642Ssam bld_partab(type) 85413642Ssam int type; 85513642Ssam { 85613642Ssam register int i, j, n; 85713642Ssam 85813642Ssam for (i = 0; i < sizeof(par_tab); i++) { 85913642Ssam n = 0; 86013642Ssam for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) 86113642Ssam n++; 86213642Ssam par_tab[i] = i; 86313642Ssam if (type == P_ONE 86413642Ssam || (type == P_EVEN && (n&01) != 0) 86513642Ssam || (type == P_ODD && (n&01) == 0)) 86613642Ssam par_tab[i] |= sizeof(par_tab); 86713642Ssam } 86813642Ssam } 86913642Ssam 87018619Sralph /* 87118619Sralph * check for occurrence of substring "sh" 87213642Ssam * 87313642Ssam * return codes: 87413642Ssam * 0 - found the string 87513642Ssam * 1 - not in the string 87613642Ssam */ 87713642Ssam notin(sh, lg) 87813642Ssam register char *sh, *lg; 87913642Ssam { 88013642Ssam while (*lg != '\0') { 88113642Ssam if (wprefix(sh, lg)) 88218619Sralph return 0; 88313642Ssam else 88413642Ssam lg++; 88513642Ssam } 88618619Sralph return 1; 88713642Ssam } 88813642Ssam 88918619Sralph /* 89023596Sbloom * Allow multiple date specifications separated by ','. 89113642Ssam */ 89218619Sralph ifdate(p) 89318619Sralph register char *p; 89413642Ssam { 895*25705Sbloom register char *np; 89618619Sralph register int ret, g; 89723596Sbloom int rtime, i; 89813642Ssam 89923596Sbloom /* pick up retry time for failures */ 90023596Sbloom /* global variable Retrytime is set here */ 90123596Sbloom if ((np = index(p, ';')) == NULL) { 90223596Sbloom Retrytime = RETRYTIME; 90323596Sbloom } else { 90423596Sbloom i = sscanf(np+1, "%d", &rtime); 90523596Sbloom if (i < 1 || rtime < 0) 90623596Sbloom rtime = 5; 90723596Sbloom Retrytime = rtime * 60; 90823596Sbloom } 90923596Sbloom 91018619Sralph ret = FAIL; 91118619Sralph MaxGrade = '\0'; 91218619Sralph do { 91323596Sbloom np = strpbrk(p, ",|"); /* prefer , but allow | for compat */ 91423596Sbloom if (np) 91523596Sbloom *np = '\0'; 91618619Sralph g = ifadate(p); 91718619Sralph DEBUG(11,"ifadate returns %o\n", g); 91818619Sralph if (g != FAIL) { 91918619Sralph ret = SUCCESS; 92018619Sralph if (g > MaxGrade) 92118619Sralph MaxGrade = g; 92218619Sralph } 92323596Sbloom if (np) 92423596Sbloom *np = ','; 92523596Sbloom p = np + 1; 92623596Sbloom } while (np); 92723596Sbloom if (MaxGrade == '\0') 92823596Sbloom MaxGrade = DefMaxGrade; 92918619Sralph return ret; 93013642Ssam } 93113642Ssam 93218619Sralph /* 93318619Sralph * this routine will check a string (string) 93413642Ssam * like "MoTu0800-1730" to see if the present 93513642Ssam * time is within the given limits. 93613642Ssam * SIDE EFFECT - Retrytime is set 93713642Ssam * 93813642Ssam * return codes: 93913642Ssam * 0 - not within limits 94013642Ssam * 1 - within limits 94113642Ssam */ 94213642Ssam 94318619Sralph ifadate(string) 94418619Sralph char *string; 94513642Ssam { 94613642Ssam static char *days[]={ 94713642Ssam "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 94813642Ssam }; 94913642Ssam time_t clock; 95018619Sralph register char *s = string; 95117834Sralph int i, tl, th, tn, dayok=0; 95213642Ssam struct tm *localtime(); 95313642Ssam struct tm *tp; 95418619Sralph char *p, MGrade; 95513642Ssam 95623596Sbloom if ((p = index(s, '/')) == NULL) 95718619Sralph MGrade = DefMaxGrade; 95818619Sralph else 95918619Sralph MGrade = p[1]; 96018619Sralph 96113642Ssam time(&clock); 96213642Ssam tp = localtime(&clock); 96317834Sralph while (isascii(*s) && isalpha(*s)) { 96413642Ssam for (i = 0; days[i]; i++) { 96513642Ssam if (prefix(days[i], s)) 96613642Ssam if (tp->tm_wday == i) 96713642Ssam dayok = 1; 96813642Ssam } 96913642Ssam 97013642Ssam if (prefix("Wk", s)) 97113642Ssam if (tp->tm_wday >= 1 && tp->tm_wday <= 5) 97213642Ssam dayok = 1; 97313642Ssam if (prefix("Any", s)) 97413642Ssam dayok = 1; 97517834Sralph if (prefix("Evening", s)) { 97617834Sralph /* Sat or Sun */ 97717834Sralph if (tp->tm_wday == 6 || tp->tm_wday == 0 97817834Sralph || tp->tm_hour >= 17 || tp->tm_hour < 8) 97917834Sralph dayok = 1; 98017834Sralph } 98117834Sralph if (prefix("Night", s)) { 98217834Sralph if (tp->tm_wday == 6 /* Sat */ 98318619Sralph || tp->tm_hour >= 23 || tp->tm_hour < 8 98418619Sralph /* Sunday before 5pm */ 98518619Sralph || (tp->tm_wday == 0 && tp->tm_hour < 17)) 98617834Sralph dayok = 1; 98717834Sralph } 988*25705Sbloom if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */ 989*25705Sbloom /* Sat or Sun */ 990*25705Sbloom if (tp->tm_wday == 6 || tp->tm_wday == 0 991*25705Sbloom || tp->tm_hour >= 18 || tp->tm_hour < 7) 992*25705Sbloom dayok = 1; 993*25705Sbloom } 99413642Ssam s++; 99513642Ssam } 99613642Ssam 99718619Sralph if (dayok == 0 && s != string) 99818619Sralph return FAIL; 99913642Ssam i = sscanf(s, "%d-%d", &tl, &th); 100018619Sralph if (i < 2) 100118619Sralph return MGrade; 100218619Sralph tn = tp->tm_hour * 100 + tp->tm_min; 100318619Sralph if (th < tl) { /* crosses midnight */ 100418619Sralph if (tl <= tn || tn < th) 100518619Sralph return MGrade; 100618619Sralph } else 100718619Sralph 100813642Ssam if (i < 2) 100918619Sralph return MGrade; 101018619Sralph if (th < tl) { /* crosses midnight */ 101117834Sralph if (tl <= tn || tn < th) 101218619Sralph return MGrade; 101317834Sralph } else 101417834Sralph if (tl <= tn && tn < th) 101518619Sralph return MGrade; 101618619Sralph return FAIL; 101713642Ssam } 101813642Ssam 101918619Sralph /* 102018619Sralph * find first digit in string 102113642Ssam * 102213642Ssam * return - pointer to first digit in string or end of string 102313642Ssam */ 102413642Ssam char * 102513642Ssam fdig(cp) 102613642Ssam register char *cp; 102713642Ssam { 102813642Ssam register char *c; 102913642Ssam 103013642Ssam for (c = cp; *c; c++) 103113642Ssam if (*c >= '0' && *c <= '9') 103213642Ssam break; 103317834Sralph return c; 103413642Ssam } 103513642Ssam 103613642Ssam /* 103713642Ssam * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 103813642Ssam * Strings are compared as if they contain all capital letters. 103913642Ssam */ 104013642Ssam snccmp(s1, s2) 104113642Ssam register char *s1, *s2; 104213642Ssam { 104313642Ssam char c1, c2; 104413642Ssam 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 105413642Ssam while (c1 == c2) { 105525127Sbloom if (*s1++ == '\0') 105617834Sralph return 0; 105713642Ssam s2++; 105825127Sbloom if (islower(*s1)) 105925127Sbloom c1 = toupper(*s1); 106025127Sbloom else 106125127Sbloom c1 = *s1; 106225127Sbloom if (islower(*s2)) 106325127Sbloom c2 = toupper(*s2); 106425127Sbloom else 106525127Sbloom c2 = *s2; 106613642Ssam } 106717834Sralph return c1 - c2; 106813642Ssam } 106925127Sbloom 107017834Sralph /* 107125127Sbloom * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 107225127Sbloom * Strings are compared as if they contain all capital letters. 107325127Sbloom */ 107425127Sbloom sncncmp(s1, s2, n) 107525127Sbloom register char *s1, *s2; 107625127Sbloom register int n; 107725127Sbloom { 107825127Sbloom char c1, c2; 107925127Sbloom 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 while ( --n >= 0 && c1 == c2) { 109025127Sbloom if (*s1++ == '\0') 109125127Sbloom return 0; 109225127Sbloom s2++; 109325127Sbloom if (islower(*s1)) 109425127Sbloom c1 = toupper(*s1); 109525127Sbloom else 109625127Sbloom c1 = *s1; 109725127Sbloom if (islower(*s2)) 109825127Sbloom c2 = toupper(*s2); 109925127Sbloom else 110025127Sbloom c2 = *s2; 110125127Sbloom } 110225127Sbloom return n<0 ? 0 : (c1 - c2); 110325127Sbloom } 110425127Sbloom /* 110517834Sralph * do chat script 110617834Sralph * occurs after local port is opened, 110717834Sralph * before 'dialing' the other machine. 110817834Sralph */ 110917834Sralph dochat(dev, flds, fd) 111017834Sralph register struct Devices *dev; 111117834Sralph char *flds[]; 111217834Sralph int fd; 111317834Sralph { 111417834Sralph register int i; 111517834Sralph register char *p; 111617834Sralph char bfr[sizeof(dev->D_argbfr)]; 111717834Sralph 111817834Sralph if (dev->D_numargs <= 5) 111917834Sralph return(0); 112017834Sralph DEBUG(4, "dochat called %d\n", dev->D_numargs); 112117834Sralph for (i = 0; i < dev->D_numargs-5; i++) { 112217834Sralph sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]); 112317834Sralph if (strcmp(bfr, dev->D_arg[D_CHAT+i])) { 112417834Sralph p = malloc((unsigned)strlen(bfr)+1); 112517834Sralph if (p != NULL) { 112617834Sralph strcpy(p, bfr); 112717834Sralph dev->D_arg[D_CHAT+i] = p; 112817834Sralph } 112917834Sralph } 113017834Sralph } 113117834Sralph /* following is a kludge because login() arglist is a kludge */ 113217834Sralph i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd); 113317834Sralph /* 113417834Sralph * If login() last did a sendthem(), must pause so things can settle. 113517834Sralph * But don't bother if chat failed. 113617834Sralph */ 113717834Sralph if (i == 0 && (dev->D_numargs&01)) 113817834Sralph sleep(2); 113917834Sralph return(i); 114017834Sralph } 1141*25705Sbloom 1142*25705Sbloom /* 1143*25705Sbloom * fix kill/echo/raw on line 1144*25705Sbloom * 1145*25705Sbloom * return codes: none 1146*25705Sbloom */ 1147*25705Sbloom fixmode(tty) 1148*25705Sbloom register int tty; 1149*25705Sbloom { 1150*25705Sbloom #ifdef USG 1151*25705Sbloom struct termio ttbuf; 1152*25705Sbloom #else !USG 1153*25705Sbloom struct sgttyb ttbuf; 1154*25705Sbloom #endif !USG 1155*25705Sbloom register struct sg_spds *ps; 1156*25705Sbloom int speed; 1157*25705Sbloom 1158*25705Sbloom if (IsTcpIp) 1159*25705Sbloom return; 1160*25705Sbloom #ifdef USG 1161*25705Sbloom ioctl(tty, TCGETA, &ttbuf); 1162*25705Sbloom ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 1163*25705Sbloom speed = ttbuf.c_cflag &= (CBAUD); 1164*25705Sbloom ttbuf.c_cflag |= (CS8|CREAD); 1165*25705Sbloom ttbuf.c_cc[VMIN] = 6; 1166*25705Sbloom ttbuf.c_cc[VTIME] = 1; 1167*25705Sbloom ioctl(tty, TCSETA, &ttbuf); 1168*25705Sbloom #else !USG 1169*25705Sbloom ioctl(tty, TIOCGETP, &ttbuf); 1170*25705Sbloom ttbuf.sg_flags = (ANYP | RAW); 1171*25705Sbloom ioctl(tty, TIOCSETP, &ttbuf); 1172*25705Sbloom speed = ttbuf.sg_ispeed; 1173*25705Sbloom ioctl(tty, TIOCEXCL, STBNULL); 1174*25705Sbloom #endif !USG 1175*25705Sbloom 1176*25705Sbloom for (ps = spds; ps->sp_val; ps++) 1177*25705Sbloom if (ps->sp_name == speed) { 1178*25705Sbloom linebaudrate = ps->sp_val; 1179*25705Sbloom DEBUG(9,"Incoming baudrate is %d\n", linebaudrate); 1180*25705Sbloom return; 1181*25705Sbloom } 1182*25705Sbloom ASSERT(linebaudrate >= 0, "BAD SPEED", CNULL, speed); 1183*25705Sbloom } 1184*25705Sbloom 1185