/*
 * DOS-FS
 * NOV 1993 Erik Bos (erik@(trashcan.)hacktic.nl)
 *
 * FindFile by Bob, hacked for dos & unixpaths by Erik.
 */

#include <ctype.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/types.h>
#include <sys/mount.h>
#endif

#include "windows.h"
#include "msdos.h"
#include "prototypes.h"
#include "autoconf.h"

/* #define DEBUG */

#define WINE_INI_USER "~/.winerc"
#define MAX_OPEN_DIRS 16
#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[MAX_OPEN_DIRS];

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;
}

void ChopOffSlash(char *path)
{
	if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == '\\')
		path[strlen(path)-1] = '\0';
}

void DOS_InitFS(void)
{
	int x;
	char drive[2], temp[256], *ptr;

	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);
		if ((ptr = (char *) malloc(strlen(temp)+1)) == NULL) {
			fprintf(stderr,"DOSFS: can't malloc for drive info!");
			continue;
		}
			ChopOffSlash(temp);
			DosDrives[x].rootdir = ptr;
			strcpy(DosDrives[x].rootdir, temp);
			strcpy(DosDrives[x].cwd, "/windows/");
			strcpy(DosDrives[x].label, "DRIVE-");
			strcat(DosDrives[x].label, drive);
			DosDrives[x].disabled = 0;
	}
	DOS_SetDefaultDrive(2);

	for (x=0; x!=MAX_DOS_DRIVES; x++) {
		if (DosDrives[x].rootdir != NULL) {
#ifdef DEBUG
			fprintf(stderr, "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
			);	
#endif
		}
	}

	for (x=0; x!=MAX_OPEN_DIRS ; x++)
		DosDirs[x].inuse = 0;

#ifdef DEBUG
	fprintf(stderr,"wine.ini = %s\n",WINE_INI);
	fprintf(stderr,"win.ini = %s\n",WIN_INI);
	fprintf(stderr,"windir = %s\n",WindowsDirectory);
	fprintf(stderr,"sysdir = %s\n",SystemDirectory);
	fprintf(stderr,"tempdir = %s\n",TempDirectory);
	fprintf(stderr,"path = %s\n",WindowsPath);
#endif
}

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

/* 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
*/

	if (DosDrives[0].rootdir != NULL)
		diskdrives++;
	if (DosDrives[1].rootdir != NULL)
		diskdrives++;
	if (diskdrives)
		diskdrives--;

	equipment = (diskdrives << 6) || 0x02;

	return (equipment);
}

int DOS_ValidDrive(int drive)
{
/*
#ifdef DEBUG
	fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive);
#endif
*/
	if (drive >= MAX_DOS_DRIVES)
		return 0;
	if (DosDrives[drive].rootdir == NULL)
		return 0;
	if (DosDrives[drive].disabled)
		return 0;

	return 1;
}

int DOS_GetDefaultDrive(void)
{
#ifdef DEBUG
	fprintf(stderr,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
#endif

	return( CurrentDrive);
}

void DOS_SetDefaultDrive(int drive)
{
#ifdef DEBUG
	fprintf(stderr,"SetDefaultDrive to %c:\n",'A'+drive);
#endif

	if (DOS_ValidDrive(drive))
		CurrentDrive = drive;
}

void ToUnix(char *s)
{
	/*  \WINDOWS\\SYSTEM   =>   /windows/system */

	char *p;

	for (p = s; *p; p++) 
	{
		if (*p != '\\')
			*s++ = tolower(*p);
		else {
			*s++ = '/';
			if (*(p+1) == '/' || *(p+1) == '\\')
				p++;
		}
	}
	*s = '\0';
}

void ToDos(char *s)
{
	/* /windows//system   =>   \WINDOWS\SYSTEM */

	char *p;
	for (p = s; *p; p++) 
	{
		if (*p != '/')
			*s++ = toupper(*p);
		else {
			*s++ = '\\';
			if (*(p+1) == '/' || *(p+1) == '\\') 
			    p++;
		}
	}
	*s = '\0';
}

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;
}

static void GetUnixDirName(char *rootdir, char *name)
{
	int filename = 1;
	char *nameptr, *cwdptr;
	
	cwdptr = rootdir + strlen(rootdir);
	nameptr = name;
/*
#ifdef DEBUG
	fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name);
#endif
*/	
	while (*nameptr) {
		if (*nameptr == '.' & !filename) {
			nameptr++;
			if (*nameptr == '\0') {
				cwdptr--;
				break;
			}
			if (*nameptr == '.') {
				cwdptr--;
				while (cwdptr != rootdir) {
					cwdptr--;
					if (*cwdptr == '/') {
						*(cwdptr+1) = '\0';
						goto next;
					}
				}
				goto next;
			}
			if (*nameptr == '\\' || *nameptr == '/') {
			next:	nameptr++;		
				filename = 0;
				continue;
			}
		}
		if (*nameptr == '\\' || *nameptr == '/') {
			filename = 0;
			if (nameptr == name)
				cwdptr = rootdir;
			*cwdptr++='/';		
			nameptr++;
			continue;
		}
		filename = 1;
		*cwdptr++ = *nameptr++;
	}
	*cwdptr = '\0';

	ToUnix(rootdir);
/*
#ifdef DEBUG
	fprintf(stderr,"%s\n", rootdir);
#endif
*/
}

char *GetUnixFileName(char *dosfilename)
{ 
	/*   a:\windows\system.ini  =>  /dos/windows/system.ini */
	
	char temp[256];
	int drive;

	if (dosfilename[1] == ':') 
	{
		drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A';
		
		if (!DOS_ValidDrive(drive))		
			return NULL;
		else
			dosfilename+=2;
	} else
		drive = CurrentDrive;

	strcpy(temp, DosDrives[drive].rootdir);
	strcat(temp, DosDrives[drive].cwd);
	GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dosfilename);

	ToUnix(temp);

#ifdef DEBUG
	fprintf(stderr,"GetUnixFileName: %s => %s\n", dosfilename, temp);
#endif

	return(temp);
}

char *GetDosFileName(char *unixfilename)
{ 
	int i;
	char temp[256];
	/*   /dos/windows/system.ini => c:\windows\system.ini */
	
	for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
		if (DosDrives[i].rootdir != NULL) {
		   if (strncmp(DosDrives[i].rootdir, unixfilename, strlen(DosDrives[i].rootdir)) == 0) {
			sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(DosDrives[i].rootdir) + 1);
			ToDos(temp);
			return temp;
		   }	
		}
	}
	strcpy(temp, unixfilename);
	ToDos(temp);
	return(temp);
}

char *DOS_GetCurrentDir(int drive)
{ 
	/* should return 'WINDOWS\SYSTEM' */

	char temp[256];

	if (!DOS_ValidDrive(drive)) 
		return 0;
	
	strcpy(temp, DosDrives[drive].cwd);
	ToDos(temp);
	fprintf(stderr, "2 %s\n", temp);
	ChopOffSlash(temp);

#ifdef DEBUG
	fprintf(stderr,"DOS_GetCWD: %c: %s\n",'A'+drive, temp + 1);
#endif
	return (temp + 1);
}

int DOS_ChangeDir(int drive, char *dirname)
{
	char temp[256];

	if (!DOS_ValidDrive(drive)) 
		return 0;

	strcpy(temp, dirname);
	ToUnix(temp);
	
	GetUnixDirName(DosDrives[drive].cwd, temp);
	strcat(DosDrives[drive].cwd,"/");
#ifdef DEBUG
	fprintf(stderr,"DOS_SetCWD: %c: %s\n",'A'+drive, DosDrives[drive].cwd);
#endif
	return 1;
}

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

	strcpy(temp, DosDrives[drive].cwd);
	GetUnixDirName(temp, dirname);
	strcat(DosDrives[drive].cwd,"/");

	ToUnix(temp);
	mkdir(temp,0);	

#ifdef DEBUG
	fprintf(stderr,"DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
#endif
	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;

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

	*size = info.f_bsize * info.f_blocks / 1024;
	*available = info.f_bavail * info.f_bsize / 1024;
	
	return 1;
}

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

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

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

#ifdef DEBUG
fprintf(stderr,"FindFile: looking for %s\n", filename);
#endif

    rootnamelen = strlen(filename);
    if ((rootname = malloc(rootnamelen + 1)) == NULL)
    	return NULL;
    strcpy(rootname, filename);
    ToUnix(rootname);

    if ((workingpath = malloc(strlen(path) + 1)) == NULL)
	return NULL;
    strcpy(workingpath, path);

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

#ifdef DEBUG
	fprintf(stderr,"in %s\n",dirname);
#endif
	
	if (d != NULL)
	{
	    while ((f = readdir(d)) != NULL)
	    {
		if (strncasecmp(rootname, f->d_name, rootnamelen) == 0)
		{
		    if (extensions == NULL || 
			strcasecmp(rootname, f->d_name) == 0)
				found = 1;
		    else 
		    if (f->d_name[rootnamelen] == '.')
			for (e = extensions; *e != NULL; e++)
			    if (strcasecmp(*e, f->d_name + rootnamelen + 1) 
				== 0)
			    {
				found = 1;
				break;
			    }

		    if (found)
		    {
			if (strchr(dirname, '\\') != NULL)
				strncpy(buffer, 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);
				ToUnix(buffer);
				return buffer;
		    	} else 
		    		found = 0; 
		    }
		}
	    }
	    closedir(d);
	}
    }
    return NULL;
}

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

	if (filename)
		return filename;

	strcpy(name, WINE_INI_USER);
	ExpandTildeString(name);
	if ((fd = open(name, O_RDONLY)) != -1) {
		close(fd);
		filename = malloc(strlen(name) + 1);
		strcpy(filename, name);
		return(filename);
	}
	if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) {
		close(fd);
		filename = malloc(strlen(WINE_INI_GLOBAL) + 1);
		strcpy(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 = malloc(1024);

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

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

static int match(char *filename, char *filemask)
{
	int x, masklength = strlen(filemask);

#ifdef DEBUG
	fprintf(stderr, "match: %s, %s\n", filename, filemask);
#endif

	for (x = 0; x != masklength ; x++) {
/*		printf("(%c%c) ", *filename, filemask[x]); 
*/
		if (!*filename)
			/* stop if EOFname */
			return 1;

		if (filemask[x] == '?') {
			/* skip the next char */
			filename++;
			continue;
		}

		if (filemask[x] == '*') {
			/* skip each char until '.' or EOFname */
			while (*filename && *filename !='.')
				filename++;
			continue;
		}
		if (filemask[x] != *filename)
			return 0;

		filename++;
	}
	return 1;
}

struct dosdirent *DOS_opendir(char *dosdirname)
{
	int x,y;
	char *unixdirname;
	char temp[256];
	
	for (x=0; x != MAX_OPEN_DIRS && DosDirs[x].inuse; x++)
		;

	if (x == MAX_OPEN_DIRS)
		return NULL;

	if ((unixdirname = GetUnixFileName(dosdirname)) == NULL)
		return NULL;

	strcpy(temp, unixdirname);
	y = strlen(temp);
	while (y--)
	{
		if (temp[y] == '/') 
		{
			temp[y++] = '\0';
			strcpy(DosDirs[x].filemask, temp +y);
			ToDos(DosDirs[x].filemask);
			break;
		}
	}

#ifdef DEBUG
	fprintf(stderr,"DOS_opendir: %s -> %s\n", unixdirname, temp);
#endif

	DosDirs[x].inuse = 1;
	strcpy(DosDirs[x].unixpath, temp);

	if ((DosDirs[x].ds = opendir(temp)) == NULL)
		return NULL;

	return &DosDirs[x];
}


struct dosdirent *DOS_readdir(struct dosdirent *de)
{
	char temp[256];
	struct dirent *d;
	struct stat st;

	if (!de->inuse)
		return NULL;
	
	do {
		if ((d = readdir(de->ds)) == NULL) 
			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);

	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;

	return de;
}

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