/*
 *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
 *
 *All right reserved
 *
 *File Name: expValueTable.c
 *File Description: expValueTable MIB operation.
 *
 *Current Version:1.0
 *Author:JianShun Tong
 *Date:2004.8.20
 */


/*
 * This file was generated by mib2c and is intended for use as
 * a mib module for the ucd-snmp snmpd agent. 
 */


/*
 * This should always be included first before anything else 
 */
#include <net-snmp/net-snmp-config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <stdio.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif


/*
 * minimal include directives 
 */
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "header_complex.h"
#include "expExpressionTable.h"
#include "expValueTable.h"
#include "expObjectTable.h"


/*
 * expValueTable_variables_oid:
 *   this is the top level oid that we want to register under.  This
 *   is essentially a prefix, with the suffix appearing in the
 *   variable below.
 */

oid             expValueTable_variables_oid[] =
    { 1, 3, 6, 1, 2, 1, 90, 1, 3, 1 };

struct s_node {
    unsigned        data;
    struct s_node  *next;
};
typedef struct s_node nodelink;
nodelink           *operater = NULL;
nodelink           *operand = NULL;

/*
 * variable2 expObjectTable_variables:
 */

struct variable2 expValueTable_variables[] = {
    /*
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
     */
#define	EXPVALUECOUNTER32VAL 2
    {EXPVALUECOUNTER32VAL,  ASN_COUNTER,  RONLY, var_expValueTable, 2, {1, 2}},
#define	EXPVALUEUNSIGNED32VAL 3
    {EXPVALUEUNSIGNED32VAL, ASN_UNSIGNED, RONLY, var_expValueTable, 2, {1, 3}},
#define	EXPVALUETIMETICKSVAL 4
    {EXPVALUETIMETICKSVAL,  ASN_UNSIGNED, RONLY, var_expValueTable, 2, {1, 4}},
#define	EXPVALUEINTEGER32VAL 5
    {EXPVALUEINTEGER32VAL,  ASN_INTEGER,  RONLY, var_expValueTable, 2, {1, 5}},
#define	EXPVALUEIPADDRESSVAL 6
    {EXPVALUEIPADDRESSVAL, ASN_IPADDRESS, RONLY, var_expValueTable, 2, {1, 6}},
#define	EXPVALUEOCTETSTRINGVAL 7
    {EXPVALUEOCTETSTRINGVAL, ASN_OCTET_STR, RONLY, var_expValueTable, 2, {1, 7}},
#define	EXPVALUEOIDVAL  8
    {EXPVALUEOIDVAL,       ASN_OBJECT_ID, RONLY, var_expValueTable, 2, {1, 8}},
#define	EXPVALUECOUNTER64VAL  9
    {EXPVALUECOUNTER64VAL, ASN_INTEGER,   RONLY, var_expValueTable, 2, {1, 9}}
};


/*
 * global storage of our data, saved in and configured by header_complex() 
 */
extern struct header_complex_index *expExpressionTableStorage;
extern struct header_complex_index *expObjectTableStorage;
struct header_complex_index *expValueTableStorage = NULL;
struct snmp_session session;

/*
 * init_expValueTable():
 *   Initialization routine.  This is called when the agent starts up.
 *   At a minimum, registration of your variables should take place here.
 */
void
init_expValueTable(void)
{
    DEBUGMSGTL(("expValueTable", "initializing...  "));


    /*
     * register ourselves with the agent to handle our mib tree 
     */
    REGISTER_MIB("expValueTable",
                 expValueTable_variables, variable2,
                 expValueTable_variables_oid);
    init_snmp("snmpapp");

    /*
     * Initialize a "session" that defines who we're going to talk to
     */
    snmp_sess_init(&session);   /* set up defaults */
    session.peername = strdup("localhost");

    DEBUGMSGTL(("expValueTable", "done.\n"));
}

struct expValueTable_data *
create_expValueTable_data(void)
{
    struct expValueTable_data *StorageNew;

    StorageNew = SNMP_MALLOC_STRUCT(expValueTable_data);

    /*
     * fill in default row values here into StorageNew 
     */
    /*
     * fill in values for all tables (even if not
     * appropriate), since its easier to do here than anywhere
     * else 
     */
    StorageNew->expExpressionOwner = strdup("");
    StorageNew->expExpressionName = strdup("");
    StorageNew->expValueInstance = calloc(1, sizeof(oid) * sizeof(2));  /* 0.0.0 */
    StorageNew->expValueInstanceLen = 3;
    return StorageNew;
}

/*
 * mteTriggerTable_add(): adds a structure node to our data set 
 */
int
expValueTable_add(struct expExpressionTable_data *expression_data,
                  char *owner, size_t owner_len, char *name,
                  size_t name_len, oid * index, size_t index_len)
{
    netsnmp_variable_list *vars = NULL;
    struct expValueTable_data *thedata, *StorageTmp;
    struct header_complex_index *hcindex;
    int             founded = 0;
    thedata = create_expValueTable_data();
    thedata->expValueCounter32Val = 0;
    thedata->expExpressionOwner = owner;
    thedata->expExpressionOwnerLen = owner_len;
    thedata->expExpressionName = name;
    thedata->expExpressionNameLen = name_len;
    thedata->expValueInstance = index;
    thedata->expValueInstanceLen = index_len;
    thedata->expression_data = expression_data;
    DEBUGMSGTL(("expValueTable", "adding data...  "));
    /*
     * add the index variables to the varbind list, which is 
     * used by header_complex to index the data 
     */


    snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen);     /* expExpressionOwner */
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen);       /* expExpressionName */
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OBJECT_ID,
                              (u_char *) thedata->expValueInstance,
                              thedata->expValueInstanceLen * sizeof(oid));

    for (hcindex = expValueTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        StorageTmp = (struct expValueTable_data *) hcindex->data;
        if (!strcmp
            (StorageTmp->expExpressionOwner, thedata->expExpressionOwner)
            && (StorageTmp->expExpressionOwnerLen ==
                thedata->expExpressionOwnerLen)
            && !strcmp(StorageTmp->expExpressionName,
                       thedata->expExpressionName)
            && (StorageTmp->expExpressionNameLen ==
                thedata->expExpressionNameLen)
            && !snmp_oid_compare(StorageTmp->expValueInstance,
                                 StorageTmp->expValueInstanceLen,
                                 thedata->expValueInstance,
                                 thedata->expValueInstanceLen)) {
            founded = 1;
            break;
        }

    }
    if (!founded) {
        header_complex_add_data(&expValueTableStorage, vars, thedata);
        DEBUGMSGTL(("expValueTable", "registered an entry\n"));
    } else {
        SNMP_FREE(thedata);
        DEBUGMSGTL(("expValueTable",
                    "already have an entry, dont registe\n"));
    }


    DEBUGMSGTL(("expValueTable", "done.\n"));
    return SNMPERR_SUCCESS;
}





unsigned long
Evaluate_Expression(struct expValueTable_data *vtable_data)
{

    struct header_complex_index *hcindex;
    struct expObjectTable_data *objstorage, *objfound;
    struct expValueTable_data *valstorage;
    valstorage = vtable_data;

    char           *expression;
    char           *result, *resultbak;
    char           *temp, *tempbak;
    char            intchar[10];
    int             dollar1, dollar2;
    int             i = 0, j, k, l;
    long            value;
    unsigned long   result_u_long;
    temp = malloc(100);
    result = malloc(100);
    tempbak = temp;
    memset(result, 0, 100);
    *result = '\0';
    resultbak = result;

    expression = vtable_data->expression_data->expExpression;

    while (*expression != '\0') {
        if (*expression == '$') {
            objfound = NULL;
            i++;
            for (j = 1; j < 100; j++) {
                if ((*(expression + j) == '+') ||
                    (*(expression + j) == '-') ||
                    (*(expression + j) == '*') ||
                    (*(expression + j) == '/') ||
                    (*(expression + j) == '(') ||
                    (*(expression + j) == ')') ||
                    *(expression + j) == '\0') {
                    break;
                }
            }
            sprintf(temp, "%.*s", j - 1, expression + 1);
            l = atoi(temp);
            expression = expression + j;
            /*
             *   here use snmpget to get value
             */
            for (hcindex = expObjectTableStorage; hcindex != NULL;
                 hcindex = hcindex->next) {
                objstorage = (struct expObjectTable_data *) hcindex->data;
                if (!strcmp
                    (objstorage->expExpressionOwner,
                     valstorage->expExpressionOwner)
                    && (objstorage->expExpressionOwnerLen ==
                        valstorage->expExpressionOwnerLen)
                    && !strcmp(objstorage->expExpressionName,
                               valstorage->expExpressionName)
                    && (objstorage->expExpressionNameLen ==
                        valstorage->expExpressionNameLen)
                    && (l == objstorage->expObjectIndex)) {
                    objfound = objstorage;
                    break;
                }
            }


            if (!objfound) {
                /* have err */
                return 0;
            }
            struct snmp_session *ss;
            struct snmp_pdu *pdu;
            struct snmp_pdu *response;

            oid             anOID[MAX_OID_LEN];
            size_t          anOID_len;

            memcpy(anOID, objfound->expObjectID,
                   objfound->expObjectIDLen * sizeof(oid));
            anOID_len = objfound->expObjectIDLen;
            if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_TRUE) {
                anOID_len =
                    anOID_len + valstorage->expValueInstanceLen - 2;
                memcpy(anOID + objfound->expObjectIDLen,
                       valstorage->expValueInstance + 2,
                       (valstorage->expValueInstanceLen -
                        2) * sizeof(oid));
            }
            struct variable_list *vars;
            int             status;
            int             count = 1;

            /*
             * Initialize the SNMP library
             */

            /*
             * Initialize a "session" that defines who we're going to talk to
             */
            session.version = vtable_data->expression_data->pdu_version;

            /*
             * set the SNMPv1 community name used for authentication 
             */
            session.community =
                vtable_data->expression_data->pdu_community;
            session.community_len =
                vtable_data->expression_data->pdu_community_len;
            /*
             * Open the session
             */
            SOCK_STARTUP;
            ss = snmp_open(&session);   /* establish the session */

            if (!ss) {
                /* err */
                exit(2);
            }
            pdu = snmp_pdu_create(SNMP_MSG_GET);
            snmp_add_null_var(pdu, anOID, anOID_len);

            /*
             * Send the Request out.
             */
            status = snmp_synch_response(ss, pdu, &response);

            /*
             * Process the response.
             */
            if (status == STAT_SUCCESS
                && response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * SUCCESS: Print the result variables
                 */

                vars = response->variables;
                value = *(vars->val.integer);
                sprintf(intchar, "%u", value);
                for (k = 1; k <= strlen(intchar); k++) {
                    *result = intchar[k - 1];
                    result++;
                }

            } else {
                /*
                 * FAILURE: print what went wrong!
                 */

                if (status == STAT_SUCCESS)
                    fprintf(stderr, "Error in packet\nReason: %s\n",
                            snmp_errstring(response->errstat));
                else
                    snmp_sess_perror("snmpget", ss);

            }

            /*
             * Clean up:
             *  1) free the response.
             *  2) close the session.
             */
            if (response)
                snmp_free_pdu(response);
            snmp_close(ss);

            SOCK_CLEANUP;

        } else {
            *result = *expression;
            result++;
            expression++;
        }
    }
    result_u_long = get_result(resultbak);
    free(tempbak);
    free(resultbak);
    return result_u_long;
}








void
expValueTable_clean(void *data)
{
    struct expValueTable_data *cleanme =
        (struct expValueTable_data *) data;
    SNMP_FREE(cleanme->expValueInstance);
    SNMP_FREE(cleanme->expValueIpAddressVal);
    SNMP_FREE(cleanme->expValueOctetStringVal);
    SNMP_FREE(cleanme->expValueOidVal);
    SNMP_FREE(cleanme);
}



