3 * NOV 1993 Erik Bos <erik@xs4all.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/param.h>
25 #include <sys/mount.h>
30 #include "prototypes.h"
36 #define WINE_INI_USER "~/.winerc"
37 #define MAX_OPEN_DIRS 16
38 #define MAX_DOS_DRIVES 26
40 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
42 char WindowsPath
[256];
44 static int CurrentDrive
= 2;
46 struct DosDriveStruct
{ /* eg: */
47 char *rootdir
; /* /usr/windows */
48 char cwd
[256]; /* / */
49 char label
[13]; /* DRIVE-A */
50 unsigned int serialnumber
; /* ABCD5678 */
54 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
55 static struct dosdirent DosDirs
[MAX_OPEN_DIRS
];
57 static void ExpandTildeString(char *s
)
60 char temp
[1024], *ptr
= temp
;
74 if ( (entry
= getpwuid(getuid())) == NULL
)
79 strcpy(s
, entry
->pw_dir
);
80 s
+= strlen(entry
->pw_dir
);
85 void ChopOffSlash(char *path
)
87 if (path
[strlen(path
)-1] == '/' || path
[strlen(path
)-1] == '\\')
88 path
[strlen(path
)-1] = '\0';
94 char drive
[2], temp
[256];
96 GetPrivateProfileString("wine", "windows", "c:\\windows",
97 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
99 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
100 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
102 GetPrivateProfileString("wine", "temp", "c:\\windows",
103 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
105 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
106 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
108 ChopOffSlash(WindowsDirectory
);
109 ToDos(WindowsDirectory
);
111 ChopOffSlash(SystemDirectory
);
112 ToDos(SystemDirectory
);
114 ChopOffSlash(TempDirectory
);
115 ToDos(TempDirectory
);
118 ExpandTildeString(WindowsPath
);
120 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
121 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
125 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
126 if (!strcmp(temp
, "*") || *temp
== '\0') {
127 DosDrives
[x
].rootdir
= NULL
;
128 DosDrives
[x
].cwd
[0] = '\0';
129 DosDrives
[x
].label
[0] = '\0';
130 DosDrives
[x
].disabled
= 1;
133 ExpandTildeString(temp
);
135 DosDrives
[x
].rootdir
= strdup(temp
);
136 strcpy(DosDrives
[x
].rootdir
, temp
);
137 strcpy(DosDrives
[x
].cwd
, "/windows/");
138 strcpy(DosDrives
[x
].label
, "DRIVE-");
139 strcat(DosDrives
[x
].label
, drive
);
140 DosDrives
[x
].disabled
= 0;
142 DosDrives
[25].rootdir
= "/";
143 strcpy(DosDrives
[25].cwd
, "/");
144 strcpy(DosDrives
[25].label
, "UNIX-FS");
145 DosDrives
[25].serialnumber
= 0x12345678;
146 DosDrives
[25].disabled
= 0;
148 DOS_SetDefaultDrive(2);
150 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
151 if (DosDrives
[x
].rootdir
!= NULL
) {
152 dprintf_dosfs(stddeb
, "DOSFS: %c: => %-40s %s %s %X %d\n",
154 DosDrives
[x
].rootdir
,
157 DosDrives
[x
].serialnumber
,
158 DosDrives
[x
].disabled
163 for (x
=0; x
!=MAX_OPEN_DIRS
; x
++)
164 DosDirs
[x
].inuse
= 0;
166 dprintf_dosfs(stddeb
,"wine.ini = %s\n",WINE_INI
);
167 dprintf_dosfs(stddeb
,"win.ini = %s\n",WIN_INI
);
168 dprintf_dosfs(stddeb
,"windir = %s\n",WindowsDirectory
);
169 dprintf_dosfs(stddeb
,"sysdir = %s\n",SystemDirectory
);
170 dprintf_dosfs(stddeb
,"tempdir = %s\n",TempDirectory
);
171 dprintf_dosfs(stddeb
,"path = %s\n",WindowsPath
);
174 WORD
DOS_GetEquipment(void)
178 int parallelports
= 0;
181 extern struct DosDeviceStruct COM
[MAX_PORTS
];
182 extern struct DosDeviceStruct LPT
[MAX_PORTS
];
184 /* borrowed from Ralph Brown's interrupt lists
186 bits 15-14: number of parallel devices
187 bit 13: [Conv] Internal modem
189 bits 11- 9: number of serial devices
191 bits 7- 6: number of diskette drives minus one
192 bits 5- 4: Initial video mode:
198 bit 2: [PS] =1 if pointing device
200 bit 1: =1 if math co-processor
201 bit 0: =1 if diskette available for boot
203 /* Currently the only of these bits correctly set are:
204 bits 15-14 } Added by William Owen Smith,
205 bits 11-9 } wos@dcs.warwick.ac.uk
210 if (DosDrives
[0].rootdir
!= NULL
)
212 if (DosDrives
[1].rootdir
!= NULL
)
217 for (x
=0; x
!=MAX_PORTS
; x
++) {
218 if (COM
[x
].devicename
)
220 if (LPT
[x
].devicename
)
223 if (serialports
> 7) /* 3 bits -- maximum value = 7 */
225 if (parallelports
> 3) /* 2 bits -- maximum value = 3 */
228 equipment
= (diskdrives
<< 6) | (serialports
<< 9) |
229 (parallelports
<< 14) | 0x02;
231 dprintf_dosfs(stddeb
, "DOS_GetEquipment : diskdrives = %d serialports = %d "
232 "parallelports = %d\n"
233 "DOS_GetEquipment : equipment = %d\n",
234 diskdrives
, serialports
, parallelports
, equipment
);
239 int DOS_ValidDrive(int drive
)
241 dprintf_dosfs(stddeb
,"ValidDrive %c (%d)\n",'A'+drive
,drive
);
242 if (drive
>= MAX_DOS_DRIVES
)
244 if (DosDrives
[drive
].rootdir
== NULL
)
246 if (DosDrives
[drive
].disabled
)
253 int DOS_ValidDirectory(char *name
)
257 dprintf_dosfs(stddeb
, "DOS_ValidDirectory: '%s'\n", name
);
258 if ((dirname
= GetUnixFileName(name
)) == NULL
)
260 if (stat(dirname
,&s
))
262 if (!S_ISDIR(s
.st_mode
))
264 dprintf_dosfs(stddeb
, "==> OK\n");
270 int DOS_GetDefaultDrive(void)
272 dprintf_dosfs(stddeb
,"GetDefaultDrive (%c)\n",'A'+CurrentDrive
);
273 return( CurrentDrive
);
276 void DOS_SetDefaultDrive(int drive
)
278 dprintf_dosfs(stddeb
,"SetDefaultDrive to %c:\n",'A'+drive
);
279 if (DOS_ValidDrive(drive
))
280 CurrentDrive
= drive
;
285 /* \WINDOWS\\SYSTEM => /windows/system */
295 if (*(p
+1) == '/' || *(p
+1) == '\\')
304 /* /windows//system => \WINDOWS\SYSTEM */
313 if (*(p
+1) == '/' || *(p
+1) == '\\')
320 int DOS_DisableDrive(int drive
)
322 if (drive
>= MAX_DOS_DRIVES
)
324 if (DosDrives
[drive
].rootdir
== NULL
)
327 DosDrives
[drive
].disabled
= 1;
331 int DOS_EnableDrive(int drive
)
333 if (drive
>= MAX_DOS_DRIVES
)
335 if (DosDrives
[drive
].rootdir
== NULL
)
338 DosDrives
[drive
].disabled
= 0;
342 static void GetUnixDirName(char *rootdir
, char *name
)
345 char *nameptr
, *cwdptr
;
347 cwdptr
= rootdir
+ strlen(rootdir
);
350 dprintf_dosfs(stddeb
,"GetUnixDirName: %s <=> %s => ",rootdir
, name
);
353 if (*nameptr
== '.' & !filename
) {
355 if (*nameptr
== '\0') {
359 if (*nameptr
== '.') {
361 while (cwdptr
!= rootdir
) {
363 if (*cwdptr
== '/') {
370 if (*nameptr
== '\\' || *nameptr
== '/') {
376 if (*nameptr
== '\\' || *nameptr
== '/') {
385 *cwdptr
++ = *nameptr
++;
391 dprintf_dosfs(stddeb
,"%s\n", rootdir
);
395 char *GetUnixFileName(char *dosfilename
)
397 /* a:\windows\system.ini => /dos/windows/system.ini */
399 static char temp
[256];
402 if (dosfilename
[1] == ':')
404 drive
= (islower(*dosfilename
) ? toupper(*dosfilename
) : *dosfilename
) - 'A';
406 if (!DOS_ValidDrive(drive
))
411 drive
= CurrentDrive
;
413 strcpy(temp
, DosDrives
[drive
].rootdir
);
414 strcat(temp
, DosDrives
[drive
].cwd
);
415 GetUnixDirName(temp
+ strlen(DosDrives
[drive
].rootdir
), dosfilename
);
417 dprintf_dosfs(stddeb
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
421 char *GetDosFileName(char *unixfilename
)
424 static char temp
[256], rootdir
[256];
425 /* /dos/windows/system.ini => c:\windows\system.ini */
427 for (i
= 0 ; i
!= MAX_DOS_DRIVES
; i
++) {
428 if (DosDrives
[i
].rootdir
!= NULL
) {
429 strcpy(rootdir
, DosDrives
[i
].rootdir
);
430 strcat(rootdir
, "/");
431 if (strncmp(rootdir
, unixfilename
, strlen(rootdir
)) == 0) {
432 sprintf(temp
, "%c:\\%s", 'A' + i
, unixfilename
+ strlen(rootdir
));
438 sprintf(temp
, "Z:%s", unixfilename
);
443 char *DOS_GetCurrentDir(int drive
)
445 /* should return 'WINDOWS\SYSTEM' */
447 static char temp
[256];
449 if (!DOS_ValidDrive(drive
))
452 strcpy(temp
, DosDrives
[drive
].cwd
);
456 dprintf_dosfs(stddeb
,"DOS_GetCWD: %c: %s\n",'A'+drive
, temp
+ 1);
460 int DOS_ChangeDir(int drive
, char *dirname
)
462 char temp
[256],old
[256];
464 if (!DOS_ValidDrive(drive
))
467 strcpy(temp
, dirname
);
469 strcpy(old
, DosDrives
[drive
].cwd
);
471 GetUnixDirName(DosDrives
[drive
].cwd
, temp
);
472 strcat(DosDrives
[drive
].cwd
,"/");
474 dprintf_dosfs(stddeb
,"DOS_SetCWD: %c: %s\n",'A'+drive
,
475 DosDrives
[drive
].cwd
);
477 if (!DOS_ValidDirectory(DosDrives
[drive
].cwd
))
479 strcpy(DosDrives
[drive
].cwd
, old
);
485 int DOS_MakeDir(int drive
, char *dirname
)
489 if (!DOS_ValidDrive(drive
))
492 strcpy(temp
, DosDrives
[drive
].cwd
);
493 GetUnixDirName(temp
, dirname
);
494 strcat(DosDrives
[drive
].cwd
,"/");
496 ToUnix(temp
+ strlen(DosDrives
[drive
].cwd
));
499 dprintf_dosfs(stddeb
,
500 "DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
504 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
506 if (!DOS_ValidDrive(drive
))
509 *serialnumber
= DosDrives
[drive
].serialnumber
;
513 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
515 if (!DOS_ValidDrive(drive
))
518 DosDrives
[drive
].serialnumber
= serialnumber
;
522 char *DOS_GetVolumeLabel(int drive
)
524 if (!DOS_ValidDrive(drive
))
527 return (DosDrives
[drive
].label
);
530 int DOS_SetVolumeLabel(int drive
, char *label
)
532 if (!DOS_ValidDrive(drive
))
535 strncpy(DosDrives
[drive
].label
, label
, 8);
539 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
543 if (!DOS_ValidDrive(drive
))
546 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
547 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",
548 DosDrives
[drive
].rootdir
);
552 *size
= info
.f_bsize
* info
.f_blocks
;
553 *available
= info
.f_bavail
* info
.f_bsize
;
558 char *FindFile(char *buffer
, int buflen
, char *filename
, char **extensions
,
561 char *workingpath
, *dirname
, *rootname
, **e
;
564 int rootnamelen
, found
= 0;
565 struct stat filestat
;
567 if (strchr(filename
, '\\') != NULL
)
569 strncpy(buffer
, GetUnixFileName(filename
), buflen
);
570 stat( buffer
, &filestat
);
571 if (S_ISREG(filestat
.st_mode
))
577 if (strchr(filename
, '/') != NULL
)
579 strncpy(buffer
, filename
, buflen
);
583 dprintf_dosfs(stddeb
,"FindFile: looking for %s\n", filename
);
584 rootnamelen
= strlen(filename
);
585 rootname
= strdup(filename
);
587 workingpath
= strdup(path
);
589 for(dirname
= strtok(workingpath
, ";");
591 dirname
= strtok(NULL
, ";"))
593 if (strchr(dirname
, '\\') != NULL
)
594 d
= opendir( GetUnixFileName(dirname
) );
596 d
= opendir( dirname
);
598 dprintf_dosfs(stddeb
,"in %s\n",dirname
);
601 while ((f
= readdir(d
)) != NULL
)
603 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) == 0)
605 if (extensions
== NULL
||
606 strcasecmp(rootname
, f
->d_name
) == 0)
609 if (f
->d_name
[rootnamelen
] == '.')
610 for (e
= extensions
; *e
!= NULL
; e
++)
611 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1)
620 if (strchr(dirname
, '\\') != NULL
)
621 strncpy(buffer
, GetUnixFileName(dirname
), buflen
);
623 strncpy(buffer
, dirname
, buflen
);
625 strncat(buffer
, "/", buflen
- strlen(buffer
));
626 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
628 stat(buffer
, &filestat
);
629 if (S_ISREG(filestat
.st_mode
)) {
644 /**********************************************************************
647 char *WineIniFileName(void)
650 static char *filename
= NULL
;
651 static char name
[256];
656 strcpy(name
, WINE_INI_USER
);
657 ExpandTildeString(name
);
658 if ((fd
= open(name
, O_RDONLY
)) != -1) {
663 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
665 filename
= WINE_INI_GLOBAL
;
668 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
669 WINE_INI_GLOBAL
, WINE_INI_USER
);
673 char *WinIniFileName(void)
675 static char *name
= NULL
;
682 strcpy(name
, GetUnixFileName(WindowsDirectory
));
684 strcat(name
, "win.ini");
686 name
= realloc(name
, strlen(name
) + 1);
691 static int match(char *filename
, char *filemask
)
693 int x
, masklength
= strlen(filemask
);
695 dprintf_dosfs(stddeb
, "match: %s, %s\n", filename
, filemask
);
696 for (x
= 0; x
!= masklength
; x
++) {
697 /* printf("(%c%c) ", *filename, filemask[x]);
700 /* stop if EOFname */
703 if (filemask
[x
] == '?') {
704 /* skip the next char */
709 if (filemask
[x
] == '*') {
710 /* skip each char until '.' or EOFname */
711 while (*filename
&& *filename
!='.')
715 if (filemask
[x
] != *filename
)
723 struct dosdirent
*DOS_opendir(char *dosdirname
)
729 for (x
=0; x
!= MAX_OPEN_DIRS
&& DosDirs
[x
].inuse
; x
++)
732 if (x
== MAX_OPEN_DIRS
)
735 if ((unixdirname
= GetUnixFileName(dosdirname
)) == NULL
)
738 strcpy(temp
, unixdirname
);
745 strcpy(DosDirs
[x
].filemask
, temp
+y
);
746 ToDos(DosDirs
[x
].filemask
);
751 dprintf_dosfs(stddeb
,"DOS_opendir: %s -> %s\n", unixdirname
, temp
);
753 DosDirs
[x
].inuse
= 1;
754 strcpy(DosDirs
[x
].unixpath
, temp
);
756 if ((DosDirs
[x
].ds
= opendir(temp
)) == NULL
)
763 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
773 if ((d
= readdir(de
->ds
)) == NULL
)
776 strcpy(de
->filename
, d
->d_name
);
777 if (d
->d_reclen
> 12)
778 de
->filename
[12] = '\0';
781 } while ( !match(de
->filename
, de
->filemask
) );
783 strcpy(temp
,de
->unixpath
);
785 strcat(temp
,de
->filename
);
786 ToUnix(temp
+ strlen(de
->unixpath
));
790 if S_ISDIR(st
.st_mode
)
791 de
->attribute
|= FA_DIREC
;
793 de
->filesize
= st
.st_size
;
794 de
->filetime
= st
.st_mtime
;
799 void DOS_closedir(struct dosdirent
*de
)