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*38207Sminshall static char sccsid[] = "@(#)utilities.c 1.13 (Berkeley) 05/30/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 } 11437226Sminshall if (NetTrace == stdout) { 115*38207Sminshall fprintf(NetTrace, "\r\n"); 116*38207Sminshall } else { 11737226Sminshall fprintf(NetTrace, "\n"); 11837226Sminshall } 11932149Sminshall length -= BYTES_PER_LINE; 12032149Sminshall offset += BYTES_PER_LINE; 12132149Sminshall if (length < 0) { 12236693Sminshall fflush(NetTrace); 12332149Sminshall return; 12432149Sminshall } 12532149Sminshall /* find next unique line */ 12632149Sminshall } 12736693Sminshall fflush(NetTrace); 12832149Sminshall } 12932149Sminshall 13032149Sminshall 13132149Sminshall void 13237226Sminshall printoption(direction, fmt, option) 13332149Sminshall char *direction, *fmt; 13437226Sminshall int option; 13532149Sminshall { 13632149Sminshall if (!showoptions) 13732149Sminshall return; 13837226Sminshall fprintf(NetTrace, "%s ", direction); 13932149Sminshall if (option < (sizeof telopts/sizeof telopts[0])) 14032149Sminshall fprintf(NetTrace, "%s %s", fmt, telopts[option]); 14132149Sminshall else 14232149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 14337226Sminshall if (NetTrace == stdout) { 14437226Sminshall fprintf(NetTrace, "\r\n"); 14537226Sminshall } else { 14637226Sminshall fprintf(NetTrace, "\n"); 14732149Sminshall } 14837226Sminshall return; 14932149Sminshall } 15032149Sminshall 15132149Sminshall void 15232149Sminshall printsub(direction, pointer, length) 15332149Sminshall char *direction, /* "<" or ">" */ 15432149Sminshall *pointer; /* where suboption data sits */ 15532149Sminshall int length; /* length of suboption data */ 15632149Sminshall { 15732149Sminshall if (showoptions) { 15832149Sminshall fprintf(NetTrace, "%s suboption ", 15932149Sminshall (direction[0] == '<')? "Received":"Sent"); 16032149Sminshall switch (pointer[0]) { 16132149Sminshall case TELOPT_TTYPE: 16232149Sminshall fprintf(NetTrace, "Terminal type "); 16332149Sminshall switch (pointer[1]) { 16432149Sminshall case TELQUAL_IS: 16532149Sminshall { 16633286Sminshall char tmpbuf[SUBBUFSIZE]; 16732149Sminshall int minlen = min(length, sizeof tmpbuf); 16832149Sminshall 16932149Sminshall memcpy(tmpbuf, pointer+2, minlen); 17032149Sminshall tmpbuf[minlen-1] = 0; 17132149Sminshall fprintf(NetTrace, "is %s.\n", tmpbuf); 17232149Sminshall } 17332149Sminshall break; 17432149Sminshall case TELQUAL_SEND: 17532149Sminshall fprintf(NetTrace, "- request to send.\n"); 17632149Sminshall break; 17732149Sminshall default: 17832149Sminshall fprintf(NetTrace, 17934849Sminshall "- unknown qualifier %d (0x%x).\n", 18034849Sminshall pointer[1], pointer[1]); 18132149Sminshall } 18232149Sminshall break; 18332149Sminshall default: 18432149Sminshall fprintf(NetTrace, "Unknown option %d (0x%x)\n", 18532149Sminshall pointer[0], pointer[0]); 18632149Sminshall } 18732149Sminshall } 18832149Sminshall } 18936278Sminshall 19036278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 19136278Sminshall * Note that we consider the buffer to run all the 19236278Sminshall * way to the kernel (thus the select). 19336278Sminshall */ 19436278Sminshall 19536278Sminshall void 19636278Sminshall EmptyTerminal() 19736278Sminshall { 19836278Sminshall #if defined(unix) 19936278Sminshall fd_set o; 20036278Sminshall 20136278Sminshall FD_ZERO(&o); 20236278Sminshall #endif /* defined(unix) */ 20336278Sminshall 20436278Sminshall if (TTYBYTES() == 0) { 20536278Sminshall #if defined(unix) 20636278Sminshall FD_SET(tout, &o); 20736278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 20836278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 20936278Sminshall #endif /* defined(unix) */ 21036278Sminshall } else { 21136278Sminshall while (TTYBYTES()) { 21236278Sminshall ttyflush(0); 21336278Sminshall #if defined(unix) 21436278Sminshall FD_SET(tout, &o); 21536278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 21636278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 21736278Sminshall #endif /* defined(unix) */ 21836278Sminshall } 21936278Sminshall } 22036278Sminshall } 22136278Sminshall 22236278Sminshall void 22336278Sminshall SetForExit() 22436278Sminshall { 22536278Sminshall setconnmode(); 22636278Sminshall #if defined(TN3270) 22736278Sminshall if (In3270) { 22836278Sminshall Finish3270(); 22936278Sminshall } 23036279Sminshall #else /* defined(TN3270) */ 23136279Sminshall do { 23236279Sminshall telrcv(); /* Process any incoming data */ 23336279Sminshall EmptyTerminal(); 23436279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 23536278Sminshall #endif /* defined(TN3270) */ 23636278Sminshall setcommandmode(); 23736278Sminshall fflush(stdout); 23836278Sminshall fflush(stderr); 23936278Sminshall #if defined(TN3270) 24036278Sminshall if (In3270) { 24136278Sminshall StopScreen(1); 24236278Sminshall } 24336278Sminshall #endif /* defined(TN3270) */ 24436278Sminshall setconnmode(); 24536278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 24636278Sminshall setcommandmode(); 24736278Sminshall } 24836278Sminshall 24936278Sminshall void 25036278Sminshall Exit(returnCode) 25136278Sminshall int returnCode; 25236278Sminshall { 25336278Sminshall SetForExit(); 25436278Sminshall exit(returnCode); 25536278Sminshall } 25636278Sminshall 25736278Sminshall void 25836278Sminshall ExitString(string, returnCode) 25936278Sminshall char *string; 26036278Sminshall int returnCode; 26136278Sminshall { 26236278Sminshall SetForExit(); 26336278Sminshall fwrite(string, 1, strlen(string), stderr); 26436278Sminshall exit(returnCode); 26536278Sminshall } 26636278Sminshall 26736278Sminshall #if defined(MSDOS) 26836278Sminshall void 26936278Sminshall ExitPerror(string, returnCode) 27036278Sminshall char *string; 27136278Sminshall int returnCode; 27236278Sminshall { 27336278Sminshall SetForExit(); 27436278Sminshall perror(string); 27536278Sminshall exit(returnCode); 27636278Sminshall } 27736278Sminshall #endif /* defined(MSDOS) */ 278