void
build_valuetable()
{
    struct expExpressionTable_data *expstorage;
    struct expObjectTable_data *objstorage, *objfound = NULL;
    struct header_complex_index *hcindex, *object_hcindex;
    char           *owner;
    size_t          owner_len;
    char           *name;
    size_t          name_len;
    char           *expression;
    oid            *index;
    int             i = 0, j, l;

    DEBUGMSGTL(("expValueTable", "building valuetable...  \n"));

    for (hcindex = expExpressionTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        expstorage = (struct expExpressionTable_data *) hcindex->data;
        if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
            expression = expstorage->expExpression;
            while (*expression != '\0') {
                if (*expression == '$') {
                    i++;
                    for (j = 1; j < 100; j++) {
                        if ((*(expression + j) == '+') ||
                            (*(expression + j) == '-') ||
                            (*(expression + j) == '*') ||
                            (*(expression + j) == '/') ||
                            (*(expression + j) == '(') ||
                            (*(expression + j) == ')') ||
                            *(expression + j) == '\0') {
                            break;
                        }
                    }
                    {
                        char temp[100];

                        sprintf(temp, "%.*s", j - 1, expression + 1);
                        l = atoi(temp);
                    }
                    for (object_hcindex = expObjectTableStorage;
                         object_hcindex != NULL;
                         object_hcindex = object_hcindex->next) {
                        objstorage =
                            (struct expObjectTable_data *) object_hcindex->
                            data;
                        if (!strcmp
                            (objstorage->expExpressionOwner,
                             expstorage->expExpressionOwner)
                            && (objstorage->expExpressionOwnerLen ==
                                expstorage->expExpressionOwnerLen)
                            && !strcmp(objstorage->expExpressionName,
                                       expstorage->expExpressionName)
                            && (objstorage->expExpressionNameLen ==
                                expstorage->expExpressionNameLen)
                            && (l == objstorage->expObjectIndex)) {
                            if (objfound == NULL) {
                                objfound = objstorage;
                            }
                            if (objstorage->expObjectIDWildcard ==
                                EXPOBJCETIDWILDCARD_TRUE)
                                objfound = objstorage;
                        }
                    }
                    expression = expression + j;
                } else {
                    expression++;
                }
            };
        }

        if (!objfound) {
            continue;
        }
        if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_FALSE) {
            index = calloc(1, MAX_OID_LEN);
            *index = 0;
            *(index + 1) = 0;
            *(index + 2) = 0;
            expValueTable_add(expstorage, objfound->expExpressionOwner,
                              objfound->expExpressionOwnerLen,
                              objfound->expExpressionName,
                              objfound->expExpressionNameLen, index, 3);
        } else {
            oid            *targetOID;
            size_t          taggetOID_len;
            targetOID = objfound->expObjectID;
            struct snmp_pdu *pdu;
            struct snmp_pdu *response;
            oid            *next_OID;
            size_t          next_OID_len;
            taggetOID_len = objfound->expObjectIDLen;
            struct variable_list *vars;
            int             status;
            int             count = 1;
            struct snmp_session *ss;
            /*
             * Initialize the SNMP library
             */


            /*
             * set the SNMP version number 
             */
            session.version = expstorage->pdu_version;

            /*
             * set the SNMPv1 community name used for authentication 
             */
            session.community = expstorage->pdu_community;
            session.community_len = expstorage->pdu_community_len;

            /*
             * Open the session
             */
            SOCK_STARTUP;
            ss = snmp_open(&session);   /* establish the session */
            if (!ss) {
                snmp_perror("ack");
                snmp_log(LOG_ERR, "something horrible happened!!!\n");
                exit(2);
            }

            next_OID = targetOID;
            next_OID_len = taggetOID_len;
            do {
                index = calloc(1, MAX_OID_LEN);
                pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);

                snmp_add_null_var(pdu, next_OID, next_OID_len);

                /*
                 * Send the Request out.
                 */
                status = snmp_synch_response(ss, pdu, &response);

                /*
                 * Process the response.
                 */
                if (status == STAT_SUCCESS
                    && response->errstat == SNMP_ERR_NOERROR) {
                    /*
                     * SUCCESS: Print the result variables
                     */

                    if (((response->variables->type >= SNMP_NOSUCHOBJECT &&
                          response->variables->type <= SNMP_ENDOFMIBVIEW)
                         || snmp_oid_compare(targetOID, taggetOID_len,
                                             response->variables->name,
                                             taggetOID_len) != 0)) {
                        break;
                    }
                    /* add to expValueTable */

                    *index = 0;
                    *(index + 1) = 0;
                    memcpy(index + 2,
                           response->variables->name + taggetOID_len,
                           (response->variables->name_length -
                            taggetOID_len) * sizeof(oid));
                    expValueTable_add(expstorage,
                                      objfound->expExpressionOwner,
                                      objfound->expExpressionOwnerLen,
                                      objfound->expExpressionName,
                                      objfound->expExpressionNameLen,
                                      index,
                                      response->variables->name_length -
                                      taggetOID_len + 2);

                    next_OID = response->variables->name;

                    next_OID_len = response->variables->name_length;




                } else {
                    /*
                     * FAILURE: print what went wrong!
                     */
                    if (status == STAT_SUCCESS)
                        fprintf(stderr, "Error in packet\nReason: %s\n",
                                snmp_errstring(response->errstat));
                    else
                        snmp_sess_perror("snmpget", ss);
                }
            } while (TRUE);

        }

    }

}



