⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmp_alarm.c

📁 snmp up 2
💻 C
字号:
/* * snmp_alarm.c: generic library based alarm timers for various parts * of an application  */#include <net-snmp/net-snmp-config.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#include <signal.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#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 <net-snmp/types.h>#include <net-snmp/output_api.h>#include <net-snmp/config_api.h>#include <net-snmp/utilities.h>#include <net-snmp/library/snmp_api.h>#include <net-snmp/library/callback.h>#include <net-snmp/library/snmp_alarm.h>static struct snmp_alarm *thealarms = NULL;static int      start_alarms = 0;static unsigned int regnum = 1;intinit_alarm_post_config(int majorid, int minorid, void *serverarg,                       void *clientarg){    start_alarms = 1;    set_an_alarm();    return SNMPERR_SUCCESS;}voidinit_snmp_alarm(void){    start_alarms = 0;    snmp_register_callback(SNMP_CALLBACK_LIBRARY,                           SNMP_CALLBACK_POST_READ_CONFIG,                           init_alarm_post_config, NULL);}voidsa_update_entry(struct snmp_alarm *a){    if (a->t.tv_sec == 0 && a->t.tv_usec == 0) {        DEBUGMSGTL(("snmp_alarm",                    "update_entry: illegal interval specified\n"));        return;    }    if (a->t_last.tv_sec == 0 && a->t_last.tv_usec == 0) {        struct timeval  t_now;        /*         * Never been called yet, call time `t' from now.           */        gettimeofday(&t_now, NULL);        a->t_last.tv_sec = t_now.tv_sec;        a->t_last.tv_usec = t_now.tv_usec;        a->t_next.tv_sec = t_now.tv_sec + a->t.tv_sec;        a->t_next.tv_usec = t_now.tv_usec + a->t.tv_usec;        while (a->t_next.tv_usec >= 1000000) {            a->t_next.tv_usec -= 1000000;            a->t_next.tv_sec += 1;        }    } else if (a->t_next.tv_sec == 0 && a->t_next.tv_usec == 0) {        /*         * We've been called but not reset for the next call.           */        if (a->flags & SA_REPEAT) {            a->t_next.tv_sec = a->t_last.tv_sec + a->t.tv_sec;            a->t_next.tv_usec = a->t_last.tv_usec + a->t.tv_usec;            while (a->t_next.tv_usec >= 1000000) {                a->t_next.tv_usec -= 1000000;                a->t_next.tv_sec += 1;            }        } else {            /*             * Single time call, remove it.               */            snmp_alarm_unregister(a->clientreg);        }    }}voidsnmp_alarm_unregister(unsigned int clientreg){    struct snmp_alarm *sa_ptr, **prevNext = &thealarms;    for (sa_ptr = thealarms;         sa_ptr != NULL && sa_ptr->clientreg != clientreg;         sa_ptr = sa_ptr->next) {        prevNext = &(sa_ptr->next);    }    if (sa_ptr != NULL) {        *prevNext = sa_ptr->next;        DEBUGMSGTL(("snmp_alarm", "unregistered alarm %d\n", 		    sa_ptr->clientreg));        /*         * Note:  do not free the clientarg, its the clients responsibility          */        free(sa_ptr);    } else {        DEBUGMSGTL(("snmp_alarm", "no alarm %d to unregister\n", clientreg));    }}voidsnmp_alarm_unregister_all(void){  struct snmp_alarm *sa_ptr, *sa_tmp;  for (sa_ptr = thealarms; sa_ptr != NULL; sa_ptr = sa_tmp) {    sa_tmp = sa_ptr->next;    free(sa_ptr);  }  DEBUGMSGTL(("snmp_alarm", "ALL alarms unregistered\n"));  thealarms = NULL;}  struct snmp_alarm *sa_find_next(void){    struct snmp_alarm *a, *lowest = NULL;    for (a = thealarms; a != NULL; a = a->next) {        if (lowest == NULL) {            lowest = a;        } else if (a->t_next.tv_sec == lowest->t_next.tv_sec) {            if (a->t_next.tv_usec < lowest->t_next.tv_usec) {                lowest = a;            }        } else if (a->t_next.tv_sec < lowest->t_next.tv_sec) {            lowest = a;        }    }    return lowest;}struct snmp_alarm *sa_find_specific(unsigned int clientreg){    struct snmp_alarm *sa_ptr;    for (sa_ptr = thealarms; sa_ptr != NULL; sa_ptr = sa_ptr->next) {        if (sa_ptr->clientreg == clientreg) {            return sa_ptr;        }    }    return NULL;}voidrun_alarms(void){    int             done = 0;    struct snmp_alarm *a = NULL;    unsigned int    clientreg;    struct timeval  t_now;    /*     * Loop through everything we have repeatedly looking for the next thing to     * call until all events are finally in the future again.       */    while (!done) {        if ((a = sa_find_next()) == NULL) {            return;        }        gettimeofday(&t_now, NULL);        if ((a->t_next.tv_sec < t_now.tv_sec) ||            ((a->t_next.tv_sec == t_now.tv_sec) &&             (a->t_next.tv_usec < t_now.tv_usec))) {            clientreg = a->clientreg;            DEBUGMSGTL(("snmp_alarm", "run alarm %d\n", clientreg));            (*(a->thecallback)) (clientreg, a->clientarg);            DEBUGMSGTL(("snmp_alarm", "alarm %d completed\n", clientreg));            if ((a = sa_find_specific(clientreg)) != NULL) {                a->t_last.tv_sec = t_now.tv_sec;                a->t_last.tv_usec = t_now.tv_usec;                a->t_next.tv_sec = 0;                a->t_next.tv_usec = 0;                sa_update_entry(a);            } else {                DEBUGMSGTL(("snmp_alarm", "alarm %d deleted itself\n",                            clientreg));            }        } else {            done = 1;        }    }}RETSIGTYPEalarm_handler(int a){    run_alarms();    set_an_alarm();}intget_next_alarm_delay_time(struct timeval *delta){    struct snmp_alarm *sa_ptr;    struct timeval  t_diff, t_now;    sa_ptr = sa_find_next();    if (sa_ptr) {        gettimeofday(&t_now, 0);        if ((t_now.tv_sec > sa_ptr->t_next.tv_sec) ||            ((t_now.tv_sec == sa_ptr->t_next.tv_sec) &&             (t_now.tv_usec > sa_ptr->t_next.tv_usec))) {            /*             * Time has already passed.  Return the smallest possible amount of             * time.               */            delta->tv_sec = 0;            delta->tv_usec = 1;            return sa_ptr->clientreg;        } else {            /*             * Time is still in the future.               */            t_diff.tv_sec = sa_ptr->t_next.tv_sec - t_now.tv_sec;            t_diff.tv_usec = sa_ptr->t_next.tv_usec - t_now.tv_usec;            while (t_diff.tv_usec < 0) {                t_diff.tv_sec -= 1;                t_diff.tv_usec += 1000000;            }            delta->tv_sec = t_diff.tv_sec;            delta->tv_usec = t_diff.tv_usec;            return sa_ptr->clientreg;        }    }    /*     * Nothing Left.       */    return 0;}voidset_an_alarm(void){    struct timeval  delta;    int             nextalarm = get_next_alarm_delay_time(&delta);    /*     * 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 (nextalarm && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,					NETSNMP_DS_LIB_ALARM_DONT_USE_SIG)) {#ifndef WIN32# ifdef HAVE_SETITIMER        struct itimerval it;        it.it_value.tv_sec = delta.tv_sec;        it.it_value.tv_usec = delta.tv_usec;        it.it_interval.tv_sec = 0;        it.it_interval.tv_usec = 0;        signal(SIGALRM, alarm_handler);        setitimer(ITIMER_REAL, &it, NULL);        DEBUGMSGTL(("snmp_alarm", "schedule alarm %d in %d.%03d seconds\n",                    nextalarm, delta.tv_sec, (delta.tv_usec / 1000)));# else  /* HAVE_SETITIMER */#  ifdef SIGALRM        signal(SIGALRM, alarm_handler);        alarm(delta.tv_sec);        DEBUGMSGTL(("snmp_alarm",                    "schedule alarm %d in roughly %d seconds\n", nextalarm,                    delta.tv_sec));#  endif  /* SIGALRM */# endif  /* HAVE_SETITIMER */#endif  /* WIN32 */    } else {        DEBUGMSGTL(("snmp_alarm", "no alarms found to schedule\n"));    }}unsigned intsnmp_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)->t.tv_sec = when;    (*sa_pptr)->t.tv_usec = 0;    (*sa_pptr)->flags = flags;    (*sa_pptr)->clientarg = clientarg;    (*sa_pptr)->thecallback = thecallback;    (*sa_pptr)->clientreg = regnum++;    (*sa_pptr)->next = NULL;    sa_update_entry(*sa_pptr);    DEBUGMSGTL(("snmp_alarm",		"registered alarm %d, t = %d.%03d, flags=0x%02x\n",                (*sa_pptr)->clientreg, (*sa_pptr)->t.tv_sec,                ((*sa_pptr)->t.tv_usec / 1000), (*sa_pptr)->flags));    if (start_alarms)        set_an_alarm();    return (*sa_pptr)->clientreg;}unsigned intsnmp_alarm_register_hr(struct timeval t, unsigned int flags,                       SNMPAlarmCallback * cb, void *cd){    struct snmp_alarm **s = NULL;    for (s = &(thealarms); *s != NULL; s = &((*s)->next));    *s = SNMP_MALLOC_STRUCT(snmp_alarm);    if (*s == NULL) {        return 0;    }    (*s)->t.tv_sec = t.tv_sec;    (*s)->t.tv_usec = t.tv_usec;    (*s)->flags = flags;    (*s)->clientarg = cd;    (*s)->thecallback = cb;    (*s)->clientreg = regnum++;    (*s)->next = NULL;    sa_update_entry(*s);    DEBUGMSGTL(("snmp_alarm",                "registered alarm %d, t = %d.%03d, flags=0x%02x\n",                (*s)->clientreg, (*s)->t.tv_sec, ((*s)->t.tv_usec / 1000),                (*s)->flags));    if (start_alarms) {        set_an_alarm();    }    return (*s)->clientreg;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -