summaryrefslogtreecommitdiff
path: root/agent/mibgroup/disman/expression/expValueTable.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/disman/expression/expValueTable.c')
-rw-r--r--agent/mibgroup/disman/expression/expValueTable.c873
1 files changed, 873 insertions, 0 deletions
diff --git a/agent/mibgroup/disman/expression/expValueTable.c b/agent/mibgroup/disman/expression/expValueTable.c
new file mode 100644
index 0000000..6b315c6
--- /dev/null
+++ b/agent/mibgroup/disman/expression/expValueTable.c
@@ -0,0 +1,873 @@
+/*
+ *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, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 2}},
+#define EXPVALUEUNSIGNED32VAL 3
+ {EXPVALUEUNSIGNED32VAL, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 3}},
+#define EXPVALUETIMETICKSVAL 4
+ {EXPVALUETIMETICKSVAL, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 4}},
+#define EXPVALUEINTEGER32VAL 5
+ {EXPVALUEINTEGER32VAL, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 5}},
+#define EXPVALUEIPADDRESSVAL 6
+ {EXPVALUEIPADDRESSVAL, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 6}},
+#define EXPVALUEOCTETSTRINGVAL 7
+ {EXPVALUEOCTETSTRINGVAL, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 7}},
+#define EXPVALUEOIDVAL 8
+ {EXPVALUEOIDVAL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
+ var_expValueTable, 2, {1, 8}},
+#define EXPVALUECOUNTER64VAL 9
+ {EXPVALUECOUNTER64VAL, ASN_INTEGER, NETSNMP_OLDAPI_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 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;
+
+ /*
+ * 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, "%lu", 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(void)
+{
+ struct expExpressionTable_data *expstorage;
+ struct expObjectTable_data *objstorage, *objfound = NULL;
+ struct header_complex_index *hcindex, *object_hcindex;
+ 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;
+ int status;
+ 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)
+{
+
+ struct expValueTable_data *StorageTmp = NULL;
+
+
+
+
+ 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("");
+ return NULL;
+ }
+}
+
+
+
+
+
+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);
+ }
+ return 0;
+}
+
+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;
+}