/*
 * var_expValueTable():
 */
unsigned char  *
var_expValueTable(struct variable *vp,
                  oid * name,
                  size_t *length,
                  int exact, size_t *var_len, WriteMethod ** write_method)
{

    static netsnmp_variable_list *vars;
    size_t          newlen =
        *length - (sizeof(expValueTable_variables_oid) / sizeof(oid) +
                   3 - 1);
    struct expValueTable_data *StorageTmp = NULL;
    unsigned int    counter32;




    DEBUGMSGTL(("expValueTable", "var_expValueTable: Entering...  \n"));

    /*
     *  before we build valuetable we must free any other valutable if exist
     */
    header_complex_free_all(expValueTableStorage, expValueTable_clean);
    expValueTableStorage = NULL;


    build_valuetable();


    /*
     * this assumes you have registered all your data properly
     */
    if ((StorageTmp =
         header_complex(expValueTableStorage, vp, name, length, exact,
                        var_len, write_method)) == NULL)
        return NULL;


    /*
     * this is where we do the value assignments for the mib results.
     */
    switch (vp->magic) {
        /*
         *   we only support counter32val
         */

    case EXPVALUECOUNTER32VAL:
        StorageTmp->expValueCounter32Val = Evaluate_Expression(StorageTmp);
        *var_len = sizeof(StorageTmp->expValueCounter32Val);
        return (u_char *) & StorageTmp->expValueCounter32Val;

    case EXPVALUEUNSIGNED32VAL:
        /* var_len = sizeof(StorageTmp->expValueUnsigned32Val); */
        /* return (u_char *) & StorageTmp->expValueUnsigned32Val;         */
        return NULL;

    case EXPVALUETIMETICKSVAL:
        /* var_len = sizeof(StorageTmp->expValueTimeTicksVal); */
        /* return (u_char *) & StorageTmp->expValueTimeTicksVal; */
        return NULL;

    case EXPVALUEINTEGER32VAL:
        /* var_len = sizeof(StorageTmp->expValueInteger32Val); */
        /* return (u_char *) & StorageTmp->expValueInteger32Val; */
        return NULL;

    case EXPVALUEIPADDRESSVAL:
        /* var_len = sizeof(StorageTmp->expValueIpAddressVal); */
        /* return (u_char *) & StorageTmp->expValueIpAddressVal; */
        return NULL;

    case EXPVALUEOCTETSTRINGVAL:
        /* var_len = sizeof(StorageTmp->expValueOctetStringVal); */
        /* return (u_char *) & StorageTmp->expValueOctetStringVal;        */
        return NULL;

    case EXPVALUEOIDVAL:
        /* var_len = StorageTmp->expValueOidValLen; */
        /* return (u_char *) & StorageTmp->expValueOidVal; */
        return NULL;

    case EXPVALUECOUNTER64VAL:
        /* var_len = sizeof(StorageTmp->expValueCounter64Val); */
        /* return (u_char *) & StorageTmp->expValueCounter64Val; */
        return NULL;
    default:
        ERROR_MSG("");
    }
}





