 /*
 * util.c
 */

#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <strings.h>
#include "pdb.h"

#define DLM ':'  /* delimiter */

#define	ATHENA

char * index();
memcpy(dest, src, len)
char	*dest, *src;
int	len;
{
	while (len-- > 0)
		*dest++	= *src++;
}



strcnt(str, c)
char	*str, c;
{
	int	cnt = 0;

	while (*str)
		if (*str++ == c)
			cnt++;
	return cnt;
}


/* returns true if it is a valid integer */

inttest(str)
char	*str;
{
/*	if (*str == '-')
		str++;   not allowing for negatives */
	while (*str) {
		if (!isdigit(*str) && *str != ' ')
			return 0;
		str++;
	}
	return 1;
}

strlower(str)
char	*str;
{
	int	cnt = 0;

	while (*str) {
		if (isupper(*str))
			*str = tolower(*str);
		str++, cnt++;
	}
	return cnt;
}

tokenize(str, argvec, maxargs)
char	str[];
char	*argvec[];
{
	char	*cp = str;
	int	argcnt = 0;

	while (argcnt < maxargs) {
		while (isspace(*cp))
			cp++;
		if (!*cp)
			break;
		argvec[argcnt++] = cp;
		while (*cp && !isspace(*cp))
			cp++;
		if (!*cp)
			break;
		*cp++ = '\0';
	}
	argvec[argcnt] = (char *) 0;
	return argcnt;
}

putstr(str)
char	*str;
{
	while (*str)
		putchar(*str), str++;
}

#ifdef ATHENA

int
is_attached(name)  /* is the filesystem attached ? this just looks in the 
attachtab file, so it is no good for the server - we aren't using this */
char *name;
{
char locker[40],line[120];
FILE *fopen(), *attachfile, *cp;
int len;

strcpy(locker,name);
/* need to check for explicit attaches */

attachfile = fopen("/usr/tmp/attachtab","r");
if (!attachfile)
  return 0;
len = strlen(locker);
while (fgets(line,110,attachfile) != '\0') {
     cp = line + 9;
     if (strncasecmp(cp,locker,len) == 0){
       fclose(attachfile);
       return 1;
     }
   }
       fclose(attachfile);
       return 0;
}

ensure_access(file, attach_src, debug)
char	file[];
char	attach_src[];
int	debug;
{
	if (!access(file, F_OK))
	     return;
	/* if (!is_attached(attach_src)) */
		do_attach(attach_src, (char *) 0, debug);
}

/*
 * Note that if the name begins with a '#' character, this
 * means do an explicit mount (the name following the '#' doesn't
 * try to be resolved to figure out the full machine:/filsys/dir
 * description, we're giving that explicitly)
 */

do_attach(name, mountpoint, debug)
char	*name, *mountpoint;
int	debug;
{
	char	*args[16],dirname[80],*thename;
	int	ca = 0;
	char	cmdline[120],*cp,*ptr,*pt;

	thename = (char *) malloc(100); /* need to free this */
	strcpy(thename,name);
        for (cp = thename;*cp;cp++)  /* swap in a colon */
	   if (*cp == '^')
	     *cp = ':';
	args[ca++] = "attach";
	if (mountpoint)
		args[ca++] = "-mountpoint",
		args[ca++] = mountpoint;
	args[ca++] = "-quiet";
	args[ca++] = "-nozephyr";
	args[ca++] = "-o"; /* change the mount options */
	args[ca++] = "retry=2set,soft,retrans=3";
	args[ca++] = "-n";  /* no kerberos */
	if (*thename == '#'){
 /* build a dir name , the default doesn't work for CMS without hesiod entry */
		strcpy(dirname,thename);
	        ptr = index(dirname,':');
	        ptr++;
		pt = index(ptr,',');
		if (pt)
		  *pt = '\0';
		sprintf(dirname,"%s",ptr);
	        args[ca++] = "-m"; /* mointpoint */
		args[ca++] = dirname;
		args[ca++] = "-explicit", thename++;
	      }
	args[ca++] = thename;
	args[ca] = (char *) 0;

	cmdline[0] = '\0';
	for (ca = 0; args[ca]; ca++)
	   strcat(cmdline, args[ca]), strcat(cmdline, " ");
	sprintf(cmdline,"%s > /dev/null",cmdline);
	if (debug) 
		printf("Running: [%s] ...\n", cmdline), fflush(stdout);
	system(cmdline);
	free(thename);
	/* if (vfork() == 0) {
		if (execvp("attach", args) == -1)
			perror("execv attach");
		_exit(0);			  execl failed... 
	} else
		wait(0);			 Waiting parent */
	
}

#endif

unsigned long	_allocated = 0;

char *
domalloc(unsigned long	bytes)
{

#ifdef MAC
	char	*cp = (char *) mlalloc(bytes);
#else
	char	*cp = (char *) malloc(bytes);
#endif

	_allocated += bytes;
	if (!cp)
		printf("Malloc failed to get %lu bytes.\n", bytes);
	return cp;
}
/* this needs to be fixed */
char *
get_token(str, num)
char   *str;
int    num;
{
char *cp,*end,*rtn_str;
int  i;
cp = str;

for (i = 0 ; i < (num -1); i++) { 
  cp = index(cp,DLM);
  if (cp != NULL)
    cp++;
    }
  end = index(cp,DLM);
  if ((cp == NULL)|| (end == NULL)) 
     return cp;
  i = end - cp;
  rtn_str = (char *) domalloc(i+1);
  strncpy(rtn_str,cp,i);
  *(rtn_str+i) = '\0';
  return rtn_str;
}

void
change_token(line,token_no,value) /* change the value of one of the tokens */
     char *line;                  /* assumes that line has enough allocated */
int  token_no;
char *value;
{
char  *cp,tempstr[100]; 
int   i;

cp = line;
for (i = 0 ; i < (token_no - 1); i++) { 
  cp = index(cp,DLM);
  if (cp != NULL)
    cp++;
    }

  if (cp != NULL) {
    cp--;
    *cp = '\0';
    cp++;
    cp = index(cp,DLM);
}

strcpy(tempstr,cp);
sprintf(line,"%s%c%s%s",line,DLM,value,tempstr);
return;
}
