3 * NOV 1993 Erik Bos (erik@(trashcan.)hacktic.nl)
5 * FindFile by Bob, hacked for dos & unixpaths by Erik.
7 * Bugfix by dash@ifi.uio.no: ToUnix() was called to often
20 #if defined(__linux__) || defined(sun)
23 #if defined(__NetBSD__) || defined(__FreeBSD__)
24 #include <sys/types.h>
25 #include <sys/mount.h>
30 #include "prototypes.h"
34 /* #define DEBUG_DOSFS /* */
35 /* #undef DEBIG_DOSFS /* */
38 #define WINE_INI_USER "~/.winerc"
39 #define MAX_OPEN_DIRS 16
40 #define MAX_DOS_DRIVES 26
42 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
44 char WindowsPath
[256];
46 static int CurrentDrive
= 2;
48 struct DosDriveStruct
{ /* eg: */
49 char *rootdir
; /* /usr/windows */
50 char cwd
[256]; /* / */
51 char label
[13]; /* DRIVE-A */
52 unsigned int serialnumber
; /* ABCD5678 */
56 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
57 static struct dosdirent DosDirs
[MAX_OPEN_DIRS
];
59 static void ExpandTildeString(char *s
)
62 char temp
[1024], *ptr
= temp
;
76 if ( (entry
= getpwuid(getuid())) == NULL
)
81 strcpy(s
, entry
->pw_dir
);
82 s
+= strlen(entry
->pw_dir
);
87 void ChopOffSlash(char *path
)
89 if (path
[strlen(path
)-1] == '/' || path
[strlen(path
)-1] == '\\')
90 path
[strlen(path
)-1] = '\0';
96 char drive
[2], temp
[256], *ptr
;
98 GetPrivateProfileString("wine", "windows", "c:\\windows",
99 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
101 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
102 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
104 GetPrivateProfileString("wine", "temp", "c:\\windows",
105 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
107 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
108 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
110 ChopOffSlash(WindowsDirectory
);
111 ToDos(WindowsDirectory
);
113 ChopOffSlash(SystemDirectory
);
114 ToDos(SystemDirectory
);
116 ChopOffSlash(TempDirectory
);
117 ToDos(TempDirectory
);
120 ExpandTildeString(WindowsPath
);
122 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
123 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
127 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
128 if (!strcmp(temp
, "*") || *temp
== '\0') {
129 DosDrives
[x
].rootdir
= NULL
;
130 DosDrives
[x
].cwd
[0] = '\0';
131 DosDrives
[x
].label
[0] = '\0';
132 DosDrives
[x
].disabled
= 1;
135 ExpandTildeString(temp
);
137 DosDrives
[x
].rootdir
= strdup(temp
);
138 strcpy(DosDrives
[x
].rootdir
, temp
);
139 strcpy(DosDrives
[x
].cwd
, "/windows/");
140 strcpy(DosDrives
[x
].label
, "DRIVE-");
141 strcat(DosDrives
[x
].label
, drive
);
142 DosDrives
[x
].disabled
= 0;
144 DOS_SetDefaultDrive(2);
146 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
147 if (DosDrives
[x
].rootdir
!= NULL
) {
148 dprintf_dosfs(stddeb
, "DOSFS: %c: => %-40s %s %s %X %d\n",
150 DosDrives
[x
].rootdir
,
153 DosDrives
[x
].serialnumber
,
154 DosDrives
[x
].disabled
159 for (x
=0; x
!=MAX_OPEN_DIRS
; x
++)
160 DosDirs
[x
].inuse
= 0;
162 dprintf_dosfs(stddeb
,"wine.ini = %s\n",WINE_INI
);
163 dprintf_dosfs(stddeb
,"win.ini = %s\n",WIN_INI
);
164 dprintf_dosfs(stddeb
,"windir = %s\n",WindowsDirectory
);
165 dprintf_dosfs(stddeb
,"sysdir = %s\n",SystemDirectory
);
166 dprintf_dosfs(stddeb
,"tempdir = %s\n",TempDirectory
);
167 dprintf_dosfs(stddeb
,"path = %s\n",WindowsPath
);
170 WORD
DOS_GetEquipment(void)
174 int parallelports
= 0;
177 extern struct DosDeviceStruct COM
[MAX_PORTS
];
178 extern struct DosDeviceStruct LPT
[MAX_PORTS
];
180 /* borrowed from Ralph Brown's interrupt lists
182 bits 15-14: number of parallel devices
183 bit 13: [Conv] Internal modem
185 bits 11- 9: number of serial devices
187 bits 7- 6: number of diskette drives minus one
188 bits 5- 4: Initial video mode:
194 bit 2: [PS] =1 if pointing device
196 bit 1: =1 if math co-processor
197 bit 0: =1 if diskette available for boot
199 /* Currently the only of these bits correctly set are:
200 bits 15-14 } Added by William Owen Smith,
201 bits 11-9 } wos@dcs.warwick.ac.uk
206 if (DosDrives
[0].rootdir
!= NULL
)
208 if (DosDrives
[1].rootdir
!= NULL
)
213 for (x
=0; x
!=MAX_PORTS
; x
++) {
214 if (COM
[x
].devicename
)
216 if (LPT
[x
].devicename
)
219 if (serialports
> 7) /* 3 bits -- maximum value = 7 */
221 if (parallelports
> 3) /* 2 bits -- maximum value = 3 */
224 equipment
= (diskdrives
<< 6) | (serialports
<< 9) |
225 (parallelports
<< 14) | 0x02;
227 dprintf_dosfs(stddeb
, "DOS_GetEquipment : diskdrives = %d serialports = %d "
228 "parallelports = %d\n"
229 "DOS_GetEquipment : equipment = %d\n",
230 diskdrives
, serialports
, parallelports
, equipment
);
235 int DOS_ValidDrive(int drive
)
237 dprintf_dosfs(stddeb
,"ValidDrive %c (%d)\n",'A'+drive
,drive
);
238 if (drive
>= MAX_DOS_DRIVES
)
240 if (DosDrives
[drive
].rootdir
== NULL
)
242 if (DosDrives
[drive
].disabled
)
249 int DOS_ValidDirectory(char *name
)
253 if ((dirname
= GetUnixFileName(name
)) == NULL
)
255 if (stat(dirname
,&s
))
257 if (!S_ISDIR(s
.st_mode
))
264 int DOS_GetDefaultDrive(void)
266 dprintf_dosfs(stddeb
,"GetDefaultDrive (%c)\n",'A'+CurrentDrive
);
267 return( CurrentDrive
);
270 void DOS_SetDefaultDrive(int drive
)
272 dprintf_dosfs(stddeb
,"SetDefaultDrive to %c:\n",'A'+drive
);
273 if (DOS_ValidDrive(drive
))
274 CurrentDrive
= drive
;
279 /* \WINDOWS\\SYSTEM => /windows/system */
289 if (*(p
+1) == '/' || *(p
+1) == '\\')
298 /* /windows//system => \WINDOWS\SYSTEM */
307 if (*(p
+1) == '/' || *(p
+1) == '\\')
314 int DOS_DisableDrive(int drive
)
316 if (drive
>= MAX_DOS_DRIVES
)
318 if (DosDrives
[drive
].rootdir
== NULL
)
321 DosDrives
[drive
].disabled
= 1;
325 int DOS_EnableDrive(int drive
)
327 if (drive
>= MAX_DOS_DRIVES
)
329 if (DosDrives
[drive
].rootdir
== NULL
)
332 DosDrives
[drive
].disabled
= 0;
336 static void GetUnixDirName(char *rootdir
, char *name
)
339 char *nameptr
, *cwdptr
;
341 cwdptr
= rootdir
+ strlen(rootdir
);
344 dprintf_dosfs(stddeb
,"GetUnixDirName: %s <=> %s => ",rootdir
, name
);
347 if (*nameptr
== '.' & !filename
) {
349 if (*nameptr
== '\0') {
353 if (*nameptr
== '.') {
355 while (cwdptr
!= rootdir
) {
357 if (*cwdptr
== '/') {
364 if (*nameptr
== '\\' || *nameptr
== '/') {
370 if (*nameptr
== '\\' || *nameptr
== '/') {
379 *cwdptr
++ = *nameptr
++;
386 fprintf(stderr
,"%s\n", rootdir
);
391 char *GetUnixFileName(char *dosfilename
)
393 /* a:\windows\system.ini => /dos/windows/system.ini */
395 static char temp
[256];
398 if (dosfilename
[1] == ':')
400 drive
= (islower(*dosfilename
) ? toupper(*dosfilename
) : *dosfilename
) - 'A';
402 if (!DOS_ValidDrive(drive
))
407 drive
= CurrentDrive
;
409 strcpy(temp
, DosDrives
[drive
].rootdir
);
410 strcat(temp
, DosDrives
[drive
].cwd
);
411 GetUnixDirName(temp
+ strlen(DosDrives
[drive
].rootdir
), dosfilename
);
413 dprintf_dosfs(stddeb
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
417 char *GetDosFileName(char *unixfilename
)
420 static char temp
[256], rootdir
[256];
421 /* /dos/windows/system.ini => c:\windows\system.ini */
423 for (i
= 0 ; i
!= MAX_DOS_DRIVES
; i
++) {
424 if (DosDrives
[i
].rootdir
!= NULL
) {
425 strcpy(rootdir
, DosDrives
[i
].rootdir
);
426 strcat(rootdir
, "/");
427 if (strncmp(rootdir
, unixfilename
, strlen(rootdir
)) == 0) {
428 sprintf(temp
, "%c:\\%s", 'A' + i
, unixfilename
+ strlen(rootdir
));
434 sprintf(temp
, "UNIX:%s", unixfilename
);
439 char *DOS_GetCurrentDir(int drive
)
441 /* should return 'WINDOWS\SYSTEM' */
445 if (!DOS_ValidDrive(drive
))
448 strcpy(temp
, DosDrives
[drive
].cwd
);
452 dprintf_dosfs(stddeb
,"DOS_GetCWD: %c: %s\n",'A'+drive
, temp
+ 1);
456 int DOS_ChangeDir(int drive
, char *dirname
)
458 char temp
[256],old
[256];
460 if (!DOS_ValidDrive(drive
))
463 strcpy(temp
, dirname
);
465 strcpy(old
, DosDrives
[drive
].cwd
);
467 GetUnixDirName(DosDrives
[drive
].cwd
, temp
);
468 strcat(DosDrives
[drive
].cwd
,"/");
470 dprintf_dosfs(stddeb
,"DOS_SetCWD: %c: %s\n",'A'+drive
,
471 DosDrives
[drive
].cwd
);
473 if (!DOS_ValidDirectory(DosDrives
[drive
].cwd
))
475 strcpy(DosDrives
[drive
].cwd
, old
);
481 int DOS_MakeDir(int drive
, char *dirname
)
485 if (!DOS_ValidDrive(drive
))
488 strcpy(temp
, DosDrives
[drive
].cwd
);
489 GetUnixDirName(temp
, dirname
);
490 strcat(DosDrives
[drive
].cwd
,"/");
492 ToUnix(temp
+ strlen(DosDrives
[drive
].cwd
));
495 dprintf_dosfs(stddeb
,
496 "DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
500 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
502 if (!DOS_ValidDrive(drive
))
505 *serialnumber
= DosDrives
[drive
].serialnumber
;
509 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
511 if (!DOS_ValidDrive(drive
))
514 DosDrives
[drive
].serialnumber
= serialnumber
;
518 char *DOS_GetVolumeLabel(int drive
)
520 if (!DOS_ValidDrive(drive
))
523 return (DosDrives
[drive
].label
);
526 int DOS_SetVolumeLabel(int drive
, char *label
)
528 if (!DOS_ValidDrive(drive
))
531 strncpy(DosDrives
[drive
].label
, label
, 8);
535 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
539 if (!DOS_ValidDrive(drive
))
542 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
543 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",
544 DosDrives
[drive
].rootdir
);
548 *size
= info
.f_bsize
* info
.f_blocks
/ 1024;
549 *available
= info
.f_bavail
* info
.f_bsize
/ 1024;
554 char *FindFile(char *buffer
, int buflen
, char *filename
, char **extensions
,
557 char *workingpath
, *dirname
, *rootname
, **e
;
560 int rootnamelen
, found
= 0;
561 struct stat filestat
;
563 if (strchr(filename
, '\\') != NULL
)
565 strncpy(buffer
, GetUnixFileName(filename
), buflen
);
566 stat( buffer
, &filestat
);
567 if (S_ISREG(filestat
.st_mode
))
573 if (strchr(filename
, '/') != NULL
)
575 strncpy(buffer
, filename
, buflen
);
579 dprintf_dosfs(stddeb
,"FindFile: looking for %s\n", filename
);
580 rootnamelen
= strlen(filename
);
581 if ((rootname
= malloc(rootnamelen
+ 1)) == NULL
)
583 strcpy(rootname
, filename
);
586 if ((workingpath
= malloc(strlen(path
) + 1)) == NULL
)
588 strcpy(workingpath
, path
);
590 for(dirname
= strtok(workingpath
, ";");
592 dirname
= strtok(NULL
, ";"))
594 if (strchr(dirname
, '\\') != NULL
)
595 d
= opendir( GetUnixFileName(dirname
) );
597 d
= opendir( dirname
);
599 dprintf_dosfs(stddeb
,"in %s\n",dirname
);
602 while ((f
= readdir(d
)) != NULL
)
604 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) == 0)
606 if (extensions
== NULL
||
607 strcasecmp(rootname
, f
->d_name
) == 0)
610 if (f
->d_name
[rootnamelen
] == '.')
611 for (e
= extensions
; *e
!= NULL
; e
++)
612 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1)
621 if (strchr(dirname
, '\\') != NULL
)
622 strncpy(buffer
, GetUnixFileName(dirname
), buflen
);
624 strncpy(buffer
, dirname
, buflen
);
626 strncat(buffer
, "/", buflen
- strlen(buffer
));
627 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
629 stat(buffer
, &filestat
);
630 if (S_ISREG(filestat
.st_mode
)) {
645 /**********************************************************************
648 char *WineIniFileName(void)
651 static char *filename
= NULL
;
657 strcpy(name
, WINE_INI_USER
);
658 ExpandTildeString(name
);
659 if ((fd
= open(name
, O_RDONLY
)) != -1) {
661 filename
= malloc(strlen(name
) + 1);
662 strcpy(filename
, name
);
665 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
667 filename
= malloc(strlen(WINE_INI_GLOBAL
) + 1);
668 strcpy(filename
, WINE_INI_GLOBAL
);
671 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
672 WINE_INI_GLOBAL
, WINE_INI_USER
);
676 char *WinIniFileName(void)
678 static char *name
= NULL
;
685 strcpy(name
, GetUnixFileName(WindowsDirectory
));
687 strcat(name
, "win.ini");
689 name
= realloc(name
, strlen(name
) + 1);
694 static int match(char *filename
, char *filemask
)
696 int x
, masklength
= strlen(filemask
);
698 dprintf_dosfs(stddeb
, "match: %s, %s\n", filename
, filemask
);
699 for (x
= 0; x
!= masklength
; x
++) {
700 /* printf("(%c%c) ", *filename, filemask[x]);
703 /* stop if EOFname */
706 if (filemask
[x
] == '?') {
707 /* skip the next char */
712 if (filemask
[x
] == '*') {
713 /* skip each char until '.' or EOFname */
714 while (*filename
&& *filename
!='.')
718 if (filemask
[x
] != *filename
)
726 struct dosdirent
*DOS_opendir(char *dosdirname
)
732 for (x
=0; x
!= MAX_OPEN_DIRS
&& DosDirs
[x
].inuse
; x
++)
735 if (x
== MAX_OPEN_DIRS
)
738 if ((unixdirname
= GetUnixFileName(dosdirname
)) == NULL
)
741 strcpy(temp
, unixdirname
);
748 strcpy(DosDirs
[x
].filemask
, temp
+y
);
749 ToDos(DosDirs
[x
].filemask
);
754 dprintf_dosfs(stddeb
,"DOS_opendir: %s -> %s\n", unixdirname
, temp
);
756 DosDirs
[x
].inuse
= 1;
757 strcpy(DosDirs
[x
].unixpath
, temp
);
759 if ((DosDirs
[x
].ds
= opendir(temp
)) == NULL
)
766 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
776 if ((d
= readdir(de
->ds
)) == NULL
)
779 strcpy(de
->filename
, d
->d_name
);
780 if (d
->d_reclen
> 12)
781 de
->filename
[12] = '\0';
784 } while ( !match(de
->filename
, de
->filemask
) );
786 strcpy(temp
,de
->unixpath
);
788 strcat(temp
,de
->filename
);
789 ToUnix(temp
+ strlen(de
->unixpath
));
793 if S_ISDIR(st
.st_mode
)
794 de
->attribute
|= FA_DIREC
;
796 de
->filesize
= st
.st_size
;
797 de
->filetime
= st
.st_mtime
;
802 void DOS_closedir(struct dosdirent
*de
)