x_snmp.c,v

来自「TCP-IP红宝书源代码」· C,V 代码 · 共 650 行 · 第 1/2 页

C,V
650
字号
head	1.1;
access;
symbols;
locks
	dls:1.1; strict;
comment	@ * @;


1.1
date	97.09.21.19.29.03;	author dls;	state Dist;
branches;
next	;


desc
@@


1.1
log
@pre-3e code
@
text
@/* x_snmp.c - x_snmp */

#include <conf.h>
#include <kernel.h>
#include <network.h>

#ifdef	SNMP
#include <tty.h>
#include <ctype.h>
#include <snmp.h>
#include <asn1.h>
#include <mib.h>

#define EXIT		'\004'		/* \004 is Cntl-d		*/
#define COMPLETE	'\011'		/* \011 is TAB			*/
#define KILLWORD	'\027'		/* \027 is Cntl-w		*/

#define M_COMPL		1		/* completion mode 		*/
#define M_CHARIN	2		/* char-in mode 		*/

#define PROMPT		"snmp > "
#define EXITSTR		"exit"

#define BUFSIZE		1024
char	buf[BUFSIZE];			/* buffer to hold the input line*/
char	str2compl[BUFSIZE];		/* string to complete 		*/
int	s2clen;				/* length of str2compl		*/
int	completions[BUFSIZE];		/* array of indices into the mib*/
					/* array to signal completions	*/
int	num_completions;		/* # of indices in completions[]*/
int	next_completion;		/* next completion to try	*/

/*------------------------------------------------------------------------
 * x_snmp - SNMP shell that does MIB object name completion
 *------------------------------------------------------------------------
 */
x_snmp(stdin, stdout, stderr, nargs, args)
int	stdin, stdout, stderr, nargs;
char	*args[];
{
	char	ch, snmpservstr[BUFSIZE];
	struct	tty	*ttyp;
	int	len, ct, i, mode;
	IPaddr	destmach;

	if (nargs != 2) {
		snusage(stdout);
		return OK;
	}
	args++;  nargs--;
	sninit();
	if ((destmach = name2ip(*args)) == SYSERR) {
		fprintf(stdout,"snmp: couldn't resolve name %s\n", *args);
		return OK;
	}
	ip2dot(snmpservstr, destmach);
	sprintf(snmpservstr + strlen(snmpservstr), ":%d", SNMPPORT);
	ttyp = &tty[stdin];
	ct = 0;
	mode = M_CHARIN;
	next_completion = num_completions = 0;

	control(stdin, TCMODER);	/* put stdin into raw mode */
	write(stdout, PROMPT, strlen(PROMPT));	/* print the prompt */

	while (TRUE) {
		if ((ch = getc(stdin)) == EOF) {
			write(stdout, EXITSTR, strlen(EXITSTR));
			putc(stdout, '\n');
			control(stdin, TCMODEC);
			return OK;
		}
		if (ch == COMPLETE) {
			if (mode == M_CHARIN) {
				mode = M_COMPL;
				/* find beginning of word */
				for (i=ct-1; i >= 0 && buf[i] != BLANK;
						i--)
					/* empty */;
				s2clen = ct - ++i;
				strncpy(str2compl, buf + i, s2clen);
				find_completions();
			}
			if (num_completions == 0) {
				putc(stdout, BELL);
				mode = M_CHARIN;
			} else
				print_completion(ttyp, &ct, stdout);
			continue;
		}
		if (ch == KILLWORD && mode == M_COMPL) {
			/* kill word in compl. mode goes back to
			   original string to complete. */
			eraseword(ttyp, &ct, stdout);
			strncpy(buf + ct, str2compl, s2clen);
			write(stdout, buf + ct, s2clen);
			ct += s2clen;
			mode = M_CHARIN;
			next_completion = num_completions = 0;
			continue;
		}
		if (mode == M_COMPL) {	/* && ch != KILLWORD */
			mode = M_CHARIN;
			str2compl[(s2clen = 0)] = '\0';
			num_completions = next_completion = 0;
		}
		if (ch == KILLWORD) {	/* && mode != M_COMPL */
			eraseword(ttyp, &ct, stdout);
			continue;
		}
		if (ch == ttyp->ikillc && ttyp->ikill) {
			eraseall(ttyp, ct, stdout);
			ct = 0;
			continue;
		}
		if (ch == ttyp->ierasec	&& ttyp->ierase) {
			if (ct > 0) 
				erase1(ttyp, --ct, stdout);
			continue;
		}
		if (ch == RETURN) {
			echoch(ch, ttyp, stdout);
			buf[ct] = '\0';
			if (strequ(buf, EXITSTR)) {
				control(stdin, TCMODEC);
				return OK;
			}
			sendquery(stdout, snmpservstr);
			for (i = 0; i < BUFSIZE; i++)
				buf[i] = '\0';
			write(stdout, PROMPT, strlen(PROMPT));
			ct = 0;
			continue;
		}
		/* all non-special characters */
		if (ct == BUFSIZE - 1) 
			putc(stdout, BELL);
		else {
			echoch(ch, ttyp, stdout);
			buf[ct++] = ch;
		}
	}
}

