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

void log_read(char *line);
void change_token(char *line, int token_no,char *value);
char *find_token(char *str, int num);
char *get_token(char *str, int num);
char *domalloc(unsigned long bytes);
void do_attach(char *name, char *mountpoint, int detach);
void ensure_access(char file[], char attach_src[], int detach);
void putstr(char *str);
void addarg(char **fcp, char *fmt, int arg);
int tokenize(char str[], char *argvec[], int maxargs);
int strlower(char *str);
int inttest(char *str);
int strcnt(char *str, char c);
int num_letters(char *str);
#ifdef SERV
int is_attached(char *name);
#endif

extern int debug;
unsigned long	_allocated = 0;
char * NULL_STR = "";
char * index();

/*  the vax bsd4.3 doesn't seem to have memcpy? */
/*
void
memcpy(char *dest, char *src, int len)
{
	while (len-- > 0)
		*dest++	= *src++;
}
*/

/**************************************************************************/
/* Count # of non-spaces in string */
int
num_nonblanks(char *str)
{
  register int count = 0;

  while (*str)
    if (*str++ != ' ')
      count++;

  return count;
}
/**************************************************************************/
/* Count # of occurences of char c in string str */
int
strcnt(char *str, char c)
{
  register int	cnt = 0;
  
  while (*str)
    if (*str++ == c)
      cnt++;
  return cnt;
}
/**************************************************************************/
/* returns nonzero if string is a valid integer */
int
inttest(char *str)
{
/*	if (*str == '-')
		str++;   
not allowing for negatives */
	while (*str) {
		if (!isdigit(*str) && *str != ' ')
			return 0;
		str++;
	}
	return 1;
}
/**************************************************************************/
/* tolower a string, returning the length of the string */
int
strlower(char *str)
{
	int	cnt = 0;

	while (*str) {
		if (isupper(*str))
			*str = tolower(*str);
		str++, cnt++;
	}
	return cnt;
}
/**************************************************************************/
int
tokenize(char str[], char *argvec[], int maxargs)
{
  char	*cp = str;
  int	argcnt = 0;
  int     endtoken;
  
  while (argcnt < maxargs) {
    while (isspace(*cp))
      cp++;
    if (!*cp)
      break;
    
    endtoken = ' ';
    if (*cp == '"' || *cp == '\'') {
	    endtoken = *cp;
	    cp++;  /* move past the quote */
	  }
    argvec[argcnt++] = cp;
    for (; *cp &&
	 ((endtoken == ' ' && !isspace(*cp)) ||
	  (endtoken != ' ' && *cp != endtoken));
	 cp++);
    
    if (!*cp)
      break;
    *cp++ = '\0';
  }
  argvec[argcnt] = (char *) 0;
  return argcnt;
}
/**************************************************************************/
void
addarg(char **fcp, char *fmt, int arg)
{
  char *usequote = "";
  char *cp = (char *) arg;

  if (strcmp (fmt, " %s") != 0)
    sprintf(*fcp, fmt, arg);
  else {
    if (*cp == '"')      /* if the first char of arg is a quote, use quotes */
      usequote = "'";
    else if (*cp == '\'')
      usequote = "\"";
    else {
      for (; *cp && !isspace(*cp); cp++);
      if (isspace(*cp)) {
	usequote = "\"";       /* can we use this type of quote? */
	for (cp = (char *) arg; *cp && *cp != *usequote; cp++);
	if (*cp == *usequote)  /* can't use this one */
	  usequote = "'";      /* use the other one */
      }
    }
    sprintf (*fcp, " %s%s%s", usequote, arg, usequote);
  }
  while (**fcp) (*fcp)++;
}
/**************************************************************************/
void
putstr(char *str)
{
  while (*str)
    putchar(*str), str++;
}
/**************************************************************************/
/* tell if given file descriptor references a directory  7/22/92 ark  */
int 
is_directory(int fd)
{
  struct stat st;

  if (fstat(fd, &st))
    return 0;
  return(st.st_mode & S_IFDIR);
}
/**************************************************************************/
#ifdef SERV
/* is the filesystem attached ? this just looks in the 
  attachtab file, so it is no good for the server - we aren't using this */
