/*
 * DOS-FS
 * NOV 1993 Erik Bos <erik@xs4all.nl>
 *
 * FindFile by Bob, hacked for dos & unixpaths by Erik.
 *
 * Bugfix by dash@ifi.uio.no: ToUnix() was called to often
 */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <pwd.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>

#if defined(__linux__) || defined(sun)
#include <sys/vfs.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/errno.h>
#endif
#ifdef __svr4__
#include <sys/statfs.h>
#endif
#include "wine.h"
#include "windows.h"
#include "msdos.h"
#include "dos_fs.h"
#include "comm.h"
#include "task.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"

#define WINE_INI_USER "~/.winerc"
#define MAX_DOS_DRIVES	26

extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256];

char WindowsPath[256];

static int CurrentDrive = 2;

struct DosDriveStruct {			/*  eg: */
	char 		*rootdir;	/*  /usr/windows 	*/
	char 		cwd[256];	/*  /			*/
	char 		label[13];	/*  DRIVE-A		*/
	unsigned int	serialnumber;	/*  ABCD5678		*/
	int 		disabled;	/*  0			*/
};

static struct DosDriveStruct DosDrives[MAX_DOS_DRIVES];
static struct dosdirent *DosDirs=NULL;

WORD ExtendedError;
BYTE ErrorClass, Action, ErrorLocus;

int DOS_Error(int e, int class, int el)
{
	ErrorClass = class;
	Action = SA_Ask4Retry;
	ErrorLocus = el;
	ExtendedError = e;

	return e;
}

void errno_to_doserr(void)
{
	switch (errno) {
		case EAGAIN:
			DOS_Error (ShareViolation, EC_Temporary, EL_Unknown);
			break;
		case EBADF:
			DOS_Error (InvalidHandle, EC_AppError, EL_Unknown);
			break;
		case ENOSPC:
			DOS_Error (DiskFull, EC_MediaError, EL_Disk);
			break;				
		case EACCES:
		case EPERM:
		case EROFS:
			DOS_Error (WriteProtected, EC_AccessDenied, EL_Unknown);
			break;
		case EBUSY:
			DOS_Error (LockViolation, EC_AccessDenied, EL_Unknown);
			break;		
		case ENOENT:
			DOS_Error (FileNotFound, EC_NotFound, EL_Unknown);
			break;				
		case EISDIR:
			DOS_Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown);
			break;
		case ENFILE:
		case EMFILE:
			DOS_Error (NoMoreFiles, EC_MediaError, EL_Unknown);
			break;
		case EEXIST:
			DOS_Error (FileExists, EC_Exists, EL_Disk);
			break;				
		default:
			dprintf_int(stddeb, "int21: unknown errno %d!\n", errno);
			DOS_Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
			break;
	}
}


static void ExpandTildeString(char *s)
{
    struct passwd *entry;
    char temp[1024], *ptr = temp;
	
    strcpy(temp, s);

    while (*ptr)
    {
	if (*ptr != '~') 
	{ 
	    *s++ = *ptr++;
	    continue;
	}

	ptr++;

	if ( (entry = getpwuid(getuid())) == NULL) 
	{
	    continue;
	}

	strcpy(s, entry->pw_dir);
	s += strlen(entry->pw_dir);
    }
    *s = 0;
}

/* Simplify the path in "name" by removing  "//"'s, "/./"'s, and
   ".."'s in names like "/usr/bin/../lib/test" */
static void DOS_SimplifyPath(char *name)
{
  char *l,*p;
  BOOL changed;

  dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name);
  do {
    changed = FALSE;
    while ((l = strstr(name,"//"))) {
      strcpy(l,l+1); changed = TRUE;
    } 
    while ((l = strstr(name,"/../"))) {
      *l = 0;
      p = strrchr(name,'/');
      if (p == NULL) p = name;
      strcpy(p,l+3);
      changed = TRUE;
    }
    while ((l = strstr(name, "/./"))) {
      strcpy(l, l+2); changed = TRUE;
    }
  } while (changed);
  dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
}


/* ChopOffSlash takes care to strip directory slashes from the
 * end off the path name, but leaves a single slash. Multiple
 * slashes at the end of a path are all removed.
 */

void ChopOffSlash(char *path)
{
    char *p = path + strlen(path) - 1;
    while ((*p == '\\') && (p > path)) *p-- = '\0';
}

void ToUnix(char *s)
{
    while(*s){
	if (*s == '\\') *s = '/';
	*s=tolower(*s); /* umsdos fs can't read files without :( */
	s++;
    }
}

void ToDos(char *s)
{
    while(*s){
	if (*s == '/') *s = '\\';
	s++;
    }
}

void DOS_InitFS(void)
{
    int x;
    char drive[2], temp[256];
    struct dosdirent *dp;    
    GetPrivateProfileString("wine", "windows", "c:\\windows", 
			    WindowsDirectory, sizeof(WindowsDirectory), WINE_INI);
    
    GetPrivateProfileString("wine", "system", "c:\\windows\\system", 
			    SystemDirectory, sizeof(SystemDirectory), WINE_INI);
    
    GetPrivateProfileString("wine", "temp", "c:\\windows", 
			    TempDirectory, sizeof(TempDirectory), WINE_INI);

    GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system", 
			    WindowsPath, sizeof(WindowsPath), WINE_INI);
    
    ChopOffSlash(WindowsDirectory);
    ToDos(WindowsDirectory);
    
    ChopOffSlash(SystemDirectory);
    ToDos(SystemDirectory);
    
    ChopOffSlash(TempDirectory);
    ToDos(TempDirectory);
    
    ToDos(WindowsPath);
    ExpandTildeString(WindowsPath);
    
    for (x=0; x!=MAX_DOS_DRIVES; x++) {
	DosDrives[x].serialnumber = (0xEB0500L | x);
	
	drive[0] = 'A' + x;
	drive[1] = '\0';
	GetPrivateProfileString("drives", drive, "*", temp, sizeof(temp), WINE_INI);
	if (!strcmp(temp, "*") || *temp == '\0') {
	    DosDrives[x].rootdir = NULL;		
	    DosDrives[x].cwd[0] = '\0';
	    DosDrives[x].label[0] = '\0';
	    DosDrives[x].disabled = 1;
	    continue;
	}
	ExpandTildeString(temp);
	ChopOffSlash(temp);
	DosDrives[x].rootdir = strdup(temp);
	strcpy(DosDrives[x].rootdir, temp);
	strcpy(DosDrives[x].cwd, "/windows/");
	strcpy(DosDrives[x].label, "DRIVE-");
	strcat(DosDrives[x].label, drive);
	DosDrives[x].disabled = 0;
    }
    DosDrives[25].rootdir = "/";
    strcpy(DosDrives[25].label, "UNIX-FS");
    DosDrives[25].serialnumber = 0x12345678;
    DosDrives[25].disabled = 0;
    
    /* Get the startup directory and try to map it to a DOS drive
     * and directory.  (i.e., if we start in /dos/windows/word and
     * drive C is defined as /dos, the starting wd for C will be
     * /windows/word)  Also set the default drive to whatever drive
     * corresponds to the directory we started in.
     */

    for (x=0; x!=MAX_DOS_DRIVES; x++) 
        if (DosDrives[x].rootdir != NULL) 
	    strcpy( DosDrives[x].cwd, "/" );

    getcwd(temp, 254);
    strcat(temp, "/");      /* For DOS_GetDosFileName */
    strcpy(DosDrives[25].cwd, temp );
    strcpy(temp, DOS_GetDosFileName(temp));
    if(temp[0] != 'Z')
    {
	ToUnix(temp + 2);
	strcpy(DosDrives[temp[0] - 'A'].cwd, &temp[2]);
	DOS_SetDefaultDrive(temp[0] - 'A');
    }
    else
    {
	DOS_SetDefaultDrive(2);
    }
    
    for (x=0; x!=MAX_DOS_DRIVES; x++) {
	if (DosDrives[x].rootdir != NULL) {
	    dprintf_dosfs(stddeb, "DOSFS: %c: => %-40s %s %s %X %d\n",
			  'A'+x,
			  DosDrives[x].rootdir,
			  DosDrives[x].cwd,
			  DosDrives[x].label,
			  DosDrives[x].serialnumber,
			  DosDrives[x].disabled);	
	}
    }
    dp = DosDirs;
    while (dp)
    {
        dp->inuse = 0;
        dp = dp->next;
    }

    dprintf_dosfs(stddeb,"wine.ini = %s\n",WINE_INI);
    dprintf_dosfs(stddeb,"win.ini = %s\n",WIN_INI);
    dprintf_dosfs(stddeb,"windir = %s\n",WindowsDirectory);
    dprintf_dosfs(stddeb,"sysdir = %s\n",SystemDirectory);
    dprintf_dosfs(stddeb,"tempdir = %s\n",TempDirectory);
    dprintf_dosfs(stddeb,"path = %s\n",WindowsPath);
}

