3 * NOV 1993 Erik Bos (erik@(trashcan.)hacktic.nl)
5 * FindFile by Bob, hacked for dos & unixpaths by Erik.
18 #if defined(__linux__) || defined(sun)
21 #if defined(__NetBSD__) || defined(__FreeBSD__)
22 #include <sys/types.h>
23 #include <sys/mount.h>
28 #include "prototypes.h"
33 #define WINE_INI_USER "~/.winerc"
34 #define MAX_OPEN_DIRS 16
35 #define MAX_DOS_DRIVES 26
37 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
39 char WindowsPath
[256];
41 static int CurrentDrive
= 2;
43 struct DosDriveStruct
{ /* eg: */
44 char *rootdir
; /* /usr/windows */
45 char cwd
[256]; /* / */
46 char label
[13]; /* DRIVE-A */
47 unsigned int serialnumber
; /* ABCD5678 */
51 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
52 static struct dosdirent DosDirs
[MAX_OPEN_DIRS
];
54 static void ExpandTildeString(char *s
)
57 char temp
[1024], *ptr
= temp
;
71 if ( (entry
= getpwuid(getuid())) == NULL
)
76 strcpy(s
, entry
->pw_dir
);
77 s
+= strlen(entry
->pw_dir
);
82 void ChopOffSlash(char *path
)
84 if (path
[strlen(path
)-1] == '/' || path
[strlen(path
)-1] == '\\')
85 path
[strlen(path
)-1] = '\0';
91 char drive
[2], temp
[256], *ptr
;
93 GetPrivateProfileString("wine", "windows", "c:\\windows",
94 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
96 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
97 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
99 GetPrivateProfileString("wine", "temp", "c:\\windows",
100 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
102 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
103 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
105 ChopOffSlash(WindowsDirectory
);
106 ToDos(WindowsDirectory
);
108 ChopOffSlash(SystemDirectory
);
109 ToDos(SystemDirectory
);
111 ChopOffSlash(TempDirectory
);
112 ToDos(TempDirectory
);
115 ExpandTildeString(WindowsPath
);
117 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
118 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
122 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
123 if (!strcmp(temp
, "*") || *temp
== '\0') {
124 DosDrives
[x
].rootdir
= NULL
;
125 DosDrives
[x
].cwd
[0] = '\0';
126 DosDrives
[x
].label
[0] = '\0';
127 DosDrives
[x
].disabled
= 1;
130 ExpandTildeString(temp
);
131 if ((ptr
= (char *) malloc(strlen(temp
)+1)) == NULL
) {
132 fprintf(stderr
,"DOSFS: can't malloc for drive info!");
136 DosDrives
[x
].rootdir
= ptr
;
137 strcpy(DosDrives
[x
].rootdir
, temp
);
138 strcpy(DosDrives
[x
].cwd
, "/windows/");
139 strcpy(DosDrives
[x
].label
, "DRIVE-");
140 strcat(DosDrives
[x
].label
, drive
);
141 DosDrives
[x
].disabled
= 0;
143 DOS_SetDefaultDrive(2);
145 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
146 if (DosDrives
[x
].rootdir
!= NULL
) {
148 fprintf(stderr
, "DOSFS: %c: => %-40s %s %s %X %d\n",
150 DosDrives
[x
].rootdir
,
153 DosDrives
[x
].serialnumber
,
154 DosDrives
[x
].disabled
160 for (x
=0; x
!=MAX_OPEN_DIRS
; x
++)
161 DosDirs
[x
].inuse
= 0;
164 fprintf(stderr
,"wine.ini = %s\n",WINE_INI
);
165 fprintf(stderr
,"win.ini = %s\n",WIN_INI
);
166 fprintf(stderr
,"windir = %s\n",WindowsDirectory
);
167 fprintf(stderr
,"sysdir = %s\n",SystemDirectory
);
168 fprintf(stderr
,"tempdir = %s\n",TempDirectory
);
169 fprintf(stderr
,"path = %s\n",WindowsPath
);
173 WORD
DOS_GetEquipment(void)
178 /* borrowed from Ralph Brown's interrupt lists
180 bits 15-14: number of parallel devices
181 bit 13: [Conv] Internal modem
183 bits 11- 9: number of serial devices
185 bits 7- 6: number of diskette drives minus one
186 bits 5- 4: Initial video mode:
192 bit 2: [PS] =1 if pointing device
194 bit 1: =1 if math co-processor
195 bit 0: =1 if diskette available for boot
198 if (DosDrives
[0].rootdir
!= NULL
)
200 if (DosDrives
[1].rootdir
!= NULL
)
205 equipment
= (diskdrives
<< 6) || 0x02;
210 int DOS_ValidDrive(int drive
)
214 fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive);
217 if (drive
>= MAX_DOS_DRIVES
)
219 if (DosDrives
[drive
].rootdir
== NULL
)
221 if (DosDrives
[drive
].disabled
)
227 int DOS_GetDefaultDrive(void)
230 fprintf(stderr
,"GetDefaultDrive (%c)\n",'A'+CurrentDrive
);
233 return( CurrentDrive
);
236 void DOS_SetDefaultDrive(int drive
)
239 fprintf(stderr
,"SetDefaultDrive to %c:\n",'A'+drive
);
242 if (DOS_ValidDrive(drive
))
243 CurrentDrive
= drive
;
248 /* \WINDOWS\\SYSTEM => /windows/system */
258 if (*(p
+1) == '/' || *(p
+1) == '\\')
267 /* /windows//system => \WINDOWS\SYSTEM */
276 if (*s
== '/' || *s
== '\\')
283 int DOS_DisableDrive(int drive
)
285 if (drive
>= MAX_DOS_DRIVES
)
287 if (DosDrives
[drive
].rootdir
== NULL
)
290 DosDrives
[drive
].disabled
= 1;
294 int DOS_EnableDrive(int drive
)
296 if (drive
>= MAX_DOS_DRIVES
)
298 if (DosDrives
[drive
].rootdir
== NULL
)
301 DosDrives
[drive
].disabled
= 0;
305 static void GetUnixDirName(char *rootdir
, char *name
)
308 char *nameptr
, *cwdptr
;
310 cwdptr
= rootdir
+ strlen(rootdir
);
314 fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name);
318 if (*nameptr
== '.' & !filename
) {
320 if (*nameptr
== '\0') {
324 if (*nameptr
== '.') {
326 while (cwdptr
!= rootdir
) {
328 if (*cwdptr
== '/') {
335 if (*nameptr
== '\\' || *nameptr
== '/') {
341 if (*nameptr
== '\\' || *nameptr
== '/') {
350 *cwdptr
++ = *nameptr
++;
357 fprintf(stderr,"%s\n", rootdir);
362 char *GetUnixFileName(char *dosfilename
)
364 /* a:\windows\system.ini => /dos/windows/system.ini */
369 if (dosfilename
[1] == ':')
371 drive
= (islower(*dosfilename
) ? toupper(*dosfilename
) : *dosfilename
) - 'A';
373 if (!DOS_ValidDrive(drive
))
378 drive
= CurrentDrive
;
380 strcpy(temp
, DosDrives
[drive
].rootdir
);
381 strcat(temp
, DosDrives
[drive
].cwd
);
382 GetUnixDirName(temp
+ strlen(DosDrives
[drive
].rootdir
), dosfilename
);
387 fprintf(stderr
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
393 char *DOS_GetCurrentDir(int drive
)
395 /* should return 'WINDOWS\SYSTEM' */
399 if (!DOS_ValidDrive(drive
))
402 strcpy(temp
, DosDrives
[drive
].cwd
);
404 fprintf(stderr
, "2 %s\n", temp
);
408 fprintf(stderr
,"DOS_GetCWD: %c: %s\n",'A'+drive
, temp
+ 1);
413 int DOS_ChangeDir(int drive
, char *dirname
)
417 if (!DOS_ValidDrive(drive
))
420 strcpy(temp
, dirname
);
423 GetUnixDirName(DosDrives
[drive
].cwd
, temp
);
424 strcat(DosDrives
[drive
].cwd
,"/");
426 fprintf(stderr
,"DOS_SetCWD: %c: %s\n",'A'+drive
, DosDrives
[drive
].cwd
);
431 int DOS_MakeDir(int drive
, char *dirname
)
435 if (!DOS_ValidDrive(drive
))
438 strcpy(temp
, DosDrives
[drive
].cwd
);
439 GetUnixDirName(temp
, dirname
);
440 strcat(DosDrives
[drive
].cwd
,"/");
446 fprintf(stderr
,"DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
451 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
453 if (!DOS_ValidDrive(drive
))
456 *serialnumber
= DosDrives
[drive
].serialnumber
;
460 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
462 if (!DOS_ValidDrive(drive
))
465 DosDrives
[drive
].serialnumber
= serialnumber
;
469 char *DOS_GetVolumeLabel(int drive
)
471 if (!DOS_ValidDrive(drive
))
474 return (DosDrives
[drive
].label
);
477 int DOS_SetVolumeLabel(int drive
, char *label
)
479 if (!DOS_ValidDrive(drive
))
482 strncpy(DosDrives
[drive
].label
, label
, 8);
486 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
490 if (!DOS_ValidDrive(drive
))
493 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
494 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",DosDrives
[drive
].rootdir
);
498 *size
= info
.f_bsize
* info
.f_blocks
/ 1024;
499 *available
= info
.f_bavail
* info
.f_bsize
/ 1024;
504 char *FindFile(char *buffer
, int buflen
, char *filename
, char **extensions
,
507 char *workingpath
, *dirname
, *rootname
, **e
;
510 int rootnamelen
, found
= 0;
511 struct stat filestat
;
513 if (strchr(filename
, '\\') != NULL
)
515 strncpy(buffer
, GetUnixFileName(filename
), buflen
);
520 if (strchr(filename
, '/') != NULL
)
522 strncpy(buffer
, filename
, buflen
);
527 fprintf(stderr
,"FindFile: looking for %s\n", filename
);
530 rootnamelen
= strlen(filename
);
531 if ((rootname
= malloc(rootnamelen
+ 1)) == NULL
)
533 strcpy(rootname
, filename
);
536 if ((workingpath
= malloc(strlen(path
) + 1)) == NULL
)
538 strcpy(workingpath
, path
);
540 for(dirname
= strtok(workingpath
, ";");
542 dirname
= strtok(NULL
, ";"))
544 if (strchr(dirname
, '\\') != NULL
)
545 d
= opendir( GetUnixFileName(dirname
) );
547 d
= opendir( dirname
);
550 fprintf(stderr
,"in %s\n",dirname
);
555 while ((f
= readdir(d
)) != NULL
)
557 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) == 0)
559 if (extensions
== NULL
||
560 strcasecmp(rootname
, f
->d_name
) == 0)
563 if (f
->d_name
[rootnamelen
] == '.')
564 for (e
= extensions
; *e
!= NULL
; e
++)
565 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1)
574 if (strchr(dirname
, '\\') != NULL
)
575 strncpy(buffer
, GetUnixFileName(dirname
), buflen
);
577 strncpy(buffer
, dirname
, buflen
);
579 strncat(buffer
, "/", buflen
- strlen(buffer
));
580 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
582 stat(buffer
, &filestat
);
583 if (S_ISREG(filestat
.st_mode
)) {
599 /**********************************************************************
602 char *WineIniFileName(void)
605 static char *filename
= NULL
;
611 strcpy(name
, WINE_INI_USER
);
612 ExpandTildeString(name
);
613 if ((fd
= open(name
, O_RDONLY
)) != -1) {
615 filename
= malloc(strlen(name
) + 1);
616 strcpy(filename
, name
);
619 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
621 filename
= malloc(strlen(WINE_INI_GLOBAL
) + 1);
622 strcpy(filename
, WINE_INI_GLOBAL
);
625 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
626 WINE_INI_GLOBAL
, WINE_INI_USER
);
630 char *WinIniFileName(void)
632 static char *name
= NULL
;
639 strcpy(name
, GetUnixFileName(WindowsDirectory
));
641 strcat(name
, "win.ini");
644 name
= realloc(name
, strlen(name
) + 1);
649 static int match(char *filename
, char *filemask
)
651 int x
, masklength
= strlen(filemask
);
654 fprintf(stderr
, "match: %s, %s\n", filename
, filemask
);
657 for (x
= 0; x
!= masklength
; x
++) {
658 /* printf("(%c%c) ", *filename, filemask[x]);
661 /* stop if EOFname */
664 if (filemask
[x
] == '?') {
665 /* skip the next char */
670 if (filemask
[x
] == '*') {
671 /* skip each char until '.' or EOFname */
672 while (*filename
&& *filename
!='.')
676 if (filemask
[x
] != *filename
)
684 struct dosdirent
*DOS_opendir(char *dosdirname
)
690 for (x
=0; x
!= MAX_OPEN_DIRS
&& DosDirs
[x
].inuse
; x
++)
693 if (x
== MAX_OPEN_DIRS
)
696 if ((unixdirname
= GetUnixFileName(dosdirname
)) == NULL
)
699 strcpy(temp
, unixdirname
);
706 strcpy(DosDirs
[x
].filemask
, temp
+y
);
707 ToDos(DosDirs
[x
].filemask
);
713 fprintf(stderr
,"DOS_opendir: %s -> %s\n", unixdirname
, temp
);
716 DosDirs
[x
].inuse
= 1;
717 strcpy(DosDirs
[x
].unixpath
, temp
);
719 if ((DosDirs
[x
].ds
= opendir(temp
)) == NULL
)
726 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
736 if ((d
= readdir(de
->ds
)) == NULL
)
743 strcpy(de
->filename
, d
->d_name
);
744 if (d
->d_reclen
> 12)
745 de
->filename
[12] = '\0';
748 } while ( !match(de
->filename
, de
->filemask
) );
750 strcpy(temp
,de
->unixpath
);
752 strcat(temp
,de
->filename
);
757 if S_ISDIR(st
.st_mode
)
758 de
->attribute
|= FA_DIREC
;
760 de
->filesize
= st
.st_size
;
761 de
->filetime
= st
.st_mtime
;
766 void DOS_closedir(struct dosdirent
*de
)