133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 533686Sbostic * Redistribution and use in source and binary forms are permitted 634898Sbostic * provided that the above copyright notice and this paragraph are 734898Sbostic * duplicated in all such forms and that any documentation, 834898Sbostic * advertising materials, and other materials related to such 934898Sbostic * distribution and use acknowledge that the software was developed 1034898Sbostic * by the University of California, Berkeley. The name of the 1134898Sbostic * University may not be used to endorse or promote products derived 1234898Sbostic * from this software without specific prior written permission. 1334898Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434898Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534898Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633686Sbostic */ 1733686Sbostic 1833686Sbostic #ifndef lint 19*38690Sborman static char sccsid[] = "@(#)utilities.c 1.14 (Berkeley) 08/21/89"; 2033686Sbostic #endif /* not lint */ 2133686Sbostic 2232149Sminshall #define TELOPTS 23*38690Sborman #define TELCMDS 2432149Sminshall #include <arpa/telnet.h> 2532381Sminshall #include <sys/types.h> 2632149Sminshall 2732149Sminshall #include <ctype.h> 2832149Sminshall 2934305Sminshall #include "general.h" 3034305Sminshall 3136280Sminshall #include "fdset.h" 3236280Sminshall 3332381Sminshall #include "ring.h" 3432381Sminshall 3536278Sminshall #include "defines.h" 3636278Sminshall 3732149Sminshall #include "externs.h" 3832149Sminshall 3932149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 40*38690Sborman int prettydump; 4132149Sminshall 4232149Sminshall /* 4332149Sminshall * upcase() 4432149Sminshall * 4532149Sminshall * Upcase (in place) the argument. 4632149Sminshall */ 4732149Sminshall 4832149Sminshall void 4932149Sminshall upcase(argument) 5032149Sminshall register char *argument; 5132149Sminshall { 5232149Sminshall register int c; 5332149Sminshall 5432149Sminshall while ((c = *argument) != 0) { 5532149Sminshall if (islower(c)) { 5632149Sminshall *argument = toupper(c); 5732149Sminshall } 5832149Sminshall argument++; 5932149Sminshall } 6032149Sminshall } 6132149Sminshall 6232149Sminshall /* 6332149Sminshall * SetSockOpt() 6432149Sminshall * 6532149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 6632149Sminshall */ 6732149Sminshall 6832149Sminshall int 6932149Sminshall SetSockOpt(fd, level, option, yesno) 7032149Sminshall int 7132149Sminshall fd, 7232149Sminshall level, 7332149Sminshall option, 7432149Sminshall yesno; 7532149Sminshall { 7632149Sminshall #ifndef NOT43 7732149Sminshall return setsockopt(fd, level, option, 7832149Sminshall (char *)&yesno, sizeof yesno); 7932149Sminshall #else /* NOT43 */ 8032149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 8132149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 8232149Sminshall option); 8332149Sminshall return -1; 8432149Sminshall } 8532149Sminshall return setsockopt(fd, level, option, 0, 0); 8632149Sminshall #endif /* NOT43 */ 8732149Sminshall } 8832149Sminshall 8932149Sminshall /* 9032149Sminshall * The following are routines used to print out debugging information. 9132149Sminshall */ 9232149Sminshall 93*38690Sborman char NetTraceFile[256] = "(standard output)"; 9432149Sminshall 9532149Sminshall void 96*38690Sborman SetNetTrace(file) 97*38690Sborman register char *file; 98*38690Sborman { 99*38690Sborman if (NetTrace && NetTrace != stdout) 100*38690Sborman fclose(NetTrace); 101*38690Sborman if (file && (strcmp(file, "-") != 0)) { 102*38690Sborman NetTrace = fopen(file, "w"); 103*38690Sborman if (NetTrace) { 104*38690Sborman strcpy(NetTraceFile, file); 105*38690Sborman return; 106*38690Sborman } 107*38690Sborman fprintf(stderr, "Cannot open %s.\n", file); 108*38690Sborman } 109*38690Sborman NetTrace = stdout; 110*38690Sborman strcpy(NetTraceFile, "(standard output)"); 111*38690Sborman } 112*38690Sborman 113*38690Sborman void 11432149Sminshall Dump(direction, buffer, length) 11532149Sminshall char direction; 11632149Sminshall char *buffer; 11732149Sminshall int length; 11832149Sminshall { 11932149Sminshall # define BYTES_PER_LINE 32 12032149Sminshall # define min(x,y) ((x<y)? x:y) 12132149Sminshall char *pThis; 12232149Sminshall int offset; 123*38690Sborman extern pettydump; 12432149Sminshall 12532149Sminshall offset = 0; 12632149Sminshall 12732149Sminshall while (length) { 12832149Sminshall /* print one line */ 12932149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 13032149Sminshall pThis = buffer; 131*38690Sborman if (prettydump) { 132*38690Sborman buffer = buffer + min(length, BYTES_PER_LINE); 133*38690Sborman while (pThis < buffer) { 134*38690Sborman fprintf(NetTrace, "%c%.2x", 135*38690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ', 136*38690Sborman (*pThis)&0xff); 137*38690Sborman pThis++; 138*38690Sborman } 139*38690Sborman } else { 140*38690Sborman buffer = buffer + min(length, BYTES_PER_LINE/2); 141*38690Sborman while (pThis < buffer) { 142*38690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff); 143*38690Sborman pThis++; 144*38690Sborman } 14532149Sminshall } 14637226Sminshall if (NetTrace == stdout) { 14738207Sminshall fprintf(NetTrace, "\r\n"); 14838207Sminshall } else { 14937226Sminshall fprintf(NetTrace, "\n"); 15037226Sminshall } 15132149Sminshall length -= BYTES_PER_LINE; 15232149Sminshall offset += BYTES_PER_LINE; 15332149Sminshall if (length < 0) { 15436693Sminshall fflush(NetTrace); 15532149Sminshall return; 15632149Sminshall } 15732149Sminshall /* find next unique line */ 15832149Sminshall } 15936693Sminshall fflush(NetTrace); 16032149Sminshall } 16132149Sminshall 16232149Sminshall 16332149Sminshall void 16437226Sminshall printoption(direction, fmt, option) 16532149Sminshall char *direction, *fmt; 16637226Sminshall int option; 16732149Sminshall { 16832149Sminshall if (!showoptions) 16932149Sminshall return; 17037226Sminshall fprintf(NetTrace, "%s ", direction); 171*38690Sborman if (TELOPT_OK(option)) 172*38690Sborman fprintf(NetTrace, "%s %s", fmt, TELOPT(option)); 173*38690Sborman else if (TELCMD_OK(option)) 174*38690Sborman fprintf(NetTrace, "%s %s", fmt, TELCMD(option)); 17532149Sminshall else 17632149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 177*38690Sborman if (NetTrace == stdout) 17837226Sminshall fprintf(NetTrace, "\r\n"); 179*38690Sborman else 18037226Sminshall fprintf(NetTrace, "\n"); 18137226Sminshall return; 18232149Sminshall } 18332149Sminshall 184*38690Sborman optionstatus() 185*38690Sborman { 186*38690Sborman register int i; 187*38690Sborman extern char will_wont_resp[], do_dont_resp[]; 188*38690Sborman 189*38690Sborman for (i = 0; i < 256; i++) { 190*38690Sborman if (do_dont_resp[i]) { 191*38690Sborman if (TELOPT_OK(i)) 192*38690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 193*38690Sborman else if (TELCMD_OK(i)) 194*38690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 195*38690Sborman else 196*38690Sborman printf("resp DO_DONT %d: %d\n", i, 197*38690Sborman do_dont_resp[i]); 198*38690Sborman if (my_want_state_is_do(i)) { 199*38690Sborman if (TELOPT_OK(i)) 200*38690Sborman printf("want DO %s\n", TELOPT(i)); 201*38690Sborman else if (TELCMD_OK(i)) 202*38690Sborman printf("want DO %s\n", TELCMD(i)); 203*38690Sborman else 204*38690Sborman printf("want DO %d\n", i); 205*38690Sborman } else { 206*38690Sborman if (TELOPT_OK(i)) 207*38690Sborman printf("want DONT %s\n", TELOPT(i)); 208*38690Sborman else if (TELCMD_OK(i)) 209*38690Sborman printf("want DONT %s\n", TELCMD(i)); 210*38690Sborman else 211*38690Sborman printf("want DONT %d\n", i); 212*38690Sborman } 213*38690Sborman } else { 214*38690Sborman if (my_state_is_do(i)) { 215*38690Sborman if (TELOPT_OK(i)) 216*38690Sborman printf(" DO %s\n", TELOPT(i)); 217*38690Sborman else if (TELCMD_OK(i)) 218*38690Sborman printf(" DO %s\n", TELCMD(i)); 219*38690Sborman else 220*38690Sborman printf(" DO %d\n", i); 221*38690Sborman } 222*38690Sborman } 223*38690Sborman if (will_wont_resp[i]) { 224*38690Sborman if (TELOPT_OK(i)) 225*38690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 226*38690Sborman else if (TELCMD_OK(i)) 227*38690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 228*38690Sborman else 229*38690Sborman printf("resp WILL_WONT %d: %d\n", 230*38690Sborman i, will_wont_resp[i]); 231*38690Sborman if (my_want_state_is_will(i)) { 232*38690Sborman if (TELOPT_OK(i)) 233*38690Sborman printf("want WILL %s\n", TELOPT(i)); 234*38690Sborman else if (TELCMD_OK(i)) 235*38690Sborman printf("want WILL %s\n", TELCMD(i)); 236*38690Sborman else 237*38690Sborman printf("want WILL %d\n", i); 238*38690Sborman } else { 239*38690Sborman if (TELOPT_OK(i)) 240*38690Sborman printf("want WONT %s\n", TELOPT(i)); 241*38690Sborman else if (TELCMD_OK(i)) 242*38690Sborman printf("want WONT %s\n", TELCMD(i)); 243*38690Sborman else 244*38690Sborman printf("want WONT %d\n", i); 245*38690Sborman } 246*38690Sborman } else { 247*38690Sborman if (my_state_is_will(i)) { 248*38690Sborman if (TELOPT_OK(i)) 249*38690Sborman printf(" WILL %s\n", TELOPT(i)); 250*38690Sborman else if (TELCMD_OK(i)) 251*38690Sborman printf(" WILL %s\n", TELCMD(i)); 252*38690Sborman else 253*38690Sborman printf(" WILL %d\n", i); 254*38690Sborman } 255*38690Sborman } 256*38690Sborman } 257*38690Sborman 258*38690Sborman } 259*38690Sborman 260*38690Sborman char *slcnames[] = { SLC_NAMES }; 261*38690Sborman 26232149Sminshall void 26332149Sminshall printsub(direction, pointer, length) 264*38690Sborman char direction; /* '<' or '>' */ 265*38690Sborman unsigned char *pointer; /* where suboption data sits */ 26632149Sminshall int length; /* length of suboption data */ 26732149Sminshall { 268*38690Sborman register int i; 269*38690Sborman 27032149Sminshall if (showoptions) { 27132149Sminshall fprintf(NetTrace, "%s suboption ", 272*38690Sborman (direction == '<')? "Received":"Sent"); 273*38690Sborman if (length >= 3) { 274*38690Sborman register int j; 275*38690Sborman 276*38690Sborman i = pointer[length-2]; 277*38690Sborman j = pointer[length-1]; 278*38690Sborman 279*38690Sborman if (i != IAC || j != SE) { 280*38690Sborman fprintf(NetTrace, "(terminated by "); 281*38690Sborman if (TELOPT_OK(i)) 282*38690Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 283*38690Sborman else if (TELCMD_OK(i)) 284*38690Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 285*38690Sborman else 286*38690Sborman fprintf(NetTrace, "%d ", i); 287*38690Sborman if (TELOPT_OK(j)) 288*38690Sborman fprintf(NetTrace, "%s", TELOPT(j)); 289*38690Sborman else if (TELCMD_OK(j)) 290*38690Sborman fprintf(NetTrace, "%s", TELCMD(j)); 291*38690Sborman else 292*38690Sborman fprintf(NetTrace, "%d", j); 293*38690Sborman fprintf(NetTrace, ", not IAC SE!) "); 294*38690Sborman } 295*38690Sborman } 296*38690Sborman length -= 2; 297*38690Sborman if (length < 1) { 298*38690Sborman fprintf(NetTrace, "(Empty suboption???)"); 299*38690Sborman return; 300*38690Sborman } 30132149Sminshall switch (pointer[0]) { 30232149Sminshall case TELOPT_TTYPE: 303*38690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 30432149Sminshall switch (pointer[1]) { 30532149Sminshall case TELQUAL_IS: 306*38690Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, pointer+2); 30732149Sminshall break; 30832149Sminshall case TELQUAL_SEND: 309*38690Sborman fprintf(NetTrace, "SEND"); 31032149Sminshall break; 31132149Sminshall default: 31232149Sminshall fprintf(NetTrace, 313*38690Sborman "- unknown qualifier %d (0x%x).", 31434849Sminshall pointer[1], pointer[1]); 31532149Sminshall } 31632149Sminshall break; 317*38690Sborman case TELOPT_TSPEED: 318*38690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 319*38690Sborman if (length < 2) { 320*38690Sborman fprintf(NetTrace, " (empty suboption???)"); 321*38690Sborman break; 322*38690Sborman } 323*38690Sborman switch (pointer[1]) { 324*38690Sborman case 0: 325*38690Sborman fprintf(NetTrace, " IS "); 326*38690Sborman fprintf(NetTrace, "%.*s", length-2, pointer+2); 327*38690Sborman break; 328*38690Sborman default: 329*38690Sborman if (pointer[1] == 1) 330*38690Sborman fprintf(NetTrace, " SEND"); 331*38690Sborman else 332*38690Sborman fprintf(NetTrace, " %d (unknown)"); 333*38690Sborman for (i = 2; i < length; i++) 334*38690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 335*38690Sborman break; 336*38690Sborman } 337*38690Sborman break; 338*38690Sborman 339*38690Sborman case TELOPT_LFLOW: 340*38690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 341*38690Sborman if (length < 2) { 342*38690Sborman fprintf(NetTrace, " (empty suboption???)"); 343*38690Sborman break; 344*38690Sborman } 345*38690Sborman switch (pointer[1]) { 346*38690Sborman case 0: 347*38690Sborman fprintf(NetTrace, " OFF"); break; 348*38690Sborman case 1: 349*38690Sborman fprintf(NetTrace, " ON"); break; 350*38690Sborman default: 351*38690Sborman fprintf(NetTrace, " %d (unknown)"); 352*38690Sborman } 353*38690Sborman for (i = 2; i < length; i++) 354*38690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 355*38690Sborman break; 356*38690Sborman 357*38690Sborman case TELOPT_NAWS: 358*38690Sborman fprintf(NetTrace, "NAWS"); 359*38690Sborman if (length < 2) { 360*38690Sborman fprintf(NetTrace, " (empty suboption???)"); 361*38690Sborman break; 362*38690Sborman } 363*38690Sborman if (length == 2) { 364*38690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 365*38690Sborman break; 366*38690Sborman } 367*38690Sborman fprintf(NetTrace, " %d %d (%d)", 368*38690Sborman pointer[1], pointer[2], 369*38690Sborman (((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])); 370*38690Sborman if (length == 4) { 371*38690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 372*38690Sborman break; 373*38690Sborman } 374*38690Sborman fprintf(NetTrace, " %d %d (%d)", 375*38690Sborman pointer[3], pointer[4], 376*38690Sborman (((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])); 377*38690Sborman for (i = 5; i < length; i++) 378*38690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 379*38690Sborman break; 380*38690Sborman 381*38690Sborman case TELOPT_LINEMODE: 382*38690Sborman fprintf(NetTrace, "LINEMODE "); 383*38690Sborman if (length < 2) { 384*38690Sborman fprintf(NetTrace, " (empty suboption???)"); 385*38690Sborman break; 386*38690Sborman } 387*38690Sborman switch (pointer[1]) { 388*38690Sborman case WILL: 389*38690Sborman fprintf(NetTrace, "WILL "); 390*38690Sborman goto common; 391*38690Sborman case WONT: 392*38690Sborman fprintf(NetTrace, "WONT "); 393*38690Sborman goto common; 394*38690Sborman case DO: 395*38690Sborman fprintf(NetTrace, "DO "); 396*38690Sborman goto common; 397*38690Sborman case DONT: 398*38690Sborman fprintf(NetTrace, "DONT "); 399*38690Sborman common: 400*38690Sborman if (length < 3) { 401*38690Sborman fprintf(NetTrace, "(no option???)"); 402*38690Sborman break; 403*38690Sborman } 404*38690Sborman switch (pointer[2]) { 405*38690Sborman case LM_FORWARDMASK: 406*38690Sborman fprintf(NetTrace, "Forward Mask"); 407*38690Sborman for (i = 3; i < length; i++) 408*38690Sborman fprintf(NetTrace, " %x", pointer[i]); 409*38690Sborman break; 410*38690Sborman default: 411*38690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 412*38690Sborman for (i = 3; i < length; i++) 413*38690Sborman fprintf(NetTrace, " %d", pointer[i]); 414*38690Sborman break; 415*38690Sborman } 416*38690Sborman break; 417*38690Sborman 418*38690Sborman case LM_SLC: 419*38690Sborman fprintf(NetTrace, "SLC"); 420*38690Sborman for (i = 2; i < length - 2; i += 3) { 421*38690Sborman if (pointer[i+SLC_FUNC] <= NSLC) 422*38690Sborman fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]); 423*38690Sborman else 424*38690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 425*38690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 426*38690Sborman case SLC_NOSUPPORT: 427*38690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 428*38690Sborman case SLC_CANTCHANGE: 429*38690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 430*38690Sborman case SLC_VARIABLE: 431*38690Sborman fprintf(NetTrace, " VARIABLE"); break; 432*38690Sborman case SLC_DEFAULT: 433*38690Sborman fprintf(NetTrace, " DEFAULT"); break; 434*38690Sborman } 435*38690Sborman fprintf(NetTrace, "%s%s%s", 436*38690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 437*38690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 438*38690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 439*38690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 440*38690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 441*38690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 442*38690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 443*38690Sborman } 444*38690Sborman for (; i < length; i++) 445*38690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 446*38690Sborman break; 447*38690Sborman 448*38690Sborman case LM_MODE: 449*38690Sborman fprintf(NetTrace, "MODE "); 450*38690Sborman if (length < 3) { 451*38690Sborman fprintf(NetTrace, "(no mode???)"); 452*38690Sborman break; 453*38690Sborman } 454*38690Sborman { 455*38690Sborman char tbuf[32]; 456*38690Sborman sprintf(tbuf, "%s%s%s", 457*38690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 458*38690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 459*38690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 460*38690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 461*38690Sborman } 462*38690Sborman if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) 463*38690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 464*38690Sborman for (i = 3; i < length; i++) 465*38690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 466*38690Sborman break; 467*38690Sborman default: 468*38690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 469*38690Sborman for (i = 2; i < length; i++) 470*38690Sborman fprintf(NetTrace, " %d", pointer[i]); 471*38690Sborman } 472*38690Sborman break; 473*38690Sborman 47432149Sminshall default: 475*38690Sborman fprintf(NetTrace, "Unknown option "); 476*38690Sborman for (i = 0; i < length; i++) 477*38690Sborman fprintf(NetTrace, " %d", pointer[i]); 478*38690Sborman break; 47932149Sminshall } 480*38690Sborman if (NetTrace == stdout) 481*38690Sborman fprintf(NetTrace, "\r\n"); 482*38690Sborman else 483*38690Sborman fprintf(NetTrace, "\n"); 48432149Sminshall } 48532149Sminshall } 48636278Sminshall 48736278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 48836278Sminshall * Note that we consider the buffer to run all the 48936278Sminshall * way to the kernel (thus the select). 49036278Sminshall */ 49136278Sminshall 49236278Sminshall void 49336278Sminshall EmptyTerminal() 49436278Sminshall { 49536278Sminshall #if defined(unix) 49636278Sminshall fd_set o; 49736278Sminshall 49836278Sminshall FD_ZERO(&o); 49936278Sminshall #endif /* defined(unix) */ 50036278Sminshall 50136278Sminshall if (TTYBYTES() == 0) { 50236278Sminshall #if defined(unix) 50336278Sminshall FD_SET(tout, &o); 50436278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 50536278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 50636278Sminshall #endif /* defined(unix) */ 50736278Sminshall } else { 50836278Sminshall while (TTYBYTES()) { 50936278Sminshall ttyflush(0); 51036278Sminshall #if defined(unix) 51136278Sminshall FD_SET(tout, &o); 51236278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 51336278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 51436278Sminshall #endif /* defined(unix) */ 51536278Sminshall } 51636278Sminshall } 51736278Sminshall } 51836278Sminshall 51936278Sminshall void 52036278Sminshall SetForExit() 52136278Sminshall { 522*38690Sborman setconnmode(0); 52336278Sminshall #if defined(TN3270) 52436278Sminshall if (In3270) { 52536278Sminshall Finish3270(); 52636278Sminshall } 52736279Sminshall #else /* defined(TN3270) */ 52836279Sminshall do { 52936279Sminshall telrcv(); /* Process any incoming data */ 53036279Sminshall EmptyTerminal(); 53136279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 53236278Sminshall #endif /* defined(TN3270) */ 53336278Sminshall setcommandmode(); 53436278Sminshall fflush(stdout); 53536278Sminshall fflush(stderr); 53636278Sminshall #if defined(TN3270) 53736278Sminshall if (In3270) { 53836278Sminshall StopScreen(1); 53936278Sminshall } 54036278Sminshall #endif /* defined(TN3270) */ 541*38690Sborman setconnmode(0); 54236278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 54336278Sminshall setcommandmode(); 54436278Sminshall } 54536278Sminshall 54636278Sminshall void 54736278Sminshall Exit(returnCode) 54836278Sminshall int returnCode; 54936278Sminshall { 55036278Sminshall SetForExit(); 55136278Sminshall exit(returnCode); 55236278Sminshall } 55336278Sminshall 55436278Sminshall void 55536278Sminshall ExitString(string, returnCode) 55636278Sminshall char *string; 55736278Sminshall int returnCode; 55836278Sminshall { 55936278Sminshall SetForExit(); 56036278Sminshall fwrite(string, 1, strlen(string), stderr); 56136278Sminshall exit(returnCode); 56236278Sminshall } 56336278Sminshall 56436278Sminshall #if defined(MSDOS) 56536278Sminshall void 56636278Sminshall ExitPerror(string, returnCode) 56736278Sminshall char *string; 56836278Sminshall int returnCode; 56936278Sminshall { 57036278Sminshall SetForExit(); 57136278Sminshall perror(string); 57236278Sminshall exit(returnCode); 57336278Sminshall } 57436278Sminshall #endif /* defined(MSDOS) */ 575