WORD DOS_GetEquipment(void)
{
    WORD equipment;
    int diskdrives = 0;
    int parallelports = 0;
    int serialports = 0;
    int x;

/* borrowed from Ralph Brown's interrupt lists 

		    bits 15-14: number of parallel devices
		    bit     13: [Conv] Internal modem
		    bit     12: reserved
		    bits 11- 9: number of serial devices
		    bit      8: reserved
		    bits  7- 6: number of diskette drives minus one
		    bits  5- 4: Initial video mode:
				    00b = EGA,VGA,PGA
				    01b = 40 x 25 color
				    10b = 80 x 25 color
				    11b = 80 x 25 mono
		    bit      3: reserved
		    bit      2: [PS] =1 if pointing device
				[non-PS] reserved
		    bit      1: =1 if math co-processor
		    bit      0: =1 if diskette available for boot
*/
/*  Currently the only of these bits correctly set are:
		bits 15-14 		} Added by William Owen Smith, 
		bits 11-9		} wos@dcs.warwick.ac.uk
		bits 7-6
		bit  2			(always set)
*/

    if (DosDrives[0].rootdir != NULL)
        diskdrives++;
    if (DosDrives[1].rootdir != NULL)
        diskdrives++;
    if (diskdrives)
        diskdrives--;
	
    for (x=0; x!=MAX_PORTS; x++) {
	if (COM[x].devicename)
	    serialports++;
	if (LPT[x].devicename)
	    parallelports++;
    }
    if (serialports > 7)		/* 3 bits -- maximum value = 7 */
        serialports=7;
    if (parallelports > 3)		/* 2 bits -- maximum value = 3 */
        parallelports=3;
    
    equipment = (diskdrives << 6) | (serialports << 9) | 
                (parallelports << 14) | 0x02;

    dprintf_dosfs(stddeb, "DOS_GetEquipment : diskdrives = %d serialports = %d "
		  "parallelports = %d\n"
		  "DOS_GetEquipment : equipment = %d\n",
		  diskdrives, serialports, parallelports, equipment);
    
    return equipment;
}

int DOS_ValidDrive(int drive)
{
    dprintf_dosfs(stddeb,"ValidDrive %c (%d)\n",'A'+drive,drive);

    if (drive < 0 || drive >= MAX_DOS_DRIVES) return 0;
    if (DosDrives[drive].rootdir == NULL) return 0;
    if (DosDrives[drive].disabled) return 0;

    dprintf_dosfs(stddeb, " -- valid\n");
    return 1;
}

static void DOS_GetCurrDir_Unix(char *buffer, int drive)
{
    TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
    
    if (pTask != NULL && (pTask->curdrive & ~0x80) == drive) {
	strcpy(buffer, pTask->curdir);
	ToUnix(buffer);
    } else {
	strcpy(buffer, DosDrives[drive].cwd);
    }
}

char *DOS_GetCurrentDir(int drive)
{ 
    static char temp[256];

    if (!DOS_ValidDrive(drive)) return 0;

    DOS_GetCurrDir_Unix(temp, drive);
    DOS_SimplifyPath( temp );
    ToDos(temp);
    ChopOffSlash(temp);

    dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
    return temp + 1;
}

char *DOS_GetUnixFileName(const char *dosfilename)
{ 
    /*   a:\windows\system.ini  =>  /dos/windows/system.ini */
    
    /* FIXME: should handle devices here (like LPT: or NUL:) */
    
    static char dostemp[256], temp[256];
    int drive = DOS_GetDefaultDrive();
    
    if (dosfilename[0] && dosfilename[1] == ':')
    {
	drive = toupper(*dosfilename) - 'A';
	dosfilename += 2;
    }    
    if (!DOS_ValidDrive(drive)) return NULL;

    strncpy( dostemp, dosfilename, 255 );
    dostemp[255] = 0;
    ToUnix(dostemp);
    strcpy(temp, DosDrives[drive].rootdir);
    if (dostemp[0] != '/') {
	DOS_GetCurrDir_Unix(temp+strlen(temp), drive);
    }
    strcat(temp, dostemp);
    DOS_SimplifyPath(temp);
	
    dprintf_dosfs(stddeb,"GetUnixFileName: %s => %s\n", dosfilename, temp);
    return temp;
}

/* Note: This function works on directories as well as long as
 * the directory ends in a slash.
 */
char *DOS_GetDosFileName(char *unixfilename)
{ 
    int i;
    static char temp[256], temp2[256];
    /*   /dos/windows/system.ini => c:\windows\system.ini */
    
    dprintf_dosfs(stddeb,"DOS_GetDosFileName: %s\n", unixfilename);
    if (unixfilename[0] == '/') {
	strncpy(temp, unixfilename, 255);
	temp[255] = 0;
    } else {
	/* Expand it if it's a relative name. */
	getcwd(temp, 255);
	if(strncmp(unixfilename, "./", 2) != 0) {
	    strcat(temp, unixfilename + 1);
	} else {	    
	    strcat(temp, "/");
	    strcat(temp, unixfilename);
	}
    }
    for (i = 0 ; i < MAX_DOS_DRIVES; i++) {
	if (DosDrives[i].rootdir != NULL) {
	    int len = strlen(DosDrives[i].rootdir);
	    dprintf_dosfs(stddeb, "  check %c:%s\n", i+'A', DosDrives[i].rootdir);
	    if (strncmp(DosDrives[i].rootdir, temp, len) == 0 && temp[len] == '/')
	    {
		sprintf(temp2, "%c:%s", 'A' + i, temp+len);
		ToDos(temp2+2);
		return temp2;
	    }	
	}
    }
    sprintf(temp, "Z:%s", unixfilename);
    ToDos(temp+2);
    return temp;
}

int DOS_ValidDirectory(int drive, char *name)
{
    char temp[256];
    struct stat s;
    
    strcpy(temp, DosDrives[drive].rootdir);
    strcat(temp, name);
    if (stat(temp, &s)) return 0;
    if (!S_ISDIR(s.st_mode)) return 0;
    dprintf_dosfs(stddeb, "==> OK\n");
    return 1;
}

int DOS_GetDefaultDrive(void)
{
    TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
    int drive = pTask == NULL ? CurrentDrive : pTask->curdrive & ~0x80;
    
    dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+drive);
    return drive;
}

void DOS_SetDefaultDrive(int drive)
{
    TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
    
    dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
    if (DOS_ValidDrive(drive) && drive != DOS_GetDefaultDrive()) {
	if (pTask == NULL) CurrentDrive = drive;
	else {
	    char temp[256];
	    pTask->curdrive = drive | 0x80;
	    strcpy(temp, DosDrives[drive].rootdir);
	    strcat(temp, DosDrives[drive].cwd);
	    strcpy(temp, DOS_GetDosFileName(temp));
	    dprintf_dosfs(stddeb, "  curdir = %s\n", temp);
	    if (strlen(temp)-2 < sizeof(pTask->curdir)) strcpy(pTask->curdir, temp+2);
	    else fprintf(stderr, "dosfs: curdir too long\n");
	}
    }
}

int DOS_DisableDrive(int drive)
{
    if (drive >= MAX_DOS_DRIVES) return 0;
    if (DosDrives[drive].rootdir == NULL) return 0;

    DosDrives[drive].disabled = 1;
    return 1;
}

