#include <sys/unix.h>
#include "cat.h"

extern int ERRNO;

main( argc, argv )
int	argc;
char	*argv[];
{
	int	flags,
		done, i;
	char	*path;

	if( argc == 0 )
	{
		fprintf( stderr, "ls: argc==0\n" );
		return(-1);
	}

	/* Go through all arguments listing things other than flags */
	for( done=0, i=1; i<argc; i++ )
	{
		docat( "", argv[i] );
		done = 1;
	}

	/* If no other directory has been listed, list the current one */
	if( done==0 )
		dump( 0 );

	return(0);
}


int docat( pre, patt )
char	*pre,
	*patt;
{
	struct direct	dirbuf;
	struct stat	statbuf;
	char		whole[256], dname[16];
	char		*orig, *first;
	int		end;
	int		d, f;

	/* Find the leading directry to search */
	orig = patt;
	first = dname;
	while( *orig && (*orig != '/') )
		*first++ = *orig++;
	*first = 0;
	end = (*orig==0) || (*(orig+1)==0);

	if( strlen(pre)==0 )
		if( strlen(dname)==0 )
		{
			docat( "/", orig+1 );
			return(0);
		}
		else
			pre = ".";

	/* Stat the preceeding path */
	if( stat( pre, &statbuf ) || ERRNO )
	{
		fprintf( stderr, "ls: can't stat %s\n", pre );
		return(0);
	}
	if( (statbuf.st_mode & F_MASK) != F_DIR )
	{
		fprintf( stderr, "ls: not a directory\n" );
		return(0);
	}

	/* Open directory and match entries */
	if( d=open(pre,O_RDONLY), ERRNO )
	{
		fprintf(stderr,"ls: couldn't open %s\n",pre);
		return( 0 );
	}
	while( read( d, (char*)&dirbuf, 16 ) == 16 )
	{
		if( dirbuf.d_name[0] == '\0' )
			continue;

		if( (strcmp(dirbuf.d_name,".")==0) || (strcmp(dirbuf.d_name,"..")==0) )
			continue;

		if( match( dirbuf.d_name, dname ) )
		{
			strcpy( whole, pre );
			strcat( whole, "/" );
			strcat( whole, dirbuf.d_name );

			if( stat( whole, &statbuf ) || ERRNO )
			{
				fprintf( stderr, "ls: can't stat %s\n", dname );
				break;
			}

			if( (statbuf.st_mode & F_MASK) != F_DIR )
			{
				if( !end )
				{
					fprintf( stderr, "ls: %s not a directory\n",whole );
					break;
				}
				if( f=open(whole,O_RDONLY), ERRNO )
				{
					fprintf(stderr,"ls: couldn't open %s\n",pre);
					break;
				}
				dump( f );
				close( f );	
			}
			else
				if( end )
				{
					fprintf( stderr, "ls: %s is a directory\n", whole );
					break;
				}
				else
					docat( whole, orig+1 );
		}
	}
	close( d );

	return( 0 );
}



int match( str, patt )
char	*str,
	*patt;
{
	if( *patt == '*' )
	{
		char	*pos = str;
		if( (!*(patt+1)) && *str )
			return( 1 );
		while( *pos )
			if( match(pos,patt+1) )
				return( 1 );
			else
				pos++;
		return( 0 );
	}
	if( (*str==0) && (*patt==0) )
		return( 1 );
	if( ! (*str && *patt) )
		return( 0 );
	if( (*str==*patt) || (*patt=='?') )
		return( match(str+1,patt+1) );
	return( 0 );
}


int dump( f )
int	f;
{
	char	buf[64];
	int	size, done;

	while( size=read(f,buf,64), size && !ERRNO )
	{
		done = 0;
		while( done < size )
			done += write( stdout, buf+done, size-done );
	}
	return( 0 );
}

