/*
** ls - List directory using unix style wildcards
**
**  usage: ls [-l] filename
**
** -l is an optional flag which will cause the directory listing to
** be printed one-up with file size and date included.  Otherwise
** directory listing is printed two-up.  The listing is NOT
** sorted.
**
** examples:
**  ls *.c       print all files which end in ".c"
**  ls -l a*     print all files which begin with "a"
**  ls -l a??b*  print all files which begin with "a" followed by any
**               two characters followed by "b" and then any other
**               characters
**
** Written by:	Rick Schaeffer    1/11/86 and placed in public domain.
**				E. 13611 26th Ave.
**				Spokane, Wa.  99216
**				Compuserve ID: 70120,174
**				Bytenet ID: ricks.
*/
 
#include "wildexp.h"

struct find fwk;

int		totfiles;
long	totsize;

main(argc,argv)
int		argc;
char	*argv[];
{
	char	pattern[128];
	int		retval,lflag;
	char	*fferror();

	lflag = 0;
	totfiles = 0;
	totsize = 0;
	if (argc <= 1)
		strcpy(pattern,"*");
	else {
		if (argc == 2) {	
			strncpy(pattern,argv[1],120);
			if (strcmp(pattern,"-l") == 0) {
				strcpy(pattern,"*");
				lflag = 1;
				}
			}
		else {
			strncpy(pattern,argv[2],120);
			if (strcmp(argv[1],"-l") == 0)
				lflag = 1;
			}
		}
	if (pattern[strlen(pattern)-1] == ':')
		strcat(pattern,"*");
	retval = findfirst(pattern,&fwk);
	if (retval > 0) {
		printf("ls: Error - %s\n",fferror(retval));
		find_cleanup(&fwk);
		exit(1);
		}
	while (retval <= 0) {
		if (retval < 0)
			break;
		if (lflag)
			print_long(&fwk);
		else
			print_short(&fwk);
		retval = findnext(&fwk);
		}
	printf("\n");
	if (lflag)
		printf("%d Files containing %ld bytes.\n",totfiles,totsize);
	find_cleanup(&fwk);
}

char *dates(s,dss)
char	*s;
struct DateStamp *dss;
{
	int	year,month,day;
	static char dpm[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

	year = 1978;
	day = dss->ds_Days;
	while (day >= 366) {
		if ((year-1976) % 4 == 0) {
			day -= 366;
			year++;
			}
		else
			if ((year-1976) % 4 != 0 && day >= 365) {
				day -= 365;
				year++;
				}
		}
	if ((year-1976) % 4 == 0) {
		day = day % 366;
		dpm[2] = 29;
		}
	else {
		day = day % 365;
		dpm[2] = 28;
		}
	for (month = 0; day > dpm[month]; month++)
		day -= dpm[month];
	sprintf(s,"%02d/%02d/%04d",month+1,day,year);
	return(s);
}

char *times(s,dss)
char	*s;
struct DateStamp *dss;
{
	int	hours,minutes,seconds;

	seconds = dss->ds_Tick / 50;
	seconds %= 60;
	minutes = dss->ds_Minute;
	hours = minutes / 60;
	minutes %= 60;
	sprintf(s,"%02d:%02d:%02d",hours,minutes,seconds);
	return(s);
}

print_long(fwk)
struct find *fwk;
{
	struct FileInfoBlock *f;
	char	s[12],t[12];

	f = fwk->fp;
	if (f->fib_DirEntryType < 0) {
		printf("%-30s %7d %s %s\n",f->fib_FileName,f->fib_Size,
			dates(s,&f->fib_Date),times(t,&f->fib_Date));
		totsize += f->fib_Size;
		}
	else
		printf("%-30s <DIR>   %s\n",f->fib_FileName,dates(s,&f->fib_Date));
	totfiles++;
}

print_short(fwk)
struct find *fwk;
{
	static int f=0;

	printf("%-30s ",fwk->fname);
	if (f == 0)
		f = 1;
	else {
		printf("\n");
		f = 0;
		}
}
