1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/misc/dos_fs.c
Alexandre Julliard fa68b75bad Release 950403
Sun Apr  2 18:31:12 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [Configure] [if1632/Imakefile]
	Removed new build and short names options.

	* [if1632/*.c] [tools/build.c]
	Implemented compiled call-back functions for better performance;
	all the relay code is now done in assembly code generated by the
	build program.
	Relay code is no longer dependent on being loaded below 64K.

	* [loader/resource.c]
	Fixed memory leak in LoadString(). A fix will also be needed for
	other resources.

	* [memory/global.c]
	Implemented global heap arenas, so we can store informations about
	global blocks, like lock counts or owner handle.
	Implemented FarGetOwner() and FarSetOwner().
	Implemented global heap TOOLHELP functions.

	* [memory/selector.c]
	Bug fix: it was not possible to re-use a free selector.

Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis  (csapuntz@mit.edu)

	*  [controls/listbox.c]
	Major work on listbox code
         - Many bugs fixed (still many bugs)
         - More messages supported
         - Code simplified

Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu)

	* [controls/edit.c]
	Lots of bug fixes related to diappearing text, lost carets,
	highlighting, segmentation faults, occurance of random
	characters, insertion of characters over selection, misplaced
	caret location, display corruption, end of line behavior, etc.

	* [controls/widgets.c]
	EDIT class doesn't want to use CS_PARENTDC flag.

Thu Mar 30 20:58:25 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
        
	* [loader/selector.c]
	  FixupFunctionPrologs() should also handle multiple data modules.
	  (this bug only became visible because MakeProcInstance() was fixed
	  in 950319)
	
	* [misc/dosfs.c]
	  Simplified DOS_SimplifyPath.
	  Small fix to DOS_opendir to reuse an entry if an open directory
	  is opened again, to prevent "too many open directories" messages.

Thu Mar 30 12:05:05 1995 Martin von Loewis  <loewis@informatik.hu-berlin.de>

	* [if1632/compobj.spec][include/compobj.h][misc/compobj.c]
	CoDisconnectObject: new stub function

	* [include/msdos.h]
	fix DOSVERSION

	* [loader/ne_image.c]
	NE_FixupSegment: Be more generous on additive fixups

	* [if1632/user.spec][misc/network.c]
	Add more WNet* stubs

Wed Mar 29 11:47:22 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c]
	  DlgDirList(): send segptr instead of linear pointer 
	  in message to static control
	* [controls/menu.c]
	  Tried to implement ownerdrawn menuitems. Doesn't work.
	* [if1632/gdi.spec] [include/windows.h] [objects/font.c]
	  Provide a stub for GetRasterizerCaps()
	* [loader/selector.c]
	  Pass end address instead of length to LocalInit() in 
	  CreateSelectors()
	* [memory/local.c]
	  LocalInit(): If there's already a local heap in the segment, do
	  nothing and return TRUE
	* [objects/linedda.c]
	  Replaced buggy LineDDA() with a Bresenham algorithm. Should work
	  now.
	* [windows/cursor.c]
	  LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some
	  more work still.

Tue Mar 21 17:54:43 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [if1632/relay.c] [if1632/callback.c] [include/dlls.h]
	  [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h]
	  [controls/widgets.c] [misc/shell.c] [misc/commdlg.c]
	  [windows/nonclient.c] [misc/message.c]
	  Added a new builtin DLL that provides 16 bit entry points for all
	  the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work
	  again.
	* [misc/shell.c]
	  RegOpenKey()/RegCreateKey() bugs fixed.
        * [loader/ne_image.c]
	  Skipping the initialization of a DLL when CS == 0 was broken.
1995-04-03 16:55:37 +00:00

959 lines
20 KiB
C

/*
* 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 <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>
#endif
#include "wine.h"
#include "windows.h"
#include "msdos.h"
#include "dos_fs.h"
#include "autoconf.h"
#include "comm.h"
#include "stddebug.h"
#include "debug.h"
#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 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';
}
void DOS_InitFS(void)
{
int x;
char drive[2], temp[256];
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].cwd, "/");
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(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
);
}
}
for (x=0; x!=MAX_OPEN_DIRS ; x++)
DosDirs[x].inuse = 0;
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)
{
int valid = 1;
dprintf_dosfs(stddeb,"ValidDrive %c (%d) -- ",'A'+drive,drive);
if (drive >= MAX_DOS_DRIVES)
valid = 0;
if (DosDrives[drive].rootdir == NULL)
valid = 0;
if (DosDrives[drive].disabled)
valid = 0;
dprintf_dosfs(stddeb, "%s\n", valid ? "Valid" : "Invalid");
return valid;
}
int DOS_ValidDirectory(char *name)
{
char *dirname;
struct stat s;
dprintf_dosfs(stddeb, "DOS_ValidDirectory: '%s'\n", name);
if ((dirname = DOS_GetUnixFileName(name)) == NULL)
return 0;
if (stat(dirname,&s))
return 0;
if (!S_ISDIR(s.st_mode))
return 0;
dprintf_dosfs(stddeb, "==> OK\n");
return 1;
}
/* Simplify the path in "name" by removing "//"'s and
".."'s in names like "/usr/bin/../lib/test" */
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 (changed);
dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
}
int DOS_GetDefaultDrive(void)
{
dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
return( CurrentDrive);
}
void DOS_SetDefaultDrive(int drive)
{
dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
if (DOS_ValidDrive(drive))
CurrentDrive = drive;
}
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;
dprintf_dosfs(stddeb,"GetUnixDirName: %s <=> %s => ",rootdir, name);
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);
dprintf_dosfs(stddeb,"%s\n", rootdir);
}
char *DOS_GetUnixFileName(char *dosfilename)
{
/* a:\windows\system.ini => /dos/windows/system.ini */
static char temp[256];
static char dostemp[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;
/* Consider dosfilename const */
strcpy(dostemp,dosfilename);
/* Expand the filename to it's full path if it doesn't
* start from the root.
*/
DOS_ExpandToFullPath(dostemp, drive);
strcpy(temp, DosDrives[drive].rootdir);
strcat(temp, DosDrives[drive].cwd);
GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dostemp);
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], rootdir[256];
/* /dos/windows/system.ini => c:\windows\system.ini */
/* Expand it if it's a relative name.
*/
DOS_ExpandToFullUnixPath(unixfilename);
for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
if (DosDrives[i].rootdir != NULL) {
strcpy(rootdir, DosDrives[i].rootdir);
strcat(rootdir, "/");
if (strncmp(rootdir, unixfilename, strlen(rootdir)) == 0) {
sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(rootdir));
ToDos(temp);
return temp;
}
}
}
sprintf(temp, "Z:%s", unixfilename);
ToDos(temp);
return(temp);
}
char *DOS_GetCurrentDir(int drive)
{
static char temp[256];
if (!DOS_ValidDrive(drive))
return 0;
strcpy(temp, DosDrives[drive].cwd);
DOS_SimplifyPath( temp );
ToDos(temp);
ChopOffSlash(temp);
dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
return (temp + 1);
}
int DOS_ChangeDir(int drive, char *dirname)
{
char temp[256],old[256];
if (!DOS_ValidDrive(drive))
return 0;
strcpy(temp, dirname);
ToUnix(temp);
strcpy(old, DosDrives[drive].cwd);
GetUnixDirName(DosDrives[drive].cwd, temp);
strcat(DosDrives[drive].cwd,"/");
dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s\n",'A'+drive,
DosDrives[drive].cwd);
if (!DOS_ValidDirectory(DosDrives[drive].cwd))
{
strcpy(DosDrives[drive].cwd, old);
return 0;
}
DOS_SimplifyPath(DosDrives[drive].cwd);
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 + strlen(DosDrives[drive].cwd));
mkdir(temp,0);
dprintf_dosfs(stddeb,
"DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
return 1;
}
/* DOS_ExpandToFullPath takes a dos-style filename and converts it
* into a full path based on the current working directory.
* (e.g., "foo.bar" => "d:\\moo\\foo.bar")
*/
void DOS_ExpandToFullPath(char *filename, int drive)
{
char temp[256];
dprintf_dosfs(stddeb, "DOS_ExpandToFullPath: Original = %s\n", filename);
/* If the filename starts with '/' or '\',
* don't bother -- we're already at the root.
*/
if(filename[0] == '/' || filename[0] == '\\')
return;
strcpy(temp, DosDrives[drive].cwd);
strcat(temp, filename);
strcpy(filename, temp);
dprintf_dosfs(stddeb, " Expanded = %s\n", temp);
}
/* DOS_ExpandToFullUnixPath takes a unix filename and converts it
* into a full path based on the current working directory. Thus,
* it's probably not a good idea to get a relative name, change the
* working directory, and then convert it...
*/
void DOS_ExpandToFullUnixPath(char *filename)
{
char temp[256];
if(filename[0] == '/')
return;
getcwd(temp, 255);
if(!strncmp(filename, "./", 2))
strcat(temp, filename + 1);
else
{
strcat(temp, "/");
strcat(temp, filename);
}
dprintf_dosfs(stddeb, "DOS_ExpandToFullUnixPath: %s => %s\n", filename, temp);
strcpy(filename, temp);
}
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;
*available = info.f_bavail * info.f_bsize;
return 1;
}
char *DOS_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, 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 (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, 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);
return buffer;
} else
found = 0;
}
}
}
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 = malloc(1024);
strcpy(name, DOS_GetUnixFileName(WindowsDirectory));
strcat(name, "/");
strcat(name, "win.ini");
name = realloc(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 x,y;
char *unixdirname;
char temp[256];
if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
return NULL;
strcpy(temp, unixdirname);
y = strlen(temp);
while (y--)
{
if (temp[y] == '/')
{
temp[y++] = '\0';
unixdirname += y;
break;
}
}
for (x=0; x <= MAX_OPEN_DIRS; x++) {
if (x == MAX_OPEN_DIRS) {
fprintf( stderr, "DOS_opendir(): Too many open directories\n");
return NULL;
}
if (!DosDirs[x].inuse) break;
if (strcmp(DosDirs[x].unixpath,temp) == 0) break;
}
strcpy(DosDirs[x].filemask, unixdirname);
ToDos(DosDirs[x].filemask);
dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, temp);
DosDirs[x].inuse = 1;
strcpy(DosDirs[x].unixpath, temp);
DosDirs[x].entnum = 0;
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;
de->entnum++; /* Increment the directory entry number */
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;
return de;
}
void DOS_closedir(struct dosdirent *de)
{
if (de && de->inuse)
{
closedir(de->ds);
de->inuse = 0;
}
}