/*
 * utils.c: various utility functions
 *
 * Copyright(c) 1997-2000 - All Rights Reserved
 *
 * See the COPYRIGHT file.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: utils.c,v 1.14 2000/07/31 22:37:23 kalt Exp $";
#endif

#include "os.h"

/* strcasestr: case insensitive version of strstr() */
char *
strcasestr(s1, s2)
  char    *s1, *s2;
{
  int	len;

  assert( s1 && s2 );

  len = strlen(s2);
  while (*s1)
    {
      if (!strncasecmp(s1, s2, len))
	  return s1;
      s1++;
    }
  return NULL;
}

/* match: some lame version
 *	returns 0 if no match.
 */
int
rmatch (pattern, string)
  char *pattern, *string;
{
  int ret;
  char Ustring[1024];

  Ustring[1023] = '\0';
  strncpy(Ustring, string, 1024);
  assert( Ustring[1023] == '\0' );

  for(ret = 0; Ustring[ret] = toupper(string[ret]); ret++);

  ret = 0; string = Ustring;
  while (*pattern || *string)
    {
      if ((*pattern == '?') || (toupper(*pattern) == *string))
	{
	  pattern++;
	  string++;
	}
      else if (*pattern=='*')
	{
	  while ((*++pattern=='*') || (*pattern=='?'))
	      if (*pattern=='?')
		  string++;
	  if (!*pattern)
	      return (1);
	  while (string = (char*) index(string, toupper(*pattern)))
	    {
	      ret += rmatch(pattern+1,string+1);
	      string++;
	    }
	  return ret;
	}
      else
	  return 0;
    }
  if (*pattern || *string)
      return (0);
  else
      return (1);
}

char *
my_cftime(s, len, format, tv)
  char *s, *format;
  int len;
  time_t tv;
{
  struct tm *stm;

  stm = localtime(&tv);
#if HAVE_STRFTIME
  if (strftime(s, len, format, stm) == 0)
      s[len-1] = '\0';
#else
  s[0] = '\0';
  if (*format)
    {
      strncpy(s, "<notime>", len);
      s[len-1] = '\0';
    }
#endif
  return s;
}

char *
my_strftime(s, len, format)
  char *s, *format;
  int len;
{
  time_t now;

  now = time(NULL);
  return my_cftime(s, len, format, now);
}

/* sic_tdiff: returns an alphanumeric representation of diff seconds.
 *	force can be used to control the format.
 */
char *
sic_tdiff(diff, force)
  time_t diff;
  char force;
{
  static char result[10][16];
  static int i = -1;
  unsigned int j, h, m, s;
  
  if (i++ == 9)
      i = 0;
  j = diff / 86400;
  h = (diff - 86400*j) / 3600;
  m = (diff - 86400*j - 3600*h) / 60;
  s = diff - 86400*j - 3600*h - 60*m;
  if (j || (force == 3))
      sprintf (result[i], "%ud%2.2u:%2.2u", j, h, m);
  else   
      if (h || (force == 2))
	  sprintf (result[i], "%2.2u:%2.2u", h, m);
      else
	  if (!force && m)
	      sprintf (result[i], "%2.2u.%2.2u", m, s);
	  else
	      if (m || (force == 1))
		  sprintf (result[i], "%2.2um", m);
	      else
		  sprintf (result[i], "%2.2us", s);
  return result[i];
}

#if !defined(HAVE_STRERROR)

# if !defined(SYS_ERRLIST_DECLARED)
extern char *sys_errlist[];
# endif

# if !defined(SYS_NERR_DECLARED)
extern int sys_nerr;
# endif

char *
strerror(err_no)
  int err_no;
{
  static  char    buff[40];
  char    *errp;

  errp = (err_no > sys_nerr ? (char *)NULL : sys_errlist[err_no]);
  
  if (errp == (char *)NULL)
    {
      errp = buff;
      sprintf(errp, "Unknown Error %d", err_no);
    }
  return errp;
}
#endif

#if defined(HAVE_GETADDRINFO)
/* aitoip: return the IP address (string) contained in the addrinfo struct */
char *
aitoip(addr)
struct addrinfo *addr;
{
    char tmp[512];

    assert(addr->ai_family == AF_INET || addr->ai_family == AF_INET6);

    if (inet_ntop(addr->ai_family, (addr->ai_family == AF_INET) ?
		  &((struct sockaddr_in *)addr->ai_addr)->sin_addr :
		  &((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr,
		  tmp, 512) == NULL)
	abort();

    return strdup(tmp);
}
#endif
