📄 pass_persist.c
字号:
char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF]; long tmp; unsigned long utmp; /* * Make sure that our basic pipe structure is malloced */ init_persist_pipes(); for (i = 1; i <= numpersistpassthrus; i++) { persistpassthru = get_exten_instance(persistpassthrus, i); rtest = snmp_oid_min_compare(name, name_len, persistpassthru->miboid, persistpassthru->miblen); if (rtest <= 0) { if (action != COMMIT) return SNMP_ERR_NOERROR; /* * setup args */ if (persistpassthru->miblen >= name_len || rtest < 0) sprint_mib_oid(buf, persistpassthru->miboid, persistpassthru->miblen); else sprint_mib_oid(buf, name, name_len); snprintf(persistpassthru->command, sizeof(persistpassthru->command), "set\n%s\n", buf); persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0; switch (var_val_type) { case ASN_INTEGER: case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: tmp = *((long *) var_val); switch (var_val_type) { case ASN_INTEGER: sprintf(buf, "integer %d\n", (int) tmp); break; case ASN_COUNTER: sprintf(buf, "counter %d\n", (int) tmp); break; case ASN_GAUGE: sprintf(buf, "gauge %d\n", (int) tmp); break; case ASN_TIMETICKS: sprintf(buf, "timeticks %d\n", (int) tmp); break; } break; case ASN_IPADDRESS: utmp = *((u_long *) var_val); utmp = ntohl(utmp); sprintf(buf, "ipaddress %d.%d.%d.%d\n", (int) ((utmp & 0xff000000) >> (8 * 3)), (int) ((utmp & 0xff0000) >> (8 * 2)), (int) ((utmp & 0xff00) >> (8)), (int) ((utmp & 0xff))); break; case ASN_OCTET_STR: memcpy(buf2, var_val, var_val_len); if (var_val_len == 0) sprintf(buf, "string \"\"\n"); else if (bin2asc(buf2, var_val_len) == (int) var_val_len) snprintf(buf, sizeof(buf), "string \"%s\"\n", buf2); else snprintf(buf, sizeof(buf), "octet \"%s\"\n", buf2); buf[ sizeof(buf)-1 ] = 0; break; case ASN_OBJECT_ID: sprint_mib_oid(buf2, (oid *) var_val, var_val_len); snprintf(buf, sizeof(buf), "objectid \"%s\"\n", buf2); buf[ sizeof(buf)-1 ] = 0; break; } strncat(persistpassthru->command, buf, sizeof(persistpassthru->command) - strlen(persistpassthru->command) - 2); persistpassthru->command[ sizeof(persistpassthru->command)-2 ] = '\n'; persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0; if (!open_persist_pipe(i, persistpassthru->name)) { return SNMP_ERR_NOTWRITABLE; } DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-writing: %s\n", persistpassthru->command)); if (!write_persist_pipe(i, persistpassthru->command)) { close_persist_pipe(i); return SNMP_ERR_NOTWRITABLE; } if (fgets(buf, sizeof(buf), persist_pipes[i].fIn) == NULL) { close_persist_pipe(i); return SNMP_ERR_NOTWRITABLE; } if (!strncasecmp(buf, "not-writable", 12)) { return SNMP_ERR_NOTWRITABLE; } else if (!strncasecmp(buf, "wrong-type", 10)) { return SNMP_ERR_WRONGTYPE; } return SNMP_ERR_NOERROR; } } if (snmp_get_do_debugging()) { sprint_mib_oid(buf2, name, name_len); DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-notfound: %s\n", buf2)); } return SNMP_ERR_NOSUCHNAME;}intpass_persist_compare(const void *a, const void *b){ const struct extensible *const *ap, *const *bp; ap = (const struct extensible * const *) a; bp = (const struct extensible * const *) b; return snmp_oid_compare((*ap)->miboid, (*ap)->miblen, (*bp)->miboid, (*bp)->miblen);}/* * Initialize our persistant pipes * - Returns 1 on success, 0 on failure. * - Initializes all FILE pointers to NULL to indicate "closed" */static intinit_persist_pipes(void){ int i; /* * if we are already taken care of, just return */ if (persist_pipes) { return persist_pipes ? 1 : 0; } /* * Otherwise malloc and initialize */ persist_pipes = (struct persist_pipe_type *) malloc(sizeof(struct persist_pipe_type) * (numpersistpassthrus + 1)); if (persist_pipes) { for (i = 0; i <= numpersistpassthrus; i++) { persist_pipes[i].fIn = persist_pipes[i].fOut = (FILE *) 0; persist_pipes[i].fdIn = persist_pipes[i].fdOut = -1; persist_pipes[i].pid = -1; } } return persist_pipes ? 1 : 0;}/* * Destruct our persistant pipes * */static voiddestruct_persist_pipes(void){ int i; /* * Return if there are no pipes */ if (!persist_pipes) { return; } for (i = 0; i <= numpersistpassthrus; i++) { close_persist_pipe(i); } free(persist_pipes); persist_pipes = (struct persist_pipe_type *) 0;}/* * returns 0 on failure, 1 on success */static intopen_persist_pipe(int iindex, char *command){ static int recurse = 0; /* used to allow one level of recursion */ DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe(%d,'%s')\n", iindex, command)); /* * Open if it's not already open */ if (persist_pipes[iindex].pid == -1) { int fdIn, fdOut, pid; /* * Did we fail? */ if ((0 == get_exec_pipes(command, &fdIn, &fdOut, &pid)) || (pid == -1)) { DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: pid == -1\n")); recurse = 0; return 0; } /* * If not, fill out our structure */ persist_pipes[iindex].pid = pid; persist_pipes[iindex].fdIn = fdIn; persist_pipes[iindex].fdOut = fdOut; persist_pipes[iindex].fIn = fdopen(fdIn, "r"); persist_pipes[iindex].fOut = fdopen(fdOut, "w"); /* * Setup our -non-buffered-io- */ setbuf(persist_pipes[iindex].fOut, (char *) 0); } /* * Send test packet always so we can self-catch */ { char buf[SNMP_MAXBUF]; /* * Should catch SIGPIPE around this call! */ if (!write_persist_pipe(iindex, "PING\n")) { DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: Error writing PING\n")); close_persist_pipe(iindex); /* * Recurse one time if we get a SIGPIPE */ if (!recurse) { recurse = 1; return open_persist_pipe(iindex, command); } recurse = 0; return 0; } if (fgets(buf, sizeof(buf), persist_pipes[iindex].fIn) == NULL) { DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: Error reading for PONG\n")); close_persist_pipe(iindex); recurse = 0; return 0; } if (strncmp(buf, "PONG", 4)) { DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: PONG not received!\n")); close_persist_pipe(iindex); recurse = 0; return 0; } } recurse = 0; return 1;}#if STRUCT_SIGACTION_HAS_SA_SIGACTION/* * Generic handler */voidsigpipe_handler(int sig, siginfo_t * sip, void *uap){ return;}#endifstatic intwrite_persist_pipe(int iindex, const char *data){#if HAVE_SIGNAL struct sigaction sa, osa; int wret = 0, werrno = 0; /* * Don't write to a non-existant process */ if (persist_pipes[iindex].pid == -1) { return 0; } /* * Setup our signal action to catch SIGPIPEs */ sa.sa_handler = NULL;#if STRUCT_SIGACTION_HAS_SA_SIGACTION sa.sa_sigaction = &sigpipe_handler;#endif sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGPIPE, &sa, &osa)) { DEBUGMSGTL(("ucd-snmp/pass_persist", "write_persist_pipe: sigaction failed: %d", errno)); } /* * Do the write */ wret = write(persist_pipes[iindex].fdOut, data, strlen(data)); werrno = errno; /* * Reset the signal handler */ sigaction(SIGPIPE, &osa, (struct sigaction *) 0); if (wret < 0) { if (werrno != EINTR) { DEBUGMSGTL(("ucd-snmp/pass_persist", "write_persist_pipe: write returned unknown error %d\n", errno)); } close_persist_pipe(iindex); return 0; }#endif /* HAVE_SIGNAL */ return 1;}static voidclose_persist_pipe(int iindex){ /* * Check and nix every item */ if (persist_pipes[iindex].fOut) { fclose(persist_pipes[iindex].fOut); persist_pipes[iindex].fOut = (FILE *) 0; } if (persist_pipes[iindex].fdOut != -1) { close(persist_pipes[iindex].fdOut); persist_pipes[iindex].fdOut = -1; } if (persist_pipes[iindex].fIn) { fclose(persist_pipes[iindex].fIn); persist_pipes[iindex].fIn = (FILE *) 0; } if (persist_pipes[iindex].fdIn != -1) { close(persist_pipes[iindex].fdIn); persist_pipes[iindex].fdIn = -1; } if (persist_pipes[iindex].pid != -1) {#if HAVE_SYS_WAIT_H waitpid(persist_pipes[iindex].pid, 0, 0);#endif persist_pipes[iindex].pid = -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -