/*
	$VER: QuickDir v1.1 (25.02.1997)
	Copyright 1997 by Dalibor Kezele

	Source code compiled with Aztec C 5.0a.
	e-mail :dkezele@mia.os.carnet.hr !!
*/

#include <exec/memory.h>
#include <libraries/dos.h>

#define FIB	FileInfoBlock

struct	FIB	*MyFIB;
struct	Lock	*MyLock;

/* -------------------------------------------------------------------- */

static char dirreport1[30] = "\033[33m DIRECTORY\033[31m";
static char emptyfile1[30] = "\033[33m     EMPTY\033[31m";
static char nocomment1[30] = "\033[37m<No comment>\033[31m";
static char over_flow1[30] = "\033[33m>\033[31m";

static char dirreport2[30] = " DIRECTORY";
static char emptyfile2[30] = "     EMPTY";
static char nocomment2[30] = "<No comment>";
static char over_flow2[30] = ">";

char *dirreport3 = &dirreport1[0];
char *emptyfile3 = &emptyfile1[0];
char *nocomment3 = &nocomment1[0];
char *over_flow3 = &over_flow1[0];

static char version[] =
	"$VER: QuickDir v1.1 (25.02.1997) Copyright 1997 by Dalibor Kezele";

/* -------------------------------------------------------------------- */

char *number(long n);

void browse(char *directory, char *pattern);
void splitpath(char *directory, char *pattern, char *source);
void checkpath(char *directory);

int mystrcmp(char *str1, char *str2);
int compare(char *string1, char *string2);
int match(char *entry, char *pattern);

/* -------------------------------------------------------------------- */

char fname[80], *filename = &fname[0];
char cname[80], *comment = &cname[0];

unsigned char ao = 1, ho = 1, fo = 1, co = 1, io = 0, xo = 0;

/* -------------------------------------------------------------------- */

int main(int argc, char **argv)
{
char dirname[80] = 0, patname[80] = 0;
register unsigned char i,j;

if(argc == 0)
	return 0;

if((argc == 2) && ((*(*(argv+1)) == '?')))  {
	printf("\033[1;37mQuickDir\033[31;0m v1.1 (25.02.1997) Copyright 1997 by Dalibor Kezele\n");
	printf("Usage: %s [options] [directory/pattern] [directory/pattern..]\n", *argv);
	printf("Options:\n");
   printf(" -f : display \033[33mF\033[31miles only\n");
	printf(" -a : don't use ANSI \033[33mC\033[31molors\n");
	printf(" -h : don't print \033[33mH\033[31meader/footer\n");
	printf(" -c : don't write \"no \033[33mC\033[31momment\"\n");
	printf("\033[3m<<< Please support PostCardWare! >>>\033[0m\n");
	return 0;
	}

if(!(MyFIB = (struct FIB *) AllocMem (sizeof(struct FIB), MEMF_CLEAR))) {
	puts("***ERROR: Unable to allocate memory!");
	return 0;
	}


for(i = 1; i < argc; i++) {
	if((*(*(argv+i)) + 0) == '-') {
		for(j = 1; j < strlen(*(argv+i)); j++) {
			switch(tolower(*(*(argv+i)+j))) {
				case 'a': ao = 0; {
					dirreport3 = &dirreport2[0];
					emptyfile3 = &emptyfile2[0];
					nocomment3 = &nocomment2[0];
					over_flow3 = &over_flow2[0];
					break;
					}
				case 'h': ho = 0; break;
				case 'c': co = 0; break;
				case 'f': io = 1; break;
				default : puts("***ERROR: Illegal option!");
				}
			}
		}
		else {
			fo = 0;
			splitpath(&dirname[0], &patname[0], *(argv + i));
			browse(&dirname[0], &patname[0]);
		}
	}

if(fo) {
	strcpy(&dirname, getcwd(&dirname, 80));
	strcpy(&patname, "*");
	browse(&dirname[0], &patname[0]);
	}

FreeMem (MyFIB, (LONG) sizeof(struct FIB));
return 0;
}

/* -------------------------------------------------------------------- */

char *number(long n)
{
char string1[80];
static char string2[80];
int i, j = 0, k = 0;

sprintf(string2, "%ld\0", n);
for(i = strlen(string2)-1; i >= 0; i--) {
	if (k == 3) {
		string1[j++] = ',';
		k = 0;
		}
	string1[j] = string2[i];
	j++;
	k++;
	}
for(i = 1; i <= j; i++) string2[i-1] = string1[j-i];
string2[j] = 0;

return string2;
}

/* -------------------------------------------------------------------- */

