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*36693Sminshall static char sccsid[] = "@(#)utilities.c 1.11 (Berkeley) 02/06/89"; 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 3036280Sminshall #include "fdset.h" 3136280Sminshall 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) { 118*36693Sminshall fflush(NetTrace); 11932149Sminshall return; 12032149Sminshall } 12132149Sminshall /* find next unique line */ 12232149Sminshall } 123*36693Sminshall fflush(NetTrace); 12432149Sminshall } 12532149Sminshall 12632149Sminshall 12732149Sminshall /*VARARGS*/ 12832149Sminshall void 12932149Sminshall printoption(direction, fmt, option, what) 13032149Sminshall char *direction, *fmt; 13132149Sminshall int option, what; 13232149Sminshall { 13332149Sminshall if (!showoptions) 13432149Sminshall return; 13532149Sminshall fprintf(NetTrace, "%s ", direction+1); 13632149Sminshall if (fmt == doopt) 13732149Sminshall fmt = "do"; 13832149Sminshall else if (fmt == dont) 13932149Sminshall fmt = "dont"; 14032149Sminshall else if (fmt == will) 14132149Sminshall fmt = "will"; 14232149Sminshall else if (fmt == wont) 14332149Sminshall fmt = "wont"; 14432149Sminshall else 14532149Sminshall fmt = "???"; 14632149Sminshall if (option < (sizeof telopts/sizeof telopts[0])) 14732149Sminshall fprintf(NetTrace, "%s %s", fmt, telopts[option]); 14832149Sminshall else 14932149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 15032149Sminshall if (*direction == '<') { 15132149Sminshall fprintf(NetTrace, "\r\n"); 15232149Sminshall return; 15332149Sminshall } 15432149Sminshall fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply"); 15532149Sminshall } 15632149Sminshall 15732149Sminshall void 15832149Sminshall printsub(direction, pointer, length) 15932149Sminshall char *direction, /* "<" or ">" */ 16032149Sminshall *pointer; /* where suboption data sits */ 16132149Sminshall int length; /* length of suboption data */ 16232149Sminshall { 16332149Sminshall if (showoptions) { 16432149Sminshall fprintf(NetTrace, "%s suboption ", 16532149Sminshall (direction[0] == '<')? "Received":"Sent"); 16632149Sminshall switch (pointer[0]) { 16732149Sminshall case TELOPT_TTYPE: 16832149Sminshall fprintf(NetTrace, "Terminal type "); 16932149Sminshall switch (pointer[1]) { 17032149Sminshall case TELQUAL_IS: 17132149Sminshall { 17233286Sminshall char tmpbuf[SUBBUFSIZE]; 17332149Sminshall int minlen = min(length, sizeof tmpbuf); 17432149Sminshall 17532149Sminshall memcpy(tmpbuf, pointer+2, minlen); 17632149Sminshall tmpbuf[minlen-1] = 0; 17732149Sminshall fprintf(NetTrace, "is %s.\n", tmpbuf); 17832149Sminshall } 17932149Sminshall break; 18032149Sminshall case TELQUAL_SEND: 18132149Sminshall fprintf(NetTrace, "- request to send.\n"); 18232149Sminshall break; 18332149Sminshall default: 18432149Sminshall fprintf(NetTrace, 18534849Sminshall "- unknown qualifier %d (0x%x).\n", 18634849Sminshall pointer[1], pointer[1]); 18732149Sminshall } 18832149Sminshall break; 18932149Sminshall default: 19032149Sminshall fprintf(NetTrace, "Unknown option %d (0x%x)\n", 19132149Sminshall pointer[0], pointer[0]); 19232149Sminshall } 19332149Sminshall } 19432149Sminshall } 19536278Sminshall 19636278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 19736278Sminshall * Note that we consider the buffer to run all the 19836278Sminshall * way to the kernel (thus the select). 19936278Sminshall */ 20036278Sminshall 20136278Sminshall void 20236278Sminshall EmptyTerminal() 20336278Sminshall { 20436278Sminshall #if defined(unix) 20536278Sminshall fd_set o; 20636278Sminshall 20736278Sminshall FD_ZERO(&o); 20836278Sminshall #endif /* defined(unix) */ 20936278Sminshall 21036278Sminshall if (TTYBYTES() == 0) { 21136278Sminshall #if defined(unix) 21236278Sminshall FD_SET(tout, &o); 21336278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 21436278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 21536278Sminshall #endif /* defined(unix) */ 21636278Sminshall } else { 21736278Sminshall while (TTYBYTES()) { 21836278Sminshall ttyflush(0); 21936278Sminshall #if defined(unix) 22036278Sminshall FD_SET(tout, &o); 22136278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 22236278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 22336278Sminshall #endif /* defined(unix) */ 22436278Sminshall } 22536278Sminshall } 22636278Sminshall } 22736278Sminshall 22836278Sminshall void 22936278Sminshall SetForExit() 23036278Sminshall { 23136278Sminshall setconnmode(); 23236278Sminshall #if defined(TN3270) 23336278Sminshall if (In3270) { 23436278Sminshall Finish3270(); 23536278Sminshall } 23636279Sminshall #else /* defined(TN3270) */ 23736279Sminshall do { 23836279Sminshall telrcv(); /* Process any incoming data */ 23936279Sminshall EmptyTerminal(); 24036279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 24136278Sminshall #endif /* defined(TN3270) */ 24236278Sminshall setcommandmode(); 24336278Sminshall fflush(stdout); 24436278Sminshall fflush(stderr); 24536278Sminshall #if defined(TN3270) 24636278Sminshall if (In3270) { 24736278Sminshall StopScreen(1); 24836278Sminshall } 24936278Sminshall #endif /* defined(TN3270) */ 25036278Sminshall setconnmode(); 25136278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 25236278Sminshall setcommandmode(); 25336278Sminshall } 25436278Sminshall 25536278Sminshall void 25636278Sminshall Exit(returnCode) 25736278Sminshall int returnCode; 25836278Sminshall { 25936278Sminshall SetForExit(); 26036278Sminshall exit(returnCode); 26136278Sminshall } 26236278Sminshall 26336278Sminshall void 26436278Sminshall ExitString(string, returnCode) 26536278Sminshall char *string; 26636278Sminshall int returnCode; 26736278Sminshall { 26836278Sminshall SetForExit(); 26936278Sminshall fwrite(string, 1, strlen(string), stderr); 27036278Sminshall exit(returnCode); 27136278Sminshall } 27236278Sminshall 27336278Sminshall #if defined(MSDOS) 27436278Sminshall void 27536278Sminshall ExitPerror(string, returnCode) 27636278Sminshall char *string; 27736278Sminshall int returnCode; 27836278Sminshall { 27936278Sminshall SetForExit(); 28036278Sminshall perror(string); 28136278Sminshall exit(returnCode); 28236278Sminshall } 28336278Sminshall #endif /* defined(MSDOS) */ 284