/*
 *
 *	variable.c
 *
 *	HNMS User Interface
 *	HNMS 2.0
 *
 *	February 1994
 *
 *	Leslie Schlecht
 *	Computer Sciences Corporation
 *	Numerical Aerodynamic Simulation Systems Division
 *	NASA Ames Research Center
 *
 *	Copyright (c) 1994 Leslie Schlecht
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 1, or (at your option)
 *	any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include	<stdio.h>
#include	<string.h>

#include	<X11/StringDefs.h>
#include	<X11/Intrinsic.h>
#include	<Xm/Xm.h>

#include	"stdhnms.h"
#include	"defines.h"
#include	"externs.h"
#include	"variable.h"

typedef		struct	vartype	{
		OID		oid;
		char		*ode;
		int		oid_type;
		MIBENTRY	mib;
		char		*instance_str;
		unsigned int	*instance_int;
		int		instance_type;
		struct vartype	*next;
		} VARTYPE;

static XmStringTable	mib_all[NUM_OBJCLASSES], mib_num[NUM_OBJCLASSES];
static int		mib_all_cnt[NUM_OBJCLASSES];
static int		mib_num_cnt[NUM_OBJCLASSES];
static char		*nullstr = "(null)";
static int		stat2col[5];

static VARTYPE		*root;

static char	buf[BUFSIZ];
static PE	nullpe;

static char	*varname[NUM_OBJCLASSES][2] = {
		{NULL, NULL,},
		{"hnmsAgent", NULL,},
		{"hnmsInternet", NULL,},
		{"hnmsNetwork", NULL,},
		{"hnmsSubnet", NULL,},
		{"hnmsIp", "ipAdEnt",},
		{"hnmsSite", NULL,},
		{"hnmsProc", NULL,},
		{"hnmsIf", "if",},
		{"hnmsEquip", NULL,},
		{"hnmsAdmin", NULL,},
		{"hnmsModule", NULL,},
		};
	

/*
 *	Add a variable to a varbindlist.
 */
void
AddVariableToVbl(vbl, var, interval)
VarBindList	*vbl;
VARTYPE		*var;
unsigned int	interval;
	{
	VarBindList_set(vbl, var->oid, nullpe, 0, 0, &interval, NULL);
	}


/*
 *	Create a new variable.
 */
void
CreateVariable(ode, addr)
char	*ode;
VARTYPE	**addr;
	{
	VARTYPE	**v, *vv;
	caddr_t	mib;
	int	instance_type, rc;

	for (v=&root; *v; v=&((*v)->next)) {
		rc = strcmp(ode, (*v)->ode);
		if (rc < 0) {
			vv = (VARTYPE*)myalloc(NULL, 1, sizeof(VARTYPE));
			vv->next = *v;
			*v = vv;
			vv->ode = newstr(ode);
			vv->oid = oid_cpy(MIB_ode2oid(ode, &(root->oid_type)));
			MIB_getbyoid(vv->oid, &(vv->mib), &(vv->instance_int),
				&(vv->instance_type));
			MIB_getbyode(vv->ode, &mib, &(vv->instance_str),
				&instance_type);
			*addr = vv;
			return;
			}
		if (rc == 0) {
			*addr = *v;
			return;
			}
		}
	vv = (VARTYPE*)myalloc(NULL, 1, sizeof(VARTYPE));
	*v = vv;
	vv->ode = newstr(ode);
	vv->oid = oid_cpy(MIB_ode2oid(ode, &(root->oid_type)));
	MIB_getbyoid(vv->oid, &(vv->mib), &(vv->instance_int),
		&(vv->instance_type));
	MIB_getbyode(vv->ode, &mib, &(vv->instance_str), &instance_type);
	*addr = vv;
	}


/*
 *	Free a varbindlist.
 */
void
FreeVbl(vbl)
VarBindList	vbl;
	{
	free_HNMP_VarBindList(vbl);
	}


/*
 *	Get the next variable from a varbindlist.
 */
int
GetNextVariableFromVbl(vbl, oid, value, len, tsc, type)
VarBindList	vbl;
OID		*oid;
caddr_t		value;
unsigned int	*tsc, *len, *type;
	{
	static VarBindList	lastvbl=NULL;
	VarBindList		v;
	unsigned int	l;
	char	zero = '\0';
	
	if (vbl)
		v = vbl;
	else if (!lastvbl)
		return(0);
	else
		v = lastvbl;
	lastvbl = v->next;

	if (!VarBindList_get(v, v->VarBind->name, value, &l, type, NULL, tsc))
		return(0);
	if (l) bcopy(&zero, value+l, 1);
	if (len) *len = l;
	*oid = v->VarBind->name;
	return(1);
	}


