1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)utilities.c 1.12 (Berkeley) 03/21/89"; 20 #endif /* not lint */ 21 22 #define TELOPTS 23 #include <arpa/telnet.h> 24 #include <sys/types.h> 25 26 #include <ctype.h> 27 28 #include "general.h" 29 30 #include "fdset.h" 31 32 #include "ring.h" 33 34 #include "defines.h" 35 36 #include "externs.h" 37 38 FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 39 40 /* 41 * upcase() 42 * 43 * Upcase (in place) the argument. 44 */ 45 46 void 47 upcase(argument) 48 register char *argument; 49 { 50 register int c; 51 52 while ((c = *argument) != 0) { 53 if (islower(c)) { 54 *argument = toupper(c); 55 } 56 argument++; 57 } 58 } 59 60 /* 61 * SetSockOpt() 62 * 63 * Compensate for differences in 4.2 and 4.3 systems. 64 */ 65 66 int 67 SetSockOpt(fd, level, option, yesno) 68 int 69 fd, 70 level, 71 option, 72 yesno; 73 { 74 #ifndef NOT43 75 return setsockopt(fd, level, option, 76 (char *)&yesno, sizeof yesno); 77 #else /* NOT43 */ 78 if (yesno == 0) { /* Can't do that in 4.2! */ 79 fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 80 option); 81 return -1; 82 } 83 return setsockopt(fd, level, option, 0, 0); 84 #endif /* NOT43 */ 85 } 86 87 /* 88 * The following are routines used to print out debugging information. 89 */ 90 91 92 void 93 Dump(direction, buffer, length) 94 char direction; 95 char *buffer; 96 int length; 97 { 98 # define BYTES_PER_LINE 32 99 # define min(x,y) ((x<y)? x:y) 100 char *pThis; 101 int offset; 102 103 offset = 0; 104 105 while (length) { 106 /* print one line */ 107 fprintf(NetTrace, "%c 0x%x\t", direction, offset); 108 pThis = buffer; 109 buffer = buffer+min(length, BYTES_PER_LINE); 110 while (pThis < buffer) { 111 fprintf(NetTrace, "%.2x", (*pThis)&0xff); 112 pThis++; 113 } 114 if (NetTrace == stdout) { 115 fprintf(NetTrace, "\n"); 116 } else { 117 fprintf(NetTrace, "\r\n"); 118 } 119 length -= BYTES_PER_LINE; 120 offset += BYTES_PER_LINE; 121 if (length < 0) { 122 fflush(NetTrace); 123 return; 124 } 125 /* find next unique line */ 126 } 127 fflush(NetTrace); 128 } 129 130 131 void 132 printoption(direction, fmt, option) 133 char *direction, *fmt; 134 int option; 135 { 136 if (!showoptions) 137 return; 138 fprintf(NetTrace, "%s ", direction); 139 if (option < (sizeof telopts/sizeof telopts[0])) 140 fprintf(NetTrace, "%s %s", fmt, telopts[option]); 141 else 142 fprintf(NetTrace, "%s %d", fmt, option); 143 if (NetTrace == stdout) { 144 fprintf(NetTrace, "\r\n"); 145 } else { 146 fprintf(NetTrace, "\n"); 147 } 148 return; 149 } 150 151 void 152 printsub(direction, pointer, length) 153 char *direction, /* "<" or ">" */ 154 *pointer; /* where suboption data sits */ 155 int length; /* length of suboption data */ 156 { 157 if (showoptions) { 158 fprintf(NetTrace, "%s suboption ", 159 (direction[0] == '<')? "Received":"Sent"); 160 switch (pointer[0]) { 161 case TELOPT_TTYPE: 162 fprintf(NetTrace, "Terminal type "); 163 switch (pointer[1]) { 164 case TELQUAL_IS: 165 { 166 char tmpbuf[SUBBUFSIZE]; 167 int minlen = min(length, sizeof tmpbuf); 168 169 memcpy(tmpbuf, pointer+2, minlen); 170 tmpbuf[minlen-1] = 0; 171 fprintf(NetTrace, "is %s.\n", tmpbuf); 172 } 173 break; 174 case TELQUAL_SEND: 175 fprintf(NetTrace, "- request to send.\n"); 176 break; 177 default: 178 fprintf(NetTrace, 179 "- unknown qualifier %d (0x%x).\n", 180 pointer[1], pointer[1]); 181 } 182 break; 183 default: 184 fprintf(NetTrace, "Unknown option %d (0x%x)\n", 185 pointer[0], pointer[0]); 186 } 187 } 188 } 189 190 /* EmptyTerminal - called to make sure that the terminal buffer is empty. 191 * Note that we consider the buffer to run all the 192 * way to the kernel (thus the select). 193 */ 194 195 void 196 EmptyTerminal() 197 { 198 #if defined(unix) 199 fd_set o; 200 201 FD_ZERO(&o); 202 #endif /* defined(unix) */ 203 204 if (TTYBYTES() == 0) { 205 #if defined(unix) 206 FD_SET(tout, &o); 207 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 208 (struct timeval *) 0); /* wait for TTLOWAT */ 209 #endif /* defined(unix) */ 210 } else { 211 while (TTYBYTES()) { 212 ttyflush(0); 213 #if defined(unix) 214 FD_SET(tout, &o); 215 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 216 (struct timeval *) 0); /* wait for TTLOWAT */ 217 #endif /* defined(unix) */ 218 } 219 } 220 } 221 222 void 223 SetForExit() 224 { 225 setconnmode(); 226 #if defined(TN3270) 227 if (In3270) { 228 Finish3270(); 229 } 230 #else /* defined(TN3270) */ 231 do { 232 telrcv(); /* Process any incoming data */ 233 EmptyTerminal(); 234 } while (ring_full_count(&netiring)); /* While there is any */ 235 #endif /* defined(TN3270) */ 236 setcommandmode(); 237 fflush(stdout); 238 fflush(stderr); 239 #if defined(TN3270) 240 if (In3270) { 241 StopScreen(1); 242 } 243 #endif /* defined(TN3270) */ 244 setconnmode(); 245 EmptyTerminal(); /* Flush the path to the tty */ 246 setcommandmode(); 247 } 248 249 void 250 Exit(returnCode) 251 int returnCode; 252 { 253 SetForExit(); 254 exit(returnCode); 255 } 256 257 void 258 ExitString(string, returnCode) 259 char *string; 260 int returnCode; 261 { 262 SetForExit(); 263 fwrite(string, 1, strlen(string), stderr); 264 exit(returnCode); 265 } 266 267 #if defined(MSDOS) 268 void 269 ExitPerror(string, returnCode) 270 char *string; 271 int returnCode; 272 { 273 SetForExit(); 274 perror(string); 275 exit(returnCode); 276 } 277 #endif /* defined(MSDOS) */ 278