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"
32 /* #define DEBUG /* */
34 #define WINE_INI_USER "~/.winerc"
35 #define MAX_OPEN_DIRS 16
36 #define MAX_DOS_DRIVES 26
38 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
40 char WindowsPath
[256];
42 static int CurrentDrive
= 2;
44 struct DosDriveStruct
{ /* eg: */
45 char *rootdir
; /* /usr/windows */
46 char cwd
[256]; /* / */
47 char label
[13]; /* DRIVE-A */
48 unsigned int serialnumber
; /* ABCD5678 */
52 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
53 static struct dosdirent DosDirs
[MAX_OPEN_DIRS
];
55 static void ExpandTildeString(char *s
)
58 char temp
[1024], *ptr
= temp
;
72 if ( (entry
= getpwuid(getuid())) == NULL
)
77 strcpy(s
, entry
->pw_dir
);
78 s
+= strlen(entry
->pw_dir
);
83 void ChopOffSlash(char *path
)
85 if (path
[strlen(path
)-1] == '/' || path
[strlen(path
)-1] == '\\')
86 path
[strlen(path
)-1] = '\0';
92 char drive
[2], temp
[256], *ptr
;
94 GetPrivateProfileString("wine", "windows", "c:\\windows",
95 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
97 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
98 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
100 GetPrivateProfileString("wine", "temp", "c:\\windows",
101 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
103 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
104 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
106 ChopOffSlash(WindowsDirectory
);
107 ToDos(WindowsDirectory
);
109 ChopOffSlash(SystemDirectory
);
110 ToDos(SystemDirectory
);
112 ChopOffSlash(TempDirectory
);
113 ToDos(TempDirectory
);
116 ExpandTildeString(WindowsPath
);
118 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
119 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
123 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
124 if (!strcmp(temp
, "*") || *temp
== '\0') {
125 DosDrives
[x
].rootdir
= NULL
;
126 DosDrives
[x
].cwd
[0] = '\0';
127 DosDrives
[x
].label
[0] = '\0';
128 DosDrives
[x
].disabled
= 1;
131 ExpandTildeString(temp
);
133 DosDrives
[x
].rootdir
= strdup(temp
);
134 strcpy(DosDrives
[x
].rootdir
, temp
);
135 strcpy(DosDrives
[x
].cwd
, "/windows/");
136 strcpy(DosDrives
[x
].label
, "DRIVE-");
137 strcat(DosDrives
[x
].label
, drive
);
138 DosDrives
[x
].disabled
= 0;
140 DOS_SetDefaultDrive(2);
142 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
143 if (DosDrives
[x
].rootdir
!= NULL
) {
145 fprintf(stderr
, "DOSFS: %c: => %-40s %s %s %X %d\n",
147 DosDrives
[x
].rootdir
,
150 DosDrives
[x
].serialnumber
,
151 DosDrives
[x
].disabled
157 for (x
=0; x
!=MAX_OPEN_DIRS
; x
++)
158 DosDirs
[x
].inuse
= 0;
161 fprintf(stderr
,"wine.ini = %s\n",WINE_INI
);
162 fprintf(stderr
,"win.ini = %s\n",WIN_INI
);
163 fprintf(stderr
,"windir = %s\n",WindowsDirectory
);
164 fprintf(stderr
,"sysdir = %s\n",SystemDirectory
);
165 fprintf(stderr
,"tempdir = %s\n",TempDirectory
);
166 fprintf(stderr
,"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;
228 fprintf(stderr
, "DOS_GetEquipment : diskdrives = %d serialports = %d "
229 "parallelports = %d\n"
230 "DOS_GetEquipment : equipment = %d\n",
231 diskdrives
, serialports
, parallelports
, equipment
);
237 int DOS_ValidDrive(int drive
)
241 fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive);
244 if (drive
>= MAX_DOS_DRIVES
)
246 if (DosDrives
[drive
].rootdir
== NULL
)
248 if (DosDrives
[drive
].disabled
)
254 int DOS_GetDefaultDrive(void)
257 fprintf(stderr
,"GetDefaultDrive (%c)\n",'A'+CurrentDrive
);
260 return( CurrentDrive
);
263 void DOS_SetDefaultDrive(int drive
)
266 fprintf(stderr
,"SetDefaultDrive to %c:\n",'A'+drive
);
269 if (DOS_ValidDrive(drive
))
270 CurrentDrive
= drive
;
275 /* \WINDOWS\\SYSTEM => /windows/system */
285 if (*(p
+1) == '/' || *(p
+1) == '\\')
294 /* /windows//system => \WINDOWS\SYSTEM */
303 if (*(p
+1) == '/' || *(p
+1) == '\\')
310 int DOS_DisableDrive(int drive
)
312 if (drive
>= MAX_DOS_DRIVES
)
314 if (DosDrives
[drive
].rootdir
== NULL
)
317 DosDrives
[drive
].disabled
= 1;
321 int DOS_EnableDrive(int drive
)
323 if (drive
>= MAX_DOS_DRIVES
)
325 if (DosDrives
[drive
].rootdir
== NULL
)
328 DosDrives
[drive
].disabled
= 0;
332 static void GetUnixDirName(char *rootdir
, char *name
)
335 char *nameptr
, *cwdptr
;
337 cwdptr
= rootdir
+ strlen(rootdir
);
341 fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name);
345 if (*nameptr
== '.' & !filename
) {
347 if (*nameptr
== '\0') {
351 if (*nameptr
== '.') {
353 while (cwdptr
!= rootdir
) {
355 if (*cwdptr
== '/') {
362 if (*nameptr
== '\\' || *nameptr
== '/') {
368 if (*nameptr
== '\\' || *nameptr
== '/') {
377 *cwdptr
++ = *nameptr
++;
384 fprintf(stderr,"%s\n", rootdir);
389 char *GetUnixFileName(char *dosfilename
)
391 /* a:\windows\system.ini => /dos/windows/system.ini */
393 static char temp
[256];
396 if (dosfilename
[1] == ':')
398 drive
= (islower(*dosfilename
) ? toupper(*dosfilename
) : *dosfilename
) - 'A';
400 if (!DOS_ValidDrive(drive
))
405 drive
= CurrentDrive
;
407 strcpy(temp
, DosDrives
[drive
].rootdir
);
408 strcat(temp
, DosDrives
[drive
].cwd
);
409 GetUnixDirName(temp
+ strlen(DosDrives
[drive
].rootdir
), dosfilename
);
414 fprintf(stderr
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
420 char *GetDosFileName(char *unixfilename
)
423 static char temp
[256], rootdir
[256];
424 /* /dos/windows/system.ini => c:\windows\system.ini */
426 for (i
= 0 ; i
!= MAX_DOS_DRIVES
; i
++) {
427 if (DosDrives
[i
].rootdir
!= NULL
) {
428 strcpy(rootdir
, DosDrives
[i
].rootdir
);
429 strcat(rootdir
, "/");
431 if (strncmp(rootdir
, unixfilename
, strlen(rootdir
)) == 0) {
432 sprintf(temp
, "%c:\\%s", 'A' + i
, unixfilename
+ strlen(rootdir
));
438 sprintf(temp
, "UNIX:%s", unixfilename
);
443 char *DOS_GetCurrentDir(int drive
)
445 /* should return 'WINDOWS\SYSTEM' */
449 if (!DOS_ValidDrive(drive
))
452 strcpy(temp
, DosDrives
[drive
].cwd
);
454 fprintf(stderr
, "2 %s\n", temp
);
458 fprintf(stderr
,"DOS_GetCWD: %c: %s\n",'A'+drive
, temp
+ 1);
463 int DOS_ChangeDir(int drive
, char *dirname
)
467 if (!DOS_ValidDrive(drive
))
470 strcpy(temp
, dirname
);
473 GetUnixDirName(DosDrives
[drive
].cwd
, temp
);
474 strcat(DosDrives
[drive
].cwd
,"/");
476 fprintf(stderr
,"DOS_SetCWD: %c: %s\n",'A'+drive
, DosDrives
[drive
].cwd
);
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
,"/");
496 fprintf(stderr
,"DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
501 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
503 if (!DOS_ValidDrive(drive
))
506 *serialnumber
= DosDrives
[drive
].serialnumber
;
510 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
512 if (!DOS_ValidDrive(drive
))
515 DosDrives
[drive
].serialnumber
= serialnumber
;
519 char *DOS_GetVolumeLabel(int drive
)
521 if (!DOS_ValidDrive(drive
))
524 return (DosDrives
[drive
].label
);
527 int DOS_SetVolumeLabel(int drive
, char *label
)
529 if (!DOS_ValidDrive(drive
))
532 strncpy(DosDrives
[drive
].label
, label
, 8);
536 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
540 if (!DOS_ValidDrive(drive
))
543 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
544 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",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
);
567 stat( buffer
, &filestat
);
568 if (S_ISREG(filestat
.st_mode
))
574 if (strchr(filename
, '/') != NULL
)
576 strncpy(buffer
, filename
, buflen
);
581 fprintf(stderr
,"FindFile: looking for %s\n", filename
);
584 rootnamelen
= strlen(filename
);
585 if ((rootname
= malloc(rootnamelen
+ 1)) == NULL
)
587 strcpy(rootname
, filename
);
590 if ((workingpath
= malloc(strlen(path
) + 1)) == NULL
)
592 strcpy(workingpath
, path
);
594 for(dirname
= strtok(workingpath
, ";");
596 dirname
= strtok(NULL
, ";"))
598 if (strchr(dirname
, '\\') != NULL
)
599 d
= opendir( GetUnixFileName(dirname
) );
601 d
= opendir( dirname
);
604 fprintf(stderr
,"in %s\n",dirname
);
609 while ((f
= readdir(d
)) != NULL
)
611 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) == 0)
613 if (extensions
== NULL
||
614 strcasecmp(rootname
, f
->d_name
) == 0)
617 if (f
->d_name
[rootnamelen
] == '.')
618 for (e
= extensions
; *e
!= NULL
; e
++)
619 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1)
628 if (strchr(dirname
, '\\') != NULL
)
629 strncpy(buffer
, GetUnixFileName(dirname
), buflen
);
631 strncpy(buffer
, dirname
, buflen
);
633 strncat(buffer
, "/", buflen
- strlen(buffer
));
634 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
636 stat(buffer
, &filestat
);
637 if (S_ISREG(filestat
.st_mode
)) {
653 /**********************************************************************
656 char *WineIniFileName(void)
659 static char *filename
= NULL
;
665 strcpy(name
, WINE_INI_USER
);
666 ExpandTildeString(name
);
667 if ((fd
= open(name
, O_RDONLY
)) != -1) {
669 filename
= malloc(strlen(name
) + 1);
670 strcpy(filename
, name
);
673 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
675 filename
= malloc(strlen(WINE_INI_GLOBAL
) + 1);
676 strcpy(filename
, WINE_INI_GLOBAL
);
679 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
680 WINE_INI_GLOBAL
, WINE_INI_USER
);
684 char *WinIniFileName(void)
686 static char *name
= NULL
;
693 strcpy(name
, GetUnixFileName(WindowsDirectory
));
695 strcat(name
, "win.ini");
698 name
= realloc(name
, strlen(name
) + 1);
703 static int match(char *filename
, char *filemask
)
705 int x
, masklength
= strlen(filemask
);
708 fprintf(stderr
, "match: %s, %s\n", filename
, filemask
);
711 for (x
= 0; x
!= masklength
; x
++) {
712 /* printf("(%c%c) ", *filename, filemask[x]);
715 /* stop if EOFname */
718 if (filemask
[x
] == '?') {
719 /* skip the next char */
724 if (filemask
[x
] == '*') {
725 /* skip each char until '.' or EOFname */
726 while (*filename
&& *filename
!='.')
730 if (filemask
[x
] != *filename
)
738 struct dosdirent
*DOS_opendir(char *dosdirname
)
744 for (x
=0; x
!= MAX_OPEN_DIRS
&& DosDirs
[x
].inuse
; x
++)
747 if (x
== MAX_OPEN_DIRS
)
750 if ((unixdirname
= GetUnixFileName(dosdirname
)) == NULL
)
753 strcpy(temp
, unixdirname
);
760 strcpy(DosDirs
[x
].filemask
, temp
+y
);
761 ToDos(DosDirs
[x
].filemask
);
767 fprintf(stderr
,"DOS_opendir: %s -> %s\n", unixdirname
, temp
);
770 DosDirs
[x
].inuse
= 1;
771 strcpy(DosDirs
[x
].unixpath
, temp
);
773 if ((DosDirs
[x
].ds
= opendir(temp
)) == NULL
)
780 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
790 if ((d
= readdir(de
->ds
)) == NULL
)
793 strcpy(de
->filename
, d
->d_name
);
794 if (d
->d_reclen
> 12)
795 de
->filename
[12] = '\0';
798 } while ( !match(de
->filename
, de
->filemask
) );
800 strcpy(temp
,de
->unixpath
);
802 strcat(temp
,de
->filename
);
807 if S_ISDIR(st
.st_mode
)
808 de
->attribute
|= FA_DIREC
;
810 de
->filesize
= st
.st_size
;
811 de
->filetime
= st
.st_mtime
;
816 void DOS_closedir(struct dosdirent
*de
)