int
is_attached(char *name)  
{
  char locker[40],line[150],*cp;
  FILE *fopen(), *attachfile;
  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,140,attachfile) != '\0') {
    cp = line + 9; 
    if (strncasecmp(cp,locker,len) == 0){
      fclose(attachfile);
      return 1;
    }
  }
  fclose(attachfile);
  return 0;
}
#endif
/**************************************************************************/
/* On Athena, try to attach a locker if the file isn't found otherwise. */
/* ARGSUSED */
void
ensure_access(char file[], char attach_src[], int detach)
{
#ifdef ATHENA
	if (!access(file, F_OK))
	     return;
		do_attach(attach_src, (char *) 0, detach);
#endif
}
/**************************************************************************/
/*
 * 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)
 */
/* ARGSUSED */
void
do_attach(char *name, char *mountpoint, int detach)
{
	char	*args[16],dirname[80],*thename;
	int	ca = 0;
	char	cmdline[120],*cp,*ptr,*pt;
/* to handle stale nfs connections */
#ifdef SERV
	if (!detach) {  /* reverse this logic!! */
	  if (debug)
	    printf("detaching...\n");
	  if (is_attached(name)) { 
	    sprintf(cmdline,"/bin/athena/detach %s",name);
	    system(cmdline);
	} 
      }
#endif
	thename = (char *) domalloc(100u);
	strcpy(thename,name);
        for (cp = thename;*cp;cp++)  /* swap in a colon */
	   if (*cp == '^')
	     *cp = ':';
	args[ca++] = "/bin/athena/attach";
	if (mountpoint)
		args[ca++] = "-mountpoint",
		args[ca++] = mountpoint;
	args[ca++] = "-quiet";
	args[ca++] = "-nozephyr";
#ifdef SERV  
	if (strcmp(name,PIPS_LOCKER) != 0)
	  args[ca++] = "-n";  /* no kerberos */
	args[ca++] = "-o"; /* change the mount options */
	args[ca++] = "retry=2set,soft,retrans=3";
#else
	  args[ca++] = "-n";  /* no kerberos */
#endif
	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);
	do_free(thename);
}
/**************************************************************************/
char *
domalloc(unsigned long	bytes)
{
  char *cp;
  
  if (bytes == 0) 
    bytes = 1;
#ifdef MAC
  cp = (char *) mlalloc(bytes);
#else
  cp = (char *) malloc(bytes);
#endif
  
  _allocated += bytes;
  if (!cp)
    printf("Malloc failed to get %lu bytes.\n", bytes);
  return cp;
}
/**************************************************************************/
/* returns a copy (malloced) of the token */
char *
get_token(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)
    cp++;
  else
    return NULL;
    }
  end = index(cp,DLM);
if (!end)
  end = index(cp,'\0');
/*
  if ((cp == NULL)|| (end == NULL)) 
     return NULL_STR; */

  i = end - cp;
  rtn_str = (char *) domalloc((unsigned int) i+1);
  strncpy(rtn_str,cp,i);
  *(rtn_str+i) = '\0';
  return rtn_str;
}
/**************************************************************************/
/* return a pointer to the begin of token in orig str 
 * does NOT null-terminate the token */
char *
find_token(char *str, int num)  
{
  char *cp;
  int  i;
  
  cp = str;
  
  for (i = 0 ; i < (num -1); i++) { 
    cp = index(cp,DLM);
    
    if (cp)
      cp++;
    else
      return cp;
  }
  
  return cp;
}
/**************************************************************************/
/* change the value of one of the tokens */
/* assumes that line has enough space allocated */
void
change_token(char *line, int token_no,char *value) 
{
  char tempstr[255];
  char  *cp; 
  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);
  }
  if ( cp && *cp )
    strcpy(tempstr,cp);
  else
    *tempstr = '\0';
  sprintf(line,"%s%c%s%s",line,DLM,value,tempstr);
  return;
}
/* write a buffer to a file */
int
write_buf_to_file(char *buf,int len,char *filepath)
{

int rc,fd;

fd = open(filepath,O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (fd < 0)
  return fd;

rc = write(fd, buf, len);
if (rc < 0)
  return rc;
rc = close(fd);
if (rc < 0)
  return rc;
return 0;
}
