/*****************************************************************************
 * File:	utils.c
 *
 * Author:	Rhett "Jonzy" Jones
 *		jonzy@cc.utah.edu
 *
 * Date:	March 6, 1993
 *
 * Modified:	March 20, 1993, by Rhett "Jonzy" Jones
 *		Cleaned up some of the routines.
 *
 * Description:	Contains various utlity routines.  See "Routines" for more
 *		information.
 *
 * Routines:	char	*StrToLower(char *str);
 *		long	GetLong(FILE *fp);
 *		int	GetInt(FILE *fp);
 *		char	*GetStr(FILE *fp,char *str,int limit);
 *		int	Str2Int(char *s);
 *		char	*Reverse(char *s, char *r);
 *		short	StrRcmp(char *s1, char *s2);
 *		int	DoSystemCall(char *format,...);
 *		char	*MyStrTok(char *str,char delimeter);
 *		char	*OnlyDigits(char *s);
 *		char	*RemoveCRLF(char *line);
 *
 * Bugs:	No known bugs.
 *
 * Copyright:	Copyright 1993, University of Utah Computer Center.
 *		This source may be freely distributed as long as this copyright
 * 		notice remains intact, and is in no way used for any monetary
 * 		gain, by any institution, business, person, or persons.
 *
 ****************************************************************************/

#include <stdarg.h>
#include <stdio.h>

/*****************************************************************************
 * StrToLower returns the string 'str' passed in, which gets converted to
 *lower case.
 ****************************************************************************/
char *StrToLower(str)
	char	*str;	/* The string we are converted to lower case. */
{	char	*s;	/* Pointer to the position we are converting. */

	for (s = str; *s; s++)
		*s = tolower(*s);
	return(str);

}	/* StrToLower */

/*****************************************************************************
 * GetLong returns a long acquired from the stream 'fp'.  This routine
 * supports a '+' or '-' as input as the first character to set the sign.
 * This routine was written because of the problems with fscanf().
 ****************************************************************************/
long GetLong(fp)
	FILE	*fp;		/* The stream we are getting input from. */
{	long	i;		/* The value we return. */
	int	c,		/* A character from the stream. */
		sign = 1;	/* Initial sign of the result. */

	while (isspace(c = fgetc(fp)));		/* Skip any whitespace. */
	if (c == '+' || c == '-')		/* Check the sign. */
		{
		sign = (c == '+') ? 1 : -1;
		c = fgetc(fp);
		}
	for (i = 0; isdigit(c); c = fgetc(fp))	/* Get the number. */
		i = i * 10 + c - '0';
#if(0)
	if (c != EOF)				/* Put the character back. */
		ungetc(c,fp);
#endif
	return(i * sign);

}	/* GetLong */

/*****************************************************************************
 * GetInt returns an int acquired from the stream 'fp'.  This routine
* supports a '+' or '-' as input as the first character to set the sign.
 * This routine was written because of the problems with fscanf().
 ****************************************************************************/
int GetInt(fp)
	FILE	*fp;		/* The stream we are getting input from. */
{	long	i;		/* The value we return. */
	int	c,		/* A character from the stream. */
		sign = 1;	/* Initial sign of the result. */

	while (isspace(c = fgetc(fp)));		/* Skip any whitespace. */
	if (c == '+' || c == '-')		/* Check the sign. */
		{
		sign = (c == '+') ? 1 : -1;
		c = fgetc(fp);
		}
	for (i = 0; isdigit(c); c = fgetc(fp))	/* Get the number. */
		i = i * 10 + c - '0';
#if(0)
	if (c != EOF)				/* Put the character back. */
		ungetc(c,fp);
#endif
	return(i * sign);


}	/* GetInt */

/*****************************************************************************
 * GetStr returns a string acquired from the stream 'fp'.
 * This routine was written because of the problems with fscanf().
 ****************************************************************************/
char *GetStr(fp,str,limit)
	FILE		*fp;		/* The stream we are getting input from. */
	char		*str;		/* Where to place the characters. */
	short		limit;		/* The maximum number of characters to read. */
{	int		i;		/* A loop counter. */
	int		c;		/* A character from the stream. */


	while (isspace(c = fgetc(fp)));		/* Skip any whitespace. */
	for (i = 0; !isspace(c); c = fgetc(fp))
		str[i++] = (char)c;
	str[i] = '\0';
#if(0)
	if (c != EOF)				/* Put the character back. */
		ungetc(c,fp);
#endif
	return(str);

}	/* GetStr */

/*****************************************************************************
 * Str2Int returns the integer equivilent of str.
 ****************************************************************************/
int Str2Int(s)
	char	*s;	/* The string we are converting to an integer. */
{	int	i;	/* The value returned by this routine. */

	for (i = 0; *s && isdigit(*s); s++)
		i = i * 10 + *s - '0';
	return(i);

}	/* Str2Int */

/*****************************************************************************
 * Reverse copies 's' into 'r' in reverse order and returns 'r'.
 ****************************************************************************/
char *Reverse(s,r)
	char	*s,	/* The string in forward order. */
		*r;	/* The result in reverse order. */
{	int	i,	/* A loop counter. */
		l;	/* The length of 's'. */

	for (l = strlen(s), i = 0; i < l; i++)
		r[i] = s[l - i - 1];
	r[l] = '\0';
	return(r);

}	/* Reverse */

/*****************************************************************************
 * StrRcmp returns true if 's1' in reverse is contained at the begining of
 * 's2' in reverse.  Otherwise it returns false.
 * Example: say 's1' = ".some.site", and 's2' = "this.some.site", if you reverse
 * both of these strings you get
 * 's1' = "etis.emos."
 * 's2' = "etis.emos.siht"  which evalutaes to true.  If 's1' is not contained
 * in 's2' we return false.
 * This routine was written to support the use of domains as hosts contained
 * in 'hosts2search'.
 ****************************************************************************/
short StrRcmp(s1,s2)
	char	*s1,	/* The string which must be in s2 (in reverse order). */
		*s2;	/* The string which must contain s1. */
{	char	r1[255],/* The string s1 in reverse. */
		r2[255];/* The string s2 in reverse. */
	int	i;	/* A loop counter. */

	for (s1 = Reverse(s1,r1), s2 = Reverse(s2,r2); *s1 && *s2; s1++, s2++)
		if (*s1 != *s2)
			return(0);
	if (*s1 && !*s2)
		return(0);
	return(1);
			
}	/* StrRcmp */

/*****************************************************************************
 * DoSystemCall does a system on the result of 'format'.
 ****************************************************************************/
int DoSystemCall(char *format,...)
{	char	str[1024] = "";		/* The string we send to the system. */
	int	result;			/* Did things turn out ok? */
	va_list	ap;			/* The arguments beyond 'format'. */

	va_start(ap,format);
	result = vsprintf(str,format,ap);
	va_end(ap);

	if (result < 0)
		fprintf(stderr,"error: DoSystemCall had vsprintf fail.\n");
	else if (result = system(str))
		fprintf(stderr,"error: DoSystemCall [%s] failed\n",str);
	return(result);

}	/* DoSystemCall */

/*****************************************************************************
 * MyStrTok returns breaks 'str' into tokens as per the token seperator
 * 'delimeter'.  This routine basicly does the samething as strtok().
 ****************************************************************************/
char *MyStrTok(str,delimeter)
	char		*str,		/* The string to tokenize. */
			delimeter;	/* The delimeter character. */
{	static char	*theStr,	/* Keep a copy the string to tokenize. */
			*s,		/* A temporary pointer. */
			*token;		/* The token to return. */

	if (str)	/* A new string to tokenize. */
		theStr = str;

	token = theStr;	/* This is the token. */

	/* Break up theStr into a token. */
	if (*theStr != delimeter)
		for (s = theStr; *s && *s != delimeter; s++)
			;

	/* Nill out the token and do some cleaning up. */
	*s++ = '\0';
	theStr = s;
	return(token);

}	/* MyStrTok */


/*****************************************************************************
 * OnlyDigits returns a null terminated string containing only the digit
 * characters contained in 's'.  What we do is convert the first non-digit
 * character in 's' to the null character and return the string.
 ****************************************************************************/
char *OnlyDigits(s)
	char	*s;		/* The input string. */
{	char	*digits;	/* The string with digits only. */

	for (digits = s; *s; s++)
		if (!isdigit(*s))
			{
			*s = '\0';
			return(digits);
			}
			
	return(digits);

}	/* OnlyDigits */

/*****************************************************************************
 * RemoveCRLF removes the carriage return or line feed by changing it to
 * the null character.
 ****************************************************************************/
char *RemoveCRLF(line)
	char	*line;		/* The line we are dealing with. */
{	char	*s;		/* Pointer into 'line'. */

	for (s = line; *s && *s != '\r' && *s != '\n'; s++)
		;	/* Go to the CR or LF position. */
	*s = '\0';
	return(s);

}	/* RemoveCRLF */

