📄 util_funcs.c
字号:
/* * util_funcs.c *//* * Portions of this file are copyrighted by: * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. */#include <net-snmp/net-snmp-config.h>#if HAVE_IO_H#include <io.h>#endif#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_MALLOC_H#include <malloc.h>#endif#include <sys/types.h>#ifdef __alpha#ifndef _BSD#define _BSD#define _myBSD#endif#endif#if HAVE_SYS_WAIT_H# include <sys/wait.h>#endif#ifdef __alpha#ifdef _myBSD#undef _BSD#undef _myBSD#endif#endif#ifndef WEXITSTATUS# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)#endif#ifndef WIFEXITED# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)#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_UNISTD_H#include <unistd.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#include <errno.h>#include <signal.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <ctype.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_BASETSD_H#include <basetsd.h>#define ssize_t SSIZE_T#endif#if HAVE_RAISE#define alarm raise#endif#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "struct.h"#include "util_funcs.h"#if HAVE_LIMITS_H#include "limits.h"#endif#ifdef USING_UCD_SNMP_ERRORMIB_MODULE#include "ucd-snmp/errormib.h"#else#define setPerrorstatus(x) snmp_log_perror(x)#endif#ifdef EXCACHETIMEstatic long cachetime;#endifextern int numprocs, numextens;voidExit(int var){ snmp_log(LOG_ERR, "Server Exiting with code %d\n", var); exit(var);}const char *make_tempfile(void){ static char name[32]; int fd = -1; strcpy(name, get_temp_file_pattern());#ifdef HAVE_MKSTEMP fd = mkstemp(name);#else if (mktemp(name)) {# ifndef WIN32 fd = open(name, O_CREAT | O_EXCL | O_WRONLY);# else /* Win32 needs _S_IREAD | _S_IWRITE to set permissions on file after closing */ fd = _open(name, _O_CREAT, _S_IREAD | _S_IWRITE | _O_EXCL | _O_WRONLY);# endif }#endif if (fd >= 0) { close(fd); DEBUGMSGTL(("make_tempfile", "temp file created: %s\n", name)); return name; } snmp_log(LOG_ERR,"make_tempfile: error creating file %s\n", name); return NULL;}intshell_command(struct extensible *ex){#if HAVE_SYSTEM const char *ofname; char shellline[STRMAX]; FILE *shellout; ofname = make_tempfile(); if (ofname == NULL) { ex->output[0] = 0; ex->result = 127; return ex->result; } snprintf(shellline, sizeof(shellline), "%s > %s", ex->command, ofname); shellline[ sizeof(shellline)-1 ] = 0; ex->result = system(shellline); ex->result = WEXITSTATUS(ex->result); shellout = fopen(ofname, "r"); if (shellout != NULL) { if (fgets(ex->output, sizeof(ex->output), shellout) == NULL) { ex->output[0] = 0; } fclose(shellout); } unlink(ofname);#else ex->output[0] = 0; ex->result = 0;#endif return (ex->result);}#define MAXOUTPUT 300intexec_command(struct extensible *ex){#if HAVE_EXECV int fd; FILE *file; if ((fd = get_exec_output(ex)) != -1) { file = fdopen(fd, "r"); if (fgets(ex->output, sizeof(ex->output), file) == NULL) { ex->output[0] = 0; } fclose(file); wait_on_exec(ex); } else#endif { ex->output[0] = 0; ex->result = 0; } return (ex->result);}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);}voidwait_on_exec(struct extensible *ex){#ifndef EXCACHETIME if (ex->pid && waitpid(ex->pid, &ex->result, 0) < 0) { setPerrorstatus("waitpid"); } ex->pid = 0;#endif}#define MAXARGS 30intget_exec_output(struct extensible *ex){#if HAVE_EXECV int fd[2], i, cnt; char ctmp[STRMAX], *cptr1, *cptr2, argvs[STRMAX], **argv, **aptr;#ifdef EXCACHETIME char cachefile[STRMAX]; char cache[MAXCACHESIZE]; ssize_t cachebytes; long curtime; static char lastcmd[STRMAX]; int cfd; static int lastresult; int readcount;#endif#ifdef EXCACHETIME sprintf(cachefile, "%s/%s", get_persistent_directory(), CACHEFILE); curtime = time(NULL); if (curtime > (cachetime + EXCACHETIME) || strcmp(ex->command, lastcmd) != 0) { strcpy(lastcmd, ex->command); cachetime = curtime;#endif if (pipe(fd)) { setPerrorstatus("pipe");#ifdef EXCACHETIME cachetime = 0;#endif return -1; } if ((ex->pid = fork()) == 0) { close(1); if (dup(fd[1]) != 1) { setPerrorstatus("dup"); return -1; } /* * write standard output and standard error to pipe. */ /* * close all other file descriptors. */ for (cnt = getdtablesize() - 1; cnt >= 2; --cnt) (void) close(cnt); (void) dup(1); /* stderr */ /* * set standard input to /dev/null */ close(0); (void) open("/dev/null", O_RDWR); for (cnt = 1, cptr1 = ex->command, cptr2 = argvs; cptr1 && *cptr1 != 0; cptr2++, cptr1++) { *cptr2 = *cptr1; if (*cptr1 == ' ') { *(cptr2++) = 0; if ((cptr1 = skip_white(cptr1)) == NULL) break; if (cptr1) { *cptr2 = *cptr1; if (*cptr1 != 0) cnt++; } } } *cptr2 = 0; *(cptr2 + 1) = 0; argv = (char **) malloc((cnt + 2) * sizeof(char *)); if (argv == NULL) return 0; /* memory alloc error */ aptr = argv; *(aptr++) = argvs; for (cptr2 = argvs, i = 1; i != cnt; cptr2++) if (*cptr2 == 0) { *(aptr++) = cptr2 + 1; i++; } while (*cptr2 != 0) cptr2++; *(aptr++) = NULL; copy_nword(ex->command, ctmp, sizeof(ctmp)); execv(ctmp, argv); perror(ctmp); exit(1); } else { close(fd[1]); if (ex->pid < 0) { close(fd[0]); setPerrorstatus("fork");#ifdef EXCACHETIME cachetime = 0;#endif return -1; }#ifdef EXCACHETIME unlink(cachefile); /* * XXX Use SNMP_FILEMODE_CLOSED instead of 644? */ if ((cfd = open(cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { setPerrorstatus(cachefile); cachetime = 0; return -1; } fcntl(fd[0], F_SETFL, O_NONBLOCK); /* don't block on reads */#ifdef HAVE_USLEEP for (readcount = 0; readcount <= MAXREADCOUNT * 100 && (cachebytes = read(fd[0], (void *) cache, MAXCACHESIZE)); readcount++) {#else for (readcount = 0; readcount <= MAXREADCOUNT && (cachebytes = read(fd[0], (void *) cache, MAXCACHESIZE)); readcount++) {#endif if (cachebytes > 0) write(cfd, (void *) cache, cachebytes); else if (cachebytes == -1 && errno != EAGAIN) { setPerrorstatus("read"); break; } else#ifdef HAVE_USLEEP usleep(10000); /* sleeps for 0.01 sec */#else sleep(1);#endif } close(cfd); close(fd[0]); /* * wait for the child to finish */ if (ex->pid > 0 && waitpid(ex->pid, &ex->result, 0) < 0) { setPerrorstatus("waitpid()"); cachetime = 0; return -1; } ex->pid = 0; ex->result = WEXITSTATUS(ex->result); lastresult = ex->result;#else /* !EXCACHETIME */ return (fd[0]);#endif }#ifdef EXCACHETIME } else { ex->result = lastresult; } if ((cfd = open(cachefile, O_RDONLY)) < 0) { setPerrorstatus(cachefile); return -1; } return (cfd);#endif#else /* !HAVE_EXECV */ return -1;#endif}intget_exec_pipes(char *cmd, int *fdIn, int *fdOut, int *pid){#if HAVE_EXECV int fd[2][2], i, cnt; char ctmp[STRMAX], *cptr1, *cptr2, argvs[STRMAX], **argv, **aptr; /* * Setup our pipes */ if (pipe(fd[0]) || pipe(fd[1])) { setPerrorstatus("pipe"); return 0; } if ((*pid = fork()) == 0) { /* First handle for the child */ close(0); if (dup(fd[0][0]) != 0) { setPerrorstatus("dup 0"); return 0; } close(1); if (dup(fd[1][1]) != 1) { setPerrorstatus("dup 1"); return 0; } /* * write standard output and standard error to pipe. */ /* * close all non-standard open file descriptors */ for (cnt = getdtablesize() - 1; cnt >= 2; --cnt) (void) close(cnt); (void) dup(1); /* stderr */ for (cnt = 1, cptr1 = cmd, cptr2 = argvs; *cptr1 != 0; cptr2++, cptr1++) { *cptr2 = *cptr1; if (*cptr1 == ' ') { *(cptr2++) = 0; if ((cptr1 = skip_white(cptr1)) == NULL) break; *cptr2 = *cptr1; if (*cptr1 != 0) cnt++; } } *cptr2 = 0; *(cptr2 + 1) = 0; argv = (char **) malloc((cnt + 2) * sizeof(char *)); if (argv == NULL) return 0; /* memory alloc error */ aptr = argv; *(aptr++) = argvs; for (cptr2 = argvs, i = 1; i != cnt; cptr2++) if (*cptr2 == 0) { *(aptr++) = cptr2 + 1; i++; } while (*cptr2 != 0) cptr2++; *(aptr++) = NULL; copy_nword(cmd, ctmp, sizeof(ctmp)); execv(ctmp, argv); perror(ctmp); exit(1); } else { close(fd[0][0]); close(fd[1][1]); if (*pid < 0) { close(fd[0][1]); close(fd[1][0]); setPerrorstatus("fork"); return 0; } *fdIn = fd[1][0]; *fdOut = fd[0][1]; return (1); /* We are returning 0 for error... */ }#endif /* !HAVE_EXECV */ return 0;}intclear_cache(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){ long tmp = 0; if (var_val_type != ASN_INTEGER) { snmp_log(LOG_NOTICE, "Wrong type != int\n"); return SNMP_ERR_WRONGTYPE; } tmp = *((long *) var_val); if (tmp == 1 && action == COMMIT) {#ifdef EXCACHETIME cachetime = 0; /* reset the cache next read */#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -