/**************************************************************
 * Copyright (C) 2001 Alex Rozin, Optical Access
 *
 *                     All Rights Reserved
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 ******************************************************************/

#include <net-snmp/net-snmp-config.h>

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# 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
#include <ctype.h>

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "event.h"

/*
 * Implementation headers 
 */
#include "agutil_api.h"
#include "row_api.h"

/*
 * File scope definitions section 
 */

/*
 * from MIB compilation 
 */
#define eventEntryFirstIndexBegin       11

#define EVENTINDEX            3
#define EVENTDESCRIPTION      4
#define EVENTTYPE             5
#define EVENTCOMMUNITY        6
#define EVENTLASTTIMESENT     7
#define EVENTOWNER            8
#define EVENTSTATUS           9

#define Leaf_event_index        1
#define Leaf_event_description  2
#define MIN_event_description   0
#define MAX_event_description   127
#define Leaf_event_type         3
#define Leaf_event_community    4
#define MIN_event_community     0
#define MAX_event_community     127
#define Leaf_event_last_time_sent 5
#define Leaf_eventOwner        6
#define Leaf_eventStatus       7


#define LOGEVENTINDEX         3
#define LOGINDEX              4
#define LOGTIME               5
#define LOGDESCRIPTION        6


/*
 * defaults & limitations 
 */

#define MAX_LOG_ENTRIES_PER_CTRL	200

typedef struct data_struct_t {
    struct data_struct_t *next;
    u_long          data_index;
    u_long          log_time;
    char           *log_description;
} DATA_ENTRY_T;

typedef enum {
    EVENT_NONE = 1,
    EVENT_LOG,
    EVENT_TRAP,
    EVENT_LOG_AND_TRAP
} EVENT_TYPE_T;

typedef struct {
    char           *event_description;
    char           *event_community;
    EVENT_TYPE_T    event_type;
    u_long          event_last_time_sent;

    SCROLLER_T      scrlr;
#if 0
    u_long          event_last_logged_index;
    u_long          event_number_of_log_entries;
    DATA_ENTRY_T   *log_list;
    DATA_ENTRY_T   *last_log_ptr;
#endif
} CRTL_ENTRY_T;

/*
 * Main section 
 */

static TABLE_DEFINTION_T EventCtrlTable;
static TABLE_DEFINTION_T *table_ptr = &EventCtrlTable;
static unsigned char zero_octet_string[1];

/*
 * Control Table RowApi Callbacks 
 */

static int
data_destructor(SCROLLER_T * scrlr, void *free_me)
{
    DATA_ENTRY_T   *lptr = free_me;

    if (lptr->log_description)
        AGFREE(lptr->log_description);

    return 0;
}

int
event_Create(RMON_ENTRY_T * eptr)
{                               /* create the body: alloc it and set defaults */
    CRTL_ENTRY_T   *body;

    eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
    if (!eptr->body)
        return -3;
    body = (CRTL_ENTRY_T *) eptr->body;

    /*
     * set defaults 
     */

    body->event_description = NULL;
    body->event_community = AGSTRDUP("public");
    /*
     * ag_trace ("Dbg: created event_community=<%s>", body->event_community); 
     */
    body->event_type = EVENT_NONE;
    ROWDATAAPI_init(&body->scrlr,
                    MAX_LOG_ENTRIES_PER_CTRL,
                    MAX_LOG_ENTRIES_PER_CTRL,
                    sizeof(DATA_ENTRY_T), &data_destructor);


    return 0;
}

int
event_Clone(RMON_ENTRY_T * eptr)
{                               /* copy entry_bod -> clone */
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
    CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;

    if (body->event_description)
        clone->event_description = AGSTRDUP(body->event_description);

    if (body->event_community)
        clone->event_community = AGSTRDUP(body->event_community);
    return 0;
}

int
event_Copy(RMON_ENTRY_T * eptr)
{
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
    CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;

    if (body->event_type != clone->event_type) {
        body->event_type = clone->event_type;
    }

    if (clone->event_description) {
        if (body->event_description)
            AGFREE(body->event_description);
        body->event_description = AGSTRDUP(clone->event_description);
    }

    if (clone->event_community) {
        if (body->event_community)
            AGFREE(body->event_community);
        body->event_community = AGSTRDUP(clone->event_community);
    }

    return 0;
}

int
event_Delete(RMON_ENTRY_T * eptr)
{
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr;

    if (body->event_description)
        AGFREE(body->event_description);

    if (body->event_community)
        AGFREE(body->event_community);

    return 0;
}

int
event_Activate(RMON_ENTRY_T * eptr)
{                               /* init logTable */
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;

    ROWDATAAPI_set_size(&body->scrlr,
                        body->scrlr.data_requested,
                        (u_char)(RMON1_ENTRY_VALID == eptr->status) );

    return 0;
}

int
event_Deactivate(RMON_ENTRY_T * eptr)
{                               /* free logTable */
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;

    /*
     * free data list 
     */
    ROWDATAAPI_descructor(&body->scrlr);

    return 0;
}

static int
write_eventControl(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            long_temp;
    char           *char_temp;
    int             leaf_id, snmp_status;
    static int      prev_action = COMMIT;
    RMON_ENTRY_T   *hdr;
    CRTL_ENTRY_T   *cloned_body;

    switch (action) {
    case RESERVE1:
    case FREE:
    case UNDO:
    case ACTION:
    case COMMIT:
    default:
        return ROWAPI_do_another_action(name, eventEntryFirstIndexBegin,
                                        action, &prev_action,
                                        table_ptr, sizeof(CRTL_ENTRY_T));

    case RESERVE2:
        /*
         * get values from PDU, check them and save them in the cloned entry 
         */
        long_temp = name[eventEntryFirstIndexBegin];
        leaf_id = (int) name[eventEntryFirstIndexBegin - 1];
        hdr = ROWAPI_find(table_ptr, long_temp);        /* it MUST be OK */
        cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
        switch (leaf_id) {
        case Leaf_event_index:
            return SNMP_ERR_NOTWRITABLE;
        case Leaf_event_description:
            char_temp = AGMALLOC(1 + MAX_event_description);
            if (!char_temp)
                return SNMP_ERR_TOOBIG;
            snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
                                                  var_val_len,
                                                  MAX_event_description,
                                                  1, NULL, char_temp);
            if (SNMP_ERR_NOERROR != snmp_status) {
                AGFREE(char_temp);
                return snmp_status;
            }

            if (cloned_body->event_description)
                AGFREE(cloned_body->event_description);

            cloned_body->event_description = AGSTRDUP(char_temp);
            /*
             * ag_trace ("rx: event_description=<%s>", cloned_body->event_description); 
             */
            AGFREE(char_temp);

            break;
        case Leaf_event_type:
            snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
                                               var_val_len,
                                               EVENT_NONE,
                                               EVENT_LOG_AND_TRAP,
                                               &long_temp);
            if (SNMP_ERR_NOERROR != snmp_status) {
                return snmp_status;
            }
            cloned_body->event_type = long_temp;
            break;
        case Leaf_event_last_time_sent:
            return SNMP_ERR_NOTWRITABLE;
        case Leaf_event_community:
            char_temp = AGMALLOC(1 + MAX_event_community);
            if (!char_temp)
                return SNMP_ERR_TOOBIG;
            snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
                                                  var_val_len,
                                                  MAX_event_community,
                                                  1, NULL, char_temp);
            if (SNMP_ERR_NOERROR != snmp_status) {
                AGFREE(char_temp);
                return snmp_status;
            }

            if (cloned_body->event_community)
                AGFREE(cloned_body->event_community);

            cloned_body->event_community = AGSTRDUP(char_temp);
            AGFREE(char_temp);

            break;
        case Leaf_eventOwner:
            if (hdr->new_owner)
                AGFREE(hdr->new_owner);
            hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
            if (!hdr->new_owner)
                return SNMP_ERR_TOOBIG;
            snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
                                                  var_val_len,
                                                  MAX_OWNERSTRING,
                                                  1, NULL, hdr->new_owner);
            if (SNMP_ERR_NOERROR != snmp_status) {
                return snmp_status;
            }

            break;
        case Leaf_eventStatus:
            snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
                                               var_val_len,
                                               RMON1_ENTRY_VALID,
                                               RMON1_ENTRY_INVALID,
                                               &long_temp);
            if (SNMP_ERR_NOERROR != snmp_status) {
                return snmp_status;
            }
            hdr->new_status = long_temp;
            break;
        default:
            ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
                     (int) leaf_id);
            return SNMP_ERR_NOSUCHNAME;
        }                       /* of switch by 'leaf_id' */
        break;
    }                           /* of switch by actions */

    prev_action = action;
    return SNMP_ERR_NOERROR;
}

unsigned char  *
var_eventTable(struct variable *vp,
               oid * name,
               size_t * length,
               int exact, size_t * var_len, WriteMethod ** write_method)
{
    static long     long_ret;
    static CRTL_ENTRY_T theEntry;
    RMON_ENTRY_T   *hdr;

    *write_method = write_eventControl;
    hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
                                     table_ptr,
                                     &theEntry, sizeof(CRTL_ENTRY_T));
    if (!hdr)
        return NULL;

    *var_len = sizeof(long);    /* default */

    switch (vp->magic) {
    case EVENTINDEX:
        long_ret = hdr->ctrl_index;
        return (unsigned char *) &long_ret;
    case EVENTDESCRIPTION:
        if (theEntry.event_description) {
            *var_len = strlen(theEntry.event_description);
            return (unsigned char *) theEntry.event_description;
        } else {
            *var_len = 0;
            return zero_octet_string;
        }
    case EVENTTYPE:
        long_ret = theEntry.event_type;
        return (unsigned char *) &long_ret;
    case EVENTCOMMUNITY:
        if (theEntry.event_community) {
            *var_len = strlen(theEntry.event_community);
            return (unsigned char *) theEntry.event_community;
        } else {
            *var_len = 0;
            return zero_octet_string;
        }
    case EVENTLASTTIMESENT:
        long_ret = theEntry.event_last_time_sent;
        return (unsigned char *) &long_ret;
    case EVENTOWNER:
        if (hdr->owner) {
            *var_len = strlen(hdr->owner);
            return (unsigned char *) hdr->owner;
        } else {
            *var_len = 0;
            return zero_octet_string;
        }
    case EVENTSTATUS:
        long_ret = hdr->status;
        return (unsigned char *) &long_ret;
    default:
        ag_trace("EventControlTable: unknown vp->magic=%d",
                 (int) vp->magic);
        ERROR_MSG("");
    }
    return NULL;
}

static SCROLLER_T *
event_extract_scroller(void *v_body)
{
    CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) v_body;
    return &body->scrlr;
}

unsigned char  *
var_logTable(struct variable *vp,
             oid * name,
             size_t * length,
             int exact, size_t * var_len, WriteMethod ** write_method)
{
    static long     long_ret;
    static DATA_ENTRY_T theEntry;
    RMON_ENTRY_T   *hdr;

    *write_method = NULL;
    hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
                                      table_ptr,
                                      &event_extract_scroller,
                                      sizeof(DATA_ENTRY_T), &theEntry);
    if (!hdr)
        return NULL;

    *var_len = sizeof(long);    /* default */

    switch (vp->magic) {
    case LOGEVENTINDEX:
        long_ret = hdr->ctrl_index;
        return (unsigned char *) &long_ret;
    case LOGINDEX:
        long_ret = theEntry.data_index;
        return (unsigned char *) &long_ret;
    case LOGTIME:
        long_ret = theEntry.log_time;
        return (unsigned char *) &long_ret;
    case LOGDESCRIPTION:
        if (theEntry.log_description) {
            *var_len = strlen(theEntry.log_description);
            return (unsigned char *) theEntry.log_description;
        } else {
            *var_len = 0;
            return zero_octet_string;
        }
    default:
        ERROR_MSG("");
    }

    return NULL;
}

/*
 * External API section 
 */

static char    *
create_explanaition(CRTL_ENTRY_T * evptr, u_char is_rising,
                    u_long alarm_index, u_long event_index,
                    oid * alarmed_var,
                    size_t alarmed_var_length,
                    u_long value, u_long the_threshold,
                    u_long sample_type, char *alarm_descr)
{
#define UNEQ_LENGTH	(1 + 11 + 4 + 11 + 1 + 20)
    char            expl[UNEQ_LENGTH];
    static char     c_oid[SPRINT_MAX_LEN];
    size_t          sz;
    char           *descr;
    register char  *pch;
    register char  *tmp;


    snprint_objid(c_oid, sizeof(c_oid)-1, alarmed_var, alarmed_var_length);
    c_oid[sizeof(c_oid)-1] = '\0';
    for (pch = c_oid;;) {
        tmp = strchr(pch, '.');
        if (!tmp)
            break;
        if (isdigit(tmp[1]) || '"' == tmp[1])
            break;
        pch = tmp + 1;
    }

    snprintf(expl, UNEQ_LENGTH, "=%ld %s= %ld :%ld, %ld",
             (unsigned long) value,
             is_rising ? ">" : "<",
             (unsigned long) the_threshold,
             (long) alarm_index, (long) event_index);
    sz = 3 + strlen(expl) + strlen(pch);
    if (alarm_descr)
        sz += strlen(alarm_descr);

    descr = AGMALLOC(sz);
    if (!descr) {
        ag_trace("Can't allocate event description");
        return NULL;
    }

    if (alarm_descr) {
        strcpy(descr, alarm_descr);
        strcat(descr, ":");
    } else
        *descr = '\0';

    strcat(descr, pch);
    strcat(descr, expl);
    return descr;
}

static void
event_send_trap(CRTL_ENTRY_T * evptr, u_char is_rising,
                u_int alarm_index,
                u_int value, u_int the_threshold,
                oid * alarmed_var, size_t alarmed_var_length,
                u_int sample_type)
{
    static oid      objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
    static oid      rmon1_trap_oid[] = { 1, 3, 6, 1, 2, 1, 16, 0, 0 };
    static oid      alarm_index_oid[] =
        { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 1, 0 };
    static oid      alarmed_var_oid[] =
        { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 3, 0 };
    static oid      sample_type_oid[] =
        { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 4, 0 };
    static oid      value_oid[] = { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 5, 0 };
    static oid      threshold_oid[] = { 1, 3, 6, 1, 2, 1, 16, 3, 1, 1, 7, 0 };     /* rising case */
    netsnmp_variable_list *var_list = NULL;

    /*
     * set the last 'oid' : risingAlarm or fallingAlarm 
     */
    if (is_rising) {
        rmon1_trap_oid[8] = 1;
        threshold_oid[10] = 7;
    } else {
        rmon1_trap_oid[8] = 2;
        threshold_oid[10] = 8;
    }
    alarm_index_oid[11] = alarm_index;
    alarmed_var_oid[11] = alarm_index;
    sample_type_oid[11] = alarm_index;
    value_oid[11]       = alarm_index;
    threshold_oid[11]   = alarm_index;

    /*
     * build the var list 
     */
    snmp_varlist_add_variable(&var_list, objid_snmptrap,
                              OID_LENGTH(objid_snmptrap),
                              ASN_OBJECT_ID, (u_char *) rmon1_trap_oid,
                              sizeof(rmon1_trap_oid));
    snmp_varlist_add_variable(&var_list, alarm_index_oid,
                              OID_LENGTH(alarm_index_oid),
                              ASN_INTEGER, (u_char *) &alarm_index,
                              sizeof(u_int));
    snmp_varlist_add_variable(&var_list, alarmed_var_oid,
                              OID_LENGTH(alarmed_var_oid),
                              ASN_OBJECT_ID, (u_char *) alarmed_var,
                              alarmed_var_length * sizeof(oid));
    snmp_varlist_add_variable(&var_list, sample_type_oid,
                              OID_LENGTH(sample_type_oid),
                              ASN_INTEGER, (u_char *) &sample_type,
                              sizeof(u_int));
    snmp_varlist_add_variable(&var_list, value_oid,
                              OID_LENGTH(value_oid),
                              ASN_INTEGER, (u_char *) &value,
                              sizeof(u_int));
    snmp_varlist_add_variable(&var_list, threshold_oid,
                              OID_LENGTH(threshold_oid),
                              ASN_INTEGER, (u_char *) &the_threshold,
                              sizeof(u_int));

    send_v2trap(var_list);
    ag_trace("rmon trap has been sent");
    snmp_free_varbind(var_list);
}


static void
event_save_log(CRTL_ENTRY_T * body, char *event_descr)
{
    register DATA_ENTRY_T *lptr;

    lptr = ROWDATAAPI_locate_new_data(&body->scrlr);
    if (!lptr) {
        ag_trace("Err: event_save_log:cannot locate ?");
        return;
    }

    lptr->log_time = body->event_last_time_sent;
    if (lptr->log_description)
        AGFREE(lptr->log_description);
    lptr->log_description = AGSTRDUP(event_descr);
    lptr->data_index = ROWDATAAPI_get_total_number(&body->scrlr);

    /*
     * ag_trace ("log has been saved, data_index=%d", (int) lptr->data_index); 
     */
}

