289 int pos = 0; |
289 int pos = 0; |
290 int lastfound = -1; |
290 int lastfound = -1; |
291 for(;pos < descriptor->filenamelen; pos++) |
291 for(;pos < descriptor->filenamelen; pos++) |
292 if (descriptor->filename[pos] == ';') |
292 if (descriptor->filename[pos] == ';') |
293 lastfound = pos; |
293 lastfound = pos; |
294 BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NO_SUCH_PATH /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1); |
294 BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NOT_FOUND /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1); |
295 BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NO_SUCH_PATH /* !!! PHYSFS_ERR_BAD_FILENAME */, -1); |
295 BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NOT_FOUND /* !!! PHYSFS_ERR_BAD_FILENAME */, -1); |
296 strncpy(filename, descriptor->filename, lastfound); |
296 strncpy(filename, descriptor->filename, lastfound); |
297 if (filename[lastfound - 1] == '.') |
297 if (filename[lastfound - 1] == '.') |
298 filename[lastfound - 1] = '\0'; /* consume trailing ., as done in all implementations */ |
298 filename[lastfound - 1] = '\0'; /* consume trailing ., as done in all implementations */ |
299 else |
299 else |
300 filename[lastfound] = '\0'; |
300 filename[lastfound] = '\0'; |
396 * Don't use path tables, they are not necessarily faster, but more complicated |
396 * Don't use path tables, they are not necessarily faster, but more complicated |
397 * to implement as they store only directories and not files, so searching for |
397 * to implement as they store only directories and not files, so searching for |
398 * a file needs to branch to the directory extent sooner or later. |
398 * a file needs to branch to the directory extent sooner or later. |
399 */ |
399 */ |
400 static int iso_find_dir_entry(ISO9660Handle *handle,const char *path, |
400 static int iso_find_dir_entry(ISO9660Handle *handle,const char *path, |
401 ISO9660FileDescriptor *descriptor, int *exists) |
401 ISO9660FileDescriptor *descriptor) |
402 { |
402 { |
403 char *subpath = 0; |
403 char *subpath = 0; |
404 PHYSFS_uint64 readpos, end_of_dir; |
404 PHYSFS_uint64 readpos, end_of_dir; |
405 char filename[255]; |
405 char filename[255]; |
406 char pathcopy[256]; |
406 char pathcopy[256]; |
407 char *mypath; |
407 char *mypath; |
408 int version = 0; |
408 int version = 0; |
409 |
409 |
410 strcpy(pathcopy, path); |
410 strcpy(pathcopy, path); |
411 mypath = pathcopy; |
411 mypath = pathcopy; |
412 *exists = 0; |
|
413 |
412 |
414 readpos = handle->rootdirstart; |
413 readpos = handle->rootdirstart; |
415 end_of_dir = handle->rootdirstart + handle->rootdirsize; |
414 end_of_dir = handle->rootdirstart + handle->rootdirsize; |
416 iso_extractsubpath(mypath, &subpath); |
415 iso_extractsubpath(mypath, &subpath); |
417 while (1) |
416 while (1) |
456 readpos = descriptor->extentpos * 2048; |
452 readpos = descriptor->extentpos * 2048; |
457 end_of_dir = readpos + descriptor->datalen; |
453 end_of_dir = readpos + descriptor->datalen; |
458 } /* if */ |
454 } /* if */ |
459 else |
455 else |
460 { |
456 { |
|
457 /* !!! FIXME: set PHYSFS_ERR_NOT_FOUND? */ |
461 /* we're at a file but have a remaining subpath -> no match */ |
458 /* we're at a file but have a remaining subpath -> no match */ |
462 return 0; |
459 return 0; |
463 } /* else */ |
460 } /* else */ |
464 } /* if */ |
461 } /* if */ |
465 } /* while */ |
462 } /* while */ |
466 |
463 |
|
464 /* !!! FIXME: set PHYSFS_ERR_NOT_FOUND? */ |
467 return 0; |
465 return 0; |
468 } /* iso_find_dir_entry */ |
466 } /* iso_find_dir_entry */ |
469 |
467 |
470 |
468 |
471 static int iso_read_ext_attributes(ISO9660Handle *handle, int block, |
469 static int iso_read_ext_attributes(ISO9660Handle *handle, int block, |
553 |
551 |
554 BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL); |
552 BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL); |
555 |
553 |
556 /* Skip system area to magic number in Volume descriptor */ |
554 /* Skip system area to magic number in Volume descriptor */ |
557 BAIL_IF_MACRO(!io->seek(io, 32769), ERRPASS, NULL); |
555 BAIL_IF_MACRO(!io->seek(io, 32769), ERRPASS, NULL); |
558 BAIL_IF_MACRO(!io->read(io, magicnumber, 5) != 5, ERRPASS, NULL); |
556 BAIL_IF_MACRO(io->read(io, magicnumber, 5) != 5, ERRPASS, NULL); |
559 if (memcmp(magicnumber, "CD001", 6) != 0) |
557 if (memcmp(magicnumber, "CD001", 6) != 0) |
560 BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL); |
558 BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL); |
561 |
559 |
562 handle = allocator.Malloc(sizeof(ISO9660Handle)); |
560 handle = allocator.Malloc(sizeof(ISO9660Handle)); |
563 GOTO_IF_MACRO(!handle, PHYSFS_ERR_OUT_OF_MEMORY, errorcleanup); |
561 GOTO_IF_MACRO(!handle, PHYSFS_ERR_OUT_OF_MEMORY, errorcleanup); |
764 fhandle->io->destroy(fhandle->io); |
762 fhandle->io->destroy(fhandle->io); |
765 return -1; |
763 return -1; |
766 } /* iso_file_open_foreign */ |
764 } /* iso_file_open_foreign */ |
767 |
765 |
768 |
766 |
769 static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename, |
767 static PHYSFS_Io *ISO9660_openRead(void *opaque, const char *filename) |
770 int *exists) |
|
771 { |
768 { |
772 PHYSFS_Io *retval = NULL; |
769 PHYSFS_Io *retval = NULL; |
773 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
770 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
774 ISO9660FileHandle *fhandle; |
771 ISO9660FileHandle *fhandle; |
775 ISO9660FileDescriptor descriptor; |
772 ISO9660FileDescriptor descriptor; |
781 |
778 |
782 retval = allocator.Malloc(sizeof(PHYSFS_Io)); |
779 retval = allocator.Malloc(sizeof(PHYSFS_Io)); |
783 GOTO_IF_MACRO(retval == 0, PHYSFS_ERR_OUT_OF_MEMORY, errorhandling); |
780 GOTO_IF_MACRO(retval == 0, PHYSFS_ERR_OUT_OF_MEMORY, errorhandling); |
784 |
781 |
785 /* find file descriptor */ |
782 /* find file descriptor */ |
786 rc = iso_find_dir_entry(handle, filename, &descriptor, exists); |
783 rc = iso_find_dir_entry(handle, filename, &descriptor); |
787 GOTO_IF_MACRO(rc, ERRPASS, errorhandling); |
784 GOTO_IF_MACRO(rc, ERRPASS, errorhandling); |
788 GOTO_IF_MACRO(!*exists, PHYSFS_ERR_NO_SUCH_PATH, errorhandling); |
|
789 |
785 |
790 fhandle->startblock = descriptor.extentpos + descriptor.extattributelen; |
786 fhandle->startblock = descriptor.extentpos + descriptor.extattributelen; |
791 fhandle->filesize = descriptor.datalen; |
787 fhandle->filesize = descriptor.datalen; |
792 fhandle->currpos = 0; |
788 fhandle->currpos = 0; |
793 fhandle->isohandle = handle; |
789 fhandle->isohandle = handle; |
814 |
810 |
815 /******************************************************************************* |
811 /******************************************************************************* |
816 * Information gathering functions |
812 * Information gathering functions |
817 ******************************************************************************/ |
813 ******************************************************************************/ |
818 |
814 |
819 static void ISO9660_enumerateFiles(PHYSFS_Dir *opaque, const char *dname, |
815 static void ISO9660_enumerateFiles(void *opaque, const char *dname, |
820 int omitSymLinks, |
|
821 PHYSFS_EnumFilesCallback cb, |
816 PHYSFS_EnumFilesCallback cb, |
822 const char *origdir, void *callbackdata) |
817 const char *origdir, void *callbackdata) |
823 { |
818 { |
824 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
819 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
825 ISO9660FileDescriptor descriptor; |
820 ISO9660FileDescriptor descriptor; |
834 end_of_dir = readpos + handle->rootdirsize; |
829 end_of_dir = readpos + handle->rootdirsize; |
835 } /* if */ |
830 } /* if */ |
836 else |
831 else |
837 { |
832 { |
838 printf("pfad %s\n",dname); |
833 printf("pfad %s\n",dname); |
839 int exists = 0; |
834 BAIL_IF_MACRO(iso_find_dir_entry(handle,dname, &descriptor), ERRPASS,); |
840 BAIL_IF_MACRO(iso_find_dir_entry(handle,dname, &descriptor, &exists), ERRPASS,); |
|
841 BAIL_IF_MACRO(!exists, ERRPASS, ); |
|
842 BAIL_IF_MACRO(!descriptor.flags.directory, ERRPASS,); |
835 BAIL_IF_MACRO(!descriptor.flags.directory, ERRPASS,); |
843 |
836 |
844 readpos = descriptor.extentpos * 2048; |
837 readpos = descriptor.extentpos * 2048; |
845 end_of_dir = readpos + descriptor.datalen; |
838 end_of_dir = readpos + descriptor.datalen; |
846 } /* else */ |
839 } /* else */ |
871 cb(callbackdata, origdir,filename); |
864 cb(callbackdata, origdir,filename); |
872 } /* while */ |
865 } /* while */ |
873 } /* ISO9660_enumerateFiles */ |
866 } /* ISO9660_enumerateFiles */ |
874 |
867 |
875 |
868 |
876 static int ISO9660_stat(PHYSFS_Dir *opaque, const char *name, int *exists, |
869 static int ISO9660_stat(void *opaque, const char *name, PHYSFS_Stat *stat) |
877 PHYSFS_Stat *stat) |
|
878 { |
870 { |
879 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
871 ISO9660Handle *handle = (ISO9660Handle*) opaque; |
880 ISO9660FileDescriptor descriptor; |
872 ISO9660FileDescriptor descriptor; |
881 ISO9660ExtAttributeRec extattr; |
873 ISO9660ExtAttributeRec extattr; |
882 BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor, exists), ERRPASS, -1); |
874 BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor), ERRPASS, -1); |
883 if (!*exists) |
|
884 return 0; |
|
885 |
875 |
886 stat->readonly = 1; |
876 stat->readonly = 1; |
887 |
877 |
888 /* try to get extended info */ |
878 /* try to get extended info */ |
889 if (descriptor.extattributelen) |
879 if (descriptor.extattributelen) |
918 |
908 |
919 /******************************************************************************* |
909 /******************************************************************************* |
920 * Not supported functions |
910 * Not supported functions |
921 ******************************************************************************/ |
911 ******************************************************************************/ |
922 |
912 |
923 static PHYSFS_Io *ISO9660_openWrite(PHYSFS_Dir *opaque, const char *name) |
913 static PHYSFS_Io *ISO9660_openWrite(void *opaque, const char *name) |
924 { |
914 { |
925 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
915 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
926 } /* ISO9660_openWrite */ |
916 } /* ISO9660_openWrite */ |
927 |
917 |
928 |
918 |
929 static PHYSFS_Io *ISO9660_openAppend(PHYSFS_Dir *opaque, const char *name) |
919 static PHYSFS_Io *ISO9660_openAppend(void *opaque, const char *name) |
930 { |
920 { |
931 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
921 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
932 } /* ISO9660_openAppend */ |
922 } /* ISO9660_openAppend */ |
933 |
923 |
934 |
924 |
935 static int ISO9660_remove(PHYSFS_Dir *opaque, const char *name) |
925 static int ISO9660_remove(void *opaque, const char *name) |
936 { |
926 { |
937 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
927 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
938 } /* ISO9660_remove */ |
928 } /* ISO9660_remove */ |
939 |
929 |
940 |
930 |
941 static int ISO9660_mkdir(PHYSFS_Dir *opaque, const char *name) |
931 static int ISO9660_mkdir(void *opaque, const char *name) |
942 { |
932 { |
943 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
933 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
944 } /* ISO9660_mkdir */ |
934 } /* ISO9660_mkdir */ |
945 |
935 |
946 |
936 |
947 const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 = |
937 const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 = |
948 { |
938 { |
|
939 CURRENT_PHYSFS_ARCHIVER_API_VERSION, |
949 { |
940 { |
950 "ISO", |
941 "ISO", |
951 "ISO9660 image file", |
942 "ISO9660 image file", |
952 "Christoph Nelles <evilazrael@evilazrael.de>", |
943 "Christoph Nelles <evilazrael@evilazrael.de>", |
953 "http://www.evilazrael.de/", |
944 "https://www.evilazrael.de/", |
|
945 0, /* supportsSymlinks */ |
954 }, |
946 }, |
955 ISO9660_openArchive, /* openArchive() method */ |
947 ISO9660_openArchive, |
956 ISO9660_enumerateFiles, /* enumerateFiles() method */ |
948 ISO9660_enumerateFiles, |
957 ISO9660_openRead, /* openRead() method */ |
949 ISO9660_openRead, |
958 ISO9660_openWrite, /* openWrite() method */ |
950 ISO9660_openWrite, |
959 ISO9660_openAppend, /* openAppend() method */ |
951 ISO9660_openAppend, |
960 ISO9660_remove, /* remove() method */ |
952 ISO9660_remove, |
961 ISO9660_mkdir, /* mkdir() method */ |
953 ISO9660_mkdir, |
962 ISO9660_closeArchive, /* closeArchive() method */ |
954 ISO9660_stat, |
963 ISO9660_stat /* stat() method */ |
955 ISO9660_closeArchive |
964 }; |
956 }; |
965 |
957 |
966 #endif /* defined PHYSFS_SUPPORTS_ISO9660 */ |
958 #endif /* defined PHYSFS_SUPPORTS_ISO9660 */ |
967 |
959 |
968 /* end of archiver_iso9660.c ... */ |
960 /* end of archiver_iso9660.c ... */ |