/*
 *	Get a variable from a varbindlist.
 */
int
GetVariableFromVbl(vbl, var, value, len, tsc, type)
VarBindList	vbl;
VARTYPE		*var;
caddr_t		value;
unsigned int	*len;
unsigned int	*tsc;
unsigned int	*type;
	{
	unsigned int	l;
	char	zero = '\0';

	if (!VarBindList_get(vbl,var->oid,value,&l,type,NULL,tsc)) return(0);
	if (l) bcopy(&zero, value+l, 1);
	if (len) *len = l;
	return(1);
	}


/*
 *	Get an interval from a varbindlist.
 */
int
GetVariableIntervalFromVbl(vbl, var, interval)
VarBindList	vbl;
VARTYPE		*var;
unsigned int	*interval;
	{
	if (!VarBindList_get(vbl,var->oid,NULL,NULL,NULL,interval,NULL))
		return(0);
	return(1);
	}


/*
 *	Determine if a variable is type string.
 */
int
IsVarString(var)
VARTYPE	*var;
	{
	if ((var->oid_type == MIB_octetstring) ||
	    (var->oid_type == MIB_displaystring))
		return(1);
	else
		return(0);
	}


/*
 *	Determine if an oid is in a variable.
 */
int
OidInVar(var, oid)
VARTYPE	*var;
OID	oid;
	{
	if (!var) return(0);
	if (!oid_cmp(oid, var->oid)) return(1);
	return(0);
	}


/*
 *	Parse the unique name into class, ustring and extention.
 */
int
ParseUniqueName(uname, class, name, ext)
char	*uname;
int	*class;
char	**name, **ext;
	{
	register	i, j;
	char		*c, *s;
	char		buf[BUFSIZ];

	if (!uname) return(0);

	*class = 0;
	for (s=c=uname; *c; c++)
		if (*c == ':') {
			*c = '\0';
			if (!strlen(s)) {
				*c = ':';
				return(0);
				}
			for (j=1; j<NUM_CLASSES+1; j++)
				if (strcmp(s,obj_class_names[j]) == 0) {
					*class = j;
					break;
					}
			*c = ':';
			c ++;
			break;
			}

	if (!strlen(c)) return(0);
	*name = c;
	*ext = NULL;
	for (; *c; c++) {
		if (*c == '_') {
			*ext = c;
			break;
			}
		}
	return(1);
	}


/*
 *	Get an ode from a variable.
 */
char*
VarOde(var)
VARTYPE	*var;
	{
	if (!var) return(nullstr);
	return(var->ode);
	}


/*
 *	Make the mib lists for the display.
 */
