📄 x_snmp.c
字号:
/* x_snmp.c - x_snmp */#include <conf.h>#include <kernel.h>#include <network.h>#include <io.h>#include <string.h>#include <mem.h>#include <stdlib.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 BELL '\007' /* control-g */#define M_COMPL 1 /* completion mode */#define M_CHARIN 2 /* char-in mode */#define PROMPT "\n\rsnmp > "#define EXITSTR "exit"#define BUFSIZE 1024char 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 *//* local routine definitions */LOCAL void echoch(char ch, int stdout);LOCAL void erase1(int ct, int stdout);LOCAL void eraseall(int ct, int stdout);LOCAL void eraseword(int *ct, int stdout);LOCAL void snusage(int stdout);LOCAL void initgetword(char *buf);LOCAL void getword(char **word);LOCAL void print_completion(int *ct, int stdout);LOCAL void find_completions(void);LOCAL int parsevalue(char **word, struct snbentry *bl);LOCAL int strnequ(char *s1, char *s2, int n);LOCAL int objd2oid(char *str, struct oid *oip);LOCAL int dot2oid(u_short id[], char *str);LOCAL int parseoidlist(struct req_desc *rqdp, char **word);LOCAL struct snbentry *parseoid(char **word);LOCAL int sendquery(int stdout, char *server);LOCAL struct snbentry *getnewbl(void);LOCAL int parseset(struct req_desc *rqdp, int stdout);/*------------------------------------------------------------------------ * x_snmp - SNMP shell that does MIB object name completion *------------------------------------------------------------------------ */intx_snmp(int stdin, int stdout, int stderr, int nargs, char *args[]){ int ch; char snmpservstr[BUFSIZE]; struct tty *ttyp; int ct, i, mode; IPaddr destmach; if (nargs != 2) { snusage(stdout); return OK; } args++; nargs--; sninit(); if ((destmach = name2ip(*args)) == (IPaddr)SYSERR) { fprintf(stdout,"snmp: couldn't resolve name %s\n", *args); return OK; } ip2dot(snmpservstr, destmach); sprintf(snmpservstr + strlen(snmpservstr), ":%d", SNMPPORT); ttyp = &ttytab[stdin]; ct = 0; mode = M_CHARIN; next_completion = num_completions = 0; control(stdin, TTC_MODER); /* 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, TTC_MODEC); return OK; } if (ch == SYSERR) { return SYSERR; } if (ch == COMPLETE) { if (mode == M_CHARIN) { mode = M_COMPL; /* find beginning of word */ for (i=ct-1; i >= 0 && buf[i] != ' '; 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(&ct, stdout); continue; } if (ch == KILLWORD && mode == M_COMPL) { /* kill word in compl. mode goes back to original string to complete. */ eraseword(&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(&ct, stdout); continue; } if ((ch == ttyp->tty_tchars.tc_kill)) { eraseall(ct, stdout); ct = 0; continue; } if ((ch == ttyp->tty_tchars.tc_erase)) { if (ct > 0) erase1(--ct, stdout); continue; } if ((ch == '\r') || (ch == '\n')) { echoch(ch, stdout); buf[ct] = '\0'; if (strequ(buf, EXITSTR)) { control(stdin, TTC_MODEC); 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, stdout); buf[ct++] = ch; } } return OK;}/*------------------------------------------------------------------------ * print_completion - write the next name completion to stdout *------------------------------------------------------------------------ */LOCAL voidprint_completion(int *ct, int stdout){ if (next_completion >= num_completions) { putc(stdout, BELL); return; } eraseword(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. *------------------------------------------------------------------------ */LOCAL voidfind_completions(void){ 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 *------------------------------------------------------------------------ */LOCAL intparsevalue(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 == NULLCH) return SYSERR; switch (SVTYPE(bl)) { case ASN1_INT: case ASN1_COUNTER: case ASN1_GAUGE: case ASN1_TIMETICKS: SVINT(bl) = atoi(*word); break; case ASN1_OCTSTR: SVSTRLEN(bl) = strlen(*word); SVSTR(bl) = (char *) getmem(SVSTRLEN(bl)); memcpy(SVSTR(bl), *word, SVSTRLEN(bl)); break; case ASN1_OBJID: SVOIDLEN(bl) = dot2oid(SVOID(bl), *word); break; case ASN1_IPADDR: SVIPADDR(bl) = dot2ip(*word); break; default: return SYSERR; } return OK;}/*------------------------------------------------------------------------ * echoch -- echo a character with visual and ocrlf options *------------------------------------------------------------------------ */LOCAL voidechoch(char ch, int stdout){ if (ch == '\n' || ch == '\r') { putc(stdout, '\r'); putc(stdout, '\n'); } else if (ch < ' ' || ch == 0177) { putc(stdout, '^'); putc(stdout, ch + 0100); /* make it printable */ } else putc(stdout, ch);}/*------------------------------------------------------------------------ * erase1 -- erase one character honoring erasing backspace *------------------------------------------------------------------------ */LOCAL voiderase1(int ct, int stdout){ char ch; ch = buf[ct]; if (ch < ' ' || ch == 0177) { putc(stdout, '\b'); putc(stdout, ' '); putc(stdout, '\b'); putc(stdout, '\b'); putc(stdout, ' '); putc(stdout, '\b'); } else { putc(stdout, '\b'); putc(stdout, ' '); putc(stdout, '\b'); }}/*------------------------------------------------------------------------ * eraseall -- erase all characters honoring erasing backspace *------------------------------------------------------------------------ */LOCAL voideraseall(int ct, int stdout){ for (--ct; ct >= 0; ct--) erase1(ct, stdout);}/*------------------------------------------------------------------------ * eraseword -- erase the previous word *------------------------------------------------------------------------ */LOCAL voideraseword( int *ct, int stdout){ /* if first character behind cursor is a blank, eat it up */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -