📄 pass_persist.c
字号:
{ int i, rtest; struct extensible *persistpassthru; char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF]; long tmp; unsigned long utmp; int itmp; /* 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); sprintf(persistpassthru->command,"set\n%s\n ",buf); 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",(int) tmp); break; case ASN_COUNTER: sprintf(buf,"counter %d",(int) tmp); break; case ASN_GAUGE: sprintf(buf,"gauge %d",(int) tmp); break; case ASN_TIMETICKS: sprintf(buf,"timeticks %d",(int) tmp); break; } break; case ASN_IPADDRESS: utmp = *((u_long *) var_val); utmp = ntohl(utmp); sprintf(buf,"ipaddress %d.%d.%d.%d", (int) ((utmp & 0xff000000) >> (8*3)), (int) ((utmp & 0xff0000) >> (8*2)), (int) ((utmp & 0xff00) >> (8)), (int) ((utmp & 0xff))); break; case ASN_OCTET_STR: itmp = sizeof(buf2); memcpy(buf2, var_val, var_val_len); if (var_val_len == 0) sprintf(buf,"string \"\""); else if (bin2asc(buf2, var_val_len) == (int)var_val_len) sprintf(buf,"string \"%s\"",buf2); else sprintf(buf,"octet \"%s\"",buf2); break; case ASN_OBJECT_ID: sprint_mib_oid(buf2, (oid *)var_val, var_val_len); sprintf(buf,"objectid \"%s\"",buf2); break; } strcat(persistpassthru->command,buf); strcat(persistpassthru->command,"\n"); 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",11)) { return SNMP_ERR_NOTWRITABLE; } else if (!strncasecmp(buf,"wrong-type",9)) { 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;}int pass_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 int init_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 void destruct_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 int open_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; get_exec_pipes( command, &fdIn, &fdOut, &pid ); /* Did we fail? */ if( 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 */void sigpipe_handler (int sig, siginfo_t *sip, void *uap){ return;}#endifstatic int write_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 void close_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 + -