#ifdef WIN32
#include <direct.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "dfeed.h"
static char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
#define BFSZ 1000
char *file_config(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/%s",ini_get(I_CONFIG),s);
	return bf;
}
char *file_log(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/%s",ini_get(I_LOGDIR),s);
	return bf;
}
int file_mtime(char *s)
{
	FILE *f;
	struct stat st;
	f = fopen(s,"r");
	if (f==NULL) return 0;
	fstat(fileno(f),&st);
	fclose(f);
	return (int) st.st_mtime;
}

int host_id(void)
{
	imsg("Should get hostid from config file \n");
	return 23;
}
char *lib_web_date(void)
{
	static char bf[BFSZ];
	static char xx[BFSZ];
	static char hour[BFSZ];
	time_t t;
	struct tm *tt;
	t = time(NULL);
	tt = gmtime(&t);
	strcpy(xx,ctime(&t));
	ncpy(hour,xx+11,8);
	sprintf(bf,"%s, %0.2d %s 19%d %s GMT",days[tt->tm_wday],tt->tm_mday,months[tt->tm_mon],tt->tm_year,hour);
	return bf;
	/* Date: Saturday, 27-Sep-97 21:28:07 GMT*/
}
char *ncpy(char *dst, const char *src, int len)
{
        char *xdst = dst;
        int xlen = len;
        for (;(*src !=0) && (len>0); ) {*dst++  = *src++; len--;}
        *dst++ = 0;
        xdst[xlen] = 0;
        return xdst;
}
char *mygetenv(char *s)
{
	imsg("mygetenv\n");
	return "";
}
int get_line(char *item, int *upto, char *bf, int bfsz)
{
	char *s;
	int len,xlen;;
	for (s=item+*upto;*s!=0;s++) {
		if (*s=='\r') {
			len = s - (item + *upto);
			xlen = len;
			if (xlen>=bfsz) xlen = bfsz-1;
			ncpy(bf,item + *upto,xlen);
			*upto += len + 2;
			return TRUE;
		}
	}
	return FALSE;

}
int get_line_lf(char *item, int *upto, char *bf, int bfsz)
{
	char *s;
	int len,xlen;;
	for (s=item+*upto;*s!=0;s++) {
		if (*s=='\n') {
			len = s - (item + *upto);
			xlen = len;
			if (xlen>=bfsz) xlen = bfsz-1;
			ncpy(bf,item + *upto,xlen);
			*upto += len + 1;
			return TRUE;
		}
	}
	return FALSE;

}
char *file_tpl(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"tpl/%s",s);
	return bf;
}
char *file_user_file(int uid, char *fname)
{
	static char bf[BFSZ];
	sprintf(bf,"users/u%d/%d/%s",(int) (uid / 100),uid,fname);

	return bf;
} /* 100K users = 1000 directories */
char *file_user(int uid)
{
	static char bf[BFSZ];
	sprintf(bf,"users/u%d/%d/u_info.dat",(int) (uid / 100),uid);

	return bf;
} /* 100K users = 1000 directories */
char *file_root(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"%s",s);
	return bf;
}
char *file_item_idx(int gid, int fn)
{
	char bf[BFSZ];
	static char bf2[BFSZ];
	sprintf(bf,"items/%d/i_%d.idx",gid,fn);
	strcpy(bf2,file_root(bf));
	return bf2;
}
char *file_item_itm(int gid, int fn)
{
	char bf[BFSZ];
	static char bf2[BFSZ];
	sprintf(bf,"items/%d/i_%d.itm",gid,fn);
	strcpy(bf2,file_root(bf));
	return bf2;
}


