📄 extensible.c
字号:
#include <config.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <signal.h>#if HAVE_MACHINE_PARAM_H#include <machine/param.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_SYS_VMMETER_H#if !(defined(bsdi2) || defined(netbsd1))#include <sys/vmmeter.h>#endif#endif#if HAVE_SYS_CONF_H#include <sys/conf.h>#endif#if HAVE_ASM_PAGE_H#include <asm/page.h>#endif#if HAVE_SYS_SWAP_H#include <sys/swap.h>#endif#if HAVE_SYS_FS_H#include <sys/fs.h>#else#if HAVE_UFS_FS_H#include <ufs/fs.h>#else#if HAVE_UFS_UFS_DINODE_H#include <ufs/ufs/dinode.h>#endif#if HAVE_UFS_FFS_FS_H#include <ufs/ffs/fs.h>#endif#endif#endif#if HAVE_MTAB_H#include <mtab.h>#endif#include <sys/stat.h>#include <errno.h>#if HAVE_FSTAB_H#include <fstab.h>#endif#if HAVE_SYS_STATFS_H#include <sys/statfs.h>#endif#if HAVE_SYS_STATVFS_H#include <sys/statvfs.h>#endif#if HAVE_SYS_VFS_H#include <sys/vfs.h>#endif#if (!defined(HAVE_STATVFS)) && defined(HAVE_STATFS)#if HAVE_SYS_MOUNT_H#include <sys/mount.h>#endif#if HAVE_SYS_SYSCTL_H#include <sys/sysctl.h>#endif#define statvfs statfs#endif#if HAVE_VM_VM_H#include <vm/vm.h>#endif#if HAVE_VM_SWAP_PAGER_H#include <vm/swap_pager.h>#endif#if HAVE_SYS_FIXPOINT_H#include <sys/fixpoint.h>#endif#if HAVE_MALLOC_H#include <malloc.h>#endif#if HAVE_STRING_H#include <string.h>#endif#include <ctype.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#ifndef HAVE_STRNCASECMPint strncasecmp(const char *s1, const char *s2, size_t n);#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include "mibincl.h"#include "struct.h"#include "extensible.h"#include "util_funcs.h"#include "read_config.h"#include "agent_read_config.h"#include "auto_nlist.h"extern struct myproc *procwatch; /* moved to proc.c */extern int numprocs; /* ditto */extern struct extensible *extens; /* In exec.c */extern struct extensible *relocs; /* In exec.c */extern int numextens; /* ditto */extern int numrelocs; /* ditto */extern struct extensible *passthrus; /* In pass.c */extern int numpassthrus; /* ditto */extern char sysName[];extern struct subtree *subtrees,subtrees_old[];extern struct variable2 extensible_relocatable_variables[];extern struct variable2 extensible_passthru_variables[];void init_extensible(void) { struct variable2 extensible_extensible_variables[] = { {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_shell, 1, {MIBINDEX}}, {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_shell, 1, {ERRORNAME}}, {SHELLCOMMAND, ASN_OCTET_STR, RONLY, var_extensible_shell, 1, {SHELLCOMMAND}}, {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_shell, 1, {ERRORFLAG}}, {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_shell, 1, {ERRORMSG}}, {ERRORFIX, ASN_INTEGER, RWRITE, var_extensible_shell, 1, {ERRORFIX}}, {ERRORFIXCMD, ASN_OCTET_STR, RONLY, var_extensible_shell, 1, {ERRORFIXCMD}} };/* Define the OID pointer to the top of the mib tree that we're registering underneath */ oid extensible_variables_oid[] = { EXTENSIBLEMIB,SHELLMIBNUM,1 }; /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("ucd-snmp/extensible", extensible_extensible_variables, variable2, extensible_variables_oid); snmpd_register_config_handler("exec", extensible_parse_config, extensible_free_config, "[miboid] name program arguments"); snmpd_register_config_handler("sh", extensible_parse_config, extensible_free_config, "[miboid] name program-or-script arguments"); snmpd_register_config_handler("execfix", execfix_parse_config, NULL, "exec-or-sh-name program [arguments...]");}void extensible_parse_config(const char *token, char* cptr){ struct extensible *ptmp, **pp; char *tcptr; /* allocate and clear memory structure */ ptmp = (struct extensible *) calloc(1, sizeof(struct extensible)); if (ptmp == NULL) return; /* XXX memory alloc error */ if (*cptr == '.') cptr++; if (isdigit(*cptr)) { /* its a relocatable extensible mib */ for (pp = &relocs, numrelocs++; *pp; pp = &((*pp)->next) ); (*pp) = ptmp; } else { /* it goes in with the general extensible table */ for (pp = &extens, numextens++; *pp; pp = &((*pp)->next) ); (*pp) = ptmp; } /* the rest is pretty much handled the same */ if (!strncasecmp(token,"sh",2)) ptmp->type = SHPROC; else ptmp->type = EXECPROC; if (isdigit(*cptr)) { ptmp->miblen = parse_miboid(cptr,ptmp->miboid); while (isdigit(*cptr) || *cptr == '.') cptr++; } /* name */ cptr = skip_white(cptr); copy_word(cptr,ptmp->name); cptr = skip_not_white(cptr); cptr = skip_white(cptr); /* command */ if (cptr == NULL) { config_perror("No command specified on line"); } else { for(tcptr=cptr; *tcptr != 0 && *tcptr != '#' && *tcptr != ';'; tcptr++); strncpy(ptmp->command,cptr,tcptr-cptr); ptmp->command[tcptr-cptr] = 0; }#ifdef EXECFIXCMD sprintf(ptmp->fixcmd, EXECFIXCMD, ptmp->name);#endif if (ptmp->miblen > 0) { register_mib(token, (struct variable *) extensible_relocatable_variables, sizeof(struct variable2), 6, ptmp->miboid, ptmp->miblen); }}void extensible_free_config (void){ struct extensible *etmp, *etmp2; for (etmp = extens; etmp != NULL;) { etmp2 = etmp; etmp = etmp->next; free(etmp2); } for (etmp = relocs; etmp != NULL;) { etmp2 = etmp; etmp = etmp->next; unregister_mib(etmp2->miboid, etmp2->miblen); free(etmp2); } relocs = NULL; extens = NULL; numextens = 0; numrelocs = 0;}struct extensible *get_exten_instance(struct extensible *exten, size_t inst){ int i; if (exten == NULL) return(NULL); for (i=1;i != (int)inst && exten != NULL; i++) exten = exten->next; return(exten);}#define MAXMSGLINES 1000struct extensible *extens=NULL; /* In exec.c */struct extensible *relocs=NULL; /* In exec.c */int numextens=0,numrelocs=0; /* ditto *//* var_extensible_shell(... Arguments: vp IN - pointer to variable entry that points here name IN/OUT - IN/name requested, OUT/name found length IN/OUT - length of IN/OUT oid's exact IN - TRUE if an exact match was requested var_len OUT - length of variable or 0 if function returned write_method *//* find a give entry in the linked list associated with a proc name */struct extensible *get_exec_by_name(char *name) { struct extensible *etmp; if (name == NULL) return NULL; for(etmp = extens; etmp != NULL && strcmp(etmp->name, name) != 0; etmp = etmp->next); return etmp;} void execfix_parse_config(const char *token, char* cptr) { char tmpname[STRMAX]; struct extensible *execp; /* don't allow two entries with the same name */ cptr = copy_word(cptr,tmpname); if ((execp = get_exec_by_name(tmpname)) == NULL) { config_perror("No exec entry registered for this exec name yet."); return; } if (strlen(cptr) > sizeof(execp->fixcmd)) { config_perror("fix command too long."); return; } strcpy(execp->fixcmd, cptr);}u_char *var_extensible_shell(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ static struct extensible *exten = 0; static long long_ret; if (header_simple_table(vp,name,length,exact,var_len,write_method,numextens)) return(NULL); if ((exten = get_exten_instance(extens,name[*length-1]))) { switch (vp->magic) { case MIBINDEX: long_ret = name[*length-1]; return((u_char *) (&long_ret)); case ERRORNAME: /* name defined in config file */ *var_len = strlen(exten->name); return((u_char *) (exten->name)); case SHELLCOMMAND: *var_len = strlen(exten->command); return((u_char *) (exten->command)); case ERRORFLAG: /* return code from the process */ if (exten->type == EXECPROC) exec_command(exten); else shell_command(exten); long_ret = exten->result; return((u_char *) (&long_ret)); case ERRORMSG: /* first line of text returned from the process */ if (exten->type == EXECPROC) exec_command(exten); else shell_command(exten); *var_len = strlen(exten->output); if (exten->output[*var_len-1] == '\n') exten->output[--(*var_len)] = '\0'; return((u_char *) (exten->output)); case ERRORFIX: *write_method = fixExecError; long_return = 0; return ((u_char *) &long_return); case ERRORFIXCMD: *var_len = strlen(exten->fixcmd); return ((u_char *) exten->fixcmd); } return NULL; } return NULL;}intfixExecError(int action, u_char *var_val, u_char var_val_type, size_t var_val_len, u_char *statP, oid *name, size_t name_len){ struct extensible *exten; long tmp=0; int fd; static struct extensible ex; FILE *file; if ((exten = get_exten_instance(extens,name[10]))) { if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "Wrong type != int\n"); return SNMP_ERR_WRONGTYPE; } tmp = *((long *) var_val); if ((tmp == 1) && (action == COMMIT) && (exten->fixcmd[0] != 0)) { sprintf(ex.command, exten->fixcmd); if ((fd = get_exec_output(&ex))) { file = fdopen(fd,"r"); while (fgets(ex.output,sizeof(ex.output),file) != NULL); fclose(file); wait_on_exec(&ex); } } return SNMP_ERR_NOERROR; } return SNMP_ERR_WRONGTYPE;}/* the relocatable extensible commands variables */struct variable2 extensible_relocatable_variables[] = { {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_relocatable, 1, {MIBINDEX}}, {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_relocatable, 1, {ERRORNAME}}, {SHELLCOMMAND, ASN_OCTET_STR, RONLY, var_extensible_relocatable, 1, {SHELLCOMMAND}}, {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_relocatable, 1, {ERRORFLAG}}, {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_relocatable, 1, {ERRORMSG}}, {ERRORFIX, ASN_INTEGER, RWRITE, var_extensible_relocatable, 1, {ERRORFIX }}};u_char *var_extensible_relocatable(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ int fd; int i; FILE *file; struct extensible *exten = 0; static long long_ret; static char errmsg[STRMAX]; struct variable myvp; oid tname[MAX_OID_LEN]; memcpy(&myvp,vp,sizeof(struct variable)); long_ret = *length; for(i=1; i <= (int)numrelocs; i++) { exten = get_exten_instance(relocs,i); if ((int)exten->miblen == (int)vp->namelen-1){ memcpy(myvp.name,exten->miboid,exten->miblen*sizeof(oid)); myvp.namelen = exten->miblen; *length = vp->namelen; memcpy(tname,vp->name,vp->namelen*sizeof(oid)); if (!header_simple_table(&myvp,tname,length,-1,var_len,write_method, -1)) break; else exten = NULL; } } if (i > (int)numrelocs || exten == NULL) { *length = long_ret; *var_len = 0; *write_method = NULL; return(NULL); } *length = long_ret; if (header_simple_table(vp,name,length,exact,var_len,write_method, ((vp->magic == ERRORMSG) ? MAXMSGLINES : 1))) return(NULL); switch (vp->magic) { case MIBINDEX: long_ret = name[*length-1]; return((u_char *) (&long_ret)); case ERRORNAME: /* name defined in config file */ *var_len = strlen(exten->name); return((u_char *) (exten->name)); case SHELLCOMMAND: *var_len = strlen(exten->command); return((u_char *) (exten->command)); case ERRORFLAG: /* return code from the process */ if (exten->type == EXECPROC) exec_command(exten); else shell_command(exten); long_ret = exten->result; return((u_char *) (&long_ret)); case ERRORMSG: /* first line of text returned from the process */ if (exten->type == EXECPROC) { if ((fd = get_exec_output(exten))){ file = fdopen(fd,"r"); for (i=0;i != (int)name[*length-1];i++) { if (fgets(errmsg,sizeof(errmsg),file) == NULL) { *var_len = 0; fclose(file); wait_on_exec(exten); return(NULL); } } fclose(file); wait_on_exec(exten); } else errmsg[0] = 0; } else { if (*length > 1) { *var_len = 0; return(NULL); } shell_command(exten); strcpy(errmsg,exten->output); } *var_len = strlen(errmsg); if (errmsg[*var_len-1] == '\n') errmsg[--(*var_len)] = '\0'; return((u_char *) (errmsg)); case ERRORFIX: *write_method = fixExecError; long_return = 0; return ((u_char *) &long_return); } return NULL;}struct subtree *find_extensible(struct subtree *tp, oid tname[], size_t tnamelen, int exact){ size_t tmp; int i; struct extensible *exten = 0; struct variable myvp; oid name[MAX_OID_LEN]; static struct subtree mysubtree[2]; for(i=1; i <= (int)numrelocs; i++) { exten = get_exten_instance(relocs,i); if (exten->miblen != 0){ memcpy(myvp.name,exten->miboid,exten->miblen*sizeof(oid)); memcpy(name,tname,tnamelen*sizeof(oid)); myvp.name[exten->miblen] = name[exten->miblen]; myvp.namelen = exten->miblen+1; tmp = exten->miblen+1; if (!header_simple_table(&myvp,name,&tmp,-1,NULL,NULL, numrelocs)) break; } } if (i > (int)numrelocs || exten == NULL) return(tp); memcpy(mysubtree[0].name,exten->miboid,exten->miblen*sizeof(oid)); mysubtree[0].namelen = exten->miblen; mysubtree[0].variables = (struct variable *)extensible_relocatable_variables; mysubtree[0].variables_len = sizeof(extensible_relocatable_variables)/sizeof(*extensible_relocatable_variables); mysubtree[0].variables_width = sizeof(*extensible_relocatable_variables); mysubtree[1].namelen = 0; return(mysubtree);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -