Release 950620
[wine/multimedia.git] / misc / dos_fs.c
blobc9864c87df60b01a13ffe01f8c069cce0f89bd8c
1 /*
2 * DOS-FS
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
8 */
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <pwd.h>
16 #include <dirent.h>
17 #include <unistd.h>
18 #include <fcntl.h>
20 #if defined(__linux__) || defined(sun)
21 #include <sys/vfs.h>
22 #endif
23 #if defined(__NetBSD__) || defined(__FreeBSD__)
24 #include <sys/param.h>
25 #include <sys/mount.h>
26 #endif
28 #include "wine.h"
29 #include "windows.h"
30 #include "msdos.h"
31 #include "dos_fs.h"
32 #include "autoconf.h"
33 #include "comm.h"
34 #include "stddebug.h"
35 #include "debug.h"
37 #define WINE_INI_USER "~/.winerc"
38 #define MAX_OPEN_DIRS 16
39 #define MAX_DOS_DRIVES 26
41 extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256];
43 char WindowsPath[256];
45 static int CurrentDrive = 2;
47 struct DosDriveStruct { /* eg: */
48 char *rootdir; /* /usr/windows */
49 char cwd[256]; /* / */
50 char label[13]; /* DRIVE-A */
51 unsigned int serialnumber; /* ABCD5678 */
52 int disabled; /* 0 */
55 static struct DosDriveStruct DosDrives[MAX_DOS_DRIVES];
56 static struct dosdirent DosDirs[MAX_OPEN_DIRS];
58 static void ExpandTildeString(char *s)
60 struct passwd *entry;
61 char temp[1024], *ptr = temp;
63 strcpy(temp, s);
65 while (*ptr)
67 if (*ptr != '~')
69 *s++ = *ptr++;
70 continue;
73 ptr++;
75 if ( (entry = getpwuid(getuid())) == NULL)
77 continue;
80 strcpy(s, entry->pw_dir);
81 s += strlen(entry->pw_dir);
83 *s = 0;
86 void ChopOffSlash(char *path)
88 if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == '\\')
89 path[strlen(path)-1] = '\0';
92 void ToUnix(char *s)
94 /* \WINDOWS\\SYSTEM => /windows/system */
96 char *p;
98 for (p = s; *p; p++)
100 if (*p != '\\')
101 *s++ = tolower(*p);
102 else {
103 *s++ = '/';
104 if (*(p+1) == '/' || *(p+1) == '\\')
105 p++;
108 *s = '\0';
111 void ToDos(char *s)
113 /* /windows//system => \WINDOWS\SYSTEM */
115 char *p;
116 for (p = s; *p; p++)
118 if (*p != '/')
119 *s++ = toupper(*p);
120 else {
121 *s++ = '\\';
122 if (*(p+1) == '/' || *(p+1) == '\\')
123 p++;
126 *s = '\0';
129 void DOS_InitFS(void)
131 int x;
132 char drive[2], temp[256];
134 GetPrivateProfileString("wine", "windows", "c:\\windows",
135 WindowsDirectory, sizeof(WindowsDirectory), WINE_INI);
137 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
138 SystemDirectory, sizeof(SystemDirectory), WINE_INI);
140 GetPrivateProfileString("wine", "temp", "c:\\windows",
141 TempDirectory, sizeof(TempDirectory), WINE_INI);
143 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
144 WindowsPath, sizeof(WindowsPath), WINE_INI);
146 ChopOffSlash(WindowsDirectory);
147 ToDos(WindowsDirectory);
149 ChopOffSlash(SystemDirectory);
150 ToDos(SystemDirectory);
152 ChopOffSlash(TempDirectory);
153 ToDos(TempDirectory);
155 ToDos(WindowsPath);
156 ExpandTildeString(WindowsPath);
158 for (x=0; x!=MAX_DOS_DRIVES; x++) {
159 DosDrives[x].serialnumber = (0xEB0500L | x);
161 drive[0] = 'A' + x;
162 drive[1] = '\0';
163 GetPrivateProfileString("drives", drive, "*", temp, sizeof(temp), WINE_INI);
164 if (!strcmp(temp, "*") || *temp == '\0') {
165 DosDrives[x].rootdir = NULL;
166 DosDrives[x].cwd[0] = '\0';
167 DosDrives[x].label[0] = '\0';
168 DosDrives[x].disabled = 1;
169 continue;
171 ExpandTildeString(temp);
172 ChopOffSlash(temp);
173 DosDrives[x].rootdir = strdup(temp);
174 strcpy(DosDrives[x].rootdir, temp);
175 strcpy(DosDrives[x].cwd, "/windows/");
176 strcpy(DosDrives[x].label, "DRIVE-");
177 strcat(DosDrives[x].label, drive);
178 DosDrives[x].disabled = 0;
180 DosDrives[25].rootdir = "/";
181 strcpy(DosDrives[25].cwd, "/");
182 strcpy(DosDrives[25].label, "UNIX-FS");
183 DosDrives[25].serialnumber = 0x12345678;
184 DosDrives[25].disabled = 0;
186 /* Get the startup directory and try to map it to a DOS drive
187 * and directory. (i.e., if we start in /dos/windows/word and
188 * drive C is defined as /dos, the starting wd for C will be
189 * /windows/word) Also set the default drive to whatever drive
190 * corresponds to the directory we started in.
193 for (x=0; x!=MAX_DOS_DRIVES; x++)
194 if (DosDrives[x].rootdir != NULL)
195 strcpy( DosDrives[x].cwd, "\\" );
197 getcwd(temp, 254);
198 strcat(temp, "/"); /* For DOS_GetDosFileName */
199 strcpy(temp, DOS_GetDosFileName(temp));
200 if(temp[0] != 'Z')
202 ToUnix(&temp[2]);
203 strcpy(DosDrives[temp[0] - 'A'].cwd, &temp[2]);
204 DOS_SetDefaultDrive(temp[0] - 'A');
206 else
208 DOS_SetDefaultDrive(2);
211 for (x=0; x!=MAX_DOS_DRIVES; x++) {
212 if (DosDrives[x].rootdir != NULL) {
213 dprintf_dosfs(stddeb, "DOSFS: %c: => %-40s %s %s %X %d\n",
214 'A'+x,
215 DosDrives[x].rootdir,
216 DosDrives[x].cwd,
217 DosDrives[x].label,
218 DosDrives[x].serialnumber,
219 DosDrives[x].disabled
224 for (x=0; x!=MAX_OPEN_DIRS ; x++)
225 DosDirs[x].inuse = 0;
227 dprintf_dosfs(stddeb,"wine.ini = %s\n",WINE_INI);
228 dprintf_dosfs(stddeb,"win.ini = %s\n",WIN_INI);
229 dprintf_dosfs(stddeb,"windir = %s\n",WindowsDirectory);
230 dprintf_dosfs(stddeb,"sysdir = %s\n",SystemDirectory);
231 dprintf_dosfs(stddeb,"tempdir = %s\n",TempDirectory);
232 dprintf_dosfs(stddeb,"path = %s\n",WindowsPath);
235 WORD DOS_GetEquipment(void)
237 WORD equipment;
238 int diskdrives = 0;
239 int parallelports = 0;
240 int serialports = 0;
241 int x;
243 /* borrowed from Ralph Brown's interrupt lists
245 bits 15-14: number of parallel devices
246 bit 13: [Conv] Internal modem
247 bit 12: reserved
248 bits 11- 9: number of serial devices
249 bit 8: reserved
250 bits 7- 6: number of diskette drives minus one
251 bits 5- 4: Initial video mode:
252 00b = EGA,VGA,PGA
253 01b = 40 x 25 color
254 10b = 80 x 25 color
255 11b = 80 x 25 mono
256 bit 3: reserved
257 bit 2: [PS] =1 if pointing device
258 [non-PS] reserved
259 bit 1: =1 if math co-processor
260 bit 0: =1 if diskette available for boot
262 /* Currently the only of these bits correctly set are:
263 bits 15-14 } Added by William Owen Smith,
264 bits 11-9 } wos@dcs.warwick.ac.uk
265 bits 7-6
266 bit 2 (always set)
269 if (DosDrives[0].rootdir != NULL)
270 diskdrives++;
271 if (DosDrives[1].rootdir != NULL)
272 diskdrives++;
273 if (diskdrives)
274 diskdrives--;
276 for (x=0; x!=MAX_PORTS; x++) {
277 if (COM[x].devicename)
278 serialports++;
279 if (LPT[x].devicename)
280 parallelports++;
282 if (serialports > 7) /* 3 bits -- maximum value = 7 */
283 serialports=7;
284 if (parallelports > 3) /* 2 bits -- maximum value = 3 */
285 parallelports=3;
287 equipment = (diskdrives << 6) | (serialports << 9) |
288 (parallelports << 14) | 0x02;
290 dprintf_dosfs(stddeb, "DOS_GetEquipment : diskdrives = %d serialports = %d "
291 "parallelports = %d\n"
292 "DOS_GetEquipment : equipment = %d\n",
293 diskdrives, serialports, parallelports, equipment);
295 return (equipment);
298 int DOS_ValidDrive(int drive)
300 int valid = 1;
302 dprintf_dosfs(stddeb,"ValidDrive %c (%d) -- ",'A'+drive,drive);
304 if (drive < 0 || drive >= MAX_DOS_DRIVES)
305 valid = 0;
306 if (DosDrives[drive].rootdir == NULL)
307 valid = 0;
308 if (DosDrives[drive].disabled)
309 valid = 0;
311 dprintf_dosfs(stddeb, "%s\n", valid ? "Valid" : "Invalid");
312 return valid;
316 int DOS_ValidDirectory(char *name)
318 char *dirname;
319 struct stat s;
320 dprintf_dosfs(stddeb, "DOS_ValidDirectory: '%s'\n", name);
321 if ((dirname = DOS_GetUnixFileName(name)) == NULL)
322 return 0;
323 if (stat(dirname,&s))
324 return 0;
325 if (!S_ISDIR(s.st_mode))
326 return 0;
327 dprintf_dosfs(stddeb, "==> OK\n");
328 return 1;
333 /* Simplify the path in "name" by removing "//"'s and
334 ".."'s in names like "/usr/bin/../lib/test" */
335 void DOS_SimplifyPath(char *name)
337 char *l,*p;
338 BOOL changed;
340 dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name);
341 do {
342 changed = FALSE;
343 while ((l = strstr(name,"//"))) {
344 strcpy(l,l+1); changed = TRUE;
346 while ((l = strstr(name,"/../"))) {
347 *l = 0;
348 p = strrchr(name,'/');
349 if (p == NULL) p = name;
350 strcpy(p,l+3);
351 changed = TRUE;
353 } while (changed);
354 dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
358 int DOS_GetDefaultDrive(void)
360 dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
361 return( CurrentDrive);
364 void DOS_SetDefaultDrive(int drive)
366 dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
367 if (DOS_ValidDrive(drive))
368 CurrentDrive = drive;
371 int DOS_DisableDrive(int drive)
373 if (drive >= MAX_DOS_DRIVES)
374 return 0;
375 if (DosDrives[drive].rootdir == NULL)
376 return 0;
378 DosDrives[drive].disabled = 1;
379 return 1;
382 int DOS_EnableDrive(int drive)
384 if (drive >= MAX_DOS_DRIVES)
385 return 0;
386 if (DosDrives[drive].rootdir == NULL)
387 return 0;
389 DosDrives[drive].disabled = 0;
390 return 1;
393 static void GetUnixDirName(char *rootdir, char *name)
395 int filename = 1;
396 char *nameptr, *cwdptr;
398 cwdptr = rootdir + strlen(rootdir);
399 nameptr = name;
401 dprintf_dosfs(stddeb,"GetUnixDirName: %s <=> %s => ",rootdir, name);
403 while (*nameptr) {
404 if (*nameptr == '.' & !filename) {
405 nameptr++;
406 if (*nameptr == '\0') {
407 cwdptr--;
408 break;
410 if (*nameptr == '.') {
411 cwdptr--;
412 while (cwdptr != rootdir) {
413 cwdptr--;
414 if (*cwdptr == '/') {
415 *(cwdptr+1) = '\0';
416 goto next;
419 goto next;
421 if (*nameptr == '\\' || *nameptr == '/') {
422 next: nameptr++;
423 filename = 0;
424 continue;
427 if (*nameptr == '\\' || *nameptr == '/') {
428 filename = 0;
429 if (nameptr == name)
430 cwdptr = rootdir;
431 *cwdptr++='/';
432 nameptr++;
433 continue;
435 filename = 1;
436 *cwdptr++ = *nameptr++;
438 *cwdptr = '\0';
440 ToUnix(rootdir);
442 dprintf_dosfs(stddeb,"%s\n", rootdir);
446 char *DOS_GetUnixFileName(char *dosfilename)
448 /* a:\windows\system.ini => /dos/windows/system.ini */
450 /* FIXME: should handle devices here (like LPT: or NUL:) */
452 static char temp[256];
453 static char dostemp[256];
454 int drive;
456 if (dosfilename[0] && (dosfilename[1] == ':'))
458 drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A';
460 if (!DOS_ValidDrive(drive))
461 return NULL;
462 else
463 dosfilename+=2;
464 } else
465 drive = CurrentDrive;
467 /* Consider dosfilename const */
468 strncpy( dostemp, dosfilename, 255 );
469 dostemp[255] = '\0';
471 /* Expand the filename to it's full path if it doesn't
472 * start from the root.
474 DOS_ExpandToFullPath(dostemp, drive);
476 strcpy(temp, DosDrives[drive].rootdir);
477 strcat(temp, DosDrives[drive].cwd);
478 GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dostemp);
480 dprintf_dosfs(stddeb,"GetUnixFileName: %s => %s\n", dosfilename, temp);
481 return(temp);
484 /* Note: This function works on directories as well as long as
485 * the directory ends in a slash.
487 char *DOS_GetDosFileName(char *unixfilename)
489 int i;
490 static char temp[256], rootdir[256];
491 /* /dos/windows/system.ini => c:\windows\system.ini */
493 /* Expand it if it's a relative name.
495 DOS_ExpandToFullUnixPath(unixfilename);
497 for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
498 if (DosDrives[i].rootdir != NULL) {
499 strcpy(rootdir, DosDrives[i].rootdir);
500 strcat(rootdir, "/");
501 if (strncmp(rootdir, unixfilename, strlen(rootdir)) == 0) {
502 sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(rootdir));
503 ToDos(temp);
504 return temp;
508 sprintf(temp, "Z:%s", unixfilename);
509 ToDos(temp);
510 return(temp);
513 char *DOS_GetCurrentDir(int drive)
515 static char temp[256];
517 if (!DOS_ValidDrive(drive))
518 return 0;
520 strcpy(temp, DosDrives[drive].cwd);
521 DOS_SimplifyPath( temp );
522 ToDos(temp);
523 ChopOffSlash(temp);
525 dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
526 return (temp + 1);
529 int DOS_ChangeDir(int drive, char *dirname)
531 char temp[256],old[256];
533 if (!DOS_ValidDrive(drive))
534 return 0;
536 strcpy(temp, dirname);
537 ToUnix(temp);
538 strcpy(old, DosDrives[drive].cwd);
540 GetUnixDirName(DosDrives[drive].cwd, temp);
541 strcat(DosDrives[drive].cwd,"/");
543 dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s\n",'A'+drive,
544 DosDrives[drive].cwd);
546 if (!DOS_ValidDirectory(DosDrives[drive].cwd))
548 strcpy(DosDrives[drive].cwd, old);
549 return 0;
551 DOS_SimplifyPath(DosDrives[drive].cwd);
552 return 1;
555 int DOS_MakeDir(int drive, char *dirname)
557 char temp[256];
559 if (!DOS_ValidDrive(drive))
560 return 0;
562 strcpy(temp, DosDrives[drive].cwd);
563 GetUnixDirName(temp, dirname);
564 strcat(DosDrives[drive].cwd,"/");
566 ToUnix(temp + strlen(DosDrives[drive].cwd));
567 mkdir(temp,0);
569 dprintf_dosfs(stddeb,
570 "DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
571 return 1;
574 /* DOS_ExpandToFullPath takes a dos-style filename and converts it
575 * into a full path based on the current working directory.
576 * (e.g., "foo.bar" => "d:\\moo\\foo.bar")
578 void DOS_ExpandToFullPath(char *filename, int drive)
580 char temp[256];
582 dprintf_dosfs(stddeb, "DOS_ExpandToFullPath: Original = %s\n", filename);
584 /* If the filename starts with '/' or '\',
585 * don't bother -- we're already at the root.
587 if(filename[0] == '/' || filename[0] == '\\')
588 return;
590 strcpy(temp, DosDrives[drive].cwd);
591 strcat(temp, filename);
592 strcpy(filename, temp);
594 dprintf_dosfs(stddeb, " Expanded = %s\n", temp);
597 /* DOS_ExpandToFullUnixPath takes a unix filename and converts it
598 * into a full path based on the current working directory. Thus,
599 * it's probably not a good idea to get a relative name, change the
600 * working directory, and then convert it...
602 void DOS_ExpandToFullUnixPath(char *filename)
604 char temp[256];
606 if(filename[0] == '/')
607 return;
609 getcwd(temp, 255);
610 if(!strncmp(filename, "./", 2))
611 strcat(temp, filename + 1);
612 else
614 strcat(temp, "/");
615 strcat(temp, filename);
617 dprintf_dosfs(stddeb, "DOS_ExpandToFullUnixPath: %s => %s\n", filename, temp);
618 strcpy(filename, temp);
621 int DOS_GetSerialNumber(int drive, unsigned long *serialnumber)
623 if (!DOS_ValidDrive(drive))
624 return 0;
626 *serialnumber = DosDrives[drive].serialnumber;
627 return 1;
630 int DOS_SetSerialNumber(int drive, unsigned long serialnumber)
632 if (!DOS_ValidDrive(drive))
633 return 0;
635 DosDrives[drive].serialnumber = serialnumber;
636 return 1;
639 char *DOS_GetVolumeLabel(int drive)
641 if (!DOS_ValidDrive(drive))
642 return NULL;
644 return (DosDrives[drive].label);
647 int DOS_SetVolumeLabel(int drive, char *label)
649 if (!DOS_ValidDrive(drive))
650 return 0;
652 strncpy(DosDrives[drive].label, label, 8);
653 return 1;
656 int DOS_GetFreeSpace(int drive, long *size, long *available)
658 struct statfs info;
660 if (!DOS_ValidDrive(drive))
661 return 0;
663 if (statfs(DosDrives[drive].rootdir, &info) < 0) {
664 fprintf(stderr,"dosfs: cannot do statfs(%s)\n",
665 DosDrives[drive].rootdir);
666 return 0;
669 *size = info.f_bsize * info.f_blocks;
670 *available = info.f_bavail * info.f_bsize;
672 return 1;
675 char *DOS_FindFile(char *buffer, int buflen, char *filename, char **extensions,
676 char *path)
678 char *workingpath, *dirname, *rootname, **e;
679 DIR *d;
680 struct dirent *f;
681 int rootnamelen;
682 struct stat filestat;
684 if (strchr(filename, '\\') != NULL)
686 strncpy(buffer, DOS_GetUnixFileName(filename), buflen);
687 stat( buffer, &filestat);
688 if (S_ISREG(filestat.st_mode))
689 return buffer;
690 else
691 return NULL;
694 if (strchr(filename, '/') != NULL)
696 strncpy(buffer, filename, buflen);
697 return buffer;
700 dprintf_dosfs(stddeb,"DOS_FindFile: looking for %s\n", filename);
701 rootnamelen = strlen(filename);
702 rootname = strdup(filename);
703 ToUnix(rootname);
704 workingpath = strdup(path);
706 for(dirname = strtok(workingpath, ";");
707 dirname != NULL;
708 dirname = strtok(NULL, ";"))
710 if (strchr(dirname, '\\') != NULL)
711 d = opendir( DOS_GetUnixFileName(dirname) );
712 else
713 d = opendir( dirname );
715 dprintf_dosfs(stddeb,"in %s\n",dirname);
716 if (d != NULL)
718 while ((f = readdir(d)) != NULL)
720 if (strcasecmp(rootname, f->d_name) != 0) {
721 if (strncasecmp(rootname, f->d_name, rootnamelen) != 0
722 || extensions == NULL
723 || f->d_name[rootnamelen] != '.')
724 continue;
726 for (e = extensions; *e != NULL; e++) {
727 if (strcasecmp(*e, f->d_name + rootnamelen + 1) == 0)
728 break;
730 if (*e == NULL) continue;
733 if (strchr(dirname, '\\') != NULL) {
734 strncpy(buffer, DOS_GetUnixFileName(dirname), buflen);
735 } else {
736 strncpy(buffer, dirname, buflen);
739 strncat(buffer, "/", buflen - strlen(buffer));
740 strncat(buffer, f->d_name, buflen - strlen(buffer));
742 stat(buffer, &filestat);
743 if (S_ISREG(filestat.st_mode)) {
744 closedir(d);
745 free(rootname);
746 return buffer;
749 closedir(d);
752 return NULL;
755 /**********************************************************************
756 * WineIniFileName
758 char *WineIniFileName(void)
760 int fd;
761 static char *filename = NULL;
762 static char name[256];
764 if (filename)
765 return filename;
767 strcpy(name, WINE_INI_USER);
768 ExpandTildeString(name);
769 if ((fd = open(name, O_RDONLY)) != -1) {
770 close(fd);
771 filename = name;
772 return(filename);
774 if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) {
775 close(fd);
776 filename = WINE_INI_GLOBAL;
777 return(filename);
779 fprintf(stderr,"wine: can't open configuration file %s or %s !\n",
780 WINE_INI_GLOBAL, WINE_INI_USER);
781 exit(1);
784 char *WinIniFileName(void)
786 static char *name = NULL;
788 if (name)
789 return name;
791 name = malloc(1024);
793 strcpy(name, DOS_GetUnixFileName(WindowsDirectory));
794 strcat(name, "/");
795 strcat(name, "win.ini");
797 name = realloc(name, strlen(name) + 1);
799 return name;
802 static int match(char *filename, char *filemask)
804 char name[12], mask[12];
805 int i;
807 dprintf_dosfs(stddeb, "match: %s, %s\n", filename, filemask);
809 for( i=0; i<11; i++ ) {
810 name[i] = ' ';
811 mask[i] = ' ';
813 name[11] = 0;
814 mask[11] = 0;
816 for( i=0; i<8; i++ )
817 if( !(*filename) || *filename == '.' )
818 break;
819 else
820 name[i] = toupper( *filename++ );
821 while( *filename && *filename != '.' )
822 filename++;
823 if( *filename )
824 filename++;
825 for( i=8; i<11; i++ )
826 if( !(*filename) )
827 break;
828 else
829 name[i] = toupper( *filename++ );
831 for( i=0; i<8; i++ )
832 if( !(*filemask) || *filemask == '.' )
833 break;
834 else if( *filemask == '*' ) {
835 int j;
836 for( j=i; j<8; j++ )
837 mask[j] = '?';
838 break;
840 else
841 mask[i] = toupper( *filemask++ );
842 while( *filemask && *filemask != '.' )
843 filemask++;
844 if( *filemask )
845 filemask++;
846 for( i=8; i<11; i++ )
847 if( !(*filemask) )
848 break;
849 else if (*filemask == '*' ) {
850 int j;
851 for( j=i; j<11; j++ )
852 mask[j] = '?';
853 break;
855 else
856 mask[i] = toupper( *filemask++ );
858 dprintf_dosfs(stddeb, "changed to: %s, %s\n", name, mask);
860 for( i=0; i<11; i++ )
861 if( ( name[i] != mask[i] ) && ( mask[i] != '?' ) )
862 return 0;
864 return 1;
867 struct dosdirent *DOS_opendir(char *dosdirname)
869 int x,y;
870 char *unixdirname;
871 char temp[256];
873 if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
874 return NULL;
876 strcpy(temp, unixdirname);
877 y = strlen(temp);
878 while (y--)
880 if (temp[y] == '/')
882 temp[y++] = '\0';
883 unixdirname += y;
884 break;
888 for (x=0; x <= MAX_OPEN_DIRS; x++) {
889 if (x == MAX_OPEN_DIRS) {
890 fprintf( stderr, "DOS_opendir(): Too many open directories\n");
891 return NULL;
893 if (!DosDirs[x].inuse) break;
894 if (strcmp(DosDirs[x].unixpath,temp) == 0) break;
897 strncpy(DosDirs[x].filemask, unixdirname, 12);
898 DosDirs[x].filemask[12] = 0;
899 ToDos(DosDirs[x].filemask);
900 dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, temp);
902 DosDirs[x].inuse = 1;
903 strcpy(DosDirs[x].unixpath, temp);
904 DosDirs[x].entnum = 0;
906 if ((DosDirs[x].ds = opendir(temp)) == NULL)
907 return NULL;
909 return &DosDirs[x];
913 struct dosdirent *DOS_readdir(struct dosdirent *de)
915 char temp[256];
916 struct dirent *d;
917 struct stat st;
919 if (!de->inuse)
920 return NULL;
922 do {
923 if ((d = readdir(de->ds)) == NULL)
924 return NULL;
926 de->entnum++; /* Increment the directory entry number */
927 strcpy(de->filename, d->d_name);
928 if (d->d_reclen > 12)
929 de->filename[12] = '\0';
931 ToDos(de->filename);
932 } while ( !match(de->filename, de->filemask) );
934 strcpy(temp,de->unixpath);
935 strcat(temp,"/");
936 strcat(temp,de->filename);
937 ToUnix(temp + strlen(de->unixpath));
939 stat (temp, &st);
940 de->attribute = 0x0;
941 if S_ISDIR(st.st_mode)
942 de->attribute |= FA_DIREC;
944 de->filesize = st.st_size;
945 de->filetime = st.st_mtime;
947 return de;
950 void DOS_closedir(struct dosdirent *de)
952 if (de && de->inuse)
954 closedir(de->ds);
955 de->inuse = 0;
959 char *DOS_GetRedirectedDir(int drive)
961 if(DOS_ValidDrive(drive))
962 return (DosDrives[drive].rootdir);
963 else
964 return ("/");