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
;
67 if ( (entry
= getpwuid(getuid())) == NULL
) {
70 strcpy(s
, entry
->pw_dir
);
71 s
+= strlen(entry
->pw_dir
);
75 void ChopOffSlash(char *path
)
77 if (path
[strlen(path
)-1] == '/' || path
[strlen(path
)-1] == '\\')
78 path
[strlen(path
)-1] = '\0';
84 char drive
[2], temp
[256], *ptr
;
86 GetPrivateProfileString("wine", "windows", "c:\\windows",
87 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
89 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
90 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
92 GetPrivateProfileString("wine", "temp", "c:\\windows",
93 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
95 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
96 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
98 ChopOffSlash(WindowsDirectory
);
99 ToDos(WindowsDirectory
);
101 ChopOffSlash(SystemDirectory
);
102 ToDos(SystemDirectory
);
104 ChopOffSlash(TempDirectory
);
105 ToDos(TempDirectory
);
108 ExpandTildeString(WindowsPath
);
110 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
111 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
115 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
116 if (!strcmp(temp
, "*") || *temp
== '\0') {
117 DosDrives
[x
].rootdir
= NULL
;
118 DosDrives
[x
].cwd
[0] = '\0';
119 DosDrives
[x
].label
[0] = '\0';
120 DosDrives
[x
].disabled
= 1;
123 ExpandTildeString(temp
);
124 if ((ptr
= (char *) malloc(strlen(temp
)+1)) == NULL
) {
125 fprintf(stderr
,"DOSFS: can't malloc for drive info!");
129 DosDrives
[x
].rootdir
= ptr
;
130 strcpy(DosDrives
[x
].rootdir
, temp
);
131 strcpy(DosDrives
[x
].cwd
, "/windows/");
132 strcpy(DosDrives
[x
].label
, "DRIVE-");
133 strcat(DosDrives
[x
].label
, drive
);
134 DosDrives
[x
].disabled
= 0;
136 DOS_SetDefaultDrive(2);
138 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
139 if (DosDrives
[x
].rootdir
!= NULL
) {
141 fprintf(stderr
, "DOSFS: %c: => %-40s %s %s %X %d\n",
143 DosDrives
[x
].rootdir
,
146 DosDrives
[x
].serialnumber
,
147 DosDrives
[x
].disabled
153 for (x
=0; x
!=MAX_OPEN_DIRS
; x
++)
154 DosDirs
[x
].inuse
= 0;
157 fprintf(stderr
,"wine.ini = %s\n",WINE_INI
);
158 fprintf(stderr
,"win.ini = %s\n",WIN_INI
);
159 fprintf(stderr
,"windir = %s\n",WindowsDirectory
);
160 fprintf(stderr
,"sysdir = %s\n",SystemDirectory
);
161 fprintf(stderr
,"tempdir = %s\n",TempDirectory
);
162 fprintf(stderr
,"path = %s\n",WindowsPath
);
166 WORD
DOS_GetEquipment(void)
171 /* borrowed from Ralph Brown's interrupt lists
173 bits 15-14: number of parallel devices
174 bit 13: [Conv] Internal modem
176 bits 11- 9: number of serial devices
178 bits 7- 6: number of diskette drives minus one
179 bits 5- 4: Initial video mode:
185 bit 2: [PS] =1 if pointing device
187 bit 1: =1 if math co-processor
188 bit 0: =1 if diskette available for boot
191 if (DosDrives
[0].rootdir
!= NULL
)
193 if (DosDrives
[1].rootdir
!= NULL
)
198 equipment
= (diskdrives
<< 6) || 0x02;
203 int DOS_ValidDrive(int drive
)
207 fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive);
210 if (drive
>= MAX_DOS_DRIVES
)
212 if (DosDrives
[drive
].rootdir
== NULL
)
214 if (DosDrives
[drive
].disabled
)
220 int DOS_GetDefaultDrive(void)
223 fprintf(stderr
,"GetDefaultDrive (%c)\n",'A'+CurrentDrive
);
226 return( CurrentDrive
);
229 void DOS_SetDefaultDrive(int drive
)
232 fprintf(stderr
,"SetDefaultDrive to %c:\n",'A'+drive
);
235 if (DOS_ValidDrive(drive
))
236 CurrentDrive
= drive
;
241 /* \WINDOWS\\SYSTEM => /windows/system */
251 if (*(p
+1) == '/' || *(p
+1) == '\\')
260 /* /windows//system => \WINDOWS\SYSTEM */
269 if (*s
== '/' || *s
== '\\')
276 int DOS_DisableDrive(int drive
)
278 if (drive
>= MAX_DOS_DRIVES
)
280 if (DosDrives
[drive
].rootdir
== NULL
)
283 DosDrives
[drive
].disabled
= 1;
287 int DOS_EnableDrive(int drive
)
289 if (drive
>= MAX_DOS_DRIVES
)
291 if (DosDrives
[drive
].rootdir
== NULL
)
294 DosDrives
[drive
].disabled
= 0;
298 static void GetUnixDirName(char *rootdir
, char *name
)
301 char *nameptr
, *cwdptr
;
303 cwdptr
= rootdir
+ strlen(rootdir
);
307 fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name);
311 if (*nameptr
== '.' & !filename
) {
313 if (*nameptr
== '\0') {
317 if (*nameptr
== '.') {
319 while (cwdptr
!= rootdir
) {
321 if (*cwdptr
== '/') {
328 if (*nameptr
== '\\' || *nameptr
== '/') {
334 if (*nameptr
== '\\' || *nameptr
== '/') {
343 *cwdptr
++ = *nameptr
++;
350 fprintf(stderr,"%s\n", rootdir);
355 char *GetUnixFileName(char *dosfilename
)
357 /* a:\windows\system.ini => /dos/windows/system.ini */
362 if (dosfilename
[1] == ':')
364 drive
= (islower(*dosfilename
) ? toupper(*dosfilename
) : *dosfilename
) - 'A';
366 if (!DOS_ValidDrive(drive
))
371 drive
= CurrentDrive
;
373 strcpy(temp
, DosDrives
[drive
].rootdir
);
374 strcat(temp
, DosDrives
[drive
].cwd
);
375 GetUnixDirName(temp
+ strlen(DosDrives
[drive
].rootdir
), dosfilename
);
380 fprintf(stderr
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
386 char *DOS_GetCurrentDir(int drive
)
388 /* should return 'WINDOWS\SYSTEM' */
392 if (!DOS_ValidDrive(drive
))
395 strcpy(temp
, DosDrives
[drive
].cwd
);
397 fprintf(stderr
, "2 %s\n", temp
);
401 fprintf(stderr
,"DOS_GetCWD: %c: %s\n",'A'+drive
, temp
+ 1);
406 int DOS_ChangeDir(int drive
, char *dirname
)
410 if (!DOS_ValidDrive(drive
))
413 strcpy(temp
, dirname
);
416 GetUnixDirName(DosDrives
[drive
].cwd
, temp
);
417 strcat(DosDrives
[drive
].cwd
,"/");
419 fprintf(stderr
,"DOS_SetCWD: %c: %s\n",'A'+drive
, DosDrives
[drive
].cwd
);
424 int DOS_MakeDir(int drive
, char *dirname
)
428 if (!DOS_ValidDrive(drive
))
431 strcpy(temp
, DosDrives
[drive
].cwd
);
432 GetUnixDirName(temp
, dirname
);
433 strcat(DosDrives
[drive
].cwd
,"/");
439 fprintf(stderr
,"DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
444 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
446 if (!DOS_ValidDrive(drive
))
449 *serialnumber
= DosDrives
[drive
].serialnumber
;
453 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
455 if (!DOS_ValidDrive(drive
))
458 DosDrives
[drive
].serialnumber
= serialnumber
;
462 char *DOS_GetVolumeLabel(int drive
)
464 if (!DOS_ValidDrive(drive
))
467 return (DosDrives
[drive
].label
);
470 int DOS_SetVolumeLabel(int drive
, char *label
)
472 if (!DOS_ValidDrive(drive
))
475 strncpy(DosDrives
[drive
].label
, label
, 8);
479 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
483 if (!DOS_ValidDrive(drive
))
486 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
487 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",DosDrives
[drive
].rootdir
);
491 *size
= info
.f_bsize
* info
.f_blocks
/ 1024;
492 *available
= info
.f_bavail
* info
.f_bsize
/ 1024;
497 char *FindFile(char *buffer
, int buflen
, char *filename
, char **extensions
,
500 char *workingpath
, *dirname
, *rootname
, **e
;
503 int rootnamelen
, found
= 0;
504 struct stat filestat
;
506 if (strchr(filename
, '\\') != NULL
)
508 strncpy(buffer
, GetUnixFileName(filename
), buflen
);
513 if (strchr(filename
, '/') != NULL
)
515 strncpy(buffer
, filename
, buflen
);
520 fprintf(stderr
,"FindFile: looking for %s\n", filename
);
523 rootnamelen
= strlen(filename
);
524 if ((rootname
= malloc(rootnamelen
+ 1)) == NULL
)
526 strcpy(rootname
, filename
);
529 if ((workingpath
= malloc(strlen(path
) + 1)) == NULL
)
531 strcpy(workingpath
, path
);
533 for(dirname
= strtok(workingpath
, ";");
535 dirname
= strtok(NULL
, ";"))
537 if (strchr(dirname
, '\\') != NULL
)
538 d
= opendir( GetUnixFileName(dirname
) );
540 d
= opendir( dirname
);
543 fprintf(stderr
,"in %s\n",dirname
);
548 while ((f
= readdir(d
)) != NULL
)
550 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) == 0)
552 if (extensions
== NULL
||
553 strcasecmp(rootname
, f
->d_name
) == 0)
556 if (f
->d_name
[rootnamelen
] == '.')
557 for (e
= extensions
; *e
!= NULL
; e
++)
558 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1)
567 if (strchr(dirname
, '\\') != NULL
)
568 strncpy(buffer
, GetUnixFileName(dirname
), buflen
);
570 strncpy(buffer
, dirname
, buflen
);
572 strncat(buffer
, "/", buflen
- strlen(buffer
));
573 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
575 fprintf(stderr
,"$$%s$$\n", buffer
);
577 stat(buffer
, &filestat
);
578 if (S_ISREG(filestat
.st_mode
)) {
594 /**********************************************************************
597 char *WineIniFileName(void)
600 static char *filename
= NULL
;
606 strcpy(name
, WINE_INI_USER
);
607 ExpandTildeString(name
);
608 if ((fd
= open(name
, O_RDONLY
)) != -1) {
610 filename
= malloc(strlen(name
) + 1);
611 strcpy(filename
, name
);
614 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
616 filename
= malloc(strlen(WINE_INI_GLOBAL
) + 1);
617 strcpy(filename
, WINE_INI_GLOBAL
);
620 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
621 WINE_INI_GLOBAL
, WINE_INI_USER
);
625 char *WinIniFileName(void)
627 static char *name
= NULL
;
634 strcpy(name
, GetUnixFileName(WindowsDirectory
));
636 strcat(name
, "win.ini");
639 name
= realloc(name
, strlen(name
) + 1);
644 static int match(char *filename
, char *filemask
)
646 int x
, masklength
= strlen(filemask
);
649 fprintf(stderr
, "match: %s, %s\n", filename
, filemask
);
652 for (x
= 0; x
!= masklength
; x
++) {
653 /* printf("(%c%c) ", *filename, filemask[x]);
656 /* stop if EOFname */
659 if (filemask
[x
] == '?') {
660 /* skip the next char */
665 if (filemask
[x
] == '*') {
666 /* skip each char until '.' or EOFname */
667 while (*filename
&& *filename
!='.')
671 if (filemask
[x
] != *filename
)
679 struct dosdirent
*DOS_opendir(char *dosdirname
)
685 for (x
=0; x
!= MAX_OPEN_DIRS
&& DosDirs
[x
].inuse
; x
++)
688 if (x
== MAX_OPEN_DIRS
)
691 if ((unixdirname
= GetUnixFileName(dosdirname
)) == NULL
)
694 strcpy(temp
, unixdirname
);
701 strcpy(DosDirs
[x
].filemask
, temp
+y
);
702 ToDos(DosDirs
[x
].filemask
);
708 fprintf(stderr
,"DOS_opendir: %s -> %s\n", unixdirname
, temp
);
711 DosDirs
[x
].inuse
= 1;
712 strcpy(DosDirs
[x
].unixpath
, temp
);
714 if ((DosDirs
[x
].ds
= opendir(temp
)) == NULL
)
721 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
731 if ((d
= readdir(de
->ds
)) == NULL
)
738 strcpy(de
->filename
, d
->d_name
);
739 if (d
->d_reclen
> 12)
740 de
->filename
[12] = '\0';
743 } while ( !match(de
->filename
, de
->filemask
) );
745 strcpy(temp
,de
->unixpath
);
747 strcat(temp
,de
->filename
);
752 if S_ISDIR(st
.st_mode
)
753 de
->attribute
|= FA_DIREC
;
755 de
->filesize
= st
.st_size
;
756 de
->filetime
= st
.st_mtime
;
761 void DOS_closedir(struct dosdirent
*de
)