/*------------------------------------------------------------------------
 * print_completion - write the next name completion to stdout
 *------------------------------------------------------------------------
 */
print_completion(ttyp, ct, stdout)
int	*ct;
int	stdout;
{
	int	i;
	
	if (next_completion >= num_completions) {
		putc(stdout, BELL);
		return;
	}
	eraseword(ttyp, ct, stdout);

	strcpy(buf + *ct, mib[completions[next_completion]].mi_prefix);
	strcat(buf + *ct, mib[completions[next_completion++]].mi_name);
	write(stdout, buf + *ct, strlen(buf) - *ct);
	*ct = strlen(buf);
}

/*------------------------------------------------------------------------
 * find_completions - find all the completions in the mib for string
 * 		      str2compl.  Put the indices of the completions
 * 		      into the completions array.
 *------------------------------------------------------------------------
 */
find_completions()
{
	int 	i;
	
	for (i = 0; i < mib_entries; i++) 
		if (strnequ(mib[i].mi_name, str2compl, s2clen))
			completions[num_completions++] = i;
	next_completion = 0;
}

/*------------------------------------------------------------------------
 * parsevalue - parse the type and value of variable to set
 *------------------------------------------------------------------------
 */
parsevalue(word, bl)
char		**word;
struct snbentry	*bl;
{
	if (strequ(*word, "int"))
		SVTYPE(bl) = ASN1_INT;
	else if (strequ(*word, "counter")) 
		SVTYPE(bl) = ASN1_COUNTER;
	else if (strequ(*word, "gauge")) 
		SVTYPE(bl) = ASN1_GAUGE;
	else if (strequ(*word, "timeticks")) 
		SVTYPE(bl) = ASN1_TIMETICKS;
	else if (strequ(*word, "str")) 
		SVTYPE(bl) = ASN1_OCTSTR;
	else if (strequ(*word, "objid")) 
		SVTYPE(bl) = ASN1_OBJID;
	else if (strequ(*word, "ipaddr")) 
		SVTYPE(bl) = ASN1_IPADDR;
	else
		return SYSERR;

	getword(word);
	if (**word == NULL)
		return SYSERR;

	switch (SVTYPE(bl)) {
	case ASN1_INT:
	case ASN1_COUNTER:
	case ASN1_GAUGE:
	case ASN1_TIMETICKS:
		SVINT(bl) = atoi(*word);
		return OK;
	case ASN1_OCTSTR:
		SVSTRLEN(bl) = strlen(*word);
		SVSTR(bl) = (char *) getmem(SVSTRLEN(bl));
kprintf("parsevalue: word (%X) - \"%s\"\n", *word, *word);
		blkcopy(SVSTR(bl), *word, SVSTRLEN(bl));
		return OK;
	case ASN1_OBJID:
		SVOIDLEN(bl) = dot2oid(SVOID(bl), *word);
		return OK;
	case ASN1_IPADDR:
		SVIPADDR(bl) = dot2ip(*word);
		return OK;
	}
}

/*------------------------------------------------------------------------
 *  echoch  --  echo a character with visual and ocrlf options
 *------------------------------------------------------------------------
 */
LOCAL echoch(ch, ttyp, stdout)
char		ch;
struct tty	*ttyp;
int		stdout;
{
	if ((ch == NEWLINE || ch == RETURN) && ttyp->ecrlf) {
		putc(stdout, RETURN);
		putc(stdout, NEWLINE);
	} else if ((ch < BLANK || ch == 0177) && ttyp->evis) {
		putc(stdout, UPARROW);
		putc(stdout, ch + 0100);	/* make it printable	*/
	} else
		putc(stdout, ch);
}

/*------------------------------------------------------------------------
 *  erase1  --  erase one character honoring erasing backspace
 *------------------------------------------------------------------------
 */
LOCAL erase1(ttyp, ct, stdout)
struct tty	*ttyp;
int 		ct;
int		stdout;
{
	char	ch;

	ch = buf[ct];
	if (ch < BLANK || ch == 0177) {
		if (ttyp->evis)	{
			putc(stdout, BACKSP);
			if (ttyp->ieback) {
				putc(stdout, BLANK);
				putc(stdout, BACKSP);
			}
		}
		putc(stdout, BACKSP);
		if (ttyp->ieback) {
			putc(stdout, BLANK);
			putc(stdout, BACKSP);
		}
	} else {
		putc(stdout, BACKSP);
		if (ttyp->ieback) {
			putc(stdout, BLANK);
			putc(stdout, BACKSP);
		}
	}
}

/*------------------------------------------------------------------------
 *  eraseall  --  erase all characters honoring erasing backspace
 *------------------------------------------------------------------------
 */
LOCAL eraseall(ttyp, ct, stdout)
struct tty	*ttyp;
int		ct;
int		stdout;
{
	for (--ct; ct >= 0; ct--) 
		erase1(ttyp, ct, stdout);
}

/*------------------------------------------------------------------------
 *  eraseword  --  erase the previous word
 *------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?