#if defined( LINUX )
#include "innbbsconf.h"
#include "bbslib.h"
#include <varargs.h>
#else
#include <varargs.h>
#include "innbbsconf.h"
#include "bbslib.h"
#endif

char    INNBBSCONF[MAXPATHLEN];
char    INNDHOME[MAXPATHLEN];
char    HISTORY[MAXPATHLEN];
char    LOGFILE[MAXPATHLEN];
char    MYBBSID[MAXPATHLEN];
char    ECHOMAIL[MAXPATHLEN];
char    BBSFEEDS[MAXPATHLEN];
char    LOCALDAEMON[MAXPATHLEN];
char    FILTERCTL[MAXPATHLEN];

int     His_Maint_Min = HIS_MAINT_MIN;
int     His_Maint_Hour = HIS_MAINT_HOUR;
int     Expiredays = EXPIREDAYS;

nodelist_t *NODELIST = NULL, **NODELIST_BYNODE = NULL;
newsfeeds_t *NEWSFEEDS = NULL, **NEWSFEEDS_BYBOARD = NULL;
#if  defined(FILTER) && defined(WITH_ECHOMAIL)
filter_t *FILTERLIST = NULL;
static char *FILTER_BUF;
int     FILTERCOUNT;
#endif

static char *NODELIST_BUF, *NEWSFEEDS_BUF;
int     NFCOUNT, NLCOUNT;
int     LOCALNODELIST = 0, NONENEWSFEEDS = 0;
#ifndef _PATH_BBSHOME
#define _PATH_BBSHOME "/u/staff/bbsroot/csie_util/bntpd/home"
#endif

char    BBSHOME[] = _PATH_BBSHOME;
static FILE *bbslogfp;

static int
        verboseFlag = 0;

static char *
        verboseFilename = NULL;
static char verbosename[MAXPATHLEN];
verboseon(filename)
char   *filename;
{
	verboseFlag = 1;
	if (filename != NULL) {
		if (strchr(filename, '/') == NULL) {
			sprintf(verbosename, "%s/innd/%s", BBSHOME, filename);
			filename = verbosename;
		}
	}
	verboseFilename = filename;
}
verboseoff()
{
	verboseFlag = 0;
}
setverboseon()
{
	verboseFlag = 1;
}
isverboselog()
{
	return verboseFlag;
}
setverboseoff()
{
	verboseoff();
	if (bbslogfp != NULL) {
		fclose(bbslogfp);
		bbslogfp = NULL;
	}
}
verboselog(va_alist)
va_dcl
{
	va_list ap;
	register char *fmt;
	char    datebuf[40];
	time_t  now;
	if (verboseFlag == 0)
		return;

	va_start(ap);

	time(&now);
	strftime(datebuf, sizeof(datebuf), "%b %d %X ", localtime(&now));

	if (bbslogfp == NULL) {
		if (verboseFilename != NULL)
			bbslogfp = fopen(verboseFilename, "a");
		else
			bbslogfp = fdopen(1, "a");
	}
	if (bbslogfp == NULL) {
		va_end(ap);
		return;
	}
	fmt = va_arg(ap, char *);
	fprintf(bbslogfp, "%s[%d] ", datebuf, getpid());
	vfprintf(bbslogfp, fmt, ap);
	fflush(bbslogfp);
	va_end(ap);
}
#ifdef PalmBBS
xbbslog(va_alist)
#else
bbslog(va_alist)
#endif
va_dcl
{
	va_list ap;
	register char *fmt;
	char    datebuf[40];
	time_t  now;
	va_start(ap);

	time(&now);
	strftime(datebuf, sizeof(datebuf), "%b %d %X ", localtime(&now));

	if (bbslogfp == NULL) {
		bbslogfp = fopen(LOGFILE, "a");
	}
	if (bbslogfp == NULL) {
		va_end(ap);
		return;
	}
	fmt = va_arg(ap, char *);
	fprintf(bbslogfp, "%s[%d] ", datebuf, getpid());
	vfprintf(bbslogfp, fmt, ap);
	fflush(bbslogfp);
	va_end(ap);
}
initial_bbs(outgoing)
char   *outgoing;
{
	FILE   *FN;
	struct stat st;
	int     fd, i;
	char   *bbsnameptr = NULL;
/* reopen bbslog */
	if (bbslogfp != NULL) {
		fclose(bbslogfp);
		bbslogfp = NULL;
	}
#ifdef WITH_ECHOMAIL
	init_echomailfp();
	init_bbsfeedsfp();
#endif

	LOCALNODELIST = 0, NONENEWSFEEDS = 0;
	sprintf(INNDHOME, "%s/innd", BBSHOME);
	sprintf(HISTORY, "%s/history", INNDHOME);
	sprintf(LOGFILE, "%s/bbslog", INNDHOME);
	sprintf(ECHOMAIL, "%s/echomail.log", BBSHOME);
	sprintf(LOCALDAEMON, "%s/.innbbsd", INNDHOME);
	sprintf(INNBBSCONF, "%s/innbbs.conf", INNDHOME);
	sprintf(BBSFEEDS, "%s/bbsfeeds.log", INNDHOME);

#if  defined(FILTER) && defined(WITH_ECHOMAIL)
	sprintf(FILTERCTL, "%s/filter.ctl", INNDHOME);
#endif

	if (isfile(INNBBSCONF)) {
		FILE   *conf;
		char    buffer[MAXPATHLEN];
		conf = fopen(INNBBSCONF, "r");
		if (conf != NULL) {
			while (fgets(buffer, sizeof buffer, conf) != NULL) {
				char   *ptr, *front = NULL, *value = NULL,
				       *value2 = NULL, *value3 = NULL;
				if (buffer[0] == '#' || buffer[0] == '\n')
					continue;
				for (front = buffer; *front && isspace(*front); front++);
				for (ptr = front; *ptr && !isspace(*ptr); ptr++);
				if (*ptr == '\0')
					continue;
				*ptr++ = '\0';
				for (; *ptr && isspace(*ptr); ptr++);
				if (*ptr == '\0')
					continue;
				value = ptr++;
				for (; *ptr && !isspace(*ptr); ptr++);
				if (*ptr) {
					*ptr++ = '\0';
					for (; *ptr && isspace(*ptr); ptr++);
					value2 = ptr++;
					for (; *ptr && !isspace(*ptr); ptr++);
					if (*ptr) {
						*ptr++ = '\0';
						for (; *ptr && isspace(*ptr); ptr++);
						value3 = ptr++;
						for (; *ptr && !isspace(*ptr); ptr++);
						if (*ptr) {
							*ptr++ = '\0';
						}
					}
				}
				if (strcasecmp(front, "expiredays") == 0) {
					Expiredays = atoi(value);
					if (Expiredays < 0) {
						Expiredays = EXPIREDAYS;
					}
				} else if (strcasecmp(front, "expiretime") == 0) {
					ptr = strchr(value, ':');
					if (ptr == NULL) {
						fprintf(stderr, "Syntax error in innbbs.conf\n");
					} else {
						*ptr++ = '\0';
						His_Maint_Hour = atoi(value);
						His_Maint_Min = atoi(ptr);
						if (His_Maint_Hour < 0)
							His_Maint_Hour = HIS_MAINT_HOUR;
						if (His_Maint_Min < 0)
							His_Maint_Min = HIS_MAINT_MIN;
					}
				} else if (strcasecmp(front, "newsfeeds") == 0) {
					if (strcmp(value, "none") == 0)
						NONENEWSFEEDS = 1;
				} else if (strcasecmp(front, "nodelist") == 0) {
					if (strcmp(value, "local") == 0)
						LOCALNODELIST = 1;
				}	/* else if (
					 * strcasecmp(front,"newsfeeds") ==
					 * 0) { printf("newsfeeds %s\n",
					 * value); } else if (
					 * strcasecmp(front,"nodelist") == 0)
					 * { printf("nodelist %s\n", value);
					 * } else if (
					 * strcasecmp(front,"bbsname") == 0)
					 * { printf("bbsname %s\n", value); } */
			}
			fclose(conf);
		}
	}
#ifdef WITH_ECHOMAIL
	bbsnameptr = (char *) fileglue("%s/bbsname.bbs", INNDHOME);
	if ((FN = fopen(bbsnameptr, "r")) == NULL) {
		fprintf(stderr, "can't open file %s\n", bbsnameptr);
		return 0;
	}
	while (fscanf(FN, "%s", MYBBSID) != EOF);
	fclose(FN);
	if (!isdir(fileglue("%s/out.going", BBSHOME))) {
		mkdir((char *) fileglue("%s/out.going", BBSHOME), 0750);
	}
	if (NONENEWSFEEDS == 0) {
#if  defined(FILTER) && defined(WITH_ECHOMAIL)
		readfilterfile(INNDHOME);
#endif
		readnffile(INNDHOME);
	}
	if (LOCALNODELIST == 0) {
		if (readnlfile(INNDHOME, outgoing) != 0)
			return 0;
	}
#endif
	return 1;
}

static int
nf_byboardcmp(a, b)
newsfeeds_t **a, **b;
{
/*
   if (!a || !*a || !(*a)->board) return -1;
   if (!b || !*b || !(*b)->board) return 1;
*/
	return strcasecmp((*a)->board, (*b)->board);
}

static int
nfcmp(a, b)
newsfeeds_t *a, *b;
{
/*
   if (!a || !a->newsgroups) return -1;
   if (!b || !b->newsgroups) return 1;
*/
	return strcasecmp(a->newsgroups, b->newsgroups);
}

static int
nlcmp(a, b)
nodelist_t *a, *b;
{
/*
   if (!a || !a->host) return -1;
   if (!b || !b->host) return 1;
*/
	return strcasecmp(a->host, b->host);
}

static int
nl_bynodecmp(a, b)
nodelist_t **a, **b;
{
/*
   if (!a || !*a || !(*a)->node) return -1;
   if (!b || !*b || !(*b)->node) return 1;
*/
	return strcasecmp((*a)->node, (*b)->node);
}
/* read in newsfeeds.bbs and nodelist.bbs */
readnlfile(inndhome, outgoing)
char   *inndhome;
char   *outgoing;
{
	FILE   *fp;
	char    buff[1024];
	struct stat st;
	int     i, count, j;
	char   *ptr, *nodelistptr;
	static  lastcount = 0;
	sprintf(buff, "%s/nodelist.bbs", inndhome);
	fp = fopen(buff, "r");
	if (fp == NULL) {
		fprintf(stderr, "open fail %s", buff);
		return -1;
	}
	if (fstat(fileno(fp), &st) != 0) {
		fprintf(stderr, "stat fail %s", buff);
		return -1;
	}
	if (NODELIST_BUF == NULL) {
		NODELIST_BUF = (char *) mymalloc(st.st_size + 1);
	} else {
		NODELIST_BUF = (char *) myrealloc(NODELIST_BUF, st.st_size + 1);
	}
	i = 0, count = 0;
	*NODELIST_BUF = '\0';
	while (fgets(buff, sizeof buff, fp) != NULL) {
		if (buff[0] == '#')
			continue;
		if (buff[0] == '\n')
			continue;
		strcpy(NODELIST_BUF + i, buff);
		i += strlen(buff);
		count++;
	}
	fclose(fp);
	if (NODELIST == NULL) {
		NODELIST = (nodelist_t *) mymalloc(sizeof(nodelist_t) * (count + 1));
		NODELIST_BYNODE = (nodelist_t **) mymalloc(sizeof(nodelist_t *) * (count + 1));
	} else {
		NODELIST = (nodelist_t *) myrealloc(NODELIST, sizeof(nodelist_t) * (count + 1));
		NODELIST_BYNODE = (nodelist_t **) myrealloc(NODELIST_BYNODE, sizeof(nodelist_t *) * (count + 1));
	}
	for (i = lastcount; i < count; i++) {
		NODELIST[i].feedfp = NULL;
	}
	lastcount = count;
	NLCOUNT = 0;
	for (ptr = NODELIST_BUF; (nodelistptr = (char *) strchr(ptr, '\n')) != NULL; ptr = nodelistptr + 1, NLCOUNT++) {
		char   *nptr, *bptr, *pptr, *tptr;
		*nodelistptr = '\0';
		NODELIST[NLCOUNT].host = "";
		NODELIST[NLCOUNT].exclusion = "";
		NODELIST[NLCOUNT].node = "";
		NODELIST[NLCOUNT].protocol = "IHAVE(119)";
		NODELIST[NLCOUNT].comments = "";
		NODELIST_BYNODE[NLCOUNT] = NODELIST + NLCOUNT;
		for (nptr = ptr; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0') {
			bbslog("nodelist.bbs %d entry read error\n", NLCOUNT);
			return -1;
		}
		/* NODELIST[NLCOUNT].id = nptr; */
		NODELIST[NLCOUNT].node = nptr;
		for (nptr++; *nptr && !isspace(*nptr);)
			nptr++;
		if (*nptr == '\0') {
			bbslog("nodelist.bbs node %d entry read error\n", NLCOUNT);
			return -1;
		}
		*nptr = '\0';
		if ((tptr = strchr(NODELIST[NLCOUNT].node, '/'))) {
			*tptr = '\0';
			NODELIST[NLCOUNT].exclusion = tptr + 1;
		} else {
			NODELIST[NLCOUNT].exclusion = "";
		}
		for (nptr++; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		if (*nptr == '+' || *nptr == '-') {
			NODELIST[NLCOUNT].feedtype = *nptr;
			if (NODELIST[NLCOUNT].feedfp != NULL) {
				fclose(NODELIST[NLCOUNT].feedfp);
			}
			if (NODELIST[NLCOUNT].feedtype == '+')
				if (outgoing != NULL) {
					NODELIST[NLCOUNT].feedfp = fopen((char *) fileglue("%s/out.going/%s.%s", BBSHOME, NODELIST[NLCOUNT].node, outgoing), "a");
				}
			nptr++;
		} else {
			NODELIST[NLCOUNT].feedtype = ' ';
		}
		NODELIST[NLCOUNT].host = nptr;
		for (nptr++; *nptr && !isspace(*nptr);)
			nptr++;
		if (*nptr == '\0') {
			continue;
		}
		*nptr = '\0';
		for (nptr++; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		NODELIST[NLCOUNT].protocol = nptr;
		for (nptr++; *nptr && !isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		*nptr = '\0';
		for (nptr++; *nptr && strchr(" \t\r\n", *nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		NODELIST[NLCOUNT].comments = nptr;
	}
	qsort(NODELIST, NLCOUNT, sizeof(nodelist_t), nlcmp);
	qsort(NODELIST_BYNODE, NLCOUNT, sizeof(nodelist_t *), nl_bynodecmp);
	return 0;
}
#if  defined(FILTER) && defined(WITH_ECHOMAIL)
readfilterfile(inndhome)
char   *inndhome;
{

	FILE   *fp;
	char    buff[1024];
	struct stat st;
	int     i, count;
	char   *ptr, *filterptr;
	sprintf(buff, "%s/filter.ctl", inndhome);
	fp = fopen(buff, "r");
	if (fp == NULL) {
		fprintf(stderr, "open fail %s", buff);
		return -1;
	}
	if (fstat(fileno(fp), &st) != 0) {
		fprintf(stderr, "stat fail %s", buff);
		return -1;
	}
	if (FILTER_BUF == NULL) {
		FILTER_BUF = (char *) mymalloc(st.st_size + 1);
	} else {
		FILTER_BUF = (char *) myrealloc(FILTER_BUF, st.st_size + 1);
	}
	*FILTER_BUF = '\0';
	i = 0, count = 0;
	while (fgets(buff, sizeof buff, fp) != NULL) {
		if (buff[0] == '#')
			continue;
		if (buff[0] == '\n')
			continue;
		strcpy(FILTER_BUF + i, buff);
		i += strlen(buff);
		count++;
	}
	fclose(fp);
	if (FILTERLIST == NULL) {
		FILTERLIST = (filter_t *) mymalloc(sizeof(filter_t) * (count + 1));
	} else {
		FILTERLIST = (filter_t *) myrealloc(FILTERLIST, sizeof(filter_t) * (count + 1));
	}
	FILTERCOUNT = 0;
	for (ptr = FILTER_BUF; (filterptr = (char *) strchr(ptr, '\n')) != NULL; ptr = filterptr + 1, FILTERCOUNT++) {
		char   *nptr, *bptr, *pptr;
		*filterptr = '\0';
		FILTERLIST[FILTERCOUNT].group = "";
		FILTERLIST[FILTERCOUNT].rcmdfilter = "";
		FILTERLIST[FILTERCOUNT].scmdfilter = "";
		for (nptr = ptr; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		FILTERLIST[FILTERCOUNT].group = nptr;
		nptr = strchr(nptr + 1, ':');
		if (*nptr == '\0')
			continue;
		*nptr = '\0';
		for (nptr = nptr + 1; *nptr && isspace(*nptr);)
			nptr++;
		FILTERLIST[FILTERCOUNT].rcmdfilter = nptr;
		nptr = strchr(nptr, ':');
		if (*nptr == '\0')
			continue;
		*nptr = '\0';
		for (nptr = nptr + 1; *nptr && isspace(*nptr);)
			nptr++;
		FILTERLIST[FILTERCOUNT].scmdfilter = nptr;
	}
}

filter_t *
search_filter(group)
char   *group;
{
	int     i;
	for (i = 0; i < FILTERCOUNT; ++i) {
		if (filtermatch(0, group, FILTERLIST[i].group))
			return FILTERLIST + i;
	}
	return NULL;
}
#endif

readnffile(inndhome)
char   *inndhome;
{
	FILE   *fp;
	char    buff[1024];
	struct stat st;
	int     i, count;
	char   *ptr, *newsfeedsptr;
	sprintf(buff, "%s/newsfeeds.bbs", inndhome);
	fp = fopen(buff, "r");
	if (fp == NULL) {
		fprintf(stderr, "open fail %s", buff);
		return -1;
	}
	if (fstat(fileno(fp), &st) != 0) {
		fprintf(stderr, "stat fail %s", buff);
		return -1;
	}
	if (NEWSFEEDS_BUF == NULL) {
		NEWSFEEDS_BUF = (char *) mymalloc(st.st_size + 1);
	} else {
		NEWSFEEDS_BUF = (char *) myrealloc(NEWSFEEDS_BUF, st.st_size + 1);
	}
	*NEWSFEEDS_BUF = '\0';
	i = 0, count = 0;
	while (fgets(buff, sizeof buff, fp) != NULL) {
		if (buff[0] == '#')
			continue;
		if (buff[0] == '\n')
			continue;
		strcpy(NEWSFEEDS_BUF + i, buff);
		i += strlen(buff);
		count++;
	}
	fclose(fp);
	if (NEWSFEEDS == NULL) {
		NEWSFEEDS = (newsfeeds_t *) mymalloc(sizeof(newsfeeds_t) * (count + 1));
		NEWSFEEDS_BYBOARD = (newsfeeds_t **) mymalloc(sizeof(newsfeeds_t *) * (count + 1));
	} else {
		NEWSFEEDS = (newsfeeds_t *) myrealloc(NEWSFEEDS, sizeof(newsfeeds_t) * (count + 1));
		NEWSFEEDS_BYBOARD = (newsfeeds_t **) myrealloc(NEWSFEEDS_BYBOARD, sizeof(newsfeeds_t *) * (count + 1));
	}
	NFCOUNT = 0;
	for (ptr = NEWSFEEDS_BUF; (newsfeedsptr = (char *) strchr(ptr, '\n')) != NULL; ptr = newsfeedsptr + 1, NFCOUNT++) {
		char   *nptr, *bptr, *pptr;
		*newsfeedsptr = '\0';
		NEWSFEEDS[NFCOUNT].newsgroups = "";
		NEWSFEEDS[NFCOUNT].board = "";
		NEWSFEEDS[NFCOUNT].path = NULL;
		NEWSFEEDS_BYBOARD[NFCOUNT] = NEWSFEEDS + NFCOUNT;
		for (nptr = ptr; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		NEWSFEEDS[NFCOUNT].newsgroups = nptr;
		for (nptr++; *nptr && !isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		*nptr = '\0';
		for (nptr++; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		NEWSFEEDS[NFCOUNT].board = nptr;
		for (nptr++; *nptr && !isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		*nptr = '\0';
		for (nptr++; *nptr && isspace(*nptr);)
			nptr++;
		if (*nptr == '\0')
			continue;
		NEWSFEEDS[NFCOUNT].path = nptr;
		for (nptr++; *nptr && !strchr("\r\n", *nptr);)
			nptr++;
		/* if (*nptr == '\0') continue; */
		*nptr = '\0';
	}


#if  defined(FILTER) && defined(WITH_ECHOMAIL)
	for (i = 0; i < NFCOUNT; i++) {
		newsfeeds_t *nfptr;
		filter_t *fptr;
		char   *ngptr, *ptr;
		int     found;
		nfptr = NEWSFEEDS + i;
		for (found = 0, ngptr = nfptr->newsgroups, ptr = strchr(ngptr, ',');
			ngptr && *ngptr && !found; ptr = strchr(ngptr, ',')) {
			if (ptr)
				*ptr = '\0';
			fptr = (filter_t *) search_filter(ngptr);
			if (fptr) {
				nfptr->rcmdfilter = fptr->rcmdfilter;
				nfptr->scmdfilter = fptr->scmdfilter;
				nfptr->rfilter = (FuncPtr) search_filtercmd(fptr->rcmdfilter);
				nfptr->sfilter = (FuncPtr) search_filtercmd(fptr->scmdfilter);
				found = 1;
			} else {
				nfptr->rcmdfilter = nfptr->scmdfilter = NULL;
				nfptr->rfilter = nfptr->sfilter = NULL;
			}
			if (ptr) {
				*ptr = ',';
				ngptr = ptr + 1;
			} else {
				break;
			}
		}
	}
#endif
	qsort(NEWSFEEDS, NFCOUNT, sizeof(newsfeeds_t), nfcmp);
	qsort(NEWSFEEDS_BYBOARD, NFCOUNT, sizeof(newsfeeds_t *), nf_byboardcmp);
}

newsfeeds_t *
search_board(board)
char   *board;
{
	newsfeeds_t nft, *nftptr, **find;
	if (NONENEWSFEEDS)
		return NULL;
	nft.board = board;
	nftptr = &nft;
	find = (newsfeeds_t **) bsearch((char *) &nftptr, NEWSFEEDS_BYBOARD, NFCOUNT, sizeof(newsfeeds_t *), nf_byboardcmp);
	if (find != NULL)
		return *find;
	return NULL;
}

nodelist_t *
search_nodelist_bynode(node)
char   *node;
{
	nodelist_t nlt, *nltptr, **find;
	if (LOCALNODELIST)
		return NULL;
	nlt.node = node;
	nltptr = &nlt;
	find = (nodelist_t **) bsearch((char *) &nltptr, NODELIST_BYNODE, NLCOUNT, sizeof(nodelist_t *), nl_bynodecmp);
	if (find != NULL)
		return *find;
	return NULL;
}


nodelist_t *
search_nodelist(site, identuser)
char   *site;
char   *identuser;
{
	nodelist_t nlt, *find;
	char    buffer[1024];
	if (LOCALNODELIST)
		return NULL;
	nlt.host = site;
	find = (nodelist_t *) bsearch((char *) &nlt, NODELIST, NLCOUNT, sizeof(nodelist_t), nlcmp);
	if (find == NULL && identuser != NULL) {
		sprintf(buffer, "%s@%s", identuser, site);
		nlt.host = buffer;
		find = (nodelist_t *) bsearch((char *) &nlt, NODELIST, NLCOUNT, sizeof(nodelist_t), nlcmp);
	}
	return find;
}

newsfeeds_t *
search_group(newsgroup)
char   *newsgroup;
{
	newsfeeds_t nft, *find;
	if (NONENEWSFEEDS)
		return NULL;
	nft.newsgroups = newsgroup;
	find = (newsfeeds_t *) bsearch((char *) &nft, NEWSFEEDS, NFCOUNT, sizeof(newsfeeds_t), nfcmp);
	return find;
}

char   *
ascii_date(now)
time_t  now;
{
	static char datebuf[40];
	/*
	 * time_t now; time(&now);
	 */
	strftime(datebuf, sizeof(datebuf), "%d %b %Y %X GMT", gmtime(&now));
	return datebuf;
}

char   *
restrdup(ptr, string)
char   *ptr;
char   *string;
{
	int     len;
	if (string == NULL) {
		if (ptr != NULL)
			*ptr = '\0';
		return ptr;
	}
	len = strlen(string) + 1;
	if (ptr != NULL) {
		ptr = (char *) myrealloc(ptr, len);
	} else
		ptr = (char *) mymalloc(len);
	strcpy(ptr, string);
	return ptr;
}



void   *
mymalloc(size)
int     size;
{
	char   *ptr = (char *) malloc(size);
	if (ptr == NULL) {
		fprintf(stderr, "cant allocate memory\n");
		syslog(LOG_ERR, "cant allocate memory %m");
		exit(1);
	}
	return ptr;
}

void   *
myrealloc(optr, size)
void   *optr;
int     size;
{
	char   *ptr = (char *) realloc(optr, size);
	if (ptr == NULL) {
		fprintf(stderr, "cant allocate memory\n");
		syslog(LOG_ERR, "cant allocate memory %m");
		exit(1);
	}
	return ptr;
}
testandmkdir(dir)
char   *dir;
{
	if (!isdir(dir)) {
		char    path[MAXPATHLEN + 12];
		sprintf(path, "mkdir -p %s", dir);
		system(path);
	}
}

static char splitbuf[2048];
static char joinbuf[1024];
#define MAXTOK 50
static char *Splitptr[MAXTOK];
char  **
split(line, pat)
char   *line, *pat;
{
	char   *p;
	int     i;
	for (i = 0; i < MAXTOK; ++i)
		Splitptr[i] = NULL;
	strncpy(splitbuf, line, sizeof splitbuf - 1);
	/* printf("%d %d\n",strlen(line),strlen(splitbuf)); */
	splitbuf[sizeof splitbuf - 1] = '\0';
	for (i = 0, p = splitbuf; *p && i < MAXTOK - 1;) {
		for (Splitptr[i++] = p; *p && !strchr(pat, *p); p++);
		if (*p == '\0')
			break;
		for (*p++ = '\0'; *p && strchr(pat, *p); p++);
	}
	return Splitptr;
}

char  **
BNGsplit(line)
char   *line;
{
	char  **ptr = split(line, ",");
	newsfeeds_t *nf1, *nf2;
	char   *n11, *n12, *n21, *n22;
	int     i, j;
	for (i = 0; ptr[i] != NULL; i++) {
		nf1 = (newsfeeds_t *) search_group(ptr[i]);
		for (j = i + 1; ptr[j] != NULL; j++) {
			if (strcmp(ptr[i], ptr[j]) == 0) {
				*ptr[j] = '\0';
				continue;
			}
			nf2 = (newsfeeds_t *) search_group(ptr[j]);
			if (nf1 && nf2) {
				if (strcmp(nf1->board, nf2->board) == 0) {
					*ptr[j] = '\0';
					continue;
				}
				for (n11 = nf1->board, n12 = (char *) strchr(n11, ',');
					n11 && *n11; n12 = (char *) strchr(n11, ',')) {
					if (n12)
						*n12 = '\0';
					for (n21 = nf2->board, n22 = (char *) strchr(n21, ',');
						n21 && *n21; n22 = (char *) strchr(n21, ',')) {
						if (n22)
							*n22 = '\0';
						if (strcmp(n11, n21) == 0) {
							*n21 = '\t';
						}
						if (n22) {
							*n22 = ',';
							n21 = n22 + 1;
						} else
							break;
					}
					if (n12) {
						*n12 = ',';
						n11 = n12 + 1;
					} else
						break;
				}
			}
		}
	}
	return ptr;
}

char  **
ssplit(line, pat)
char   *line, *pat;
{
	char   *p;
	int     i;
	for (i = 0; i < MAXTOK; ++i)
		Splitptr[i] = NULL;
	strncpy(splitbuf, line, 1024);
	for (i = 0, p = splitbuf; *p && i < MAXTOK;) {
		for (Splitptr[i++] = p; *p && !strchr(pat, *p); p++);
		if (*p == '\0')
			break;
		*p = 0;
		p++;
/*	   for (*p='\0'; strchr(pat,*p);p++);*/
	}
	return Splitptr;
}

char   *
join(lineptr, pat, num)
char  **lineptr, *pat;
int     num;
{
	int     i;
	joinbuf[0] = '\0';
	if (lineptr[0] != NULL)
		strncpy(joinbuf, lineptr[0], 1024);
	else {
		joinbuf[0] = '\0';
		return joinbuf;
	}
	for (i = 1; i < num; i++) {
		strcat(joinbuf, pat);
		if (lineptr[i] != NULL)
			strcat(joinbuf, lineptr[i]);
		else
			break;
	}
	return joinbuf;
}

char   *
parselocaltime(date_buf)
char   *date_buf;
{
	static char buffer[40];
	char    week[30], mon[30], day[30], time[30], year[30];
	/* add null to prevent from long string */
	if (strlen(date_buf) > 30)
		date_buf[30] = '\0';
	sscanf(date_buf, "%s %s %s %s %s", week, mon, day, time, year);
	sprintf(buffer, "%.4s %.4s %.4s %.10s", day, mon, year, time);
	return buffer;
}


#ifdef BBSLIB
main()
{
	initial_bbs("feed");
	printf("%s\n", ascii_date());
}
#endif