int DOS_EnableDrive(int drive)
{
    if (drive >= MAX_DOS_DRIVES) return 0;
    if (DosDrives[drive].rootdir == NULL) return 0;

    DosDrives[drive].disabled = 0;
    return 1;
}

int DOS_ChangeDir(int drive, char *dirname)
{
    TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
    char temp[256];
    
    if (!DOS_ValidDrive(drive)) return 0;

    if (dirname[0] == '\\') {
	strcpy(temp, dirname);
    } else {
	DOS_GetCurrDir_Unix(temp, drive);
	strcat(temp, dirname);
    }
    ToUnix(temp);
    strcat(temp, "/");
    DOS_SimplifyPath(temp);
    dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s ==> %s\n", 'A'+drive, dirname, temp);

    if (!DOS_ValidDirectory(drive, temp)) return 0;
    strcpy(DosDrives[drive].cwd, temp);
    if (pTask != NULL && DOS_GetDefaultDrive() == drive) {
	strcpy(temp, DosDrives[drive].rootdir);
	strcat(temp, DosDrives[drive].cwd);
	strcpy(temp, DOS_GetDosFileName(temp));
	dprintf_dosfs(stddeb, "  curdir = %s\n", temp);
	if (strlen(temp)-2 < sizeof(pTask->curdir)) strcpy(pTask->curdir, temp+2);
	else fprintf(stderr, "dosfs: curdir too long\n");
    }
    return 1;
}

