/* $Id: tools.c,v 1.24 1995/11/12 11:09:16 akool Exp akool $
 *
 * ISDN accounting for isdn4linux. (Utilities)
 *
 * Copyright 1995 by Andreas Kool (akool@Kool.f.EUnet.de)
 *
 * 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, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Log: tools.c,v $
 * Revision 1.24  1995/11/12  11:09:16  akool
 * Initial revision
 *
 */


#define  PUBLIC /**/
#include "isdnlog.h"


char *Months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
       	    	     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };


static char proto[] = "                   0,000000000";


time_t atom(register char *p)
{
  register char     *p1 = p;
  auto 	   struct tm tm;


  tm.tm_mon = 0;

  while ((tm.tm_mon < 12) && memcmp(p1, Months[tm.tm_mon], 3)) tm.tm_mon++;

  p1 += 4;
  p = p1 + 2;

  *p = 0;

  day = tm.tm_mday = atoi(p1);

  p1 += 3;
  p = p1 + 2;
  *p = 0;
  tm.tm_hour = atoi(p1);

  p1 = ++p;
  p += 2;
  *p = 0;
  tm.tm_min = atoi(p1);

  p1 = ++p;
  p += 2;
  *p = 0;
  tm.tm_sec = atoi(p1);

  p1 = ++p;
  p += 4;
  *p = 0;

  tm.tm_year = atoi(p1 + 2);

  tm.tm_wday = tm.tm_yday;
  tm.tm_isdst = -1;

  return(mktime(&tm));
} /* atom */


void readconfig(char *myname)
{
  register char *p;
  register int   cc, n = 0;
  auto     FILE *f;
  auto     char  s[BUFSIZ], msn[64], name[64], infoarg[64];
  auto	   int	 zone;


  mymsns = 3;
  knowns = retnum = 0;
  hangup = NULL;

  if ((f = fopen(CONFFILE, "r")) != (FILE *)NULL) {

    while (fgets(s, BUFSIZ, f) != NULL) {

      n++;

      if ((*s != '#') && (*s != '\n')) {

        if (p = strchr(s, '\n')) {
          *p = 0;

          while (*--p == ' ')
            *p = 0;
        } /* if */

        if (!memcmp(s, "MYMSNS=", 7))
          mymsns = atoi(s + 7);
        else if (!memcmp(s, "HANGUP=", 7))
          hangup = strdup(s + 7);

	else {
	  cc = sscanf(s, "%s %s %d %s", msn, name, &zone, infoarg);

          if (cc == 3) {
            *infoarg = 0;
            cc = 4;
          } /* if */

	  if (cc == 4) {
            known = realloc(known, sizeof(KNOWN *) * knowns + 1);

	    if (known[knowns] = (KNOWN *)malloc(sizeof(KNOWN))) {
  	      known[knowns]->num = strdup(msn);
  	      known[knowns]->who = strdup(name);
              known[knowns]->infoarg = strdup(infoarg);

  	      known[knowns]->zone = zone;

  	      known[knowns]->dur[CALLING] = known[knowns]->dur[CALLED] = 0.0;
  	      known[knowns]->eh[YOUPAY] = known[knowns]->eh[IPAY] =
  	      known[knowns]->usage = 0;

              knowns++;
	    }
            else {
  	      fprintf(stderr, "%s: WARNING: Out of memory\n", myname);
              break;
            } /* else */
          }
          else
  	    fprintf(stderr, "%s: WARNING: Syntax error in %s, line #%d\n", myname, CONFFILE, n);
	} /* else */
      } /* if */
    } /* while */

    fclose(f);

  } /* if */
} /* readconfig */


static char *cclass(register char *p, register int sub)
{
  register int c, d, not, found;


  if (not = (*p == NOT))
    p++;

  found = not;

  do {
    if (!*p)
      return(NULL);

    c = *p & QCMASK;

    if (p[1] == '-' && p[2] != ']') {
      d = p[2] & QCMASK;
      p++;
    }
    else
      d = c;

    if ((c == sub) || (c <= sub) && (sub <= d))
      found = !not;
  } while (*++p != ']');

  return(found ? p + 1 : NULL);
} /* cclass */


int match(register char *s, register char *p)
{
  register int sc, pcc;


  if (!*s || !*p)
    return(0);

  while ((pcc = *p++ & QCMASK)) {
    sc = *s++ & QMASK;

    switch (pcc) {
      case '[' : if (!(p = cclass(p, sc)))
	           return(0);
	         break;

      case '?' : if (!sc)
	           return(0);
	         break;

      case '*' : s--;
	         do {
	           if (!*p || match(s, p))
	             return(1);
	         } while (*s++);
	         return(0);

      default  : if (sc != (pcc &~QUOTE))
	           return(0);
    } /* switch */
  } /* while */

  return(!*s);
} /* match */


char *num2nam(char *num)
{
  register int i;


  if (*num) {
    for (i = 0; i < knowns; i++)
      if (match(num, known[i]->num)) {
        if (++retnum == MAXRET)
          retnum = 0;

        return(strcpy(retstr[retnum], known[i]->who));
      } /* if */
  } /* if */

  return(num);
} /* num2nam */


char *double2str(double n, int l, int d, int flags)
{
  register char *p, *ps, *pd, *px;
  auto     int   decpt, sign, dec, dp;
  auto     char  buf[BUFSIZ];


  if (++retnum == MAXRET)
    retnum = 0;

  p = retstr[retnum] + l + 1;
  *p = 0;

  dec = d ? d : -1;
  dp = l - dec;

  *buf = '0';
  memcpy(buf + 1, ecvt(n, DIGITS, &decpt, &sign), DIGITS);

  ps = buf;
  px = ps + decpt + d;

  if (px >= buf) {
    int rfound = 0;
    pd = px + 1;

    if (*pd > '4') {
      pd++;
      rfound++;
    } /* if */

    if (rfound) {
      while (pd > px)
	if (*pd >= '5') {
	  pd--;
	  while (*pd == '9')
	    *pd-- = '0';
	  *pd += 1;
	}
	else
	  pd--;
    } /* if */

    if (*buf == '1')
      decpt++;
    else
      ps++;

    if ((dp < 2 + sign) || ((decpt ? decpt : 1) + sign) >= dp) {
      memset(retstr[retnum] + 1, '*', *retstr[retnum] = l);
      return(retstr[retnum] + 1);
    } /* if */

  } /* if */

  memcpy(retstr[retnum] + 1, proto + 21 - l + dec, *retstr[retnum] = l);

  if (!((decpt < 0) && ((dec + decpt) <= 0))) {
    pd = retstr[retnum] + dp - decpt;

    if (sign) {
      if (decpt > 0)
	*(pd - 1) = '-';
      else
	*(retstr[retnum] + dp - 2) = '-';
    } /* if */

    while (decpt-- > 0)
      *pd++ = *ps++;

    pd++; /* skip comma */

    while (d-- > 0)
      *pd++ = *ps++;
  } /* if */

  if (flags & DEB) {
    p = retstr[retnum] + 1;

    while (*p == ' ')
      p++;

    return(p);
  } /* if */

  return(retstr[retnum] + 1);

} /* double2str */
