xref: /csrg-svn/usr.bin/telnet/utilities.c (revision 36278)
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*36278Sminshall static char sccsid[] = "@(#)utilities.c	1.8 (Berkeley) 11/30/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 
3032381Sminshall #include "ring.h"
3132381Sminshall 
32*36278Sminshall #include "defines.h"
33*36278Sminshall 
3432149Sminshall #include "externs.h"
3532149Sminshall 
3632149Sminshall FILE	*NetTrace = 0;		/* Not in bss, since needs to stay */
3732149Sminshall 
3832149Sminshall /*
3932149Sminshall  * upcase()
4032149Sminshall  *
4132149Sminshall  *	Upcase (in place) the argument.
4232149Sminshall  */
4332149Sminshall 
4432149Sminshall void
4532149Sminshall upcase(argument)
4632149Sminshall register char *argument;
4732149Sminshall {
4832149Sminshall     register int c;
4932149Sminshall 
5032149Sminshall     while ((c = *argument) != 0) {
5132149Sminshall 	if (islower(c)) {
5232149Sminshall 	    *argument = toupper(c);
5332149Sminshall 	}
5432149Sminshall 	argument++;
5532149Sminshall     }
5632149Sminshall }
5732149Sminshall 
5832149Sminshall /*
5932149Sminshall  * SetSockOpt()
6032149Sminshall  *
6132149Sminshall  * Compensate for differences in 4.2 and 4.3 systems.
6232149Sminshall  */
6332149Sminshall 
6432149Sminshall int
6532149Sminshall SetSockOpt(fd, level, option, yesno)
6632149Sminshall int
6732149Sminshall 	fd,
6832149Sminshall 	level,
6932149Sminshall 	option,
7032149Sminshall 	yesno;
7132149Sminshall {
7232149Sminshall #ifndef	NOT43
7332149Sminshall     return setsockopt(fd, level, option,
7432149Sminshall 				(char *)&yesno, sizeof yesno);
7532149Sminshall #else	/* NOT43 */
7632149Sminshall     if (yesno == 0) {		/* Can't do that in 4.2! */
7732149Sminshall 	fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
7832149Sminshall 				option);
7932149Sminshall 	return -1;
8032149Sminshall     }
8132149Sminshall     return setsockopt(fd, level, option, 0, 0);
8232149Sminshall #endif	/* NOT43 */
8332149Sminshall }
8432149Sminshall 
8532149Sminshall /*
8632149Sminshall  * The following are routines used to print out debugging information.
8732149Sminshall  */
8832149Sminshall 
8932149Sminshall 
9032149Sminshall void
9132149Sminshall Dump(direction, buffer, length)
9232149Sminshall char	direction;
9332149Sminshall char	*buffer;
9432149Sminshall int	length;
9532149Sminshall {
9632149Sminshall #   define BYTES_PER_LINE	32
9732149Sminshall #   define min(x,y)	((x<y)? x:y)
9832149Sminshall     char *pThis;
9932149Sminshall     int offset;
10032149Sminshall 
10132149Sminshall     offset = 0;
10232149Sminshall 
10332149Sminshall     while (length) {
10432149Sminshall 	/* print one line */
10532149Sminshall 	fprintf(NetTrace, "%c 0x%x\t", direction, offset);
10632149Sminshall 	pThis = buffer;
10732149Sminshall 	buffer = buffer+min(length, BYTES_PER_LINE);
10832149Sminshall 	while (pThis < buffer) {
10932149Sminshall 	    fprintf(NetTrace, "%.2x", (*pThis)&0xff);
11032149Sminshall 	    pThis++;
11132149Sminshall 	}
11232149Sminshall 	fprintf(NetTrace, "\n");
11332149Sminshall 	length -= BYTES_PER_LINE;
11432149Sminshall 	offset += BYTES_PER_LINE;
11532149Sminshall 	if (length < 0) {
11632149Sminshall 	    return;
11732149Sminshall 	}
11832149Sminshall 	/* find next unique line */
11932149Sminshall     }
12032149Sminshall }
12132149Sminshall 
12232149Sminshall 
12332149Sminshall /*VARARGS*/
12432149Sminshall void
12532149Sminshall printoption(direction, fmt, option, what)
12632149Sminshall 	char *direction, *fmt;
12732149Sminshall 	int option, what;
12832149Sminshall {
12932149Sminshall 	if (!showoptions)
13032149Sminshall 		return;
13132149Sminshall 	fprintf(NetTrace, "%s ", direction+1);
13232149Sminshall 	if (fmt == doopt)
13332149Sminshall 		fmt = "do";
13432149Sminshall 	else if (fmt == dont)
13532149Sminshall 		fmt = "dont";
13632149Sminshall 	else if (fmt == will)
13732149Sminshall 		fmt = "will";
13832149Sminshall 	else if (fmt == wont)
13932149Sminshall 		fmt = "wont";
14032149Sminshall 	else
14132149Sminshall 		fmt = "???";
14232149Sminshall 	if (option < (sizeof telopts/sizeof telopts[0]))
14332149Sminshall 		fprintf(NetTrace, "%s %s", fmt, telopts[option]);
14432149Sminshall 	else
14532149Sminshall 		fprintf(NetTrace, "%s %d", fmt, option);
14632149Sminshall 	if (*direction == '<') {
14732149Sminshall 		fprintf(NetTrace, "\r\n");
14832149Sminshall 		return;
14932149Sminshall 	}
15032149Sminshall 	fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply");
15132149Sminshall }
15232149Sminshall 
15332149Sminshall void
15432149Sminshall printsub(direction, pointer, length)
15532149Sminshall char	*direction,		/* "<" or ">" */
15632149Sminshall 	*pointer;		/* where suboption data sits */
15732149Sminshall int	length;			/* length of suboption data */
15832149Sminshall {
15932149Sminshall     if (showoptions) {
16032149Sminshall 	fprintf(NetTrace, "%s suboption ",
16132149Sminshall 				(direction[0] == '<')? "Received":"Sent");
16232149Sminshall 	switch (pointer[0]) {
16332149Sminshall 	case TELOPT_TTYPE:
16432149Sminshall 	    fprintf(NetTrace, "Terminal type ");
16532149Sminshall 	    switch (pointer[1]) {
16632149Sminshall 	    case TELQUAL_IS:
16732149Sminshall 		{
16833286Sminshall 		    char tmpbuf[SUBBUFSIZE];
16932149Sminshall 		    int minlen = min(length, sizeof tmpbuf);
17032149Sminshall 
17132149Sminshall 		    memcpy(tmpbuf, pointer+2, minlen);
17232149Sminshall 		    tmpbuf[minlen-1] = 0;
17332149Sminshall 		    fprintf(NetTrace, "is %s.\n", tmpbuf);
17432149Sminshall 		}
17532149Sminshall 		break;
17632149Sminshall 	    case TELQUAL_SEND:
17732149Sminshall 		fprintf(NetTrace, "- request to send.\n");
17832149Sminshall 		break;
17932149Sminshall 	    default:
18032149Sminshall 		fprintf(NetTrace,
18134849Sminshall 				"- unknown qualifier %d (0x%x).\n",
18234849Sminshall 				pointer[1], pointer[1]);
18332149Sminshall 	    }
18432149Sminshall 	    break;
18532149Sminshall 	default:
18632149Sminshall 	    fprintf(NetTrace, "Unknown option %d (0x%x)\n",
18732149Sminshall 					pointer[0], pointer[0]);
18832149Sminshall 	}
18932149Sminshall     }
19032149Sminshall }
191*36278Sminshall 
192*36278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty.
193*36278Sminshall  *			Note that we consider the buffer to run all the
194*36278Sminshall  *			way to the kernel (thus the select).
195*36278Sminshall  */
196*36278Sminshall 
197*36278Sminshall void
198*36278Sminshall EmptyTerminal()
199*36278Sminshall {
200*36278Sminshall #if	defined(unix)
201*36278Sminshall     fd_set	o;
202*36278Sminshall 
203*36278Sminshall     FD_ZERO(&o);
204*36278Sminshall #endif	/* defined(unix) */
205*36278Sminshall 
206*36278Sminshall     if (TTYBYTES() == 0) {
207*36278Sminshall #if	defined(unix)
208*36278Sminshall 	FD_SET(tout, &o);
209*36278Sminshall 	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
210*36278Sminshall 			(struct timeval *) 0);	/* wait for TTLOWAT */
211*36278Sminshall #endif	/* defined(unix) */
212*36278Sminshall     } else {
213*36278Sminshall 	while (TTYBYTES()) {
214*36278Sminshall 	    ttyflush(0);
215*36278Sminshall #if	defined(unix)
216*36278Sminshall 	    FD_SET(tout, &o);
217*36278Sminshall 	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
218*36278Sminshall 				(struct timeval *) 0);	/* wait for TTLOWAT */
219*36278Sminshall #endif	/* defined(unix) */
220*36278Sminshall 	}
221*36278Sminshall     }
222*36278Sminshall }
223*36278Sminshall 
224*36278Sminshall void
225*36278Sminshall SetForExit()
226*36278Sminshall {
227*36278Sminshall     setconnmode();
228*36278Sminshall #if	defined(TN3270)
229*36278Sminshall     if (In3270) {
230*36278Sminshall 	Finish3270();
231*36278Sminshall     }
232*36278Sminshall #endif	/* defined(TN3270) */
233*36278Sminshall     setcommandmode();
234*36278Sminshall     fflush(stdout);
235*36278Sminshall     fflush(stderr);
236*36278Sminshall #if	defined(TN3270)
237*36278Sminshall     if (In3270) {
238*36278Sminshall 	StopScreen(1);
239*36278Sminshall     }
240*36278Sminshall #endif	/* defined(TN3270) */
241*36278Sminshall     setconnmode();
242*36278Sminshall     EmptyTerminal();			/* Flush the path to the tty */
243*36278Sminshall     setcommandmode();
244*36278Sminshall }
245*36278Sminshall 
246*36278Sminshall void
247*36278Sminshall Exit(returnCode)
248*36278Sminshall int returnCode;
249*36278Sminshall {
250*36278Sminshall     SetForExit();
251*36278Sminshall     exit(returnCode);
252*36278Sminshall }
253*36278Sminshall 
254*36278Sminshall void
255*36278Sminshall ExitString(string, returnCode)
256*36278Sminshall char *string;
257*36278Sminshall int returnCode;
258*36278Sminshall {
259*36278Sminshall     SetForExit();
260*36278Sminshall     fwrite(string, 1, strlen(string), stderr);
261*36278Sminshall     exit(returnCode);
262*36278Sminshall }
263*36278Sminshall 
264*36278Sminshall #if defined(MSDOS)
265*36278Sminshall void
266*36278Sminshall ExitPerror(string, returnCode)
267*36278Sminshall char *string;
268*36278Sminshall int returnCode;
269*36278Sminshall {
270*36278Sminshall     SetForExit();
271*36278Sminshall     perror(string);
272*36278Sminshall     exit(returnCode);
273*36278Sminshall }
274*36278Sminshall #endif /* defined(MSDOS) */
275