int DOS_MakeDir(int drive, char *dirname)
{
    char temp[256], currdir[256];
    
    if (!DOS_ValidDrive(drive)) return 0;	

    strcpy(temp, DosDrives[drive].rootdir);
    DOS_GetCurrDir_Unix(currdir, drive);
    strcat(temp, currdir);
    strcat(temp, dirname);
    ToUnix(temp);
    DOS_SimplifyPath(temp);
    if (mkdir(temp, S_IRWXU | S_IRWXG | S_IRWXO) == -1)
    {
        dprintf_dosfs(stddeb, "DOS_MakeDir: %c:\%s => %s failed errno %d",'A'+drive, dirname, temp, errno);
        return 0;
    }
    dprintf_dosfs(stddeb, "DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
    return 1;
}

int DOS_GetSerialNumber(int drive, unsigned long *serialnumber)
{
	if (!DOS_ValidDrive(drive)) 
		return 0;

	*serialnumber = DosDrives[drive].serialnumber;
	return 1;
}

int DOS_SetSerialNumber(int drive, unsigned long serialnumber)
{
	if (!DOS_ValidDrive(drive)) 
		return 0;

	DosDrives[drive].serialnumber = serialnumber;
	return 1;
}

char *DOS_GetVolumeLabel(int drive)
{
	if (!DOS_ValidDrive(drive)) 
		return NULL;

	return DosDrives[drive].label;
}

int DOS_SetVolumeLabel(int drive, char *label)
{
	if (!DOS_ValidDrive(drive)) 
		return 0;

	strncpy(DosDrives[drive].label, label, 8);
	return 1;
}

int DOS_GetFreeSpace(int drive, long *size, long *available)
{
	struct statfs info;

	if (!DOS_ValidDrive(drive))
		return 0;

#ifdef __svr4__
	if (statfs(DosDrives[drive].rootdir, &info, 0, 0) < 0) {
#else
	if (statfs(DosDrives[drive].rootdir, &info) < 0) {
#endif
		fprintf(stderr,"dosfs: cannot do statfs(%s)\n",
			DosDrives[drive].rootdir);
		return 0;
	}

	*size = info.f_bsize * info.f_blocks;
#ifdef __svr4__
	*available = info.f_bfree * info.f_bsize;
#else
	*available = info.f_bavail * info.f_bsize;
#endif

	return 1;
}

char *DOS_FindFile(char *buffer, int buflen, const char *filename, char **extensions, 
		char *path)
{
    char *workingpath, *dirname, *rootname, **e;
    DIR *d;
    struct dirent *f;
    int rootnamelen;
    struct stat filestat;

    if (strchr(filename, '\\') != NULL)
    {
	strncpy(buffer, DOS_GetUnixFileName(filename), buflen);
	stat( buffer, &filestat);
	if (S_ISREG(filestat.st_mode))
	    return buffer;
	else
	    return NULL;
    }

    if (strchr(filename, '/') != NULL)
    {
	strncpy(buffer, filename, buflen);
	return buffer;
    }

    dprintf_dosfs(stddeb,"DOS_FindFile: looking for %s\n", filename);
    rootnamelen = strlen(filename);
    rootname = strdup(filename);
    ToUnix(rootname);
    workingpath = strdup(path);

    for(dirname = strtok(workingpath, ";"); 
	dirname != NULL;
	dirname = strtok(NULL, ";"))
    {
	if (strchr(dirname, '\\') != NULL)
		d = opendir( DOS_GetUnixFileName(dirname) );
	else
		d = opendir( dirname );

    	dprintf_dosfs(stddeb,"in %s\n",dirname);
	if (d != NULL)
	{
	    while ((f = readdir(d)) != NULL)
	    {		
		if (strcasecmp(rootname, f->d_name) != 0) {
		    if (strncasecmp(rootname, f->d_name, rootnamelen) != 0
		      || extensions == NULL 
		      || f->d_name[rootnamelen] != '.')
		        continue;

		    for (e = extensions; *e != NULL; e++) {
			if (strcasecmp(*e, f->d_name + rootnamelen + 1) == 0)
			    break;
		    }
		    if (*e == NULL) continue;
		}

		if (strchr(dirname, '\\') != NULL) {
		    strncpy(buffer, DOS_GetUnixFileName(dirname), buflen);
		} else {
		    strncpy(buffer, dirname, buflen);
		}

		strncat(buffer, "/", buflen - strlen(buffer));
		strncat(buffer, f->d_name, buflen - strlen(buffer));
		
		stat(buffer, &filestat);
		if (S_ISREG(filestat.st_mode)) {
		    closedir(d);
		    free(rootname);
		    DOS_SimplifyPath(buffer);
		    return buffer;
		} 
	    }
	    closedir(d);
	}
    }
    return NULL;
}

/**********************************************************************
 *		WineIniFileName
 */
char *WineIniFileName(void)
{
	int fd;
	static char *filename = NULL;
	static char name[256];

	if (filename)
		return filename;

	strcpy(name, WINE_INI_USER);
	ExpandTildeString(name);
	if ((fd = open(name, O_RDONLY)) != -1) {
		close(fd);
		filename = name;
		return filename;
	}
	if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) {
		close(fd);
		filename = WINE_INI_GLOBAL;
		return filename;
	}
	fprintf(stderr,"wine: can't open configuration file %s or %s !\n",
		WINE_INI_GLOBAL, WINE_INI_USER);
	exit(1);
}

char *WinIniFileName(void)
{
	static char *name = NULL;
	
	if (name)
		return name;
		
	name = xmalloc(1024);

	strcpy(name, DOS_GetUnixFileName(WindowsDirectory));
	strcat(name, "/");
	strcat(name, "win.ini");

	name = xrealloc(name, strlen(name) + 1);
	
	return name;
}

static int match(char *filename, char *filemask)
{
        char name[12], mask[12];
        int i;

        dprintf_dosfs(stddeb, "match: %s, %s\n", filename, filemask);
 
	for( i=0; i<11; i++ ) {
	  name[i] = ' ';
	  mask[i] = ' ';
	}
	name[11] = 0;
	mask[11] = 0; 
 
	for( i=0; i<8; i++ )
	  if( !(*filename) || *filename == '.' )
  	    break;
	  else
            name[i] = toupper( *filename++ );
        while( *filename && *filename != '.' )
	  filename++;
        if( *filename )
	  filename++;
        for( i=8; i<11; i++ )
	  if( !(*filename) )
	    break;
	  else
	    name[i] = toupper( *filename++ );

	for( i=0; i<8; i++ )
	  if( !(*filemask) || *filemask == '.' )
	    break;
	  else if( *filemask == '*' ) {
	    int j;
	    for( j=i; j<8; j++ )
	      mask[j] = '?';
	    break;
          }
	  else
	    mask[i] = toupper( *filemask++ );
	while( *filemask && *filemask != '.' )
	  filemask++;	   
	if( *filemask )
	  filemask++;
	for( i=8; i<11; i++ )
	  if( !(*filemask) )
	    break;
	  else if (*filemask == '*' ) {
	    int j;
	    for( j=i; j<11; j++ )
	      mask[j] = '?';
	    break;
	  }
	  else
	    mask[i] = toupper( *filemask++ );
	
    	dprintf_dosfs(stddeb, "changed to: %s, %s\n", name, mask);

	for( i=0; i<11; i++ )
	  if( ( name[i] != mask[i] ) && ( mask[i] != '?' ) )
	    return 0;

	return 1;
}

struct dosdirent *DOS_opendir(char *dosdirname)
{
    int len;
    char *unixdirname;
    char dirname[256];
    DIR  *ds;
    struct dosdirent *dp;
    
    if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL) return NULL;
    
    len = strrchr(unixdirname, '/') - unixdirname + 1;
    strncpy(dirname, unixdirname, len);
    dirname[len] = 0;
    unixdirname = strrchr(unixdirname, '/') + 1;
    if ((ds = opendir(dirname)) == NULL)
        return NULL;

    dp = DosDirs;
    while (dp)
    {
        if (dp->inuse)
            break;
        if (strcmp(dp->unixpath, dirname) == 0)
            break;
        dp = dp->next;
    }
    if (!dp)
    {
        dp = xmalloc(sizeof(struct dosdirent));
        dp->next = DosDirs;
        DosDirs = dp;
    }
    
    strncpy(dp->filemask, unixdirname, 12);
    dp->filemask[12] = 0;
    dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, dirname);

    dp->inuse = 1;
    strcpy(dp->unixpath, dirname);
    dp->entnum = 0;

    if (closedir(ds) == -1) 
    {
        dp->inuse = 0;
        return NULL;
    }
    return dp;
}


