xref: /csrg-svn/usr.bin/telnet/utilities.c (revision 36693)
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*36693Sminshall static char sccsid[] = "@(#)utilities.c	1.11 (Berkeley) 02/06/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 	}
11432149Sminshall 	fprintf(NetTrace, "\n");
11532149Sminshall 	length -= BYTES_PER_LINE;
11632149Sminshall 	offset += BYTES_PER_LINE;
11732149Sminshall 	if (length < 0) {
118*36693Sminshall 	    fflush(NetTrace);
11932149Sminshall 	    return;
12032149Sminshall 	}
12132149Sminshall 	/* find next unique line */
12232149Sminshall     }
123*36693Sminshall     fflush(NetTrace);
12432149Sminshall }
12532149Sminshall 
12632149Sminshall 
12732149Sminshall /*VARARGS*/
12832149Sminshall void
12932149Sminshall printoption(direction, fmt, option, what)
13032149Sminshall 	char *direction, *fmt;
13132149Sminshall 	int option, what;
13232149Sminshall {
13332149Sminshall 	if (!showoptions)
13432149Sminshall 		return;
13532149Sminshall 	fprintf(NetTrace, "%s ", direction+1);
13632149Sminshall 	if (fmt == doopt)
13732149Sminshall 		fmt = "do";
13832149Sminshall 	else if (fmt == dont)
13932149Sminshall 		fmt = "dont";
14032149Sminshall 	else if (fmt == will)
14132149Sminshall 		fmt = "will";
14232149Sminshall 	else if (fmt == wont)
14332149Sminshall 		fmt = "wont";
14432149Sminshall 	else
14532149Sminshall 		fmt = "???";
14632149Sminshall 	if (option < (sizeof telopts/sizeof telopts[0]))
14732149Sminshall 		fprintf(NetTrace, "%s %s", fmt, telopts[option]);
14832149Sminshall 	else
14932149Sminshall 		fprintf(NetTrace, "%s %d", fmt, option);
15032149Sminshall 	if (*direction == '<') {
15132149Sminshall 		fprintf(NetTrace, "\r\n");
15232149Sminshall 		return;
15332149Sminshall 	}
15432149Sminshall 	fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply");
15532149Sminshall }
15632149Sminshall 
15732149Sminshall void
15832149Sminshall printsub(direction, pointer, length)
15932149Sminshall char	*direction,		/* "<" or ">" */
16032149Sminshall 	*pointer;		/* where suboption data sits */
16132149Sminshall int	length;			/* length of suboption data */
16232149Sminshall {
16332149Sminshall     if (showoptions) {
16432149Sminshall 	fprintf(NetTrace, "%s suboption ",
16532149Sminshall 				(direction[0] == '<')? "Received":"Sent");
16632149Sminshall 	switch (pointer[0]) {
16732149Sminshall 	case TELOPT_TTYPE:
16832149Sminshall 	    fprintf(NetTrace, "Terminal type ");
16932149Sminshall 	    switch (pointer[1]) {
17032149Sminshall 	    case TELQUAL_IS:
17132149Sminshall 		{
17233286Sminshall 		    char tmpbuf[SUBBUFSIZE];
17332149Sminshall 		    int minlen = min(length, sizeof tmpbuf);
17432149Sminshall 
17532149Sminshall 		    memcpy(tmpbuf, pointer+2, minlen);
17632149Sminshall 		    tmpbuf[minlen-1] = 0;
17732149Sminshall 		    fprintf(NetTrace, "is %s.\n", tmpbuf);
17832149Sminshall 		}
17932149Sminshall 		break;
18032149Sminshall 	    case TELQUAL_SEND:
18132149Sminshall 		fprintf(NetTrace, "- request to send.\n");
18232149Sminshall 		break;
18332149Sminshall 	    default:
18432149Sminshall 		fprintf(NetTrace,
18534849Sminshall 				"- unknown qualifier %d (0x%x).\n",
18634849Sminshall 				pointer[1], pointer[1]);
18732149Sminshall 	    }
18832149Sminshall 	    break;
18932149Sminshall 	default:
19032149Sminshall 	    fprintf(NetTrace, "Unknown option %d (0x%x)\n",
19132149Sminshall 					pointer[0], pointer[0]);
19232149Sminshall 	}
19332149Sminshall     }
19432149Sminshall }
19536278Sminshall 
19636278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty.
19736278Sminshall  *			Note that we consider the buffer to run all the
19836278Sminshall  *			way to the kernel (thus the select).
19936278Sminshall  */
20036278Sminshall 
20136278Sminshall void
20236278Sminshall EmptyTerminal()
20336278Sminshall {
20436278Sminshall #if	defined(unix)
20536278Sminshall     fd_set	o;
20636278Sminshall 
20736278Sminshall     FD_ZERO(&o);
20836278Sminshall #endif	/* defined(unix) */
20936278Sminshall 
21036278Sminshall     if (TTYBYTES() == 0) {
21136278Sminshall #if	defined(unix)
21236278Sminshall 	FD_SET(tout, &o);
21336278Sminshall 	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
21436278Sminshall 			(struct timeval *) 0);	/* wait for TTLOWAT */
21536278Sminshall #endif	/* defined(unix) */
21636278Sminshall     } else {
21736278Sminshall 	while (TTYBYTES()) {
21836278Sminshall 	    ttyflush(0);
21936278Sminshall #if	defined(unix)
22036278Sminshall 	    FD_SET(tout, &o);
22136278Sminshall 	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
22236278Sminshall 				(struct timeval *) 0);	/* wait for TTLOWAT */
22336278Sminshall #endif	/* defined(unix) */
22436278Sminshall 	}
22536278Sminshall     }
22636278Sminshall }
22736278Sminshall 
22836278Sminshall void
22936278Sminshall SetForExit()
23036278Sminshall {
23136278Sminshall     setconnmode();
23236278Sminshall #if	defined(TN3270)
23336278Sminshall     if (In3270) {
23436278Sminshall 	Finish3270();
23536278Sminshall     }
23636279Sminshall #else	/* defined(TN3270) */
23736279Sminshall     do {
23836279Sminshall 	telrcv();			/* Process any incoming data */
23936279Sminshall 	EmptyTerminal();
24036279Sminshall     } while (ring_full_count(&netiring));	/* While there is any */
24136278Sminshall #endif	/* defined(TN3270) */
24236278Sminshall     setcommandmode();
24336278Sminshall     fflush(stdout);
24436278Sminshall     fflush(stderr);
24536278Sminshall #if	defined(TN3270)
24636278Sminshall     if (In3270) {
24736278Sminshall 	StopScreen(1);
24836278Sminshall     }
24936278Sminshall #endif	/* defined(TN3270) */
25036278Sminshall     setconnmode();
25136278Sminshall     EmptyTerminal();			/* Flush the path to the tty */
25236278Sminshall     setcommandmode();
25336278Sminshall }
25436278Sminshall 
25536278Sminshall void
25636278Sminshall Exit(returnCode)
25736278Sminshall int returnCode;
25836278Sminshall {
25936278Sminshall     SetForExit();
26036278Sminshall     exit(returnCode);
26136278Sminshall }
26236278Sminshall 
26336278Sminshall void
26436278Sminshall ExitString(string, returnCode)
26536278Sminshall char *string;
26636278Sminshall int returnCode;
26736278Sminshall {
26836278Sminshall     SetForExit();
26936278Sminshall     fwrite(string, 1, strlen(string), stderr);
27036278Sminshall     exit(returnCode);
27136278Sminshall }
27236278Sminshall 
27336278Sminshall #if defined(MSDOS)
27436278Sminshall void
27536278Sminshall ExitPerror(string, returnCode)
27636278Sminshall char *string;
27736278Sminshall int returnCode;
27836278Sminshall {
27936278Sminshall     SetForExit();
28036278Sminshall     perror(string);
28136278Sminshall     exit(returnCode);
28236278Sminshall }
28336278Sminshall #endif /* defined(MSDOS) */
284