
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "cus.h"
#include "defines.h"
#include "lbio.h"

int inlsys(char *lsysfile, char *hostname)
{
	int rc;
	FILE *fp = NULL;
	char *buf = NULL;
	long len;
	LB *lb = NULL;
	int i;
	char *p;

	if ((fp = fopen(lsysfile, "r")) == NULL)
		CU(ERR);
	if (fseek(fp, 0L, SEEK_END) == -1L)
		CU(ERR);
	if ((len = ftell(fp)) == -1L)
		CU(ERR);
	if (fseek(fp, 0L, SEEK_SET) == -1L)
		CU(ERR);
	if ((buf = (char *)malloc(len)) == NULL)
		CU(ERR);
	if ((fread(buf, len, 1, fp) != 1) && ferror(fp))
		CU(ERR);
	if ((lb = lbopen(buf, buf+len-1)) == NULL)
		CU(ERR);
	if (lbseek(lb, 0, LBSEEK_SET) == NULL)
		CU(ERR);

	do {
		if ((lb->lb_wLnCur != 0) && (*(lb->lb_cpLnCur) != '#')) {
			for (i=0, p = lb->lb_cpLnCur; i < lb->lb_wLnCur; i++, p++)
				if (*p == SP)
					break;
			if ((*p == SP) && (i == strlen(hostname)))
				if (!(strnicmp(lb->lb_cpLnCur, hostname, i)))
					CU(TRUE);
		}
	} while (lbseek(lb, 1, LBSEEK_CUR));

	rc = FALSE;

	CUS:
	if (lb)	lbfree(lb);
	if (fp) fclose(fp);
	if (buf) free(buf);
	return rc;
}




/*	|	The second field (Any in the examples above) has been implemented
	|    for 1.06D and beyond.  There are no spaces anywhere in the field:
	|
	|	    Any 	    the system can be called at any time
	|
	|	    Never	    the system can never be calleod
	|
	|	    hh:mm-hh:mm     any day in the hour range indicated (24hr time)
	|
	|	    MoTuWeThFrSaSuhh:mm-hh:mm
	|			    On the days indicated in the hour range indicated.
	|
	|	    <timespec>,<timespec>
	|	    MoTuWeThFr02:00-03:00,SaSu00:00-23:59
	|			    On the days indicated in the hour range indicated,
	|			    time specs separated by commas.

									-- quoted from manual of uucico V1.15D	*/

#define WDAYNAME_NUM 7
#define WDAYNAME_LEN 2
#define DAYHOURS_NUM 24

static char wday_name[WDAYNAME_NUM][WDAYNAME_LEN+1] = {
	"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"
};

static int cmptime(char *timestr)
{
	int rc;
	time_t t;
	struct tm *tm;
	int day;
	int i;
	int sh, sm, eh, em;
	char hours[DAYHOURS_NUM];
	int dh, dm;
	int shTmp, ehTmp;
	char *cp;

	if (strcmpi("Any", timestr) == 0)
		CU(0);
	if (strcmpi("Never", timestr) == 0)
		CU(-1);

	time(&t);
	tm = localtime(&t);

	for (cp = timestr; cp != NULL; cp = strpbrk(cp, ",")) {
		if (*cp == ',')
			++cp;

		day = 0;
		while(isalpha(*cp)) {
			for (i = 0; i < WDAYNAME_NUM; i++) {
				if (strnicmp(cp, wday_name[i], WDAYNAME_LEN) == 0) {
					day |= 1L << i;
					cp += 2;
				}
			}
		}
		if (day == 0)
			day = ~0;

		if (sscanf(cp, "%d:%d-%d:%d", &sh, &sm, &eh, &em) != 4)
			continue;

		for (i = 0; i < DAYHOURS_NUM; i++)
			hours[i] = 0;

		dh = eh - sh;
		if (dh < 0)
			dh += DAYHOURS_NUM;

		ehTmp = sh + dh;
		shTmp = sh;

		while (shTmp <= ehTmp) {
			hours[shTmp++] = 1;
			if (shTmp == DAYHOURS_NUM) {
				shTmp -= DAYHOURS_NUM;
				ehTmp -= DAYHOURS_NUM;
			}
		}

		if ( !(day & (1L << tm->tm_wday)) )
			continue;
		if ( !hours[tm->tm_hour] )
			continue;
		if ( (tm->tm_hour == sh) && (tm->tm_min < sm) )
			continue;
		if ( (tm->tm_hour == eh) && (tm->tm_min > em) )
			continue;

		dm = em - tm->tm_min;
		dh = eh - tm->tm_hour;

		CU(dh * 60 + dm);
	}

	rc = -1;

CUS:
	return rc;
}


