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.10 (Berkeley) 12/01/88"; 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 fprintf(NetTrace, "\n"); 115 length -= BYTES_PER_LINE; 116 offset += BYTES_PER_LINE; 117 if (length < 0) { 118 return; 119 } 120 /* find next unique line */ 121 } 122 } 123 124 125 /*VARARGS*/ 126 void 127 printoption(direction, fmt, option, what) 128 char *direction, *fmt; 129 int option, what; 130 { 131 if (!showoptions) 132 return; 133 fprintf(NetTrace, "%s ", direction+1); 134 if (fmt == doopt) 135 fmt = "do"; 136 else if (fmt == dont) 137 fmt = "dont"; 138 else if (fmt == will) 139 fmt = "will"; 140 else if (fmt == wont) 141 fmt = "wont"; 142 else 143 fmt = "???"; 144 if (option < (sizeof telopts/sizeof telopts[0])) 145 fprintf(NetTrace, "%s %s", fmt, telopts[option]); 146 else 147 fprintf(NetTrace, "%s %d", fmt, option); 148 if (*direction == '<') { 149 fprintf(NetTrace, "\r\n"); 150 return; 151 } 152 fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply"); 153 } 154 155 void 156 printsub(direction, pointer, length) 157 char *direction, /* "<" or ">" */ 158 *pointer; /* where suboption data sits */ 159 int length; /* length of suboption data */ 160 { 161 if (showoptions) { 162 fprintf(NetTrace, "%s suboption ", 163 (direction[0] == '<')? "Received":"Sent"); 164 switch (pointer[0]) { 165 case TELOPT_TTYPE: 166 fprintf(NetTrace, "Terminal type "); 167 switch (pointer[1]) { 168 case TELQUAL_IS: 169 { 170 char tmpbuf[SUBBUFSIZE]; 171 int minlen = min(length, sizeof tmpbuf); 172 173 memcpy(tmpbuf, pointer+2, minlen); 174 tmpbuf[minlen-1] = 0; 175 fprintf(NetTrace, "is %s.\n", tmpbuf); 176 } 177 break; 178 case TELQUAL_SEND: 179 fprintf(NetTrace, "- request to send.\n"); 180 break; 181 default: 182 fprintf(NetTrace, 183 "- unknown qualifier %d (0x%x).\n", 184 pointer[1], pointer[1]); 185 } 186 break; 187 default: 188 fprintf(NetTrace, "Unknown option %d (0x%x)\n", 189 pointer[0], pointer[0]); 190 } 191 } 192 } 193 194 /* EmptyTerminal - called to make sure that the terminal buffer is empty. 195 * Note that we consider the buffer to run all the 196 * way to the kernel (thus the select). 197 */ 198 199 void 200 EmptyTerminal() 201 { 202 #if defined(unix) 203 fd_set o; 204 205 FD_ZERO(&o); 206 #endif /* defined(unix) */ 207 208 if (TTYBYTES() == 0) { 209 #if defined(unix) 210 FD_SET(tout, &o); 211 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 212 (struct timeval *) 0); /* wait for TTLOWAT */ 213 #endif /* defined(unix) */ 214 } else { 215 while (TTYBYTES()) { 216 ttyflush(0); 217 #if defined(unix) 218 FD_SET(tout, &o); 219 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 220 (struct timeval *) 0); /* wait for TTLOWAT */ 221 #endif /* defined(unix) */ 222 } 223 } 224 } 225 226 void 227 SetForExit() 228 { 229 setconnmode(); 230 #if defined(TN3270) 231 if (In3270) { 232 Finish3270(); 233 } 234 #else /* defined(TN3270) */ 235 do { 236 telrcv(); /* Process any incoming data */ 237 EmptyTerminal(); 238 } while (ring_full_count(&netiring)); /* While there is any */ 239 #endif /* defined(TN3270) */ 240 setcommandmode(); 241 fflush(stdout); 242 fflush(stderr); 243 #if defined(TN3270) 244 if (In3270) { 245 StopScreen(1); 246 } 247 #endif /* defined(TN3270) */ 248 setconnmode(); 249 EmptyTerminal(); /* Flush the path to the tty */ 250 setcommandmode(); 251 } 252 253 void 254 Exit(returnCode) 255 int returnCode; 256 { 257 SetForExit(); 258 exit(returnCode); 259 } 260 261 void 262 ExitString(string, returnCode) 263 char *string; 264 int returnCode; 265 { 266 SetForExit(); 267 fwrite(string, 1, strlen(string), stderr); 268 exit(returnCode); 269 } 270 271 #if defined(MSDOS) 272 void 273 ExitPerror(string, returnCode) 274 char *string; 275 int returnCode; 276 { 277 SetForExit(); 278 perror(string); 279 exit(returnCode); 280 } 281 #endif /* defined(MSDOS) */ 282