/***************
*
* g:\exe\txf\src\txldir.c
*/
#include "txl.h"

#define SORT_DATE	1
#define SORT_SIZE	2
#define SORT_NAME	3
#define SORT_EXT	4
#define SORT_FAPX	5
#define PRI_NUM		28

extern int (*qsort_func_tbl[6])(struct find_t_s *x, struct find_t_s *y);
extern int dirsortoption;

#if 0		/* 自己書換え版 */
char *castlow(char *str)
{
	int i;
	if (castname) {
		for (i = 0; *(str + i) != 0; i++) {
			*(str + i) = tolower(*(str + i));
		}
	}
	return (str);

}
#else
char *castlow1(char *str)
{
	static char low[80];
	static int old = 0;
	int i;
	old = 16 - old;
	if (castname) {
		for (i = 0; *(str + i) != 0; i++) {
			*(low + i + old) = tolower(*(str + i));
		}
		*(low + i + old) = NUL;
		return (low + old);
	}
	else {
		return (str);
	}

}
char *castlow2(char *str)
{
	static char low[80];
	static int old = 0;
	int i;
	old = 16 - old;
	if (castname) {
		for (i = 0; *(str + i) != 0; i++) {
			*(low + i + old) = tolower(*(str + i));
		}
		*(low + i + old) = NUL;
		return (low + old);
	}
	else {
		return (str);
	}

}
#endif

void subdir(struct find_t_s *fcbs, FILE *fp, char *name, int base)
{
	int i = 0, j, len = 0, other;
	struct find_t newfcb;	/* 43ﾊﾞｲﾄ	*/
	char *ext;
/*	int year, month, day, hour, minute, second;	*/

	strcpy(line1, inputfile);
	ext = line1 + strlen(line1) - 3;
	strcpy(ext, name);
	strcat(ext, "\\*.*");
	if (_dos_findfirst(line1, _A_SUBDIR, &newfcb) == 0) {
		do {
			if ((*(newfcb.name) != '.') && (newfcb.attrib & _A_SUBDIR)) {
				fcbs[base + i].attrib = newfcb.attrib;
				fcbs[base + i].wr_time = newfcb.wr_time;
				fcbs[base + i].wr_date = newfcb.wr_date;
				fcbs[base + i].size = newfcb.size;
				strcpy(fcbs[base + i].name, newfcb.name);
				i++;
				if (base + i >= maxfcbs) {
					break;
				}
			}
		} while (_dos_findnext(&newfcb) == 0);
	}
	if (i > 1) {
		if (sortoption != 0) {
			qsort(&(fcbs[base]), i, sizeof(struct find_t_s),
					qsort_func_tbl[abs(sortoption)]);
		}
	}
	for (j = 0; j < i; j++) {
		len = strlen(line3);
		if (name != line3) {
			sprintf(line3, "%s\\%s", name, fcbs[base+j].name);
		}
		/* 空いてる変数は何でも使う(^^;) */
		fprintf(fp, "%s\\%-*s    <DIR>  ", castlow1(name),
				21 - strlen(name), castlow2(fcbs[base+j].name));
		if (name == line3) {
			strcat(line3, "\\");
			strcat(line3, fcbs[base+j].name);
		}
		other = 1;
		if (dspforumname) {
			other = dspmyforum(line3, fp);
		}
		if (other) {
			fputc('\n', fp);
		}
		subdir(fcbs, fp, line3, base + i + 1);
		*(line3 + len) = NUL;
	}
}

int serchdir(struct find_t_s *fcbs, unsigned int attr, long *para)
{
	struct find_t newfcb;	/* 43ﾊﾞｲﾄ	*/
	int i = 0, j, entry;
	char *ext;

	if (_dos_findfirst(inputfile, attr, &newfcb) == 0) {
		do {
			if (newfcb.attrib & _A_SUBDIR) {
				if (*(newfcb.name) != '.') {
					fcbs[i].attrib = newfcb.attrib;
					fcbs[i].wr_time = newfcb.wr_time;
					fcbs[i].wr_date = newfcb.wr_date;
					fcbs[i].size = newfcb.size;
					strcpy(fcbs[i].name, newfcb.name);
					i++;
					if (i >= maxfcbs) {
						break;
					}
				}
			}
			else {
				entry = 1;
				for (j = 0; j < maxexclude; j++) {
					if ((ext = jstrchr(newfcb.name, '.')) != NULL) {
						if (far_strncmp((char *)(&(para[j])), ext, 4) == 0) {
							entry = 0;
							break;
						}
					}
				}
				if (entry) {
					fcbs[i].attrib = newfcb.attrib;
					fcbs[i].wr_time = newfcb.wr_time;
					fcbs[i].wr_date = newfcb.wr_date;
					fcbs[i].size = newfcb.size;
					strcpy(fcbs[i].name, newfcb.name);
					i++;
					if (i >= maxfcbs) {
						break;
					}
				}
			}
		} while (_dos_findnext(&newfcb) == 0);
	}
	if (i > 1) {
		if (sortoption != 0) {
			qsort(fcbs, i, sizeof(struct find_t_s), qsort_func_tbl[abs(sortoption)]);
		}
	}
	return (i);
}

