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*36279Sminshall static char sccsid[] = "@(#)utilities.c 1.9 (Berkeley) 11/30/88"; 2033686Sbostic #endif /* not lint */ 2133686Sbostic 2232149Sminshall #define TELOPTS 2332149Sminshall #include <arpa/telnet.h> 2432381Sminshall #include <sys/types.h> 2532149Sminshall 2632149Sminshall #include <ctype.h> 2732149Sminshall 2834305Sminshall #include "general.h" 2934305Sminshall 3032381Sminshall #include "ring.h" 3132381Sminshall 3236278Sminshall #include "defines.h" 3336278Sminshall 3432149Sminshall #include "externs.h" 3532149Sminshall 3632149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 3732149Sminshall 3832149Sminshall /* 3932149Sminshall * upcase() 4032149Sminshall * 4132149Sminshall * Upcase (in place) the argument. 4232149Sminshall */ 4332149Sminshall 4432149Sminshall void 4532149Sminshall upcase(argument) 4632149Sminshall register char *argument; 4732149Sminshall { 4832149Sminshall register int c; 4932149Sminshall 5032149Sminshall while ((c = *argument) != 0) { 5132149Sminshall if (islower(c)) { 5232149Sminshall *argument = toupper(c); 5332149Sminshall } 5432149Sminshall argument++; 5532149Sminshall } 5632149Sminshall } 5732149Sminshall 5832149Sminshall /* 5932149Sminshall * SetSockOpt() 6032149Sminshall * 6132149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 6232149Sminshall */ 6332149Sminshall 6432149Sminshall int 6532149Sminshall SetSockOpt(fd, level, option, yesno) 6632149Sminshall int 6732149Sminshall fd, 6832149Sminshall level, 6932149Sminshall option, 7032149Sminshall yesno; 7132149Sminshall { 7232149Sminshall #ifndef NOT43 7332149Sminshall return setsockopt(fd, level, option, 7432149Sminshall (char *)&yesno, sizeof yesno); 7532149Sminshall #else /* NOT43 */ 7632149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 7732149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 7832149Sminshall option); 7932149Sminshall return -1; 8032149Sminshall } 8132149Sminshall return setsockopt(fd, level, option, 0, 0); 8232149Sminshall #endif /* NOT43 */ 8332149Sminshall } 8432149Sminshall 8532149Sminshall /* 8632149Sminshall * The following are routines used to print out debugging information. 8732149Sminshall */ 8832149Sminshall 8932149Sminshall 9032149Sminshall void 9132149Sminshall Dump(direction, buffer, length) 9232149Sminshall char direction; 9332149Sminshall char *buffer; 9432149Sminshall int length; 9532149Sminshall { 9632149Sminshall # define BYTES_PER_LINE 32 9732149Sminshall # define min(x,y) ((x<y)? x:y) 9832149Sminshall char *pThis; 9932149Sminshall int offset; 10032149Sminshall 10132149Sminshall offset = 0; 10232149Sminshall 10332149Sminshall while (length) { 10432149Sminshall /* print one line */ 10532149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 10632149Sminshall pThis = buffer; 10732149Sminshall buffer = buffer+min(length, BYTES_PER_LINE); 10832149Sminshall while (pThis < buffer) { 10932149Sminshall fprintf(NetTrace, "%.2x", (*pThis)&0xff); 11032149Sminshall pThis++; 11132149Sminshall } 11232149Sminshall fprintf(NetTrace, "\n"); 11332149Sminshall length -= BYTES_PER_LINE; 11432149Sminshall offset += BYTES_PER_LINE; 11532149Sminshall if (length < 0) { 11632149Sminshall return; 11732149Sminshall } 11832149Sminshall /* find next unique line */ 11932149Sminshall } 12032149Sminshall } 12132149Sminshall 12232149Sminshall 12332149Sminshall /*VARARGS*/ 12432149Sminshall void 12532149Sminshall printoption(direction, fmt, option, what) 12632149Sminshall char *direction, *fmt; 12732149Sminshall int option, what; 12832149Sminshall { 12932149Sminshall if (!showoptions) 13032149Sminshall return; 13132149Sminshall fprintf(NetTrace, "%s ", direction+1); 13232149Sminshall if (fmt == doopt) 13332149Sminshall fmt = "do"; 13432149Sminshall else if (fmt == dont) 13532149Sminshall fmt = "dont"; 13632149Sminshall else if (fmt == will) 13732149Sminshall fmt = "will"; 13832149Sminshall else if (fmt == wont) 13932149Sminshall fmt = "wont"; 14032149Sminshall else 14132149Sminshall fmt = "???"; 14232149Sminshall if (option < (sizeof telopts/sizeof telopts[0])) 14332149Sminshall fprintf(NetTrace, "%s %s", fmt, telopts[option]); 14432149Sminshall else 14532149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 14632149Sminshall if (*direction == '<') { 14732149Sminshall fprintf(NetTrace, "\r\n"); 14832149Sminshall return; 14932149Sminshall } 15032149Sminshall fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply"); 15132149Sminshall } 15232149Sminshall 15332149Sminshall void 15432149Sminshall printsub(direction, pointer, length) 15532149Sminshall char *direction, /* "<" or ">" */ 15632149Sminshall *pointer; /* where suboption data sits */ 15732149Sminshall int length; /* length of suboption data */ 15832149Sminshall { 15932149Sminshall if (showoptions) { 16032149Sminshall fprintf(NetTrace, "%s suboption ", 16132149Sminshall (direction[0] == '<')? "Received":"Sent"); 16232149Sminshall switch (pointer[0]) { 16332149Sminshall case TELOPT_TTYPE: 16432149Sminshall fprintf(NetTrace, "Terminal type "); 16532149Sminshall switch (pointer[1]) { 16632149Sminshall case TELQUAL_IS: 16732149Sminshall { 16833286Sminshall char tmpbuf[SUBBUFSIZE]; 16932149Sminshall int minlen = min(length, sizeof tmpbuf); 17032149Sminshall 17132149Sminshall memcpy(tmpbuf, pointer+2, minlen); 17232149Sminshall tmpbuf[minlen-1] = 0; 17332149Sminshall fprintf(NetTrace, "is %s.\n", tmpbuf); 17432149Sminshall } 17532149Sminshall break; 17632149Sminshall case TELQUAL_SEND: 17732149Sminshall fprintf(NetTrace, "- request to send.\n"); 17832149Sminshall break; 17932149Sminshall default: 18032149Sminshall fprintf(NetTrace, 18134849Sminshall "- unknown qualifier %d (0x%x).\n", 18234849Sminshall pointer[1], pointer[1]); 18332149Sminshall } 18432149Sminshall break; 18532149Sminshall default: 18632149Sminshall fprintf(NetTrace, "Unknown option %d (0x%x)\n", 18732149Sminshall pointer[0], pointer[0]); 18832149Sminshall } 18932149Sminshall } 19032149Sminshall } 19136278Sminshall 19236278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 19336278Sminshall * Note that we consider the buffer to run all the 19436278Sminshall * way to the kernel (thus the select). 19536278Sminshall */ 19636278Sminshall 19736278Sminshall void 19836278Sminshall EmptyTerminal() 19936278Sminshall { 20036278Sminshall #if defined(unix) 20136278Sminshall fd_set o; 20236278Sminshall 20336278Sminshall FD_ZERO(&o); 20436278Sminshall #endif /* defined(unix) */ 20536278Sminshall 20636278Sminshall if (TTYBYTES() == 0) { 20736278Sminshall #if defined(unix) 20836278Sminshall FD_SET(tout, &o); 20936278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 21036278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 21136278Sminshall #endif /* defined(unix) */ 21236278Sminshall } else { 21336278Sminshall while (TTYBYTES()) { 21436278Sminshall ttyflush(0); 21536278Sminshall #if defined(unix) 21636278Sminshall FD_SET(tout, &o); 21736278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 21836278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 21936278Sminshall #endif /* defined(unix) */ 22036278Sminshall } 22136278Sminshall } 22236278Sminshall } 22336278Sminshall 22436278Sminshall void 22536278Sminshall SetForExit() 22636278Sminshall { 22736278Sminshall setconnmode(); 22836278Sminshall #if defined(TN3270) 22936278Sminshall if (In3270) { 23036278Sminshall Finish3270(); 23136278Sminshall } 232*36279Sminshall #else /* defined(TN3270) */ 233*36279Sminshall do { 234*36279Sminshall telrcv(); /* Process any incoming data */ 235*36279Sminshall EmptyTerminal(); 236*36279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 23736278Sminshall #endif /* defined(TN3270) */ 23836278Sminshall setcommandmode(); 23936278Sminshall fflush(stdout); 24036278Sminshall fflush(stderr); 24136278Sminshall #if defined(TN3270) 24236278Sminshall if (In3270) { 24336278Sminshall StopScreen(1); 24436278Sminshall } 24536278Sminshall #endif /* defined(TN3270) */ 24636278Sminshall setconnmode(); 24736278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 24836278Sminshall setcommandmode(); 24936278Sminshall } 25036278Sminshall 25136278Sminshall void 25236278Sminshall Exit(returnCode) 25336278Sminshall int returnCode; 25436278Sminshall { 25536278Sminshall SetForExit(); 25636278Sminshall exit(returnCode); 25736278Sminshall } 25836278Sminshall 25936278Sminshall void 26036278Sminshall ExitString(string, returnCode) 26136278Sminshall char *string; 26236278Sminshall int returnCode; 26336278Sminshall { 26436278Sminshall SetForExit(); 26536278Sminshall fwrite(string, 1, strlen(string), stderr); 26636278Sminshall exit(returnCode); 26736278Sminshall } 26836278Sminshall 26936278Sminshall #if defined(MSDOS) 27036278Sminshall void 27136278Sminshall ExitPerror(string, returnCode) 27236278Sminshall char *string; 27336278Sminshall int returnCode; 27436278Sminshall { 27536278Sminshall SetForExit(); 27636278Sminshall perror(string); 27736278Sminshall exit(returnCode); 27836278Sminshall } 27936278Sminshall #endif /* defined(MSDOS) */ 280