#include <sys/unix.h>
#include "mkdir.h"

extern int ERRNO;

main( argc, argv )
int	argc;
char	*argv[];
{
	int	i;

	if( argc < 2 )
	{
		fprintf( stderr, "usage: %s dirnames\n", argv[0] );
		return(-1);
	}

	/* Go through all arguments making things */
	for( i=1; i<argc; i++ )
		paths( "", argv[i] );

	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;
	int		found;

	/* 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, "mkdir: can't stat %s\n", pre );
		return(0);
	}
	if( (statbuf.st_mode & F_MASK) != F_DIR )
	{
		fprintf( stderr, "mkdir: %s is not a directory\n", pre );
		return(0);
	}

	/* Open directory and match entries */
	if( d=open(pre,O_RDONLY), ERRNO )
	{
		fprintf(stderr,"mkdir: couldn't open %s\n",pre);
		return( 0 );
	}
	found = 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, "mkdir: can't stat %s\n", dname );
				break;
			}
	
			if( (statbuf.st_mode & F_MASK) != F_DIR )
			{
				if( !end )
				{
					fprintf( stderr, "mkdir: %s not a directory\n",whole );
					break;
				}
				fprintf( stderr, "mkdir: file %s exists\n", dname );
				found = 1;
				break;
			}
			else
				if( end )
				{
					fprintf( stderr, "mkdir: directory %s exists\n", dname );
					found = 1;
					break;
				}
				else
					paths( whole, orig+1 );
		}
	}
	close( d );
	if( end && (found==0) )
	{
		strcpy( whole, pre );
		strcat( whole, "/" );
		strcat( whole, patt );
		domake( pre, whole );
	}
	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 );
}

domake( pre, whole )
char	*whole,
	*pre;
{
	char	dots[128];
	
	if( mknod( whole, 040777, 0 ) != 0 )
	{
		fprintf(stderr,"mkdir: mknod error\n");
		return;
	}
	chown( whole, getuid(), getgid() );
	strcpy(dots,whole);
	strcat(dots,"/.");
	if( link(whole,dots) != 0 )
	{
		fprintf(stderr,"mkdir: link dot error\n");
		return;
	}
	chown( whole, getuid(), getgid() );
	strcat(dots,".");
	if( link(pre,dots) != 0 )
	{
		fprintf(stderr,"mkdir: link dotdot error\n");
		return;
	}
	chown( whole, getuid(), getgid() );
}