void browse(char *directory, char *pattern)
{
int cnt = 0, fcnt = 0, dcnt = 0, bcnt = 0;
char *size;
long lenght;

if(!(MyLock = (struct Lock *) Lock (directory, ACCESS_READ)))
	printf("***ERROR: Unable to find directory \"%s\"!\n", directory);
else
	{
	if(!(Examine (MyLock, MyFIB)))
		printf("***ERROR: Unable to examine directory \"%s\"!\n", directory);
	else
		{
		SetSignal(NULL, SIGBREAKF_CTRL_C);
		if(ho) {
			if(ao) {
				printf("Listing of directory: \033[1m\"%s\"\033[0m\n", directory);
				printf("\033[36;43m     bytes  directory/filename  ");
				printf("comment                                 \033[31;40m\n");
				}
			else {
				printf("Listing of directory: \"%s\"\n", directory);
				printf("     bytes  directory/filename  comment\n");
				}
			}
		while (ExNext (MyLock, MyFIB)) {
			if(compare(MyFIB -> fib_FileName, pattern)) {
				strcpy(filename, MyFIB -> fib_FileName);
				strcpy(filename + 18, over_flow3);
				strcpy(comment, MyFIB -> fib_Comment);
				strcpy(comment + 39, over_flow3);

				if((!*comment) && co) strcpy(comment, nocomment3);

				lenght = MyFIB -> fib_Size;
				cnt++;

				if(!lenght) size = emptyfile3;
					else { size = number(lenght); bcnt += lenght; }
					
				if(MyFIB -> fib_EntryType > 0) { size = dirreport3; dcnt++; }
					else fcnt++;

				if((long) SetSignal(NULL, NULL) & SIGBREAKF_CTRL_C) {
					SetSignal(0L, SIGBREAKF_CTRL_C);
					puts("***ERROR: QuickDir halted!");
					break;
					}

				if((io) && (MyFIB -> fib_EntryType >0)) continue;

				printf("%10s  %-19s %-40s\n", size, filename, comment);
				} /* if */

			} /* while */

		if(!cnt) printf("Directory empty or doesn't exist!\n");

		if(ho) {
			if(ao) {
				printf("\033[36;43m listed: %3d entries, ", cnt);
				printf("%3d files, %11s bytes, ", fcnt, number(bcnt));
				printf("%3d directories.    \033[31;40m\n", dcnt);
				}
			else {
				printf(" listed: %3d entries, ", cnt);
				printf("%3d files, %11s bytes, ", fcnt, number(bcnt));
				printf("%3d directories.\n", dcnt);
				}
			}

		} /* else */

	UnLock (MyLock);
	} /* else */
}

/* -------------------------------------------------------------------- */
void splitpath(char *directory, char *pattern, char *source)
{
int i;
register unsigned char a = 1;

for(i = strlen(source) - 1; i >= 0; i--) {

	if((*(source+i) == '*') || (*(source+i) == '?')) { a = 0; continue; }

	if(((*(source+i) == '/') || (*(source+i) == ':')) && (a == 0)) {
		strncpy(directory, source, i + 1);
		*(directory + i + 1) = 0;
		strncpy(pattern, source + i + 1, strlen(source) - i);
		checkpath(directory);
		break;
		}
	}
if(a) {
	strcpy(directory, source);
	strcpy(pattern, "*");
	}
else {
	strcpy(directory, getcwd(directory, 80));
	strcpy(pattern, source);
	}

checkpath(directory);

}

/* -------------------------------------------------------------------- */

void checkpath(char *directory)
{
	unsigned char a;

	a = strlen(directory);

	if((*(directory + a - 1) == ':') || (*(directory + a -1) == '/')) return;

	*(directory + a) = '/';
	*(directory + a + 1) = 0;
}

/* -------------------------------------------------------------------- */

int mystrcmp(char *str1, char *str2)
{
	if(strlen(str1) != strlen(str2)) return 0;

	while(*str1)
		if (tolower(*str1++) != tolower(*str2++)) return 0;

	return 1;
}

/* -------------------------------------------------------------------- */

int compare(char *string1, char *string2)
{
register unsigned char i;

for(i = 0; i < strlen(string2); i++)
	if((string2[i] == '*') || (string2[i] == '?'))
		return(match(string1, string2));

	return mystrcmp(string1, string2);
}

/* -------------------------------------------------------------------- */

int match(char *entry, char *pattern)
{
register unsigned char i = 0, j = 0, x = 0;

while((i < strlen(pattern)) && (j < strlen(entry))) {
	if(pattern[i] != '?') {
		if(pattern[i] != '*') {
			if(tolower(pattern[i]) != tolower(entry[j])) return 0;	
			}
		else {
			if (++i == strlen(pattern)) return 1;
			if ((pattern[i] == '?') && (pattern[i] == '*')) return 0;
			x = 0;
			while(j < strlen(entry)) {
				if(tolower(pattern[i]) == tolower(entry[j])) { x = 1; break; }
				j++;
				}
			if((j == strlen(entry)) && (x != 1)) return 0;
			}
		}
	i++; j++;
	}
return 1;
}
