#include <sys/unix.h>
#include "rm.h"

extern int ERRNO;

main( argc, argv )
int	argc;
char	*argv[];
{
	int	done, i;
	char	*path;

	if( argc == 0 )
	{
		fprintf( stderr, "rm: argc==0\n" );
		return(-1);
	}

	/* Go through all arguments listing things other than flags */
	for( done=0, i=1; i<argc; i++ )
	{
		if( argv[i][0] != '-' )
		{
			paths( "", argv[i] );
			done = 1;
		}
	}

	/* If no other directory has been listed, list the current one */
	if( done==0 )
		fprintf(stderr,"rm: no file removed\n");

	return(0);
}


int paths( pre, patt )
char	*pre,
	*patt;
{
	struct direct	dirbuf;
	struct stat	statbuf;
	char		whole[256], dname[16], file[16];
	char		*orig, *first;
	int		end;
	int		d;

	/* 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 )
		{
			paths( "/", orig+1 );
			return(0);
		}
		else
			pre = ".";

	/* Stat the preceeding path */
	if( stat( pre, &statbuf ) || ERRNO )
	{
		fprintf( stderr, "rm: can't stat %s\n", pre );
		return(0);
	}
	if( (statbuf.st_mode & F_MASK) != F_DIR )
	{
		fprintf( stderr, "rm: not a directory\n" );
		return(0);
	}

	/* Open directory and match entries */
	if( d=open(pre,O_RDONLY), ERRNO )
	{
		fprintf(stderr,"rm: 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, "rm: can't stat %s\n", dname );
				break;
			}

			if( (statbuf.st_mode & F_MASK) != F_DIR )
			{
				if( !end )
				{
					fprintf( stderr, "rm: %s not a directory\n",whole );
					break;
				}
				rmfile( whole );
			}
			else
				if( end )
					rmdir( whole );
				else
					paths( 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 rmfile( path )
char	*path;
{
	if( unlink( path ), ERRNO )
		fprintf(stderr,"rm: error unlinking file %s\n",path);
}

/* Copied from ucp.c */
int rmdir( path )
char	*path;
{
	struct stat	statbuf;
	char		newpath[100];
	struct direct	dir;
	int		fd;

	if( (fd = open(path,O_RDONLY)) < 0 )
	{
		fprintf( stderr, "rmdir: %s unreadable\n", path );
		return(-1);
	}
	while( read(fd,(char*)&dir,sizeof(dir)) == sizeof(dir) )
	{
		if( dir.d_ino == 0 )
			continue;
		if( !strcmp(dir.d_name, ".") || !strcmp(dir.d_name, "..") )
			continue;
		fprintf( stderr, "rmdir: %s not empty\n", path );
		close(fd);
		return(-1);
	}
	close(fd);

	strcpy(newpath,path);
	strcat(newpath,"/.");
	if( unlink(newpath) != 0 )
	{
		fprintf(stderr,"rmdir: can't unlink \".\"  error %i\n",ERRNO);
		return(-1);
	}

	strcat(newpath,".");
	if( unlink(newpath) != 0 )
	{
		fprintf(stderr,"rmdir: can't unlink \"..\"  error %i\n",ERRNO);
		return(-1);
	}

	if (unlink(path) != 0)
	{
		fprintf(stderr,"rmdir: unlink error %i\n",ERRNO);
		return(-1);
	}

	return(0);
}