int token_split(char *s, char *p[], char *sep, int tmax)
{
        int n=0;

        for (;*s!=0;) {
                s += strspn(s,sep);  /* Skip spaces */
                if (*s==0) break;
                p[n++] = s;
                s += strcspn(s,sep);  /* Find end of word */
                if (*s==0) break;               
                *s = 0; s++;
                if ((n+1)>=tmax) {
                        imsg("Too many tokens in this header line %d %d\n",n,tmax);
                        break;
                }
        }
        p[n] = NULL;
        return n;
}
int lib_mkdir(char *s)
{
   int r;
   char bf[BFSZ];
   
   ncpy(bf,s,BFSZ-1);
   if (strlen(s)<2) return TRUE;
   s = bf+2;
   for (;*s!=0; s++)  {
      if ((*s=='/') || (*s == '\\'))  {
         *s = 0;
#ifdef WIN32
         r = mkdir(bf);
#else
         r = mkdir(bf,0770);
#endif
         *s = '/';
      }
   }
   return TRUE;
}
int lib_exists(char *s)
{
        FILE *f;
        int r;
        f = fopen(s,"r");
	if (f==NULL) {
		if (errno!=ENOENT) imsg("lib_exists(%s) %s\n",s,strerror(errno));
	}
        if (f==NULL) r = FALSE;
        else r = TRUE;
        if (f!=NULL) fclose(f);
        return r;
}

char *strstrnc(char *str, char *substr)
{
	char *s;
	char xstr[BFSZ];
	char xsubstr[BFSZ];
	ncpy(xstr,str,BFSZ-1);
	ncpy(xsubstr,substr,BFSZ-1);
	strlwr(xstr);
	strlwr(xsubstr);
	s = strstr(xstr,xsubstr);
	if (s==NULL) return NULL;
	return str + (s-xstr);
}
char *bar_encode(char *s)
{
	char *ss=s;
	for (;*s!=0;s++) {
		if (*s=='|') *s = ':';
		if (*s=='\r') *s = (char) 200;
		if (*s=='\n') *s = (char) 201;
	}
	return ss;
}
char *bar_decode(char *s)
{
	char *ss=s;
	for (;*s!=0;s++) {
		if (*s=='|') *s = ':';
		if (*s==200) *s = ' ';
		if (*s==201) *s = '\n';
	}
	return ss;
}
#ifdef WIN32
char *file_exe(char *fname)
{
        static char sysdir[BFSZ];
        static char binpath[BFSZ];
        GetSystemDirectory(sysdir,BFSZ-1);
        sprintf(binpath,"%s\\%s",sysdir,fname);
        return binpath;
}
#else
char *file_exe(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/%s",ini_get(I_CONFIG),s);
	return bf;
}
#endif


char *file_work(char *s)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/%s",ini_get(I_WORKAREA),s);
	return bf;
}
char *file_dnews(void)
{
#ifdef WIN32
	return file_exe("dnews.conf");	
#else
	return "/etc/dnews.conf";
#endif
}
char *mystrchr(const char *s, int c)
{
        for (;*s!=0;s++) if (*s==c) return (char *) s;
        return NULL;
}

char *mystrstr(const char *s, const char *w)
{
        const char *ww = w;
        int len; 

        len = strlen(w);
        for (;*s!=0;) {
                s = mystrchr(s,*w);
                if (s==NULL) return NULL;
                if (strncmp(s,w,len)==0) return (char *) s;
                s++;
        }
        return NULL;
}
#define xisspace(x) ((x==' ') || (x=='\t'))
char *get_word(char *s,int n) /*comp.os.vms 001 000 m*/
{
        static char tmp[600];
        int i;
        char *ss=s;

        for (;(*ss!=0) && xisspace(*ss);) ss++; 
        for (i=0; i<n && *ss!=0; i++) {
                ss++;
                if (*ss==0) return "";
                for (;(*ss!=0) && !xisspace(*ss);) ss++; 
                for (;(*ss!=0) && xisspace(*ss);) ss++; 
                if (*ss==0) return "";
                ss--; 
                if (ss==NULL) return "";
        }
        if (*ss==0) return "";
        if (xisspace(*ss)) ss++;
        ncpy(tmp,ss,499);
        ss = tmp;
        for (;(*ss!=0) && (!xisspace(*ss));) ss++; 
        if (ss==NULL) ss = tmp + strlen(tmp);
        *ss = 0;
        return tmp; 
}
char *file_bque(int x)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/q_%d.que",file_work("dfeed"),x);
	return bf;
}
char *file_bque_tmp(int x)
{
	static char bf[BFSZ];
	sprintf(bf,"%s/q_%d.tmp",file_work("dfeed"),x);
	return bf;
}
char *feed_fname(char *xname, char *xext);
char *file_send(char *site)
{
	return feed_fname(site,".send");	
}
char *file_feed(char *site)
{
	return feed_fname(site,".feed");	
}
char *file_feedlog(char *site)
{
	return feed_fname(site,".log");	
}
char *file_sendtmp(char *site)
{
	return feed_fname(site,".dfeed");
}
char *file_sendupto(char *site)
{
	return feed_fname(site,".dup");
}
char *feed_fname(char *xname, char *xext)
{
        static char bf[400],ext[100],name[400];
        char *out;
        char *s;
        ncpy(ext,xext,20);
        ncpy(name,xname,200);
        strcpy(bf,file_work(""));
        for (s=name,out=bf+strlen(bf);*s!=0;s++,out++) {
                if (*s=='.') *out = '_';
                else *out = *s;
                if (*out==':') *out = '_'; /* So address:port works */  
        }        
        *out = 0;
        strcat(out,ext);
        return bf;
}
static const unsigned char charmap[] = {
        0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
        0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
        0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
        0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
        0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
        0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
        0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
        0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
        0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
        0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
        0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
        0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
        0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
        0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
        0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
        0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
        0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
        0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
        0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
        0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
        0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
        0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
        0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
        0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
        0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
        0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
        0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
        0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
        0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
        0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
        0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
        0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
};