void
CreateMibLists()
	{
	MIBENTRY	mib;
	int		mibclass, i, j, k, numeric, l, foundit;
	XmString	xs;
	char		*vn;

	for (i=0; i<NUM_OBJCLASSES; i++) {
		mib_all_cnt[i] = 0;
		mib_num_cnt[i] = 0;
		}
	for (k=0,mib=MIB_walk(1); mib; k++,mib=MIB_walk(0)) {
		if (  !((mib->type == MIB_ipaddr) ||
			(mib->type == MIB_displaystring) ||
			(mib->type == MIB_octetstring)))
			numeric = True;
		else
			numeric = False;
		if (strncmp(mib->ode, "hnmsObj", 7) == 0) {
			for (i=1; i<NUM_OBJCLASSES; i++) {
				mib_all_cnt[i] ++;
				if (numeric)
					mib_num_cnt[i] ++;
				}
			continue;
			}
		foundit = False;
		for (i=1; i<NUM_OBJCLASSES; i++) {
			for (j=0; j<2; j++) {
				if (!varname[i][j]) continue;
				vn = varname[i][j];
				l = strlen(vn);
				if (strncmp(mib->ode, vn, l) == 0) {
					foundit = True;
					mib_all_cnt[i] ++;
					if (numeric)
						mib_num_cnt[i] ++;
					}
				}
			if (foundit) break;
			}
		if (!foundit) {
			mib_all_cnt[OBJ_processor] ++;
			if (numeric) mib_num_cnt[OBJ_processor] ++;
			}
		}

	for (i=0; i<NUM_OBJCLASSES; i++) {
		if (mib_all_cnt[i])
			mib_all[i] = (XmStringTable)myalloc(NULL,
				mib_all_cnt[i], sizeof(XmString*));
		if (mib_num_cnt[i])
			mib_num[i] = (XmStringTable)myalloc(NULL,
				mib_num_cnt[i], sizeof(XmString*));
		}
	for (i=0; i<NUM_OBJCLASSES; i++) {
		mib_all_cnt[i] = 0;
		mib_num_cnt[i] = 0;
		}
	for (k=0,mib=MIB_walk(1); mib; k++,mib=MIB_walk(0)) {
		if (  !((mib->type == MIB_ipaddr) ||
			(mib->type == MIB_displaystring) ||
			(mib->type == MIB_octetstring)))
			numeric = True;
		else
			numeric = False;
		if (strncmp(mib->ode, "hnmsObj", 7) == 0) {
			strcpy(buf, mib->ode);
			strcat(buf, ".0");
			xs = X_STR(buf);
			for (i=1; i<NUM_OBJCLASSES; i++) {
				mib_all[i][mib_all_cnt[i]] = xs;
				mib_all_cnt[i] ++;
				if (numeric) {
					mib_num[i][mib_num_cnt[i]] = xs;
					mib_num_cnt[i] ++;
					}
				}
			continue;
			}
		foundit = False;
		for (i=1; i<NUM_OBJCLASSES; i++) {
			for (j=0; j<2; j++) {
				if (!varname[i][j]) continue;
				vn = varname[i][j];
				l = strlen(vn);
				if (strncmp(mib->ode, vn, l) == 0) {
					foundit = True;
					strcpy(buf, mib->ode);
					strcat(buf, ".0");
					xs = X_STR(buf);
					mib_all[i][mib_all_cnt[i]] = xs;
					mib_all_cnt[i] ++;
					if (!numeric) continue;
					mib_num[i][mib_num_cnt[i]] = xs;
					mib_num_cnt[i] ++;
					}
				}
			if (foundit) break;
			}
		if (!foundit) {
			strcpy(buf, mib->ode);
			strcat(buf, ".0");
			xs = X_STR(buf);
			mib_all[OBJ_processor][mib_all_cnt[OBJ_processor]] = xs;
			mib_all_cnt[OBJ_processor] ++;
			if (!numeric) continue;
			mib_num[OBJ_processor][mib_num_cnt[OBJ_processor]] = xs;
			mib_num_cnt[OBJ_processor] ++;
			}
		}
	stat2col[STATUS_NOSTATUS] = WHITE;
	stat2col[STATUS_REACHABLE] = GREEN;
	stat2col[STATUS_NONRESPONSIVE] = YELLOW;
	stat2col[STATUS_UNREACHABLE] = RED;
	stat2col[STATUS_UNKNOWN] = MAGENTA;
	}


XmStringTable
GetMibItems(objclass)
int	objclass;
	{
	return(mib_all[objclass]);
	}


int
GetMibItemCount(objclass)
int	objclass;
	{
	return(mib_all_cnt[objclass]);
	}


XmStringTable
GetNumericMibItems(objclass)
int	objclass;
	{
	return(mib_num[objclass]);
	}


int
GetNumericMibItemCount(objclass)
int	objclass;
	{
	return(mib_num_cnt[objclass]);
	}


int
GetMessageInt(msg, data)
Message	msg;
int	data;
	{
	caddr_t	msgdata;

	if (!(msgdata = Message_get(msg, data))) {
		HNMS_err("Message_get");
		return(0);
		}
	return(*((int*)msgdata));
	}

void
InitializeVariables()
	{
	nullpe = pe_create_null();
	/*
	PARAM_set_int(oid_hnmsModuleHnmpConnTimeout, 60);
	*/
	}


void
SetVarType(var, type)
VARTYPE	*var;
int	type;
	{
	var->oid_type = type;
	}
	
	
void
VariableToStr(varlist, varstr, count)
VARTYPE	**varlist;
char	**varstr;
int	count;
	{
	register	i;
	char		strbuf[BUFSIZ];
	
	if (!varlist) return;
	strcpy(strbuf, "");
	for (i=0; i<count; i++) {
		strcat(strbuf, varlist[i]->ode);
		strcat(strbuf, "\n");
		}
	*varstr = newstr(strbuf);
	}
	
	
void
StrToVariable(varstr, varlist, count)
char	*varstr;
caddr_t	varlist;
int	count;
	{
	register	i;
	char		*p;
	VARTYPE		**var;
	int		type;
	
	if (!count || !varstr) {
		varlist = NULL;
		return;
		}
	var = (VARTYPE**)myalloc(NULL, count, sizeof(VARTYPE*));
	strcpy(buf, varstr);
	i = 0;
	for (p=gettoken(buf); p; p=gettoken(NULL)) {
		CreateVariable(p, &(var[i]));
		i ++;
		}
	bcopy(&var, varlist, sizeof(VARTYPE**));
	}


int
StatusColor(status)
int	status;
	{
	if ((status < 0) || (status > 4)) return(MAGENTA);
	return(stat2col[status]);
	}