void dirmain(struct find_t_s *fcbs, FILE *fp, unsigned int attr, long *para)
{
	int i, j, other;
	PRIORITY *pri;
	char *ext;
	int year, month, day, hour, minute, second, timestamp = 1;
	char fname[13];

	i = serchdir(fcbs, attr, para);

	for (j = 0; j < i; j++) {	/* 表示	*/
		strcpy(fname, fcbs[j].name);
		if (dspfile) {
			if ((ext = jstrchr(fname, '.')) != NULL) {
				*ext = NUL;
				ext++;
			}
			else {
				ext = strchr(fname, '\0');	/* ﾀﾞﾐｰ	*/
			}
		}
		if (fcbs[j].attrib & _A_SUBDIR) {
			if (dspfile) {
				fprintf(fp, "%-8s %-3s <DIR>     ",
						castlow1(fname), castlow2(ext));
			}
			else {
				fprintf(fp, "%-12s <DIR>     ", castlow1(fname));
			}
		}
		else {
			if (dspfile) {
				fprintf(fp, "%-8s %-3s %8ld  ",
						castlow1(fname), castlow2(ext), fcbs[j].size);
			}
			else {
				fprintf(fp, "%-12s %8ld  ",
						castlow1(fname), fcbs[j].size);
			}
		}
		year = (fcbs[j].wr_date >> 9) + 80;
		month = (fcbs[j].wr_date >> 5) & 0x0f;
		day = fcbs[j].wr_date &0x1f;
		fprintf(fp, "%02d-%02d-%02d  ", (year) % 100, month, day);
		if (dirinfo) {
			timestamp = 0;
/*			fprintf(stderr, "%s\n", fcbs[j].name);	*/
			if (matchstr("%%%%%%%%.LOG", fcbs[j].name)) {	/* NORMAL LOG */
				timestamp = 1;
			}
			else if (matchstr("***%%%%%.ML%", fcbs[j].name)) {/* CATLOG MAIL */
				catlogmail(fcbs[j].name, fp);
			}
			else if (matchstr("MES%%'_%%.TXT", fcbs[j].name)) {/* CATLOG LOG */
				catlogmes(fcbs[j].name, fp);
			}
			else if (matchstr("MES%%.LOG", fcbs[j].name)) {/* MES_MODE LOG */
				catlogmes(fcbs[j].name, fp);
			}
			else if (matchstr("LIB%%.TXT", fcbs[j].name)) {	/* CATLOG LIB */
				catloglib(fcbs[j].name, fp);
			}
			else if (strstr(fcbs[j].name, ".RTN") != NULL) {	/* RTN LIST */
				rtnmes(fcbs[j].name, fp);
			}
			else if (strstr(fcbs[j].name, ".LST") != NULL) {	/* LIB LIST */
				liblist(fcbs[j].name, fp);
			}
			else if (matchstr("***%%%%%.LOG", fcbs[j].name)) {/* HP/PATIO LOG*/
				idlog(fcbs[j].name, fp);
			}
			else {
				pri = howpri(&(fcbs[j]));
				other = 1;
				if (dspforumname) {
					other = dspmyforum(fcbs[j].name, fp);
				}
				if ((other) && ((~(pri->pri)) & 0x0100)) {
					fputs(pri->str, fp);
					fputc('\n', fp);
				}
				else if (other) {
					fputc('\n', fp);
				}
			}
/*			fprintf(stderr, "(%d)%s\n", pri->pri, pri->str);	*/
		}
		if (timestamp) {
			hour = fcbs[j].wr_time>>11;
			minute = (fcbs[j].wr_time>>5) & 0x3f;
			second = (fcbs[j].wr_time & 0x1f)<<1;
			fprintf(fp, "%2d:%02d:%02d\n", hour, minute, second);
#if 0	/* 何をしていたのか良く分からない(^^;)---1994.04.10 */
			if (abs(sortoption) == SORT_FAPX) {
				pri = howpri(&(fcbs[j]));
			}
			else {
				pri = &(kindofpri[PRI_NUM - 1]);	/* ﾀﾞﾐｰ */
			}
#endif
		}
		if ((fcbs[j].attrib & _A_SUBDIR) && (recursivedir)) {
			for (other = 0; -1<= finfo[other].key; other = finfo[other].next) {
				if (finfo[other].key == -1) {
					if (far_strcmp(finfo[other].fname, fcbs[j].name) == 0) {
						subdir(fcbs, fp, fcbs[j].name, i);
					}
				}
				if (finfo[other].next == 0) {
					break;
				}
			}
		}
	}
}