void
push(nodelink ** stack, unsigned long value)
{
    nodelink           *newnode;
    newnode = (nodelink *) malloc(sizeof(nodelink));
    if (!newnode) {
        printf("\nMemory allocation failure!");
        return;
    }
    newnode->data = value;
    newnode->next = *stack;
    *stack = newnode;
}

unsigned long
pop(nodelink ** stack)
{
    unsigned long   value;
    nodelink           *top;
    top = *stack;
    *stack = (*stack)->next;
    value = top->data;
    free(top);
    return value;
}

int
priority(char operater)
{
    switch (operater) {
    case '*':
    case '/':
        return 4;
    case '+':
    case '-':
        return 3;
    case ')':
        return 2;
    case '(':
        return 1;
    default:
        return 0;
    }
}

unsigned long
calculate(int operater, unsigned long a, unsigned long b)
{
    switch (operater) {
    case '+':
        return (a + b);
    case '-':
        return (a - b);
    case '*':
        return (a * b);
    case '/':
        if (operater == '/' && b == 0) {
            printf("\nDivision mustn\'t be 0!");
            exit(0);
        } else
            return (a / b);
    }
}

unsigned long
get_operand(char *p, int *length)
{
    char            c[13];
    int             i = 0, k = 1;
    unsigned long   result = 0;
    while (*p <= 57 && *p >= 48)
        c[i++] = *(p++);
    *length += --i;
    for (; i >= 0; i--) {
        result += (c[i] - 48) * k;
        k *= 10;
    }
    return result;
}

int
operator_class(char c)
{
    if (c <= 57 && c >= 48)
        return 1;
    if (c == 42 || c == 43 || c == 45 || c == 47)
        return 2;
    if (c == 41)
        return 3;
    if (c == 40)
        return 4;
    return 0;
}

unsigned long
get_result(char *expr)
{
    int             position = 0;
    unsigned long   op = 0, a = 0, b = 0, result = 0;
    char           *expression;
    expression = expr;
    while (*(expression + position) != '\0'
           && *(expression + position) != '\n') {
        switch (operator_class(*(expression + position))) {
        case 1:
            push(&operand, get_operand(expression + position, &position));
            break;
        case 2:
            if (operater != NULL)
                while (operater != NULL
                       && priority(*(expression + position)) <=
                       priority(operater->data)) {
                    a = pop(&operand);
                    b = pop(&operand);
                    op = pop(&operater);
                    push(&operand, calculate(op, b, a));
                }
            push(&operater, *(expression + position));
            break;
        case 3:
            while (operater != NULL && operater->data != '(') {
                a = pop(&operand);
                b = pop(&operand);
                op = pop(&operater);
                push(&operand, calculate(op, b, a));
            }
            if (operater->data == '(')
                pop(&operater);
            break;
        case 4:
            push(&operater, '(');
            break;
        default:
            printf("\nInvalid character in expression:");
            a = 0;
            while (*(expression + (int) a) != '\n'
                   && *(expression + (int) a) != '\0') {
                if (a != position)
                    printf("%c", *(expression + (int) a));
                else
                    printf("<%c>", *(expression + (int) a));
                a++;
            }
            exit(0);
        }                       /* end switch */
        position++;
    }
    while (operater != NULL) {
        op = pop(&operater);
        a = pop(&operand);
        b = pop(&operand);
        push(&operand, calculate(op, b, a));
    }
    result = pop(&operand);
    return result;
}
