📄 proc.c
字号:
#include <config.h>#ifdef solaris2#define _KMEMUSER /* Needed by <sys/user.h> */#include <sys/types.h> /* helps define struct rlimit */#endif#if HAVE_IO_H /* win32 */#include <io.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_MALLOC_H#include <malloc.h>#endif#include <math.h>#include <ctype.h>#include <sys/types.h>#if HAVE_NETINET_IN_H#include <netinet/in.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#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include "mibincl.h"#include "struct.h"#include "proc.h"#ifdef USING_UCD_SNMP_ERRORMIB_MODULE#include "errormib.h"#else#define setPerrorstatus(x) snmp_log_perror(x)#endif#include "util_funcs.h"#include "read_config.h"#include "agent_read_config.h"#include "system.h"#ifdef USING_UCD_SNMP_ERRORMIB_MODULE#include "errormib.h"#endifstatic struct myproc *get_proc_instance (struct myproc *, oid);struct myproc *procwatch = NULL;static struct extensible fixproc;int numprocs=0;void init_proc(void) {/* define the structure we're going to ask the agent to register our information at */ struct variable2 extensible_proc_variables[] = { {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_proc, 1, {MIBINDEX}}, {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_proc, 1, {ERRORNAME}}, {PROCMIN, ASN_INTEGER, RONLY, var_extensible_proc, 1, {PROCMIN}}, {PROCMAX, ASN_INTEGER, RONLY, var_extensible_proc, 1, {PROCMAX}}, {PROCCOUNT, ASN_INTEGER, RONLY, var_extensible_proc, 1, {PROCCOUNT}}, {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_proc, 1, {ERRORFLAG}}, {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_proc, 1, {ERRORMSG}}, {ERRORFIX, ASN_INTEGER, RWRITE, var_extensible_proc, 1, {ERRORFIX}}, {ERRORFIXCMD, ASN_OCTET_STR, RONLY, var_extensible_proc, 1, {ERRORFIXCMD}} };/* Define the OID pointer to the top of the mib tree that we're registering underneath */ oid proc_variables_oid[] = { EXTENSIBLEMIB,PROCMIBNUM,1 }; /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("ucd-snmp/proc", extensible_proc_variables, variable2, \ proc_variables_oid); snmpd_register_config_handler("proc", proc_parse_config, proc_free_config, "process-name [max-num] [min-num]"); snmpd_register_config_handler("procfix", procfix_parse_config, NULL, "process-name program [arguments...]");}/* Define snmpd.conf reading routines first. They get called automatically by the invocation of a macro in the proc.h file. */void proc_free_config(void) { struct myproc *ptmp, *ptmp2; for (ptmp = procwatch; ptmp != NULL;) { ptmp2 = ptmp; ptmp = ptmp->next; free(ptmp2); } procwatch = NULL; numprocs = 0;}/* find a give entry in the linked list associated with a proc name */static struct myproc *get_proc_by_name(char *name) { struct myproc *ptmp; if (name == NULL) return NULL; for(ptmp = procwatch; ptmp != NULL && strcmp(ptmp->name, name) != 0; ptmp = ptmp->next); return ptmp;} void procfix_parse_config(const char *token, char* cptr){ char tmpname[STRMAX]; struct myproc *procp; /* don't allow two entries with the same name */ cptr = copy_word(cptr,tmpname); if ((procp = get_proc_by_name(tmpname)) == NULL) { config_perror("No proc entry registered for this proc name yet."); return; } if (strlen(cptr) > sizeof(procp->fixcmd)) { config_perror("fix command too long."); return; } strcpy(procp->fixcmd, cptr);}void proc_parse_config(const char *token, char* cptr){ char tmpname[STRMAX]; struct myproc **procp = &procwatch; /* don't allow two entries with the same name */ copy_word(cptr,tmpname); if (get_proc_by_name(tmpname) != NULL) { config_perror("Already have an entry for this process."); return; } /* skip past used ones */ while (*procp != NULL) procp = &((*procp)->next); (*procp) = (struct myproc *) malloc(sizeof(struct myproc)); if (*procp == NULL) return; /* memory alloc error */ (*procp)->next = NULL; numprocs++; /* not blank and not a comment */ copy_word(cptr,(*procp)->name); cptr = skip_not_white(cptr); if ((cptr = skip_white(cptr))) { (*procp)->max = atoi(cptr); cptr = skip_not_white(cptr); if ((cptr = skip_white(cptr))) (*procp)->min = atoi(cptr); else (*procp)->min = 0; } else { (*procp)->max = 0; (*procp)->min = 0; }#ifdef PROCFIXCMD sprintf((*procp)->fixcmd, PROCFIXCMD, (*procp)->name);#endif DEBUGMSGTL(("ucd-snmp/proc", "Read: %s (%d) (%d)\n", (*procp)->name, (*procp)->max, (*procp)->min));}/* The routine that handles everything */u_char *var_extensible_proc(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ struct myproc *proc; static long long_ret; static char errmsg[300]; if (header_simple_table(vp,name,length,exact,var_len,write_method,numprocs)) return(NULL); if ((proc = get_proc_instance(procwatch,name[*length-1]))) { switch (vp->magic) { case MIBINDEX: long_ret = name[*length-1]; return((u_char *) (&long_ret)); case ERRORNAME: /* process name to check for */ *var_len = strlen(proc->name); return((u_char *) (proc->name)); case PROCMIN: long_ret = proc->min; return((u_char *) (&long_ret)); case PROCMAX: long_ret = proc->max; return ((u_char *) (&long_ret)); case PROCCOUNT: long_ret = sh_count_procs(proc->name); return ((u_char *) (& long_ret)); case ERRORFLAG: long_ret = sh_count_procs(proc->name); if (long_ret >= 0 && ((proc->min && long_ret < proc->min) || (proc->max && long_ret > proc->max) || (proc->min == 0 && proc->max == 0 && long_ret < 1))) { long_ret = 1; } else { long_ret = 0; } return ((u_char *) (& long_ret)); case ERRORMSG: long_ret = sh_count_procs(proc->name); if (long_ret < 0) { errmsg[0] = 0; /* catch out of mem errors return 0 count */ } else if (proc->min && long_ret < proc->min) { sprintf(errmsg,"Too few %s running (# = %d)", proc->name, (int) long_ret); } else if (proc->max && long_ret > proc->max) { sprintf(errmsg,"Too many %s running (# = %d)", proc->name, (int) long_ret); } else if (proc->min == 0 && proc->max == 0 && long_ret < 1) { sprintf(errmsg,"No %s process running.", proc->name); } else { errmsg[0] = 0; } *var_len = strlen(errmsg); return((u_char *) errmsg); case ERRORFIX: *write_method = fixProcError; long_return = fixproc.result; return ((u_char *) &long_return); case ERRORFIXCMD: if (proc->fixcmd) { *var_len = strlen(proc->fixcmd); return (u_char *)proc->fixcmd; } errmsg[0] = 0; *var_len = 0; return ((u_char *) errmsg); } return NULL; } return NULL;}intfixProcError(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 myproc *proc; long tmp=0; if ((proc = get_proc_instance(procwatch,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) { if (proc->fixcmd[0]) { strcpy(fixproc.command, proc->fixcmd); exec_command(&fixproc); } } return SNMP_ERR_NOERROR; } return SNMP_ERR_WRONGTYPE;}static struct myproc *get_proc_instance(struct myproc *proc, oid inst){ int i; if (proc == NULL) return(NULL); for (i=1; (i != (int)inst) && (proc != NULL); i++) proc = proc->next; return(proc);}#ifdef bsdi2#include <sys/param.h>#include <sys/sysctl.h>#define PP(pp, field) ((pp)->kp_proc . field)#define EP(pp, field) ((pp)->kp_eproc . field)#define VP(pp, field) ((pp)->kp_eproc.e_vm . field)/* these are for keeping track of the proc array */static int nproc = 0;static int onproc = -1;static struct kinfo_proc *pbase = 0;int sh_count_procs(char *procname){ register int i,ret = 0; register struct kinfo_proc *pp; static int mib[] = { CTL_KERN, KERN_PROC , KERN_PROC_ALL };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -