expValueTable.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:27k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
  3.  *
  4.  *All right reserved
  5.  *
  6.  *File Name: expValueTable.c
  7.  *File Description: expValueTable MIB operation.
  8.  *
  9.  *Current Version:1.0
  10.  *Author:JianShun Tong
  11.  *Date:2004.8.20
  12.  */
  13. /*
  14.  * This file was generated by mib2c and is intended for use as
  15.  * a mib module for the ucd-snmp snmpd agent. 
  16.  */
  17. /*
  18.  * This should always be included first before anything else 
  19.  */
  20. #include <net-snmp/net-snmp-config.h>
  21. #if HAVE_STDLIB_H
  22. #include <stdlib.h>
  23. #endif
  24. #include <stdio.h>
  25. #if HAVE_STRING_H
  26. #include <string.h>
  27. #else
  28. #include <strings.h>
  29. #endif
  30. #ifdef HAVE_LIMITS_H
  31. #include <limits.h>
  32. #endif
  33. /*
  34.  * minimal include directives 
  35.  */
  36. #include <net-snmp/net-snmp-includes.h>
  37. #include <net-snmp/agent/net-snmp-agent-includes.h>
  38. #include "header_complex.h"
  39. #include "expExpressionTable.h"
  40. #include "expValueTable.h"
  41. #include "expObjectTable.h"
  42. /*
  43.  * expValueTable_variables_oid:
  44.  *   this is the top level oid that we want to register under.  This
  45.  *   is essentially a prefix, with the suffix appearing in the
  46.  *   variable below.
  47.  */
  48. oid             expValueTable_variables_oid[] =
  49.     { 1, 3, 6, 1, 2, 1, 90, 1, 3, 1 };
  50. struct s_node {
  51.     unsigned        data;
  52.     struct s_node  *next;
  53. };
  54. typedef struct s_node link;
  55. link           *operater = NULL;
  56. link           *operand = NULL;
  57. /*
  58.  * variable2 expObjectTable_variables:
  59.  */
  60. struct variable2 expValueTable_variables[] = {
  61.     /*
  62.      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
  63.      */
  64. #define EXPVALUECOUNTER32VAL 2
  65.     {EXPVALUECOUNTER32VAL,  ASN_COUNTER,  RONLY, var_expValueTable, 2, {1, 2}},
  66. #define EXPVALUEUNSIGNED32VAL 3
  67.     {EXPVALUEUNSIGNED32VAL, ASN_UNSIGNED, RONLY, var_expValueTable, 2, {1, 3}},
  68. #define EXPVALUETIMETICKSVAL 4
  69.     {EXPVALUETIMETICKSVAL,  ASN_UNSIGNED, RONLY, var_expValueTable, 2, {1, 4}},
  70. #define EXPVALUEINTEGER32VAL 5
  71.     {EXPVALUEINTEGER32VAL,  ASN_INTEGER,  RONLY, var_expValueTable, 2, {1, 5}},
  72. #define EXPVALUEIPADDRESSVAL 6
  73.     {EXPVALUEIPADDRESSVAL, ASN_IPADDRESS, RONLY, var_expValueTable, 2, {1, 6}},
  74. #define EXPVALUEOCTETSTRINGVAL 7
  75.     {EXPVALUEOCTETSTRINGVAL, ASN_OCTET_STR, RONLY, var_expValueTable, 2, {1, 7}},
  76. #define EXPVALUEOIDVAL  8
  77.     {EXPVALUEOIDVAL,       ASN_OBJECT_ID, RONLY, var_expValueTable, 2, {1, 8}},
  78. #define EXPVALUECOUNTER64VAL  9
  79.     {EXPVALUECOUNTER64VAL, ASN_INTEGER,   RONLY, var_expValueTable, 2, {1, 9}}
  80. };
  81. /*
  82.  * global storage of our data, saved in and configured by header_complex() 
  83.  */
  84. extern struct header_complex_index *expExpressionTableStorage;
  85. extern struct header_complex_index *expObjectTableStorage;
  86. struct header_complex_index *expValueTableStorage = NULL;
  87. struct snmp_session session;
  88. /*
  89.  * init_expValueTable():
  90.  *   Initialization routine.  This is called when the agent starts up.
  91.  *   At a minimum, registration of your variables should take place here.
  92.  */
  93. void
  94. init_expValueTable(void)
  95. {
  96.     DEBUGMSGTL(("expValueTable", "initializing...  "));
  97.     /*
  98.      * register ourselves with the agent to handle our mib tree 
  99.      */
  100.     REGISTER_MIB("expValueTable",
  101.                  expValueTable_variables, variable2,
  102.                  expValueTable_variables_oid);
  103.     init_snmp("snmpapp");
  104.     /*
  105.      * Initialize a "session" that defines who we're going to talk to
  106.      */
  107.     snmp_sess_init(&session);   /* set up defaults */
  108.     session.peername = "localhost";
  109.     DEBUGMSGTL(("expValueTable", "done.n"));
  110. }
  111. struct expValueTable_data *
  112. create_expValueTable_data(void)
  113. {
  114.     struct expValueTable_data *StorageNew;
  115.     StorageNew = SNMP_MALLOC_STRUCT(expValueTable_data);
  116.     /*
  117.      * fill in default row values here into StorageNew 
  118.      */
  119.     /*
  120.      * fill in values for all tables (even if not
  121.      * appropriate), since its easier to do here than anywhere
  122.      * else 
  123.      */
  124.     StorageNew->expExpressionOwner = strdup("");
  125.     StorageNew->expExpressionName = strdup("");
  126.     StorageNew->expValueInstance = calloc(1, sizeof(oid) * sizeof(2));  /* 0.0.0 */
  127.     StorageNew->expValueInstanceLen = 3;
  128.     return StorageNew;
  129. }
  130. /*
  131.  * mteTriggerTable_add(): adds a structure node to our data set 
  132.  */
  133. int
  134. expValueTable_add(struct expExpressionTable_data *expression_data,
  135.                   char *owner, size_t owner_len, char *name,
  136.                   size_t name_len, oid * index, size_t index_len)
  137. {
  138.     netsnmp_variable_list *vars = NULL;
  139.     struct expValueTable_data *thedata, *StorageTmp;
  140.     struct header_complex_index *hcindex;
  141.     int             founded = 0;
  142.     thedata = create_expValueTable_data();
  143.     thedata->expValueCounter32Val = 0;
  144.     thedata->expExpressionOwner = owner;
  145.     thedata->expExpressionOwnerLen = owner_len;
  146.     thedata->expExpressionName = name;
  147.     thedata->expExpressionNameLen = name_len;
  148.     thedata->expValueInstance = index;
  149.     thedata->expValueInstanceLen = index_len;
  150.     thedata->expression_data = expression_data;
  151.     DEBUGMSGTL(("expValueTable", "adding data...  "));
  152.     /*
  153.      * add the index variables to the varbind list, which is 
  154.      * used by header_complex to index the data 
  155.      */
  156.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen);     /* expExpressionOwner */
  157.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen);       /* expExpressionName */
  158.     snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OBJECT_ID,
  159.                               (u_char *) thedata->expValueInstance,
  160.                               thedata->expValueInstanceLen * sizeof(oid));
  161.     for (hcindex = expValueTableStorage; hcindex != NULL;
  162.          hcindex = hcindex->next) {
  163.         StorageTmp = (struct expValueTable_data *) hcindex->data;
  164.         if (!strcmp
  165.             (StorageTmp->expExpressionOwner, thedata->expExpressionOwner)
  166.             && (StorageTmp->expExpressionOwnerLen ==
  167.                 thedata->expExpressionOwnerLen)
  168.             && !strcmp(StorageTmp->expExpressionName,
  169.                        thedata->expExpressionName)
  170.             && (StorageTmp->expExpressionNameLen ==
  171.                 thedata->expExpressionNameLen)
  172.             && !snmp_oid_compare(StorageTmp->expValueInstance,
  173.                                  StorageTmp->expValueInstanceLen,
  174.                                  thedata->expValueInstance,
  175.                                  thedata->expValueInstanceLen)) {
  176.             founded = 1;
  177.             break;
  178.         }
  179.     }
  180.     if (!founded) {
  181.         header_complex_add_data(&expValueTableStorage, vars, thedata);
  182.         DEBUGMSGTL(("expValueTable", "registered an entryn"));
  183.     } else {
  184.         SNMP_FREE(thedata);
  185.         DEBUGMSGTL(("expValueTable",
  186.                     "already have an entry, dont registen"));
  187.     }
  188.     DEBUGMSGTL(("expValueTable", "done.n"));
  189.     return SNMPERR_SUCCESS;
  190. }
  191. unsigned long
  192. Evaluate_Expression(struct expValueTable_data *vtable_data)
  193. {
  194.     struct header_complex_index *hcindex;
  195.     struct expObjectTable_data *objstorage, *objfound;
  196.     struct expValueTable_data *valstorage;
  197.     valstorage = vtable_data;
  198.     char           *expression;
  199.     char           *result, *resultbak;
  200.     char           *temp, *tempbak;
  201.     char            intchar[10];
  202.     int             dollar1, dollar2;
  203.     int             i = 0, j, k, l;
  204.     long            value;
  205.     unsigned long   result_u_long;
  206.     temp = malloc(100);
  207.     result = malloc(100);
  208.     tempbak = temp;
  209.     memset(result, 0, 100);
  210.     *result = '';
  211.     resultbak = result;
  212.     expression = vtable_data->expression_data->expExpression;
  213.     while (*expression != '') {
  214.         if (*expression == '$') {
  215.             objfound = NULL;
  216.             i++;
  217.             for (j = 1; j < 100; j++) {
  218.                 if ((*(expression + j) == '+') ||
  219.                     (*(expression + j) == '-') ||
  220.                     (*(expression + j) == '*') ||
  221.                     (*(expression + j) == '/') ||
  222.                     (*(expression + j) == '(') ||
  223.                     (*(expression + j) == ')') ||
  224.                     *(expression + j) == '') {
  225.                     break;
  226.                 }
  227.             }
  228.             strncpy(temp, expression + 1, j - 1);
  229.             *(temp + j - 1) = '';
  230.             l = atoi(temp);
  231.             expression = expression + j;
  232.             /*
  233.              *   here use snmpget to get value
  234.              */
  235.             for (hcindex = expObjectTableStorage; hcindex != NULL;
  236.                  hcindex = hcindex->next) {
  237.                 objstorage = (struct expObjectTable_data *) hcindex->data;
  238.                 if (!strcmp
  239.                     (objstorage->expExpressionOwner,
  240.                      valstorage->expExpressionOwner)
  241.                     && (objstorage->expExpressionOwnerLen ==
  242.                         valstorage->expExpressionOwnerLen)
  243.                     && !strcmp(objstorage->expExpressionName,
  244.                                valstorage->expExpressionName)
  245.                     && (objstorage->expExpressionNameLen ==
  246.                         valstorage->expExpressionNameLen)
  247.                     && (l == objstorage->expObjectIndex)) {
  248.                     objfound = objstorage;
  249.                     break;
  250.                 }
  251.             }
  252.             if (!objfound) {
  253.                 /* have err */
  254.                 return 0;
  255.             }
  256.             struct snmp_session *ss;
  257.             struct snmp_pdu *pdu;
  258.             struct snmp_pdu *response;
  259.             oid             anOID[MAX_OID_LEN];
  260.             size_t          anOID_len;
  261.             memcpy(anOID, objfound->expObjectID,
  262.                    objfound->expObjectIDLen * sizeof(oid));
  263.             anOID_len = objfound->expObjectIDLen;
  264.             if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_TRUE) {
  265.                 anOID_len =
  266.                     anOID_len + valstorage->expValueInstanceLen - 2;
  267.                 memcpy(anOID + objfound->expObjectIDLen,
  268.                        valstorage->expValueInstance + 2,
  269.                        (valstorage->expValueInstanceLen -
  270.                         2) * sizeof(oid));
  271.             }
  272.             struct variable_list *vars;
  273.             int             status;
  274.             int             count = 1;
  275.             /*
  276.              * Initialize the SNMP library
  277.              */
  278.             /*
  279.              * Initialize a "session" that defines who we're going to talk to
  280.              */
  281.             session.version = vtable_data->expression_data->pdu_version;
  282.             /*
  283.              * set the SNMPv1 community name used for authentication 
  284.              */
  285.             session.community =
  286.                 vtable_data->expression_data->pdu_community;
  287.             session.community_len =
  288.                 vtable_data->expression_data->pdu_community_len;
  289.             /*
  290.              * Open the session
  291.              */
  292.             SOCK_STARTUP;
  293.             ss = snmp_open(&session);   /* establish the session */
  294.             if (!ss) {
  295.                 /* err */
  296.                 exit(2);
  297.             }
  298.             pdu = snmp_pdu_create(SNMP_MSG_GET);
  299.             snmp_add_null_var(pdu, anOID, anOID_len);
  300.             /*
  301.              * Send the Request out.
  302.              */
  303.             status = snmp_synch_response(ss, pdu, &response);
  304.             /*
  305.              * Process the response.
  306.              */
  307.             if (status == STAT_SUCCESS
  308.                 && response->errstat == SNMP_ERR_NOERROR) {
  309.                 /*
  310.                  * SUCCESS: Print the result variables
  311.                  */
  312.                 vars = response->variables;
  313.                 value = *(vars->val.integer);
  314.                 sprintf(intchar, "%u", value);
  315.                 for (k = 1; k <= strlen(intchar); k++) {
  316.                     *result = intchar[k - 1];
  317.                     result++;
  318.                 }
  319.             } else {
  320.                 /*
  321.                  * FAILURE: print what went wrong!
  322.                  */
  323.                 if (status == STAT_SUCCESS)
  324.                     fprintf(stderr, "Error in packetnReason: %sn",
  325.                             snmp_errstring(response->errstat));
  326.                 else
  327.                     snmp_sess_perror("snmpget", ss);
  328.             }
  329.             /*
  330.              * Clean up:
  331.              *  1) free the response.
  332.              *  2) close the session.
  333.              */
  334.             if (response)
  335.                 snmp_free_pdu(response);
  336.             snmp_close(ss);
  337.             SOCK_CLEANUP;
  338.         } else {
  339.             *result = *expression;
  340.             result++;
  341.             expression++;
  342.         }
  343.     }
  344.     result_u_long = get_result(resultbak);
  345.     free(tempbak);
  346.     free(resultbak);
  347.     return result_u_long;
  348. }
  349. void
  350. expValueTable_clean(void *data)
  351. {
  352.     struct expValueTable_data *cleanme =
  353.         (struct expValueTable_data *) data;
  354.     SNMP_FREE(cleanme->expValueInstance);
  355.     SNMP_FREE(cleanme->expValueIpAddressVal);
  356.     SNMP_FREE(cleanme->expValueOctetStringVal);
  357.     SNMP_FREE(cleanme->expValueOidVal);
  358.     SNMP_FREE(cleanme);
  359. }
  360. void
  361. build_valuetable()
  362. {
  363.     struct expExpressionTable_data *expstorage, *expfound;
  364.     struct expObjectTable_data *objstorage, *objfound = NULL;
  365.     struct header_complex_index *hcindex, *object_hcindex;
  366.     char           *owner;
  367.     size_t          owner_len;
  368.     char           *name;
  369.     size_t          name_len;
  370.     char           *expression;
  371.     size_t          expression_len;
  372.     oid            *index;
  373.     char           *result, *resultbak;
  374.     char           *temp, *tempbak;
  375.     int             i = 0, j, k, l;
  376.     temp = malloc(100);
  377.     result = malloc(100);
  378.     tempbak = temp;
  379.     memset(result, 0, 100);
  380.     *result = '';
  381.     resultbak = result;
  382.     DEBUGMSGTL(("expValueTable", "building valuetable...  n"));
  383.     for (hcindex = expExpressionTableStorage; hcindex != NULL;
  384.          hcindex = hcindex->next) {
  385.         expstorage = (struct expExpressionTable_data *) hcindex->data;
  386.         if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
  387.             expression = expstorage->expExpression;
  388.             expression_len = expstorage->expExpressionLen;
  389.             while (*expression != '') {
  390.                 if (*expression == '$') {
  391.                     i++;
  392.                     for (j = 1; j < 100; j++) {
  393.                         if ((*(expression + j) == '+') ||
  394.                             (*(expression + j) == '-') ||
  395.                             (*(expression + j) == '*') ||
  396.                             (*(expression + j) == '/') ||
  397.                             (*(expression + j) == '(') ||
  398.                             (*(expression + j) == ')') ||
  399.                             *(expression + j) == '') {
  400.                             break;
  401.                         }
  402.                     }
  403.                     strncpy(temp, expression + 1, j - 1);
  404.                     *(temp + j - 1) = '';
  405.                     l = atoi(temp);
  406.                     for (object_hcindex = expObjectTableStorage;
  407.                          object_hcindex != NULL;
  408.                          object_hcindex = object_hcindex->next) {
  409.                         objstorage =
  410.                             (struct expObjectTable_data *) object_hcindex->
  411.                             data;
  412.                         if (!strcmp
  413.                             (objstorage->expExpressionOwner,
  414.                              expstorage->expExpressionOwner)
  415.                             && (objstorage->expExpressionOwnerLen ==
  416.                                 expstorage->expExpressionOwnerLen)
  417.                             && !strcmp(objstorage->expExpressionName,
  418.                                        expstorage->expExpressionName)
  419.                             && (objstorage->expExpressionNameLen ==
  420.                                 expstorage->expExpressionNameLen)
  421.                             && (l == objstorage->expObjectIndex)) {
  422.                             if (objfound == NULL) {
  423.                                 expfound = expstorage;
  424.                                 objfound = objstorage;
  425.                             }
  426.                             if (objstorage->expObjectIDWildcard ==
  427.                                 EXPOBJCETIDWILDCARD_TRUE)
  428.                                 objfound = objstorage;
  429.                         }
  430.                     }
  431.                     expression = expression + j;
  432.                 } else {
  433.                     expression++;
  434.                 }
  435.             };
  436.         }
  437.         if (!objfound) {
  438.             continue;
  439.         }
  440.         if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_FALSE) {
  441.             index = calloc(1, MAX_OID_LEN);
  442.             *index = 0;
  443.             *(index + 1) = 0;
  444.             *(index + 2) = 0;
  445.             expValueTable_add(expstorage, objfound->expExpressionOwner,
  446.                               objfound->expExpressionOwnerLen,
  447.                               objfound->expExpressionName,
  448.                               objfound->expExpressionNameLen, index, 3);
  449.         } else {
  450.             oid            *targetOID;
  451.             size_t          taggetOID_len;
  452.             targetOID = objfound->expObjectID;
  453.             struct snmp_pdu *pdu;
  454.             struct snmp_pdu *response;
  455.             oid            *next_OID;
  456.             size_t          next_OID_len;
  457.             taggetOID_len = objfound->expObjectIDLen;
  458.             struct variable_list *vars;
  459.             int             status;
  460.             int             count = 1;
  461.             struct snmp_session *ss;
  462.             /*
  463.              * Initialize the SNMP library
  464.              */
  465.             /*
  466.              * set the SNMP version number 
  467.              */
  468.             session.version = expstorage->pdu_version;
  469.             /*
  470.              * set the SNMPv1 community name used for authentication 
  471.              */
  472.             session.community = expstorage->pdu_community;
  473.             session.community_len = expstorage->pdu_community_len;
  474.             /*
  475.              * Open the session
  476.              */
  477.             SOCK_STARTUP;
  478.             ss = snmp_open(&session);   /* establish the session */
  479.             if (!ss) {
  480.                 snmp_perror("ack");
  481.                 snmp_log(LOG_ERR, "something horrible happened!!!n");
  482.                 exit(2);
  483.             }
  484.             next_OID = targetOID;
  485.             next_OID_len = taggetOID_len;
  486.             do {
  487.                 index = calloc(1, MAX_OID_LEN);
  488.                 pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
  489.                 snmp_add_null_var(pdu, next_OID, next_OID_len);
  490.                 /*
  491.                  * Send the Request out.
  492.                  */
  493.                 status = snmp_synch_response(ss, pdu, &response);
  494.                 /*
  495.                  * Process the response.
  496.                  */
  497.                 if (status == STAT_SUCCESS
  498.                     && response->errstat == SNMP_ERR_NOERROR) {
  499.                     /*
  500.                      * SUCCESS: Print the result variables
  501.                      */
  502.                     if (((response->variables->type >= SNMP_NOSUCHOBJECT &&
  503.                           response->variables->type <= SNMP_ENDOFMIBVIEW)
  504.                          || snmp_oid_compare(targetOID, taggetOID_len,
  505.                                              response->variables->name,
  506.                                              taggetOID_len) != 0)) {
  507.                         break;
  508.                     }
  509.                     /* add to expValueTable */
  510.                     *index = 0;
  511.                     *(index + 1) = 0;
  512.                     memcpy(index + 2,
  513.                            response->variables->name + taggetOID_len,
  514.                            (response->variables->name_length -
  515.                             taggetOID_len) * sizeof(oid));
  516.                     expValueTable_add(expstorage,
  517.                                       objfound->expExpressionOwner,
  518.                                       objfound->expExpressionOwnerLen,
  519.                                       objfound->expExpressionName,
  520.                                       objfound->expExpressionNameLen,
  521.                                       index,
  522.                                       response->variables->name_length -
  523.                                       taggetOID_len + 2);
  524.                     next_OID = response->variables->name;
  525.                     next_OID_len = response->variables->name_length;
  526.                 } else {
  527.                     /*
  528.                      * FAILURE: print what went wrong!
  529.                      */
  530.                     if (status == STAT_SUCCESS)
  531.                         fprintf(stderr, "Error in packetnReason: %sn",
  532.                                 snmp_errstring(response->errstat));
  533.                     else
  534.                         snmp_sess_perror("snmpget", ss);
  535.                 }
  536.             } while (TRUE);
  537.         }
  538.     }
  539. }
  540. /*
  541.  * var_expValueTable():
  542.  */
  543. unsigned char  *
  544. var_expValueTable(struct variable *vp,
  545.                   oid * name,
  546.                   size_t *length,
  547.                   int exact, size_t *var_len, WriteMethod ** write_method)
  548. {
  549.     static netsnmp_variable_list *vars;
  550.     size_t          newlen =
  551.         *length - (sizeof(expValueTable_variables_oid) / sizeof(oid) +
  552.                    3 - 1);
  553.     struct expValueTable_data *StorageTmp = NULL;
  554.     unsigned int    counter32;
  555.     DEBUGMSGTL(("expValueTable", "var_expValueTable: Entering...  n"));
  556.     /*
  557.      *  before we build valuetable we must free any other valutable if exist
  558.      */
  559.     header_complex_free_all(expValueTableStorage, expValueTable_clean);
  560.     expValueTableStorage = NULL;
  561.     build_valuetable();
  562.     /*
  563.      * this assumes you have registered all your data properly
  564.      */
  565.     if ((StorageTmp =
  566.          header_complex(expValueTableStorage, vp, name, length, exact,
  567.                         var_len, write_method)) == NULL)
  568.         return NULL;
  569.     /*
  570.      * this is where we do the value assignments for the mib results.
  571.      */
  572.     switch (vp->magic) {
  573.         /*
  574.          *   we only support counter32val
  575.          */
  576.     case EXPVALUECOUNTER32VAL:
  577.         StorageTmp->expValueCounter32Val = Evaluate_Expression(StorageTmp);
  578.         *var_len = sizeof(StorageTmp->expValueCounter32Val);
  579.         return (u_char *) & StorageTmp->expValueCounter32Val;
  580.     case EXPVALUEUNSIGNED32VAL:
  581.         /* var_len = sizeof(StorageTmp->expValueUnsigned32Val); */
  582.         /* return (u_char *) & StorageTmp->expValueUnsigned32Val;         */
  583.         return NULL;
  584.     case EXPVALUETIMETICKSVAL:
  585.         /* var_len = sizeof(StorageTmp->expValueTimeTicksVal); */
  586.         /* return (u_char *) & StorageTmp->expValueTimeTicksVal; */
  587.         return NULL;
  588.     case EXPVALUEINTEGER32VAL:
  589.         /* var_len = sizeof(StorageTmp->expValueInteger32Val); */
  590.         /* return (u_char *) & StorageTmp->expValueInteger32Val; */
  591.         return NULL;
  592.     case EXPVALUEIPADDRESSVAL:
  593.         /* var_len = sizeof(StorageTmp->expValueIpAddressVal); */
  594.         /* return (u_char *) & StorageTmp->expValueIpAddressVal; */
  595.         return NULL;
  596.     case EXPVALUEOCTETSTRINGVAL:
  597.         /* var_len = sizeof(StorageTmp->expValueOctetStringVal); */
  598.         /* return (u_char *) & StorageTmp->expValueOctetStringVal;        */
  599.         return NULL;
  600.     case EXPVALUEOIDVAL:
  601.         /* var_len = StorageTmp->expValueOidValLen; */
  602.         /* return (u_char *) & StorageTmp->expValueOidVal; */
  603.         return NULL;
  604.     case EXPVALUECOUNTER64VAL:
  605.         /* var_len = sizeof(StorageTmp->expValueCounter64Val); */
  606.         /* return (u_char *) & StorageTmp->expValueCounter64Val; */
  607.         return NULL;
  608.     default:
  609.         ERROR_MSG("");
  610.     }
  611. }
  612. void
  613. push(link ** stack, unsigned long value)
  614. {
  615.     link           *newnode;
  616.     newnode = (link *) malloc(sizeof(link));
  617.     if (!newnode) {
  618.         printf("nMemory allocation failure!");
  619.         return;
  620.     }
  621.     newnode->data = value;
  622.     newnode->next = *stack;
  623.     *stack = newnode;
  624. }
  625. unsigned long
  626. pop(link ** stack)
  627. {
  628.     unsigned long   value;
  629.     link           *top;
  630.     top = *stack;
  631.     *stack = (*stack)->next;
  632.     value = top->data;
  633.     free(top);
  634.     return value;
  635. }
  636. int
  637. priority(char operater)
  638. {
  639.     switch (operater) {
  640.     case '*':
  641.     case '/':
  642.         return 4;
  643.     case '+':
  644.     case '-':
  645.         return 3;
  646.     case ')':
  647.         return 2;
  648.     case '(':
  649.         return 1;
  650.     default:
  651.         return 0;
  652.     }
  653. }
  654. unsigned long
  655. calculate(int operater, unsigned long a, unsigned long b)
  656. {
  657.     switch (operater) {
  658.     case '+':
  659.         return (a + b);
  660.     case '-':
  661.         return (a - b);
  662.     case '*':
  663.         return (a * b);
  664.     case '/':
  665.         if (operater == '/' && b == 0) {
  666.             printf("nDivision mustn't be 0!");
  667.             exit(0);
  668.         } else
  669.             return (a / b);
  670.     }
  671. }
  672. unsigned long
  673. get_operand(char *p, int *length)
  674. {
  675.     char            c[13];
  676.     int             i = 0, k = 1;
  677.     unsigned long   result = 0;
  678.     while (*p <= 57 && *p >= 48)
  679.         c[i++] = *(p++);
  680.     *length += --i;
  681.     for (; i >= 0; i--) {
  682.         result += (c[i] - 48) * k;
  683.         k *= 10;
  684.     }
  685.     return result;
  686. }
  687. int
  688. operator_class(char c)
  689. {
  690.     if (c <= 57 && c >= 48)
  691.         return 1;
  692.     if (c == 42 || c == 43 || c == 45 || c == 47)
  693.         return 2;
  694.     if (c == 41)
  695.         return 3;
  696.     if (c == 40)
  697.         return 4;
  698.     return 0;
  699. }
  700. unsigned long
  701. get_result(char *expr)
  702. {
  703.     int             position = 0;
  704.     unsigned long   op = 0, a = 0, b = 0, result = 0;
  705.     char           *expression;
  706.     expression = expr;
  707.     while (*(expression + position) != ''
  708.            && *(expression + position) != 'n') {
  709.         switch (operator_class(*(expression + position))) {
  710.         case 1:
  711.             push(&operand, get_operand(expression + position, &position));
  712.             break;
  713.         case 2:
  714.             if (operater != NULL)
  715.                 while (operater != NULL
  716.                        && priority(*(expression + position)) <=
  717.                        priority(operater->data)) {
  718.                     a = pop(&operand);
  719.                     b = pop(&operand);
  720.                     op = pop(&operater);
  721.                     push(&operand, calculate(op, b, a));
  722.                 }
  723.             push(&operater, *(expression + position));
  724.             break;
  725.         case 3:
  726.             while (operater != NULL && operater->data != '(') {
  727.                 a = pop(&operand);
  728.                 b = pop(&operand);
  729.                 op = pop(&operater);
  730.                 push(&operand, calculate(op, b, a));
  731.             }
  732.             if (operater->data == '(')
  733.                 pop(&operater);
  734.             break;
  735.         case 4:
  736.             push(&operater, '(');
  737.             break;
  738.         default:
  739.             printf("nInvalid character in expression:");
  740.             a = 0;
  741.             while (*(expression + (int) a) != 'n'
  742.                    && *(expression + (int) a) != '') {
  743.                 if (a != position)
  744.                     printf("%c", *(expression + (int) a));
  745.                 else
  746.                     printf("<%c>", *(expression + (int) a));
  747.                 a++;
  748.             }
  749.             exit(0);
  750.         }                       /* end switch */
  751.         position++;
  752.     }
  753.     while (operater != NULL) {
  754.         op = pop(&operater);
  755.         a = pop(&operand);
  756.         b = pop(&operand);
  757.         push(&operand, calculate(op, b, a));
  758.     }
  759.     result = pop(&operand);
  760.     return result;
  761. }