/*
 * This file is part of an snmp query application.
 * This file contains routines that manage agent lists.
 *
 * Copyright 1990 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 *
 * Tom Coppeto
 * MIT Network Services
 * 15 April 1990
 *
 *    $Source: /afs/net.mit.edu/tools/src/simon/RCS/cluster.c,v $
 *    $Author: tom $
 *    $Locker:  $
 *    $Log:	cluster.c,v $
 * Revision 1.4  91/02/21  13:53:15  tom
 * changed array to link list
 * 
 * Revision 1.3  90/07/25  10:29:25  tom
 * ? will list clusters in prompt_for_cluster()
 * 
 * Revision 1.2  90/07/20  21:37:35  tom
 * static/extern compiler warning fixed
 * 
 * Revision 1.1  90/07/20  21:17:30  tom
 * Initial revision
 * 
 *
 */

#ifndef lint
static char *rcsid = "$Header: /afs/net.mit.edu/tools/src/simon/RCS/cluster.c,v 1.4 91/02/21 13:53:15 tom Exp $";
#endif


#include <simon.h>
#include <mit-copyright.h>

CLUSTER *ClusterList = (CLUSTER *) NULL;

/*
 * callbacks
 */


/*
 * Function:    cmd_change_cluster()
 * Description:
 */

void
cmd_create_cluster(argc, argv)
     int argc;
     char *argv[];
{
  char *new = (char *) NULL;
  CLUSTER *c;

  pname = argv[0];
  bzero(cmdbuf, sizeof(cmdbuf));

  while (*++argv != (char *) NULL)
    {
      if(**argv != '-')
        {
          if(new == (char *) NULL)
            {
              strncpy(cmdbuf, *argv, sizeof(cmdbuf)-1);
	      new = &cmdbuf[0];
              continue;
            }
          else
            fprintf(stderr, "Too many clusters specified on command line.\n");
        }
      else
        if(strcmp(*argv, "-help") != 0)
          fprintf(stderr, "Unknown option \"%s\".\n", *argv);

      printf("usage: %s [<cluster name>]\n", pname);
      return;
    }

  if(new == (char *) NULL)
    {
      get_prompted_input("name of new cluster: ", cmdbuf, sizeof(cmdbuf));
      if(*cmdbuf == '\0')
        {
          printf("Request cancelled.\n");
          return;
	}
      new = &cmdbuf[0];
    }

  if(is_cluster(new) == TRUE)
    {
      fprintf(stderr, "\"%s\" is already an assigned cluster.\n", new);
      free(new);
      return;
    }

  if((c = create_cluster(new)) == (CLUSTER *) NULL)
    {
      fprintf(stderr, "Unable to create cluster \"%s\".\n", new);
      return;
    }
  
  bzero(cmdbuf, sizeof(cmdbuf));
  while(make_agent(c, cmdbuf) == SUCCESS)
    bzero(cmdbuf, sizeof(cmdbuf));
  
  printf("Cluster created.\n");
  return;
}




/*
 * Function:    cmd_add_cluster()
 * Description: 
 */

void 
cmd_delete_cluster(argc, argv)
     int argc;
     char *argv[];
{
  int i, j;

  pname = argv[0];
  if(ClusterList == (CLUSTER *) NULL)
    {
      fprintf(stderr, "There are no clusters to delete.\n");
      return;
    }

  i = 0;
  while (*++argv != (char *) NULL)
    {
      if(**argv != '-')
        {
	  if((argptr[i++] = 
	      (char *) prompt_for_cluster("cluster to delete: ", *argv)) 
	     == (char *) NULL)
	    {
	      fprintf(stderr, "Request cancelled.\n");
	      return;
	    }
	  continue;
	}
      else
	if(strcmp(*argv, "-help") != 0)
          fprintf(stderr, "Unknown option \"%s\".\n", *argv);

      printf("usage: %s [<cluster names>]\n", pname);
      return;
    }

  if(i == 0)
    if((argptr[i++] = 
	(char *) prompt_for_cluster("cluster to delete: ", NULL)) 
       == (char *) NULL)
      {
	fprintf(stderr, "Request cancelled.\n");
	return;
      }

  for(j = 0; j < i; j++)
    if(delete_cluster((CLASS *) argptr[j]) != SUCCESS)
      fprintf(stderr,  "Unable to delete cluster \"%s\".\n", 
	      ((CLUSTER *) argptr[j])->name);
    else
      printf("Cluster \"%s\" deleted.\n", ((CLUSTER *) argptr[j])->name);
  
  return;
}




/*
 * Function:    cmd_show_clusters()
 * Description: 
 */

void 
cmd_show_clusters(argc, argv)
     int argc;
     char *argv[];
{
  CLUSTER *cluster;
  char *name = (char *) NULL;

  pname = argv[0];
  bzero(cmdbuf, sizeof(cmdbuf));

  while (*++argv != (char *) NULL)
    {
      if(**argv != '-')
	{
	  if(name == (char *) NULL)
	    {
	      strncpy(cmdbuf, *argv, sizeof(cmdbuf)-1);
	      name = &cmdbuf[0];
	      continue;
	    }
	  else
	    fprintf(stderr, "Too many clusters specified.\n");
	}
      
      if(strcmp(*argv, "-help") != 0)
	fprintf(stderr, "Unknown option \"%s\".\n", *argv);
    
      printf("usage: %s [<cluster name>]\n", pname);
      return;
    }

  if(name != (char *) NULL)
    {
      if((cluster = prompt_for_cluster("cluster to show: ", name)) 
	 == (CLUSTER *) NULL)
	{
	  printf("Request cancelled.\n");
	  return;
	}
      
      list_cluster_agents(cluster);
      return;
    }
  list_clusters();      
}