struct dosdirent *DOS_readdir(struct dosdirent *de)
{
	char temp[WINE_PATH_LENGTH];
	struct dirent *d;
	struct stat st;
	DIR	*ds;
	int	i;

	if (!de->inuse)
		return NULL;
	if (!(ds=opendir(de->unixpath))) return NULL;
	/* skip all already read directory entries. 
	 * the dir has hopefully not been modified in the meantime
	 */
	for (i=de->entnum;i--;)
		readdir(ds);
   
        if (de->search_attribute & FA_LABEL)  {	
	    int drive;
	    de->search_attribute &= ~FA_LABEL; /* don't find it again */
	    for(drive = 0; drive < MAX_DOS_DRIVES; drive++) {
		if (DosDrives[drive].rootdir != NULL &&
		    strcmp(DosDrives[drive].rootdir, de->unixpath) == 0)
		{
		    strcpy(de->filename, DOS_GetVolumeLabel(drive));
		    de->attribute = FA_LABEL;
		    return de;
		}
	    }
	}
    
	do {
	    de->entnum++;   /* Increment the directory entry number */
	    if ((d = readdir(ds)) == NULL)  {
		closedir(ds);
		return NULL;
	    }
	    strcpy(de->filename, d->d_name);
	    if (d->d_reclen > 12)
	    de->filename[12] = '\0';

	    ToDos(de->filename);
	} while ( !match(de->filename, de->filemask) );

	strcpy(temp,de->unixpath);
	strcat(temp,"/");
	strcat(temp,de->filename);
	ToUnix(temp + strlen(de->unixpath));

	stat (temp, &st);
	de->attribute = 0x0;
	if S_ISDIR(st.st_mode)
		de->attribute |= FA_DIREC;
	
	de->filesize = st.st_size;
	de->filetime = st.st_mtime;

	closedir(ds);
	return de;
}

void DOS_closedir(struct dosdirent *de)
{
	if (de && de->inuse)
		de->inuse = 0;
}

char *DOS_GetRedirectedDir(int drive)
{
    if(DOS_ValidDrive(drive))
        return (DosDrives[drive].rootdir);
    else
        return ("/");
}
