/*
 * W-NEWS       A simple NEWS processing package.
 *		util.c - several small library routines.
 *
 * Version:     @(#)util.c     4.50    03-Feb-1995
 *
 * Authors:     Edvard Tuinder, <ed@ow.org>
 *		Miquel van Smoorenburg, <miquels@drinkel.ow.org>
 *              Copyright 1993 MicroWalt Corporation
 *		Copyright 1994,1995 Cistron Software C.V.
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 */
#include "libwnews.h"
#if HAVE_STATFS
#  ifdef LINUX
#   include <sys/vfs.h>
#  else
#   include <sys/statfs.h>
#  endif
#endif


/* Convert groupname to directory name */
char *
gtof(group)
char *group;
{
  static char temp[256];
  register char *s;

  strcpy(temp, group);
  for(s = temp; *s; s++)
	*s = *s == '.' ? '/' : *s;
  return(temp);
}


/* Compare two strings case-independant. */
int
strnicmp(s1, s2, len)
char *s1;
char *s2;
int len;
{
  char c1, c2;

  while(len && *s1 && *s2) {
	c1 = isupper(*s1) ? tolower(*s1) : *s1;
	c2 = isupper(*s2) ? tolower(*s2) : *s2;
	if (c1 != c2) return(c1 - c2);
	s1++, s2++;
	len--;
  }
  if (len == 0 || (*s1 == 0 && *s2 == 0)) return(0);
  return(1);
}


/* See if a character from s1 is in s2. */
int
any(s1, s2)
char *s1, *s2;
{
  while(*s1) {
	if (strchr(s2, *s1)) return(1);
	s1++;
  }
  return(0);
}


/* Save a string in a malloc'ed area. */
char *
strsave(s)
char *s;
{
  char *p;

  if ((p = (char *)malloc(strlen(s) + 1)) != (char *)NULL)
	strcpy(p, s);
  return(p);
}


/* How much disk space is left? Blocks of 1K. */
long
free_space(dir)
char *dir;
{
#if HAVE_STATFS
  struct statfs st;

  if (statfs(dir, &st) < 0) {
	logmsg(LOGERR, "cannot fstat(%s)\n", dir);
	return(1000L);
  }
#  ifdef COH4
  return((st.f_bfree * st.f_bsize) / 1024);
#  else
  return((st.f_bavail * st.f_bsize) / 1024);
#  endif
#else
  /* Just return an arbitrary number, 1000 blocks should be OK. */
  return(1000L);
#endif
}

static int
isdir(s)
char *s;
{
  struct stat st;

  if (stat(s, &st) < 0) return(0);
  if (!S_ISDIR(st.st_mode)) return(0);
  return(1);
}

/* Recursively create directories. */
int
wmkspooldir(name, isgroup)
char *name;
int isgroup;
{
  char buff[512];
  char *sp, *bp;
  int quit = 0;

  /* Relative to SPOOLDIR? */
  if (!isgroup && name[0] == '/') {
	strcpy(buff, name);
	sp = name + 1;
  } else {
	sprintf(buff, "%s/%s", SPOOLDIR, name);
	sp = buff + strlen(SPOOLDIR) + 1;
  }

  if (isdir(buff)) return(OK);

  /* Change newsgroup into directory name */
  if (isgroup)
	for(bp = buff; *bp; bp++) if (*bp == '.') *bp = '/';

  while (!quit) {
	if ((sp = strchr(sp, '/')) == (char *)NULL)
		quit = 1;
	else
		*sp = 0;
	if (buff[0] && !isdir(buff)) {
		if ((wmkdir(buff, 0755)) != 0) {
			logmsg(LOGERR, "cannot mkdir(%s)\n", buff);
			return(ERROR);
		}
	}
	if (sp) *sp++ = '/';
  }
  return(OK);
}


#ifdef COHERENT
/* wmktime routine by Udo Munk. */
long
timesec(year, month, day, hour, min, sec)
int year, month, day, hour, min, sec;
{
  static int daypermonth [12] = {
	0, 31, 28+31, 31+59, 30+31+59, 31+30+31+59,
	30+151, 31+30+151, 31+31+30+151, 30+243, 31+30+243, 30+31+30+243
  };
  int years, leaps;
  long days, secs;

  years = year - 1970; 
  leaps = (years + 1) / 4;
  if (((years % 4) == 2) && (month > 1)) ++leaps;
  days = (long)years * 365 + (long)leaps + (long)daypermonth[month] +
                                                               (long)(day-1);
  secs = days * 86400L + (long)hour * 3600 + (long)min * 60 + (long)sec;
  return(secs);
}

time_t
wmktime(timeptr)
struct tm *timeptr;
{
  time_t t;

  t = timesec(timeptr->tm_year+1900,timeptr->tm_mon,timeptr->tm_mday,
               timeptr->tm_hour,timeptr->tm_min, timeptr->tm_sec);
  return(t);
}
#else	/* !(LINUX || COHERENT) */
time_t
wmktime(timeptr)
struct tm *timeptr;
{
  return(mktime(timeptr));
}
#endif /* LINUX || COHERENT */
