snmp_alarm.c
资源名称:snmp.src.rar [点击查看]
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:6k
源码类别:
SNMP编程
开发平台:
C/C++
- /* snmp_alarm.c: generic library based alarm timers for various parts
- of an application */
- #include <config.h>
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <signal.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <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 <ip/socket.h>
- #endif
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #include "asn1.h"
- #include "snmp_api.h"
- #include "snmp_debug.h"
- #include "tools.h"
- #include "default_store.h"
- #include "callback.h"
- #include "snmp_alarm.h"
- static struct snmp_alarm *thealarms;
- static int start_alarms = 0;
- static unsigned int regnum = 1;
- extern time_t time(time_t *);
- #undef SIGALRM
- int
- init_alarm_post_config(int majorid, int minorid, void *serverarg,
- void *clientarg) {
- start_alarms = 1;
- set_an_alarm();
- return SNMPERR_SUCCESS;
- }
- void
- init_snmp_alarm(void) {
- start_alarms = 0;
- snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
- init_alarm_post_config, NULL);
- }
- void
- sa_update_entry(struct snmp_alarm *alrm) {
- time_t t_temp;
- if (alrm->seconds == 0) {
- DEBUGMSGTL(("snmp_alarm_update_entry","illegal 0 length alarm timer specifiedn"));
- return; /* illegal */
- }
- if (alrm->lastcall == 0) {
- /* never been called yet, call seconds from now. */
- alrm->lastcall = time(&t_temp);
- alrm->nextcall = alrm->lastcall + alrm->seconds;
- } else if (alrm->nextcall == 0) {
- /* We've been called but not reset for the next? call */
- if ((alrm->flags & SA_REPEAT) == SA_REPEAT) {
- alrm->nextcall = alrm->lastcall + alrm->seconds;
- } else {
- /* single time call, remove it */
- snmp_alarm_unregister(alrm->clientreg);
- }
- }
- }
- void
- snmp_alarm_unregister(unsigned int clientreg) {
- struct snmp_alarm *sa_ptr, *alrm=NULL;
- if (thealarms == NULL)
- return;
- if (clientreg == thealarms->clientreg) {
- alrm = thealarms;
- thealarms = alrm->next;
- }
- else {
- for(sa_ptr = thealarms;
- sa_ptr != NULL && sa_ptr->next->clientreg != clientreg;
- sa_ptr = sa_ptr->next);
- if (sa_ptr) {
- if (sa_ptr->next) {
- alrm = sa_ptr->next;
- sa_ptr->next = sa_ptr->next->next;
- }
- }
- }
- /* Note: do not free the clientarg, its the clients responsibility */
- if (alrm)
- free(alrm);
- }
- struct snmp_alarm *
- sa_find_next(void) {
- struct snmp_alarm *sa_ptr, *sa_ret = NULL;
- for(sa_ptr = thealarms; sa_ptr != NULL; sa_ptr = sa_ptr->next) {
- if (sa_ret == NULL || sa_ptr->nextcall < sa_ret->nextcall)
- sa_ret = sa_ptr;
- }
- return sa_ret;
- }
- void
- run_alarms(void) {
- int done=0;
- struct snmp_alarm *sa_ptr;
- time_t t_temp;
- /* loop through everything we have repeatedly looking for the next
- thing to call until all events are finally in the future again */
- DEBUGMSGTL(("snmp_alarm_run_alarms","looking for alarms to run...n"));
- while(done == 0) {
- sa_ptr = sa_find_next();
- if (sa_ptr == NULL)
- return;
- if (sa_ptr->nextcall <= time(&t_temp)) {
- DEBUGMSGTL(("snmp_alarm_run_alarms"," running alarm %dn",
- sa_ptr->clientreg));
- (*(sa_ptr->thecallback))(sa_ptr->clientreg, sa_ptr->clientarg);
- DEBUGMSGTL(("snmp_alarm_run_alarms"," ... donen"));
- sa_ptr->lastcall = time(&t_temp);
- sa_ptr->nextcall = 0;
- sa_update_entry(sa_ptr);
- } else {
- done = 1;
- }
- }
- DEBUGMSGTL(("snmp_alarm_run_alarms","Done.n"));
- }
- RETSIGTYPE
- alarm_handler(int a) {
- run_alarms();
- set_an_alarm();
- }
- int
- get_next_alarm_delay_time(void) {
- struct snmp_alarm *sa_ptr;
- int nexttime = 0;
- time_t t_temp;
- sa_ptr = sa_find_next();
- if (sa_ptr) {
- nexttime = sa_ptr->nextcall - time(&t_temp);
- if (nexttime <= 0)
- nexttime = 1; /* occurred already, return 1 second */
- }
- return nexttime;
- }
- void
- set_an_alarm(void) {
- int nexttime = get_next_alarm_delay_time();
- /* we don't use signals if they asked us nicely not to. It's
- expected they'll check the next alarm time and do their own
- calling of run_alarms(). */
- if (!ds_get_boolean(DS_LIBRARY_ID, DS_LIB_ALARM_DONT_USE_SIG) && nexttime) {
- #ifndef WIN32
- #ifdef SIGALRM
- alarm(nexttime);
- DEBUGMSGTL(("snmp_alarm_set_an_alarm","setting an alarm for %d seconds from nown",nexttime));
- signal(SIGALRM, alarm_handler);
- #endif /* SIGALRM */
- #endif
- } else {
- DEBUGMSGTL(("snmp_alarm_set_an_alarm","no alarms found to handlen"));
- }
- }
- unsigned int
- snmp_alarm_register(unsigned int when, unsigned int flags,
- SNMPAlarmCallback *thecallback, void *clientarg) {
- struct snmp_alarm **sa_pptr;
- if (thealarms != NULL) {
- for(sa_pptr = &thealarms; (*sa_pptr) != NULL;
- sa_pptr = &((*sa_pptr)->next));
- } else {
- sa_pptr = &thealarms;
- }
- *sa_pptr = SNMP_MALLOC_STRUCT(snmp_alarm);
- if (*sa_pptr == NULL)
- return 0;
- (*sa_pptr)->seconds = when;
- (*sa_pptr)->flags = flags;
- (*sa_pptr)->clientarg = clientarg;
- (*sa_pptr)->thecallback = thecallback;
- (*sa_pptr)->clientreg = regnum++;
- sa_update_entry(*sa_pptr);
- DEBUGMSGTL(("snmp_alarm_register","registered alarm %d, secends=%d, flags=%dn",
- (*sa_pptr)->clientreg, (*sa_pptr)->seconds, (*sa_pptr)->flags));
- if (start_alarms)
- set_an_alarm();
- return (*sa_pptr)->clientreg;
- }