int strcmpnc(char *s1, char *s2) {
        const unsigned char *cm = charmap,
             *us1 = (const unsigned char *)s1,
             *us2 = (const unsigned char *)s2;

        while (cm[*us1] == cm[*us2++])
                if (*us1++ == '\0')
                        return (0);
        return (cm[*us1] - cm[*--us2]);
}



int strncmpnc(const char *s1, const char *s2, int len)
{
        int i;
        for (i=0;i<len;i++,s1++,s2++) {
                if (tolower(*s1)<tolower(*s2)) return -1;
                if (tolower(*s1)>tolower(*s2)) return 1;
                if (*s1 == 0) return -1;
                if (*s2 == 0) return 1;
        }
        return 0;
}
char *file_spool(int x)
{
	if (x<0) return "bad_spool";
	if (x>=I_LAST_ONE_HERE) return "bad_spool";
	return ini_get(I_SPOOL+x);
}
int file_size(FILE *f)
{
        struct stat bf;
        if (fstat(fileno(f),&bf)!=0) {
		emsg("FATAL Could not get file length\n"); return 0;
	}
        return bf.st_size;
}
int lib_filesize(char *s)
{
        FILE *f;
        int len;
        f = fopen(s,"r");
        if (f==NULL) {
 /*               dmsg("lib: Can't open {%s} {%s} \n",s,strerror(errno));*/
                return 0;
        }
        len = file_size(f);
        fclose(f);
        return len;
}
#ifndef WIN32
int lib_usleep(int x)
{
#ifndef NONANO
	struct timespec rqtp;
	rqtp.tv_sec = x/1000000;
	rqtp.tv_nsec = (x%1000000)*1000;
	nanosleep(&rqtp,NULL);
#else
	usleep(x);
#endif
}
#endif

int lib_msleep(int x)
{
#ifdef WIN32
	Sleep(x);
#else
	lib_usleep(x*1000);
#endif
	return TRUE;
}
#ifdef NOUPPER
#define _tolower(_c)    ( (_c)-'A'+'a' )
#define _toupper(_c)    ( (_c)-'a'+'A' )
#endif

char *strupr(char *s)
{
        char *ss=s;
        for (;*s!=0;s++) if (islower(*s)) *s = _toupper(*s);
        return ss;
}
char *strlwr(char *s)
{
        char *ss=s;
        for (;*s!=0;s++) if (isupper(*s)) if (*s>0) *s = _tolower(*s);
        return ss;
}
#ifdef WIN32
#include <windows.h>
#endif
int lib_msec(void) /* Return time in msec if possible */
{
	static int base;
	if (base==0) base = time(NULL)-(24*60*60);
#ifdef WIN32
	{
		SYSTEMTIME systime;
		GetSystemTime(&systime);
		return ((time(NULL)-base)*1000)+(systime.wMilliseconds);
	}
#else
	{
		struct timeval tsec;
		struct timezone xtzone;
		gettimeofday(&tsec,&xtzone);
		return ((tsec.tv_sec-base)*1000)+(tsec.tv_usec/1000);
	}
#endif
}