/*
 * Function:    cmd_show_unknown_clusters()
 * Description: 
 */

void 
cmd_show_unknown_clusters(argc, argv)
     int argc;
     char *argv[];
{

  pname = argv[0];
  while (*++argv != (char *) NULL)
    {
      if(**argv == '-')
        {
          if(strcmp(*argv, "-help") != 0)
            fprintf(stderr, "Unknown option \"%s\".\n", *argv);
          printf("usage: %s\n", pname);
          return;
        }
    }

  list_clusters();
  return;
}



/*
 * utilities
 */


CLUSTER *
prompt_for_cluster(prompt, name)
     char *prompt;
     char *name;
{
  CLUSTER *cluster;
  char buf[BUF_SIZE];
  int confused;

  if(!ClusterList)
    return((CLUSTER *) NULL);
    
  while(!name || (*name == '?') || !(cluster = get_cluster(name)))
    {
      confused = TRUE;
      if(!name)
	fprintf(stderr, "\"%s\" is not a registered cluster.\n", name);
      while(confused == TRUE)
	{
	  get_prompted_input(prompt, buf, sizeof(buf));
	  if(*buf == '\0')
	    return((CLUSTER *) NULL);

	  if(strcmp(buf, "?") == 0)
	    {
	      printf("choose a cluster from one of the following:\n");
	      list_clusters();
	      printf("or hit <return> to abort.\n");
	      continue;
	    }

	  name = &buf[0];
	  confused = MAYBE;
	}
    }
  return(cluster);      
}



void
list_clusters()
{
  CLUSTER *cptr;
  int i = 0;

  if(!ClusterList)
    printf("You have no cluster.\n");
  else
    {
      putchar ('\n');	   
      cptr = ClusterList;
      while(cptr)
	{
	  printf("%3d: %-30s\n", i++ +1, cptr->name);
	  cptr = cptr->next;
	}
      putchar ('\n');      
    }
}




void 
list_cluster_agents(cluster)
     CLUSTER *cluster;
{
  AGENT *aptr;
  int i = 1;
  
  aptr = cluster->agents;
  putchar('\n');
  printf("(%s)\n", cluster->name);
  while(aptr)
    {
      printf(" %2d: %-32s %s\n", i++, aptr->name, inet_ntoa(aptr->in));
      aptr = aptr->next;
    }
  putchar('\n');
  return;
}





CLUSTER *
get_default_cluster()
{
  return(ClusterList);
}



/*
 * Function:    add_cluster()
 * Description:
 */

CLUSTER *
create_cluster(cluster)
     char *cluster;
{
  CLUSTER *c;
  CLUSTER *last;

  if(!(c = (CLUSTER *) malloc(sizeof(CLUSTER))))
    {
      perror("add_cluster");
      return((CLUSTER *) NULL);
    }

  bzero(c, sizeof(CLUSTER));
  c->name = copy_string(cluster);
  
  if(!ClusterList)
    ClusterList = c;
  else
    {
      last = ClusterList;
      while(last->next)
	last = last->next;
      last->next = c;
    }
  return(c);
}



/*
 * Function:    delete_cluster()
 * Description:
 */

int
delete_cluster(cluster)
     CLUSTER *cluster;
{
  CLUSTER *c;
  CLUSTER *s;

  if(!ClusterList)
    return(ERROR);

  c = ClusterList;
  s = (CLUSTER *) NULL;
  while(c)
    {
      if(c == cluster)
	{
	  c = c->next;
	  free_cluster(s->next);
	  s->next = c;
	  return(SUCCESS);
	} 
      s = c;
      c = c->next;
    }

  return(ERROR);
}




/*
 * Function:    is_cluster()
 * Description:
 */

int
is_cluster(a)
     char *a;
{
  CLUSTER *c;

  c = ClusterList;
  while(c)
    {
      if(strcmp(a, c->name) == 0)
	return(TRUE);
      c = c->next;
    }
  return(FALSE);
}




CLUSTER *
get_cluster(cluster)
     char *cluster;
{
  CLUSTER *c;
  int num;
  int i = 0;

  if(!cluster)
    return((CLUSTER *) NULL);

  c = ClusterList;
  while(c)
    if(strcmp(cluster, c->name) == 0)
      return(c);
    else
      c = c->next;

  if(isnumber(cluster))
    {
      num = atoi(cluster);
      if(num > 0)
	{
	  c = ClusterList;
	  while(c && (i < num))
	    {
	      ++i;
	      c = c->next;
	    }
	  return(c);
	}
    }
  return((CLUSTER *) NULL);
}




void 
free_cluster(c)
     CLUSTER *c;
{
  AGENT *a;
  AGENT *s;

  if(!c)
    return;

  if(c->name != (char *) NULL)
    free(c->name);
  
  s = a = c->agents;
  while(a)
    {
      s = a->next;
      free(a);
      a = s;
    }
  free(c);  
  return;
}

