xref: /csrg-svn/usr.bin/telnet/utilities.c (revision 36279)
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*36279Sminshall static char sccsid[] = "@(#)utilities.c	1.9 (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 
3236278Sminshall #include "defines.h"
3336278Sminshall 
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 }
19136278Sminshall 
19236278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty.
19336278Sminshall  *			Note that we consider the buffer to run all the
19436278Sminshall  *			way to the kernel (thus the select).
19536278Sminshall  */
19636278Sminshall 
19736278Sminshall void
19836278Sminshall EmptyTerminal()
19936278Sminshall {
20036278Sminshall #if	defined(unix)
20136278Sminshall     fd_set	o;
20236278Sminshall 
20336278Sminshall     FD_ZERO(&o);
20436278Sminshall #endif	/* defined(unix) */
20536278Sminshall 
20636278Sminshall     if (TTYBYTES() == 0) {
20736278Sminshall #if	defined(unix)
20836278Sminshall 	FD_SET(tout, &o);
20936278Sminshall 	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
21036278Sminshall 			(struct timeval *) 0);	/* wait for TTLOWAT */
21136278Sminshall #endif	/* defined(unix) */
21236278Sminshall     } else {
21336278Sminshall 	while (TTYBYTES()) {
21436278Sminshall 	    ttyflush(0);
21536278Sminshall #if	defined(unix)
21636278Sminshall 	    FD_SET(tout, &o);
21736278Sminshall 	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
21836278Sminshall 				(struct timeval *) 0);	/* wait for TTLOWAT */
21936278Sminshall #endif	/* defined(unix) */
22036278Sminshall 	}
22136278Sminshall     }
22236278Sminshall }
22336278Sminshall 
22436278Sminshall void
22536278Sminshall SetForExit()
22636278Sminshall {
22736278Sminshall     setconnmode();
22836278Sminshall #if	defined(TN3270)
22936278Sminshall     if (In3270) {
23036278Sminshall 	Finish3270();
23136278Sminshall     }
232*36279Sminshall #else	/* defined(TN3270) */
233*36279Sminshall     do {
234*36279Sminshall 	telrcv();			/* Process any incoming data */
235*36279Sminshall 	EmptyTerminal();
236*36279Sminshall     } while (ring_full_count(&netiring));	/* While there is any */
23736278Sminshall #endif	/* defined(TN3270) */
23836278Sminshall     setcommandmode();
23936278Sminshall     fflush(stdout);
24036278Sminshall     fflush(stderr);
24136278Sminshall #if	defined(TN3270)
24236278Sminshall     if (In3270) {
24336278Sminshall 	StopScreen(1);
24436278Sminshall     }
24536278Sminshall #endif	/* defined(TN3270) */
24636278Sminshall     setconnmode();
24736278Sminshall     EmptyTerminal();			/* Flush the path to the tty */
24836278Sminshall     setcommandmode();
24936278Sminshall }
25036278Sminshall 
25136278Sminshall void
25236278Sminshall Exit(returnCode)
25336278Sminshall int returnCode;
25436278Sminshall {
25536278Sminshall     SetForExit();
25636278Sminshall     exit(returnCode);
25736278Sminshall }
25836278Sminshall 
25936278Sminshall void
26036278Sminshall ExitString(string, returnCode)
26136278Sminshall char *string;
26236278Sminshall int returnCode;
26336278Sminshall {
26436278Sminshall     SetForExit();
26536278Sminshall     fwrite(string, 1, strlen(string), stderr);
26636278Sminshall     exit(returnCode);
26736278Sminshall }
26836278Sminshall 
26936278Sminshall #if defined(MSDOS)
27036278Sminshall void
27136278Sminshall ExitPerror(string, returnCode)
27236278Sminshall char *string;
27336278Sminshall int returnCode;
27436278Sminshall {
27536278Sminshall     SetForExit();
27636278Sminshall     perror(string);
27736278Sminshall     exit(returnCode);
27836278Sminshall }
27936278Sminshall #endif /* defined(MSDOS) */
280