/* Nessuslib -- the Nessus Library
 * Copyright (C) 1998 Renaud Deraison
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Arglists management
 */

#define EXPORTING
#include <includes.h>


ExtFunc
void arg_add_value(arglst, name, type, length, value)
  struct arglist * arglst;
  const char * name;
  int type;
  long length;
  void * value;
{
	if(!arglst)return;
	
	/* Go to the end of our list... */
	while(arglst->next)arglst = arglst->next;

	arglst->name = estrdup(name);
	arglst->value = value;
	
	arglst->length = length;
	arglst->type = type;
	arglst->next = emalloc(sizeof(struct arglist));
	arglst->next->next = NULL;
}


ExtFunc int 
arg_set_value(arglst, name, length, value)
 struct arglist * arglst;
 const char * name;
 long length;
 void *value;
{
  /* We look for the asked name */
  while(arglst->next && strcmp(arglst->name, name))
    arglst = arglst->next;
  
  if(arglst->next)
    {
      arglst->value = value;
      return(0);
    }
  else return(-1); 
}

ExtFunc int 
arg_set_type(arglst, name, type)
 struct arglist * arglst;
 const char * name;
 int type;
{
  while(arglst->next && strcmp(name, arglst->name))arglst=arglst->next;
  if(!(arglst->next))return(-1);
  else arglst->type = type;
  return 0;
}
  
  
ExtFunc void * 
arg_get_value(args, name)
 struct arglist * args;
 const char * name;
{
 int flag=0;
 if(!args)return(NULL); 
  while(args && args->next && !flag)
  	{
        if(args->name && !strcmp(name, args->name))flag=1;
  	else args=args->next;
  	}
  if(flag && args && args->next)return(args->value);
  else return(NULL);
}


ExtFunc int 
arg_get_type(args,name)
 struct arglist * args;
 const char * name;
{
  while(args->next && strcmp(name, args->name))args=args->next;
  if(args->next)
    return(args->type);
  else return(-1);
}


ExtFunc void arg_dup(dst, src)
 struct arglist * dst;
 struct arglist * src;
{
 while(src && src->next)
 {
  dst->name = estrdup(src->name);
  dst->type = src->type;
  dst->length = src->length;
  switch(src->type)
  {
   case ARG_INT :
   case ARG_PTR : 
    dst->value = src->value;
    break;
    
   case ARG_STRING :
    if(src->value){
     dst->value = estrdup((char*)src->value);
    }
    break;
 
  case ARG_ARGLIST :
    dst->value = emalloc(sizeof(struct arglist));
    arg_dup((struct arglist *)dst->value, (struct arglist *)src->value);
    break;
  }
  dst->next = emalloc(sizeof(struct arglist));
  dst = dst->next;
  src = src->next;
 }
}


ExtFunc void 
arg_dump(args, level)
 struct arglist * args;
 int level;
{
	const char * spaces = "--------------------";
	if(!args)
	{
		printf("Error ! args == NULL\n");
		return;
	}
	
	while(args && args->next)
	{
		switch(args->type)
		{
			case ARG_STRING :
			
			fprintf(stderr, "%sargs->%s : %s\n",spaces+(20-level),
			args->name,
			(char *)args->value);
			break;
			case ARG_ARGLIST :
			
			fprintf(stderr, "%sargs->%s :\n", spaces+(20-level),
			args->name);
			arg_dump(args->value, level+1);
			break;
			case ARG_INT :
			fprintf(stderr, "%sargs->%s : %d\n",spaces+(20-level),
			args->name,
			(int)args->value);
			break;
			default :
			fprintf(stderr, "%sargs->%s : %d\n",spaces+(20-level),
			args->name,
			(int)args->value);
			break;
		}
		args = args->next;
	}
}


ExtFunc void
arg_free(arg)
 struct arglist* arg;
{
 while(arg)
 {
  struct arglist * next = arg->next;
  efree(&arg);
  arg = next;
 }
}


ExtFunc void arg_free_all(arg)
 struct arglist* arg;
{
 while(arg)
 {
  struct arglist * next = arg->next;
  switch(arg->type)
  {
   case ARG_ARGLIST :
    arg_free_all(arg->value);
    break;
   case ARG_STRING :
    efree(&arg->value);
    break;
  }
  efree(&arg);
  arg = next;
 }
}
