/* 
  WIDE AREA INFORMATION SERVER SOFTWARE:
   No guarantees or restrictions.  See the readme file for the full standard
   disclaimer.

   This is part of the shell user-interface tools for the WAIS software.
   Do with it as you please.

   Version 0.82
   Sun Jun  2 1991

   jonathan@Think.COM

*/

#define _C_UTIL

#include "wais.h"

int charlistlength(list)
char **list;
{
  int num;

  if(list) {
    for(num = 0; list[num] != NULL; num++);
    return num;
  }
  else 
    return 0;
}

int listlength(list)
List list;
{
  int num;
  List l;

  for(num = 0, l = list; l != NULL; num++, l = l->nextNode);

  return num;
}



#define BEFORE 1
#define DURING 2
#define QUOTE 5

/* ripped out of gmacs-ui.c */
int find_string_slot(source, key, value, value_size, delete_internal_quotes)
char *source, *key, *value;
long value_size;
boolean delete_internal_quotes;
{
  char ch;
  short state = BEFORE;
  long position = 0;  /* position in value */
  char *pos =strstr(source, key); /* address into source */

  value[0] = '\0';		/* initialize to nothing */

  if(NULL == pos)
    return(1);

  for(pos = pos + strlen(key); pos < source + strlen(source); pos++){
    ch = *pos;
    if((state == BEFORE) && (ch == '\"'))
      state = DURING;
    else if ((state == DURING) && (ch == '\\')){
      state = QUOTE;	
      if(!delete_internal_quotes){
	value[position] = ch;
	position++;
	if(position >= value_size){
	  value[value_size - 1] = '\0';
	  return(-1);
	}
      }
    }
    else if ((state == DURING) && (ch == '"')){	
      value[position] = '\0';
      return(0);
    }
    else if ((state == QUOTE) || (state == DURING)){
      if(state ==  QUOTE)
	state = DURING;
      value[position] = ch;
      position++;
      if(position >= value_size){
	value[value_size - 1] = '\0';
	return(-1);
      }
    }
    /* otherwise we are still before the start of the value */
  }
  value[position] = '\0';
  return(-1); /* error because we are in the middle of the string */
}

void find_value(source, key, value, value_size)
char *source, *key, *value;
int value_size;
{
  char ch;
  long position = 0;  /* position in value */
  char *pos =strstr(source, key); /* address into source */

  value[0] = '\0';		/* initialize to nothing */

  if(NULL == pos)
    return;

  pos = pos + strlen(key);
  ch = *pos;
  /* skip leading quotes and spaces */
  while((ch == '\"') || (ch == ' ')) {
    pos++; ch = *pos;
  }
  for(position = 0; pos < source + strlen(source); pos++){
    if((ch = *pos) == ' ') {
      value[position] = '\0';
      return;
    }
    value[position] = ch;
    position++;
    if(position >= value_size){
      value[value_size - 1] = '\0';
      return;
    }
  }
  value[position] = '\0';
}

any*
copy_any(thing)
any *thing;
{
  int i;
  any* result;

  result = NULL;

  if(thing != NULL) {
    if((result = (any*)s_malloc(sizeof(any))) != NULL) {
      result->bytes = NULL;
      result->size = thing->size;
      if((result->bytes = s_malloc(thing->size)) != NULL) {
	for(i = 0; i < thing->size; i++)
	  result->bytes[i] = thing->bytes[i];
      }
    }
  }
  return result;
}

#include <sockets.h>

boolean init_for_source(source, request, length, response)
Source source;
char *request;
long length;
char *response;
{
  char userInfo[500];
  char hostname[80];

  gethostname(hostname, 80);
#ifdef TELL_USER
  sprintf(userInfo, "waisq %s, from host: %s, user: %s",
	  VERSION, hostname, getenv("USER"));
#else
  sprintf(userInfo, "waisq %s, from host: %s", VERSION, hostname);
#endif

  if(source->initp == FALSE) {
    source->buffer_length = MAX_MESSAGE_LEN;
    if(source->server[0] == 0)
      source->connection = NULL;
    else
      if ((source->connection = connect_to_server(source->server,
						  atoi(source->service))) == NULL) {
	PrintStatus("Bad Connection to server.\n");
	source->initp == FALSE;
	return source->initp;
      }
    source->buffer_length = 
      init_connection(request, response,
		      length,
		      source->connection,
		      userInfo);

    if (source->buffer_length < 0) {
      PrintStatus("Bad Connection to server.\n");
      source->initp == FALSE;
    }
    else {
      SList s;

      source->initp = TRUE;
      /* set the init and connection for other sources with the same
	 host and port. */
      for (s = Sources; s != NULL; s = s->nextSource) {
      	if (s->thisSource != source) {
	  if (strcmp(s->thisSource->server, source->server) == 0 &&
	      strcmp(s->thisSource->service, source->service) == 0) {
	    s->thisSource->connection = source->connection;
	    s->thisSource->buffer_length = source->buffer_length;
	    s->thisSource->initp = TRUE;
	  }
	}
      }
    }
    return source->initp;
  }
  return source->initp;
}
