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