int
event_api_send_alarm(u_char is_rising,
                     u_long alarm_index,
                     u_long event_index,
                     oid * alarmed_var,
                     size_t alarmed_var_length,
                     u_long sample_type,
                     u_long value, u_long the_threshold, char *alarm_descr)
{
    RMON_ENTRY_T   *eptr;
    CRTL_ENTRY_T   *evptr;

    if (!event_index)
        return SNMP_ERR_NOERROR;

#if 0
    ag_trace("event_api_send_alarm(%d,%d,%d,'%s')",
             (int) is_rising, (int) alarm_index, (int) event_index,
             alarm_descr);
#endif
    eptr = ROWAPI_find(table_ptr, event_index);
    if (!eptr) {
        /*
         * ag_trace ("event cannot find entry %ld", event_index); 
         */
        return SNMP_ERR_NOSUCHNAME;
    }

    evptr = (CRTL_ENTRY_T *) eptr->body;
    evptr->event_last_time_sent = AGUTIL_sys_up_time();


    if (EVENT_TRAP == evptr->event_type
        || EVENT_LOG_AND_TRAP == evptr->event_type) {
        event_send_trap(evptr, is_rising, alarm_index, value,
                        the_threshold, alarmed_var, alarmed_var_length,
                        sample_type);
    }

    if (EVENT_LOG == evptr->event_type
        || EVENT_LOG_AND_TRAP == evptr->event_type) {
        register char  *explain;

        explain = create_explanaition(evptr, is_rising,
                                      alarm_index, event_index,
                                      alarmed_var, alarmed_var_length,
                                      value, the_threshold,
                                      sample_type, alarm_descr);
        /*
         * if (explain) ag_trace ("Dbg:'%s'", explain); 
         */
        event_save_log(evptr, explain);
        if (explain)
            AGFREE(explain);
    }

    return SNMP_ERR_NOERROR;
}

#if 1                           /* debug, but may be used for init. TBD: may be token snmpd.conf ? */
int
add_event_entry(int ctrl_index,
                char *event_description,
                EVENT_TYPE_T event_type, char *event_community)
{
    register RMON_ENTRY_T *eptr;
    register CRTL_ENTRY_T *body;
    int             ierr;

    ierr = ROWAPI_new(table_ptr, ctrl_index);
    if (ierr) {
        ag_trace("ROWAPI_new failed with %d", ierr);
        return ierr;
    }

    eptr = ROWAPI_find(table_ptr, ctrl_index);
    if (!eptr) {
        ag_trace("ROWAPI_find failed");
        return -4;
    }

    body = (CRTL_ENTRY_T *) eptr->body;

    /*
     * set parameters 
     */

    if (event_description) {
        if (body->event_description)
            AGFREE(body->event_description);
        body->event_description = AGSTRDUP(event_description);
    }

    if (event_community) {
        if (body->event_community)
            AGFREE(body->event_community);
        body->event_community = AGSTRDUP(event_community);
    }

    body->event_type = event_type;

    eptr->new_status = RMON1_ENTRY_VALID;
    ierr = ROWAPI_commit(table_ptr, ctrl_index);
    if (ierr) {
        ag_trace("ROWAPI_commit failed with %d", ierr);
    }

    return ierr;
}
#endif

/*
 * Registration & Initializatio section 
 */

oid             eventTable_variables_oid[] =
    { 1, 3, 6, 1, 2, 1, 16, 9, 1 };
oid             logTable_variables_oid[] = { 1, 3, 6, 1, 2, 1, 16, 9, 2 };

struct variable2 eventTable_variables[] = {
    /*
     * magic number        , variable type, ro/rw , callback fn  ,           L, oidsuffix 
     */
    {EVENTINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_eventTable, 2, {1, 1}},
    {EVENTDESCRIPTION, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_eventTable, 2, {1, 2}},
    {EVENTTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_eventTable, 2, {1, 3}},
    {EVENTCOMMUNITY, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_eventTable, 2, {1, 4}},
    {EVENTLASTTIMESENT, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
     var_eventTable, 2, {1, 5}},
    {EVENTOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_eventTable, 2, {1, 6}},
    {EVENTSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_eventTable, 2, {1, 7}}
};

struct variable2 logTable_variables[] = {
    /*
     * magic number        , variable type, ro/rw , callback fn  ,           L, oidsuffix 
     */
    {LOGEVENTINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_logTable, 2, {1, 1}},
    {LOGINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_logTable, 2, {1, 2}},
    {LOGTIME, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
     var_logTable, 2, {1, 3}},
    {LOGDESCRIPTION, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_logTable, 2, {1, 4}}

};

void
init_event(void)
{
    REGISTER_MIB("eventTable", eventTable_variables, variable2,
                 eventTable_variables_oid);
    REGISTER_MIB("logTable", logTable_variables, variable2,
                 logTable_variables_oid);

    ROWAPI_init_table(&EventCtrlTable, "Event", 0, &event_Create, &event_Clone, &event_Delete, NULL,    /* &event_Validate, */
                      &event_Activate, &event_Deactivate, &event_Copy);
#if 0
    add_event_entry(3, "Alarm", EVENT_LOG_AND_TRAP, NULL);
    /*
     * add_event_entry (5, ">=", EVENT_LOG_AND_TRAP, NULL); 
     */
#endif
}
