/*************************************************************
/*
/* Program rshow
/*
/* This program contains an example of how the user can
/* retrieve the value of a variable of a
/* process in the KLOE DAQ environment.
/*
/* Usage:
/*
/*       rshow -p process [-n node] -v variable\n
/*
/* E. Pasqualucci 25-10-1996
/*
/*************************************************************

/* standard include files */

#include <stdio.h>

/* snmp include files */

#include "snmp.h"
#include "asn1.h"
#include "snmp_impl.h"
#include "snmp_api.h"

/* Process template include files */

#include "template.h"
#include "dummy.h"

/* kloe specific include files */

#include "ksnmp.h"
#include "netmap.h"
#include "ksnmplib_protos.h"

/* global variables */

extern char ownpname[];

char command[] = "show ";

char *variable = (char *) NULL;
char *remote_node = (char *) NULL;
char *process = (char *) NULL;
char *msg;
char *destination;

char **rvar_name = (char **) NULL;

struct snmp_session *sess = (struct snmp_session *) NULL;

void init_options (int argc, char **argv)
{
    int arg;
    int i;

    for(arg = 1; arg < argc; arg++)
        if (argv[arg][0] == '-')
            switch(argv[arg][1])
            {
                case 'p':
                    arg++;
                    process = argv[arg];
                    break;
                case 'n':
                    arg++;
                    remote_node = argv[arg];
                    break;
                case 'v':
                    arg++;
                    variable = argv[arg];
                    break;
                default:
                    printf("invalid option: -%c\n", argv[arg][1]);
                    break;
            }

    if (variable == (char *) NULL || process == (char *) NULL)
    {
        fprintf (stderr, " Usage: rshow -p process [-n node] -v variable\n");
        exit (0);
    }
}

void init_rshow (void)
{
    msg = (char *) calloc (sizeof(command) + sizeof(variable) + 1,
                           sizeof(char));
    destination = (char *) calloc (sizeof(process)
                                   + (remote_node == NULL ? 0 :
                                   sizeof(remote_node)) + 1, sizeof (char));
    strcpy (msg, command);
    strcat (msg, variable);
    strcpy (destination, process);

    if (remote_node)
    {
        strcat (destination, "@");
        strcat (destination, remote_node);
    }
    else
        if (Attach_Table() == -1)
        {
            printf("Error in Attach_Table()\n");
            exit(0);
        }

    strcpy (ownpname, "rshow");
}

char *search_remote_vlist (struct snmp_session *ss, char *proc, char *varname)
{
    int rootlen;
    int prclen;

    char tmpbuf[KSNMP_MAX_NAME_LEN];
    char varnode[KSNMP_MAX_NAME_LEN];
    char varroot[KSNMP_MAX_NAME_LEN];

    char *vget_tail;

    struct snmp_pdu *cmd_pdu;
    struct variable_list *vlist;

/*  Looks for the process index */

    rootlen = (int) strlen (KSNMP_MIB_PROCNAME_ROOT);
    strcpy (varnode, KSNMP_MIB_PROCNAME_ROOT);

    while (cmd_pdu = ksnmp_get_next (ss, varnode, rootlen))
    {
        register char *p1, *p2;

        vlist = cmd_pdu->variables;
        sprint_objid (varnode, vlist->name, vlist->name_length);
        sprint_value (tmpbuf, vlist->name, vlist->val_len, vlist);
        p1 = tmpbuf + 1;
        p2 = strchr (tmpbuf+1, (int) '"');
        prclen = (int) (p2 - p1) > (int) strlen (proc) ?
                 (int) (p2 - p1) : (int) strlen (proc);
        if (!strncmp (p1, proc, prclen))
            break;
    }

    if (!cmd_pdu)
    {
        printf (" search_remote_vlist : non existent process : %s\n", proc);
        snmp_close (ss);
        exit (0);
    }

/*  Looks for the variable index */

    strcpy (varroot, KSNMP_MIB_VARNAME_ROOT);
    strcat (varroot, strrchr (varnode, (int) '.'));
    rootlen = (int) strlen (varroot);

    while (cmd_pdu = ksnmp_get_next (ss, varroot, rootlen))
    {
        register char *p1, *p2;

        vlist = cmd_pdu->variables;
        sprint_objid (varroot, vlist->name, vlist->name_length);
        sprint_value (tmpbuf, vlist->name, vlist->val_len, vlist);
        p1 = tmpbuf + 1;
        p2 = strchr (tmpbuf+1, (int) '"');
        prclen = (int) (p2 - p1) > (int) strlen (varname) ?
                 (int) (p2 - p1) : (int) strlen (varname);
        if (!strncmp (p1, varname, prclen))
            break;
    }

    if (!cmd_pdu)
    {
        printf (" search_remote_vlist : non existent variable : %s\n",
                varname);
        snmp_close (ss);
        exit (0);
    }

/*  Builds the tail of the snmp variable to get */

    vget_tail = (char *) calloc (strlen (strrchr (varnode, (int) '.')) +
                                 strlen (strrchr (varnode, (int) '.')),
                                 sizeof (char));

    strcpy (vget_tail, strrchr (varnode, (int) '.'));
    strcat (vget_tail, strrchr (varroot, (int) '.'));

    return vget_tail;
}

void do_rshow (void)
{
    register int i;

    short stpe;

    char *value;
    char *tail;

    struct snmp_pdu *response;
    struct variable_list *vars;

    Send_Message (destination, msg);
    Get_Ack (destination, msg);

    if (remote_node)
    {
        if (!rvar_name)
	{
            if (!(sess = ksnmp_session_init (remote_node,
                                             "public", KSNMP_KLOE_PORT)))
            {
                printf (" do rshow : could not open snmp session on %s\n",
                        remote_node);
                exit (0);
            }

            rvar_name = (char **) calloc ((size_t) 3, sizeof (char *));

            tail = search_remote_vlist (sess, process, variable);

            for (i=0 ; i < 3 ; ++i)
                rvar_name[i] = (char *) calloc ((size_t) KSNMP_MAX_NAME_LEN,
                                                sizeof (char));

            strcpy (rvar_name[0], KSNMP_MIB_VARSIZE_ROOT);
            strcat (rvar_name[0], tail);
            strcpy (rvar_name[1], KSNMP_MIB_VARTYPE_ROOT);
            strcat (rvar_name[1], tail);
            strcpy (rvar_name[2], KSNMP_MIB_VARVALUE_ROOT);
            strcat (rvar_name[2], tail);
        }

        response = ksnmp_get (sess, rvar_name, 3);

        for(vars = response->variables; vars; vars = vars->next_variable)
            print_variable(vars->name, vars->name_length, vars);
    }
    else
    {
        value = (char *)(var_dict_usr[i].addr);

        var_read_value (process, variable, &stpe, value);

        if (stpe == STRING)
           printf ("%s:  %s, type %d, value %s \n",
                   process, variable, stpe, value);
        else if (stpe == INTEGER)
           printf ("%s:  %s, type %d, value %d \n",
                   process, variable, stpe, *(int *) value);
        else
           printf ("%s:  %s, type %d, value %f \n",
                   process, variable, stpe, *(float *) value);
    }
}

void end_rshow (void)
{
    if (sess)
        snmp_close (sess);
}

main (int argc, char **argv)
{
/*  This is an example of how to retrieve a variable of a process */

    init_options (argc, argv);
    init_mib();
    init_rshow();
    do_rshow();
    end_rshow();
}