/*
 * 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 */
	
	static 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;
	static 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;
	}
}
