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
21 #if defined(__linux__) || defined(sun)
24 #if defined(__NetBSD__) || defined(__FreeBSD__)
25 #include <sys/param.h>
26 #include <sys/mount.h>
27 #include <sys/errno.h>
30 #include <sys/statfs.h>
42 #define WINE_INI_USER "~/.winerc"
43 #define MAX_DOS_DRIVES 26
45 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
47 char WindowsPath
[256];
49 static int CurrentDrive
= 2;
51 struct DosDriveStruct
{ /* eg: */
52 char *rootdir
; /* /usr/windows */
53 char cwd
[256]; /* / */
54 char label
[13]; /* DRIVE-A */
55 unsigned int serialnumber
; /* ABCD5678 */
59 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
60 static struct dosdirent
*DosDirs
=NULL
;
63 BYTE ErrorClass
, Action
, ErrorLocus
;
65 int DOS_Error(int e
, int class, int el
)
68 Action
= SA_Ask4Retry
;
75 void errno_to_doserr(void)
79 DOS_Error (ShareViolation
, EC_Temporary
, EL_Unknown
);
82 DOS_Error (InvalidHandle
, EC_AppError
, EL_Unknown
);
85 DOS_Error (DiskFull
, EC_MediaError
, EL_Disk
);
90 DOS_Error (WriteProtected
, EC_AccessDenied
, EL_Unknown
);
93 DOS_Error (LockViolation
, EC_AccessDenied
, EL_Unknown
);
96 DOS_Error (FileNotFound
, EC_NotFound
, EL_Unknown
);
99 DOS_Error (CanNotMakeDir
, EC_AccessDenied
, EL_Unknown
);
103 DOS_Error (NoMoreFiles
, EC_MediaError
, EL_Unknown
);
106 DOS_Error (FileExists
, EC_Exists
, EL_Disk
);
109 dprintf_int(stddeb
, "int21: unknown errno %d!\n", errno
);
110 DOS_Error (GeneralFailure
, EC_SystemFailure
, EL_Unknown
);
116 static void ExpandTildeString(char *s
)
118 struct passwd
*entry
;
119 char temp
[1024], *ptr
= temp
;
133 if ( (entry
= getpwuid(getuid())) == NULL
)
138 strcpy(s
, entry
->pw_dir
);
139 s
+= strlen(entry
->pw_dir
);
144 /* Simplify the path in "name" by removing "//"'s, "/./"'s, and
145 ".."'s in names like "/usr/bin/../lib/test" */
146 static void DOS_SimplifyPath(char *name
)
151 dprintf_dosfs(stddeb
,"SimplifyPath: Before %s\n",name
);
154 while ((l
= strstr(name
,"//"))) {
155 strcpy(l
,l
+1); changed
= TRUE
;
157 while ((l
= strstr(name
,"/../"))) {
159 p
= strrchr(name
,'/');
160 if (p
== NULL
) p
= name
;
164 while ((l
= strstr(name
, "/./"))) {
165 strcpy(l
, l
+2); changed
= TRUE
;
168 dprintf_dosfs(stddeb
,"SimplifyPath: After %s\n",name
);
172 /* ChopOffSlash takes care to strip directory slashes from the
173 * end off the path name, but leaves a single slash. Multiple
174 * slashes at the end of a path are all removed.
177 void ChopOffSlash(char *path
)
179 char *p
= path
+ strlen(path
) - 1;
180 while ((*p
== '\\') && (p
> path
)) *p
-- = '\0';
186 if (*s
== '\\') *s
= '/';
187 *s
=tolower(*s
); /* umsdos fs can't read files without :( */
195 if (*s
== '/') *s
= '\\';
200 void DOS_InitFS(void)
203 char drive
[2], temp
[256];
204 struct dosdirent
*dp
;
205 GetPrivateProfileString("wine", "windows", "c:\\windows",
206 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
208 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
209 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
211 GetPrivateProfileString("wine", "temp", "c:\\windows",
212 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
214 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
215 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
217 ChopOffSlash(WindowsDirectory
);
218 ToDos(WindowsDirectory
);
220 ChopOffSlash(SystemDirectory
);
221 ToDos(SystemDirectory
);
223 ChopOffSlash(TempDirectory
);
224 ToDos(TempDirectory
);
227 ExpandTildeString(WindowsPath
);
229 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
230 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
234 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
235 if (!strcmp(temp
, "*") || *temp
== '\0') {
236 DosDrives
[x
].rootdir
= NULL
;
237 DosDrives
[x
].cwd
[0] = '\0';
238 DosDrives
[x
].label
[0] = '\0';
239 DosDrives
[x
].disabled
= 1;
242 ExpandTildeString(temp
);
244 DosDrives
[x
].rootdir
= strdup(temp
);
245 strcpy(DosDrives
[x
].rootdir
, temp
);
246 strcpy(DosDrives
[x
].cwd
, "/windows/");
247 strcpy(DosDrives
[x
].label
, "DRIVE-");
248 strcat(DosDrives
[x
].label
, drive
);
249 DosDrives
[x
].disabled
= 0;
251 DosDrives
[25].rootdir
= "/";
252 strcpy(DosDrives
[25].label
, "UNIX-FS");
253 DosDrives
[25].serialnumber
= 0x12345678;
254 DosDrives
[25].disabled
= 0;
256 /* Get the startup directory and try to map it to a DOS drive
257 * and directory. (i.e., if we start in /dos/windows/word and
258 * drive C is defined as /dos, the starting wd for C will be
259 * /windows/word) Also set the default drive to whatever drive
260 * corresponds to the directory we started in.
263 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++)
264 if (DosDrives
[x
].rootdir
!= NULL
)
265 strcpy( DosDrives
[x
].cwd
, "/" );
268 strcat(temp
, "/"); /* For DOS_GetDosFileName */
269 strcpy(DosDrives
[25].cwd
, temp
);
270 strcpy(temp
, DOS_GetDosFileName(temp
));
274 strcpy(DosDrives
[temp
[0] - 'A'].cwd
, &temp
[2]);
275 DOS_SetDefaultDrive(temp
[0] - 'A');
279 DOS_SetDefaultDrive(2);
282 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
283 if (DosDrives
[x
].rootdir
!= NULL
) {
284 dprintf_dosfs(stddeb
, "DOSFS: %c: => %-40s %s %s %X %d\n",
286 DosDrives
[x
].rootdir
,
289 DosDrives
[x
].serialnumber
,
290 DosDrives
[x
].disabled
);
300 dprintf_dosfs(stddeb
,"wine.ini = %s\n",WINE_INI
);
301 dprintf_dosfs(stddeb
,"win.ini = %s\n",WIN_INI
);
302 dprintf_dosfs(stddeb
,"windir = %s\n",WindowsDirectory
);
303 dprintf_dosfs(stddeb
,"sysdir = %s\n",SystemDirectory
);
304 dprintf_dosfs(stddeb
,"tempdir = %s\n",TempDirectory
);
305 dprintf_dosfs(stddeb
,"path = %s\n",WindowsPath
);
308 WORD
DOS_GetEquipment(void)
312 int parallelports
= 0;
316 /* borrowed from Ralph Brown's interrupt lists
318 bits 15-14: number of parallel devices
319 bit 13: [Conv] Internal modem
321 bits 11- 9: number of serial devices
323 bits 7- 6: number of diskette drives minus one
324 bits 5- 4: Initial video mode:
330 bit 2: [PS] =1 if pointing device
332 bit 1: =1 if math co-processor
333 bit 0: =1 if diskette available for boot
335 /* Currently the only of these bits correctly set are:
336 bits 15-14 } Added by William Owen Smith,
337 bits 11-9 } wos@dcs.warwick.ac.uk
342 if (DosDrives
[0].rootdir
!= NULL
)
344 if (DosDrives
[1].rootdir
!= NULL
)
349 for (x
=0; x
!=MAX_PORTS
; x
++) {
350 if (COM
[x
].devicename
)
352 if (LPT
[x
].devicename
)
355 if (serialports
> 7) /* 3 bits -- maximum value = 7 */
357 if (parallelports
> 3) /* 2 bits -- maximum value = 3 */
360 equipment
= (diskdrives
<< 6) | (serialports
<< 9) |
361 (parallelports
<< 14) | 0x02;
363 dprintf_dosfs(stddeb
, "DOS_GetEquipment : diskdrives = %d serialports = %d "
364 "parallelports = %d\n"
365 "DOS_GetEquipment : equipment = %d\n",
366 diskdrives
, serialports
, parallelports
, equipment
);
371 int DOS_ValidDrive(int drive
)
373 dprintf_dosfs(stddeb
,"ValidDrive %c (%d)\n",'A'+drive
,drive
);
375 if (drive
< 0 || drive
>= MAX_DOS_DRIVES
) return 0;
376 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
377 if (DosDrives
[drive
].disabled
) return 0;
379 dprintf_dosfs(stddeb
, " -- valid\n");
383 static void DOS_GetCurrDir_Unix(char *buffer
, int drive
)
385 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
387 if (pTask
!= NULL
&& (pTask
->curdrive
& ~0x80) == drive
) {
388 strcpy(buffer
, pTask
->curdir
);
391 strcpy(buffer
, DosDrives
[drive
].cwd
);
395 char *DOS_GetCurrentDir(int drive
)
397 static char temp
[256];
399 if (!DOS_ValidDrive(drive
)) return 0;
401 DOS_GetCurrDir_Unix(temp
, drive
);
402 DOS_SimplifyPath( temp
);
406 dprintf_dosfs(stddeb
,"DOS_GetCWD: %c:%s\n", 'A'+drive
, temp
);
410 char *DOS_GetUnixFileName(const char *dosfilename
)
412 /* a:\windows\system.ini => /dos/windows/system.ini */
414 /* FIXME: should handle devices here (like LPT: or NUL:) */
416 static char dostemp
[256], temp
[256];
417 int drive
= DOS_GetDefaultDrive();
419 if (dosfilename
[0] && dosfilename
[1] == ':')
421 drive
= toupper(*dosfilename
) - 'A';
424 if (!DOS_ValidDrive(drive
)) return NULL
;
426 strncpy( dostemp
, dosfilename
, 255 );
429 strcpy(temp
, DosDrives
[drive
].rootdir
);
430 if (dostemp
[0] != '/') {
431 DOS_GetCurrDir_Unix(temp
+strlen(temp
), drive
);
433 strcat(temp
, dostemp
);
434 DOS_SimplifyPath(temp
);
436 dprintf_dosfs(stddeb
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
440 /* Note: This function works on directories as well as long as
441 * the directory ends in a slash.
443 char *DOS_GetDosFileName(char *unixfilename
)
446 static char temp
[256], temp2
[256];
447 /* /dos/windows/system.ini => c:\windows\system.ini */
449 dprintf_dosfs(stddeb
,"DOS_GetDosFileName: %s\n", unixfilename
);
450 if (unixfilename
[0] == '/') {
451 strncpy(temp
, unixfilename
, 255);
454 /* Expand it if it's a relative name. */
456 if(strncmp(unixfilename
, "./", 2) == 0) {
457 strcat(temp
, unixfilename
+ 1);
460 strcat(temp
, unixfilename
);
463 for (i
= 0 ; i
< MAX_DOS_DRIVES
; i
++) {
464 if (DosDrives
[i
].rootdir
!= NULL
) {
465 int len
= strlen(DosDrives
[i
].rootdir
);
466 dprintf_dosfs(stddeb
, " check %c:%s\n", i
+'A', DosDrives
[i
].rootdir
);
467 if (strncmp(DosDrives
[i
].rootdir
, temp
, len
) == 0 && temp
[len
] == '/')
469 sprintf(temp2
, "%c:%s", 'A' + i
, temp
+len
);
475 sprintf(temp
, "Z:%s", unixfilename
);
480 int DOS_ValidDirectory(int drive
, char *name
)
485 strcpy(temp
, DosDrives
[drive
].rootdir
);
487 if (stat(temp
, &s
)) return 0;
488 if (!S_ISDIR(s
.st_mode
)) return 0;
489 dprintf_dosfs(stddeb
, "==> OK\n");
493 int DOS_GetDefaultDrive(void)
495 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
496 int drive
= pTask
== NULL
? CurrentDrive
: pTask
->curdrive
& ~0x80;
498 dprintf_dosfs(stddeb
,"GetDefaultDrive (%c)\n",'A'+drive
);
502 void DOS_SetDefaultDrive(int drive
)
504 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
506 dprintf_dosfs(stddeb
,"SetDefaultDrive to %c:\n",'A'+drive
);
507 if (DOS_ValidDrive(drive
) && drive
!= DOS_GetDefaultDrive()) {
508 if (pTask
== NULL
) CurrentDrive
= drive
;
511 pTask
->curdrive
= drive
| 0x80;
512 strcpy(temp
, DosDrives
[drive
].rootdir
);
513 strcat(temp
, DosDrives
[drive
].cwd
);
514 strcpy(temp
, DOS_GetDosFileName(temp
));
515 dprintf_dosfs(stddeb
, " curdir = %s\n", temp
);
516 if (strlen(temp
)-2 < sizeof(pTask
->curdir
)) strcpy(pTask
->curdir
, temp
+2);
517 else fprintf(stderr
, "dosfs: curdir too long\n");
522 int DOS_DisableDrive(int drive
)
524 if (drive
>= MAX_DOS_DRIVES
) return 0;
525 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
527 DosDrives
[drive
].disabled
= 1;
531 int DOS_EnableDrive(int drive
)
533 if (drive
>= MAX_DOS_DRIVES
) return 0;
534 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
536 DosDrives
[drive
].disabled
= 0;
540 int DOS_ChangeDir(int drive
, char *dirname
)
542 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
545 if (!DOS_ValidDrive(drive
)) return 0;
547 if (dirname
[0] == '\\') {
548 strcpy(temp
, dirname
);
550 DOS_GetCurrDir_Unix(temp
, drive
);
551 strcat(temp
, dirname
);
555 DOS_SimplifyPath(temp
);
556 dprintf_dosfs(stddeb
,"DOS_SetCWD: %c: %s ==> %s\n", 'A'+drive
, dirname
, temp
);
558 if (!DOS_ValidDirectory(drive
, temp
)) return 0;
559 strcpy(DosDrives
[drive
].cwd
, temp
);
560 if (pTask
!= NULL
&& DOS_GetDefaultDrive() == drive
) {
561 strcpy(temp
, DosDrives
[drive
].rootdir
);
562 strcat(temp
, DosDrives
[drive
].cwd
);
563 strcpy(temp
, DOS_GetDosFileName(temp
));
564 dprintf_dosfs(stddeb
, " curdir = %s\n", temp
);
565 if (strlen(temp
)-2 < sizeof(pTask
->curdir
)) strcpy(pTask
->curdir
, temp
+2);
566 else fprintf(stderr
, "dosfs: curdir too long\n");
571 int DOS_MakeDir(int drive
, char *dirname
)
573 char temp
[256], currdir
[256];
575 if (!DOS_ValidDrive(drive
)) return 0;
577 strcpy(temp
, DosDrives
[drive
].rootdir
);
578 DOS_GetCurrDir_Unix(currdir
, drive
);
579 strcat(temp
, currdir
);
580 strcat(temp
, dirname
);
582 DOS_SimplifyPath(temp
);
583 if (mkdir(temp
, S_IRWXU
| S_IRWXG
| S_IRWXO
) == -1)
585 dprintf_dosfs(stddeb
, "DOS_MakeDir: %c:\%s => %s failed errno %d",'A'+drive
, dirname
, temp
, errno
);
588 dprintf_dosfs(stddeb
, "DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
592 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
594 if (!DOS_ValidDrive(drive
))
597 *serialnumber
= DosDrives
[drive
].serialnumber
;
601 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
603 if (!DOS_ValidDrive(drive
))
606 DosDrives
[drive
].serialnumber
= serialnumber
;
610 char *DOS_GetVolumeLabel(int drive
)
612 if (!DOS_ValidDrive(drive
))
615 return DosDrives
[drive
].label
;
618 int DOS_SetVolumeLabel(int drive
, char *label
)
620 if (!DOS_ValidDrive(drive
))
623 strncpy(DosDrives
[drive
].label
, label
, 8);
627 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
631 if (!DOS_ValidDrive(drive
))
635 if (statfs(DosDrives
[drive
].rootdir
, &info
, 0, 0) < 0) {
637 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
639 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",
640 DosDrives
[drive
].rootdir
);
644 *size
= info
.f_bsize
* info
.f_blocks
;
646 *available
= info
.f_bfree
* info
.f_bsize
;
648 *available
= info
.f_bavail
* info
.f_bsize
;
654 char *DOS_FindFile(char *buffer
, int buflen
, const char *filename
, char **extensions
,
657 char *workingpath
, *dirname
, *rootname
, **e
;
661 struct stat filestat
;
663 if (strchr(filename
, '\\') != NULL
)
665 strncpy(buffer
, DOS_GetUnixFileName(filename
), buflen
);
666 stat( buffer
, &filestat
);
667 if (S_ISREG(filestat
.st_mode
))
673 if (strchr(filename
, '/') != NULL
)
675 strncpy(buffer
, filename
, buflen
);
679 dprintf_dosfs(stddeb
,"DOS_FindFile: looking for %s\n", filename
);
680 rootnamelen
= strlen(filename
);
681 rootname
= strdup(filename
);
683 workingpath
= strdup(path
);
685 for(dirname
= strtok(workingpath
, ";");
687 dirname
= strtok(NULL
, ";"))
689 if (strchr(dirname
, '\\') != NULL
)
690 d
= opendir( DOS_GetUnixFileName(dirname
) );
692 d
= opendir( dirname
);
694 dprintf_dosfs(stddeb
,"in %s\n",dirname
);
697 while ((f
= readdir(d
)) != NULL
)
699 if (strcasecmp(rootname
, f
->d_name
) != 0) {
700 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) != 0
701 || extensions
== NULL
702 || f
->d_name
[rootnamelen
] != '.')
705 for (e
= extensions
; *e
!= NULL
; e
++) {
706 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1) == 0)
709 if (*e
== NULL
) continue;
712 if (strchr(dirname
, '\\') != NULL
) {
713 strncpy(buffer
, DOS_GetUnixFileName(dirname
), buflen
);
715 strncpy(buffer
, dirname
, buflen
);
718 strncat(buffer
, "/", buflen
- strlen(buffer
));
719 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
721 stat(buffer
, &filestat
);
722 if (S_ISREG(filestat
.st_mode
)) {
725 DOS_SimplifyPath(buffer
);
735 /**********************************************************************
738 char *WineIniFileName(void)
741 static char *filename
= NULL
;
742 static char name
[256];
747 strcpy(name
, WINE_INI_USER
);
748 ExpandTildeString(name
);
749 if ((fd
= open(name
, O_RDONLY
)) != -1) {
754 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
756 filename
= WINE_INI_GLOBAL
;
759 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
760 WINE_INI_GLOBAL
, WINE_INI_USER
);
764 char *WinIniFileName(void)
766 static char *name
= NULL
;
771 name
= xmalloc(1024);
773 strcpy(name
, DOS_GetUnixFileName(WindowsDirectory
));
775 strcat(name
, "win.ini");
777 name
= xrealloc(name
, strlen(name
) + 1);
782 static int match(char *filename
, char *filemask
)
784 char name
[12], mask
[12];
787 dprintf_dosfs(stddeb
, "match: %s, %s\n", filename
, filemask
);
789 for( i
=0; i
<11; i
++ ) {
797 if( !(*filename
) || *filename
== '.' )
800 name
[i
] = toupper( *filename
++ );
801 while( *filename
&& *filename
!= '.' )
805 for( i
=8; i
<11; i
++ )
809 name
[i
] = toupper( *filename
++ );
812 if( !(*filemask
) || *filemask
== '.' )
814 else if( *filemask
== '*' ) {
821 mask
[i
] = toupper( *filemask
++ );
822 while( *filemask
&& *filemask
!= '.' )
826 for( i
=8; i
<11; i
++ )
829 else if (*filemask
== '*' ) {
831 for( j
=i
; j
<11; j
++ )
836 mask
[i
] = toupper( *filemask
++ );
838 dprintf_dosfs(stddeb
, "changed to: %s, %s\n", name
, mask
);
840 for( i
=0; i
<11; i
++ )
841 if( ( name
[i
] != mask
[i
] ) && ( mask
[i
] != '?' ) )
847 struct dosdirent
*DOS_opendir(char *dosdirname
)
853 struct dosdirent
*dp
;
855 if ((unixdirname
= DOS_GetUnixFileName(dosdirname
)) == NULL
) return NULL
;
857 len
= strrchr(unixdirname
, '/') - unixdirname
+ 1;
858 strncpy(dirname
, unixdirname
, len
);
860 unixdirname
= strrchr(unixdirname
, '/') + 1;
861 if ((ds
= opendir(dirname
)) == NULL
)
869 if (strcmp(dp
->unixpath
, dirname
) == 0)
875 dp
= xmalloc(sizeof(struct dosdirent
));
880 strncpy(dp
->filemask
, unixdirname
, 12);
881 dp
->filemask
[12] = 0;
882 dprintf_dosfs(stddeb
,"DOS_opendir: %s / %s\n", unixdirname
, dirname
);
885 strcpy(dp
->unixpath
, dirname
);
888 if (closedir(ds
) == -1)
897 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
899 char temp
[WINE_PATH_LENGTH
];
907 if (!(ds
=opendir(de
->unixpath
))) return NULL
;
908 /* skip all already read directory entries.
909 * the dir has hopefully not been modified in the meantime
911 for (i
=de
->entnum
;i
--;)
914 if (de
->search_attribute
& FA_LABEL
) {
916 de
->search_attribute
&= ~FA_LABEL
; /* don't find it again */
917 for(drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++) {
918 if (DosDrives
[drive
].rootdir
!= NULL
&&
919 strcmp(DosDrives
[drive
].rootdir
, de
->unixpath
) == 0)
921 strcpy(de
->filename
, DOS_GetVolumeLabel(drive
));
922 de
->attribute
= FA_LABEL
;
929 de
->entnum
++; /* Increment the directory entry number */
930 if ((d
= readdir(ds
)) == NULL
) {
934 strcpy(de
->filename
, d
->d_name
);
935 if (d
->d_reclen
> 12)
936 de
->filename
[12] = '\0';
939 strcpy(temp
,de
->unixpath
);
941 strcat(temp
,d
->d_name
);
944 if S_ISDIR(st
.st_mode
)
945 de
->attribute
|= FA_DIREC
;
947 } while (!(de
->attribute
& FA_DIREC
) &&
948 !match(de
->filename
, de
->filemask
) );
951 de
->filesize
= st
.st_size
;
952 de
->filetime
= st
.st_mtime
;
958 void DOS_closedir(struct dosdirent
*de
)
964 char *DOS_GetRedirectedDir(int drive
)
966 if(DOS_ValidDrive(drive
))
967 return (DosDrives
[drive
].rootdir
);