int timerestriction(char *lsysfile, char *cpHost)
{
	int rc;
	FILE *fpLsys = NULL;
	char *cpBuf = NULL;
	long wLsys;
	LB *lb = NULL;
	char *cp;
	char *timeentry;
	int wHost;

	if ((fpLsys = fopen(lsysfile, "r")) == NULL)
		CU(ERR);
	if (fseek(fpLsys, 0L, SEEK_END) == -1L)
		CU(ERR);
	if ((wLsys = ftell(fpLsys)) == -1L)
		CU(ERR);
	if (fseek(fpLsys, 0L, SEEK_SET) == -1L)
		CU(ERR);
	if ((cpBuf = (char *)malloc(wLsys)) == NULL)
		CU(ERR);
	if ((fread(cpBuf, wLsys, 1, fpLsys) != 1) && ferror(fpLsys))
		CU(ERR);
	if ((lb = lbopen(cpBuf, cpBuf + wLsys -1)) == NULL)
		CU(ERR);
	if (lbseek(lb, 0, LBSEEK_SET) == NULL)
		CU(ERR);

	wHost = strlen(cpHost);

	do {
		if (	(lb->lb_wLnCur <= wHost)
			||	(strnicmp(lb->lb_cpLnCur, cpHost, wHost) != 0)	)
			continue;
		cp = lb->lb_cpLnCur + wHost;
		while ( (*cp == SP) || (*cp == HT) )
			++cp;
		if ( (*cp == NL) || (*cp == NUL) )
			continue;
		timeentry = cp;
		while ( (*cp != SP) && (*cp != HT) && (*cp != NL) && (*cp != NUL) )
			++cp;
		*cp = NUL;
		CU( cmptime(timeentry) );
	} while (lbseek(lb, 1, LBSEEK_CUR));

	rc = -1;

CUS:
	if (lb)
		lbfree(lb);
	if (fpLsys)
		fclose(fpLsys);
	if (cpBuf)
		free(cpBuf);
	return rc;
}


int lsysbps(char *cpLsys, char *cpHost)
{
	int rc;
	FILE *fp = NULL;
	char *buf = NULL;
	long len;
	LB *lb = NULL;
	int i;
	char *cp;
	int wHost;

	if ((fp = fopen(cpLsys, "r")) == NULL)
		CU(0);
	if (fseek(fp, 0L, SEEK_END) == -1L)
		CU(0);
	if ((len = ftell(fp)) == -1L)
		CU(0);
	if (fseek(fp, 0L, SEEK_SET) == -1L)
		CU(0);
	if ((buf = (char *)malloc(len)) == NULL)
		CU(0);
	if ((fread(buf, len, 1, fp) != 1) && ferror(fp))
		CU(0);
	if ((lb = lbopen(buf, buf+len-1)) == NULL)
		CU(0);
	if (lbseek(lb, 0, LBSEEK_SET) == NULL)
		CU(0);

	wHost = strlen(cpHost);

	do {
		if (	(lb->lb_wLnCur <= wHost)
			||	(strnicmp(lb->lb_cpLnCur, cpHost, wHost) != 0)	)
			continue;
		for (i = 0, cp = lb->lb_cpLnCur; cp != NULL; cp = strpbrk(cp, " \t"), i++) {
			if ( (*cp == ' ') || (*cp == '\t') )
				++cp;
			if (i >= 3)
				break;
		}
		CU(atoi(cp));

	} while (lbseek(lb, 1, LBSEEK_CUR));

	rc = 0;

	CUS:
	if (lb)
		lbfree(lb);
	if (buf)
		free(buf);
	if (fp)
		fclose(fp);
	return rc;
}