void dir(int dirsort, int filesort)
{
	int i;
	struct find_t_s *fcbs;	/* find_t配列へのﾎﾟｲﾝﾀ	*/
	FILE *fp = NULL;
	char *myforum = "MYFORUM.LOG";
	char *dirend;
	long *para;

	if (outputfile != NULL) {
		fp = fopen(outputfile, "w");
/*		fprintf(stdout, "writefile = %s(%d)\n", outputfile, fp);	*/
	}
	else {
		fp = fpmes;
	}
	if (fp == NULL) {
		Exit(1);
/*		fp = stdout;	*/
/*		puts("outout stdout");	*/
	}

	para = malloc(3000*4);
	if (para == NULL) {
		goto ERROR;
	}

	strcpy(line2, inputfile);
	if (matchstr("*:\\", inputfile) && *(inputfile +3) != NUL) {
		if (*(jstrrchr(inputfile, '\\') + 1) != NUL) {
			strcat(line2, "\\");
			strcat(inputfile, "\\");
		}
	}
	strcat(inputfile, "*.*");

	for (i = 1024; (fcbs = malloc(i * sizeof(struct find_t_s))) == NULL; i--) {
		if (i <= 0) {
			goto ERROR;
		}
	}
	maxfcbs = i;
/*	if (dspforumname) {	*/
/*	fprintf(stdout, "fcbs(subdir)=%d\n", i);	@@@debug	*/
	for (i = 512; (finfo = farmalloc(i * sizeof(struct _foruminfo))) == NULL;
			i -= 4) {
		if (i <= 0) {
			goto ERROR;
		}
	}
	maxfinfo = i;
	maxfinfodata = 0;
	finfo[0].key = 0x7fff;
	finfo[0].next = 0;
	finfo[0].fname[0] = NUL;
	finfo[0].title[0] = NUL;

	dirend = strchr(line2, NUL);
	strcpy(dirend, myforum);
#if 0
	strcpy(dirend, title);
	readtitle(line2);
#endif
	readtitle(txfsetfile, para);

	readmyforum(line2);
#if 0	/* 雅びさんの要望により削除 */
	if (finfo[0].next == 0) {
		dspforumname = 0;
	}
#endif
/*	}	*/

	dirsortoption = dirsort;
	sortoption = filesort;
	dirmain(fcbs, fp, _A_SUBDIR | _A_NORMAL | _A_ARCH | _A_RDONLY, para);

	if (fp != fpmes) {
		fclose(fp);
	}

	farfree(finfo);
	free(fcbs);
	free(para);
	return;
ERROR:
	fprintf(fp, "Error: out of memory(dir)\n");
	if (fp != fpmes) {
		fclose(fp);
	}
	Exit(1);
}

void dirdriver(char *val[])
{
	int i = 0;
	int sortswitch = 0;
	int dirsort = 0;
	int filesort = 0;
	char inputpath[80];	/* うーん、inputfileを操作しているとは思わなかった */

	for (i = 0; val[i] != NULL; i++) {
		if (val[i][0] == '-') {
			switch (val[i][1]) {
			case 'C':
				castname = 0;
				break;
			case 'c':
				castname = 1;
				break;
			case 'i':
			case 'I':
				dirinfo = 1;
				break;
			case 'o':
			case 'O':
				if (val[i+1][0] != '-') {
					outputfile = val[i+1];
					i++;
				}
				break;
			case 'd':
			case 'D':
				sortoption = SORT_DATE;
				sortswitch = 1;
				break;
			case 's':
			case 'S':
				sortoption = SORT_SIZE;
				sortswitch = 1;
				break;
			case 'n':
			case 'N':
				sortoption = SORT_NAME;
				sortswitch = 1;
				break;
			case 'e':
			case 'E':
				sortoption = SORT_EXT;
				sortswitch = 1;
				break;
			case 'x':
			case 'X':
				sortoption = SORT_FAPX;
				sortswitch = 1;
				break;
			case 'f':
				dspfile = 1;
				break;
			case 'r':
			case 'R':
				recursivedir = 1;
				break;
			case 'F':
				dspforumname = 1;
				break;
			default:
/*				fprintf(stderr, "Error:invailed parameter'%Fs'\n", val[i]);	*/
				Exit(1);
			}
		}
		else if (inputfile == NULL) {
			strcpy(inputpath, val[i]);
			inputfile = inputpath;		/* inputfileをﾒﾓﾘ確保しているものと */
		}								/* して処理していたようなので逃げる */

#if 0	/* ここを無効にするとｵﾌﾟｼｮﾝ無しの２番目引数が無効になる */
		else if (inputfile == NULL) {
			outputfile = val[i];
		}
#endif

		if (sortswitch) {
			dirsort = sortoption;
			filesort = sortoption;
			if (val[i][2] != '-') {
				dirsort = -(sortoption);
			}
			if (val[i][3] != '-') {
				filesort = -(sortoption);
			}
			sortswitch = 0;
		}
	}
	dir(dirsort, filesort);
	Exit(0);
}
