From 96877abf85ed2ededbfb60e693f8f3a6b382b2f6 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Thu, 27 Oct 2016 22:51:59 +0000 Subject: [PATCH] [MKISOFS] Import a minimal version of the highly portable mkisofs tool from schily-2016-10-27 (https://sf.net/projects/schilytools) and use it for creating ReactOS ISOs from now on. mkisofs is the de-facto standard ISO creation tool on most platforms and actively maintained. Compared to cdmake, its features have matured and it adds ISO9660:1999 support among many other things. I can import its UDF features as soon as we need them. mkisofs has been integrated into our buildsystem in the sdk/tools/mkisofs folder with these subfolders: * "reactos" Host-specific include files that are usually generated by the upstream buildsystem. For us, I have handcrafted them to be enough for mkisofs and compatible with Windows, Linux and Mac OS X. Follow the original layout of the generated files whenever you have to edit these. * "schilytools" Contains the actual mkisofs code and dependencies while maintaining the original directory layout. Only synchronize with newer versions, but never modify. Submit patches upstream instead :) ISOs are now being built with a single ISO9660:1999 filesystem instead of classic ISO9660 + Joliet. For the moment, you can switch back to cdmake using -DUSE_MKISOFS:BOOL=0 on the CMake commandline. cdmake will be completely removed in about a month if no problems occur. CORE-11988 svn path=/trunk/; revision=73051 --- reactos/CMakeLists.txt | 8 +- reactos/boot/CMakeLists.txt | 88 +- reactos/sdk/cmake/host-tools.cmake | 2 +- reactos/sdk/tools/CMakeLists.txt | 1 + reactos/sdk/tools/mkisofs/CMakeLists.txt | 87 + reactos/sdk/tools/mkisofs/reactos/align.h | 22 + reactos/sdk/tools/mkisofs/reactos/avoffset.h | 2 + reactos/sdk/tools/mkisofs/reactos/xconfig.h | 207 + .../tools/mkisofs/schilytools/CDDL.Schily.txt | 376 ++ .../mkisofs/schilytools/cdrecord/version.h | 6 + .../schilytools/include/schily/align.h | 173 + .../schilytools/include/schily/archdefs.h | 288 ++ .../schilytools/include/schily/avoffset.h | 164 + .../schilytools/include/schily/btorder.h | 124 + .../schilytools/include/schily/ccomdefs.h | 90 + .../schilytools/include/schily/checkerr.h | 95 + .../schilytools/include/schily/ctype.h | 40 + .../schilytools/include/schily/device.h | 153 + .../schilytools/include/schily/dirent.h | 225 + .../schilytools/include/schily/dlfcn.h | 110 + .../schilytools/include/schily/errno.h | 62 + .../schilytools/include/schily/fcntl.h | 134 + .../schilytools/include/schily/float.h | 56 + .../schilytools/include/schily/fnmatch.h | 103 + .../schilytools/include/schily/getargs.h | 171 + .../schilytools/include/schily/iconv.h | 72 + .../schilytools/include/schily/intcvt.h | 114 + .../schilytools/include/schily/inttypes.h | 38 + .../mkisofs/schilytools/include/schily/io.h | 46 + .../schilytools/include/schily/libport.h | 416 ++ .../schilytools/include/schily/limits.h | 54 + .../schilytools/include/schily/locale.h | 50 + .../mkisofs/schilytools/include/schily/math.h | 34 + .../schilytools/include/schily/maxpath.h | 113 + .../schilytools/include/schily/mconfig.h | 559 +++ .../schilytools/include/schily/nlsdefs.h | 103 + .../schilytools/include/schily/param.h | 76 + .../schilytools/include/schily/patmatch.h | 130 + .../schilytools/include/schily/prototyp.h | 132 + .../schilytools/include/schily/schily.h | 658 +++ .../schilytools/include/schily/siconv.h | 63 + .../schilytools/include/schily/sigblk.h | 62 + .../schilytools/include/schily/standard.h | 159 + .../mkisofs/schilytools/include/schily/stat.h | 402 ++ .../schilytools/include/schily/stdint.h | 488 ++ .../schilytools/include/schily/stdio.h | 124 + .../schilytools/include/schily/stdlib.h | 72 + .../schilytools/include/schily/string.h | 108 + .../mkisofs/schilytools/include/schily/time.h | 164 + .../schilytools/include/schily/types.h | 47 + .../schilytools/include/schily/unistd.h | 183 + .../schilytools/include/schily/utypes.h | 158 + .../schilytools/include/schily/varargs.h | 140 + .../schilytools/include/schily/wchar.h | 180 + .../schilytools/include/schily/wctype.h | 99 + .../schilytools/include/schily/windows.h | 88 + .../schilytools/include/schily/xconfig.h | 180 + .../mkisofs/schilytools/libschily/astoll.c | 164 + .../mkisofs/schilytools/libschily/checkerr.c | 323 ++ .../mkisofs/schilytools/libschily/comerr.c | 373 ++ .../mkisofs/schilytools/libschily/dirent.c | 157 + .../mkisofs/schilytools/libschily/eaccess.c | 56 + .../mkisofs/schilytools/libschily/error.c | 88 + .../mkisofs/schilytools/libschily/fconv.c | 416 ++ .../mkisofs/schilytools/libschily/fillbytes.c | 99 + .../mkisofs/schilytools/libschily/fnmatch.c | 341 ++ .../mkisofs/schilytools/libschily/format.c | 1706 +++++++ .../mkisofs/schilytools/libschily/getargs.c | 1339 ++++++ .../mkisofs/schilytools/libschily/geterrno.c | 38 + .../schilytools/libschily/getexecpath.c | 80 + .../schilytools/libschily/gettimeofday.c | 89 + .../tools/mkisofs/schilytools/libschily/gid.c | 64 + .../mkisofs/schilytools/libschily/jsprintf.c | 198 + .../schilytools/libschily/jssnprintf.c | 89 + .../mkisofs/schilytools/libschily/match.c | 470 ++ .../tools/mkisofs/schilytools/libschily/mem.c | 104 + .../mkisofs/schilytools/libschily/movebytes.c | 125 + .../mkisofs/schilytools/libschily/raisecond.c | 172 + .../mkisofs/schilytools/libschily/saveargs.c | 221 + .../schilytools/libschily/searchinpath.c | 245 + .../mkisofs/schilytools/libschily/seterrno.c | 41 + .../schilytools/libschily/stdio/cvmod.c | 59 + .../mkisofs/schilytools/libschily/stdio/dat.c | 19 + .../schilytools/libschily/stdio/fcons.c | 79 + .../schilytools/libschily/stdio/ffileread.c | 40 + .../schilytools/libschily/stdio/fgetline.c | 138 + .../schilytools/libschily/stdio/fileopen.c | 35 + .../schilytools/libschily/stdio/filewrite.c | 92 + .../schilytools/libschily/stdio/flag.c | 135 + .../schilytools/libschily/stdio/niwrite.c | 42 + .../schilytools/libschily/stdio/schilyio.h | 233 + .../mkisofs/schilytools/libschily/streql.c | 41 + .../mkisofs/schilytools/libschily/strlcat.c | 59 + .../mkisofs/schilytools/libschily/strlcpy.c | 52 + .../tools/mkisofs/schilytools/libschily/uid.c | 64 + .../mkisofs/schilytools/libschily/zerobytes.c | 90 + .../mkisofs/schilytools/libsiconv/sic_nls.c | 551 +++ .../tools/mkisofs/schilytools/mkisofs/boot.c | 542 +++ .../mkisofs/schilytools/mkisofs/bootinfo.h | 34 + .../mkisofs/schilytools/mkisofs/defaults.h | 150 + .../mkisofs/schilytools/mkisofs/diskmbr.h | 53 + .../mkisofs/schilytools/mkisofs/eltorito.c | 686 +++ .../tools/mkisofs/schilytools/mkisofs/hash.c | 461 ++ .../tools/mkisofs/schilytools/mkisofs/inode.c | 460 ++ .../mkisofs/schilytools/mkisofs/iso9660.h | 376 ++ .../mkisofs/schilytools/mkisofs/isonum.c | 228 + .../mkisofs/schilytools/mkisofs/joliet.c | 1456 ++++++ .../tools/mkisofs/schilytools/mkisofs/match.c | 397 ++ .../tools/mkisofs/schilytools/mkisofs/match.h | 88 + .../mkisofs/schilytools/mkisofs/mkisofs.c | 3941 +++++++++++++++++ .../mkisofs/schilytools/mkisofs/mkisofs.h | 873 ++++ .../tools/mkisofs/schilytools/mkisofs/multi.c | 2234 ++++++++++ .../tools/mkisofs/schilytools/mkisofs/name.c | 542 +++ .../tools/mkisofs/schilytools/mkisofs/rock.c | 944 ++++ .../tools/mkisofs/schilytools/mkisofs/rock.h | 54 + .../tools/mkisofs/schilytools/mkisofs/scsi.h | 20 + .../mkisofs/schilytools/mkisofs/stream.c | 257 ++ .../mkisofs/schilytools/mkisofs/sunlabel.h | 194 + .../tools/mkisofs/schilytools/mkisofs/tree.c | 2991 +++++++++++++ .../tools/mkisofs/schilytools/mkisofs/write.c | 3017 +++++++++++++ 120 files changed, 36797 insertions(+), 27 deletions(-) create mode 100644 reactos/sdk/tools/mkisofs/CMakeLists.txt create mode 100644 reactos/sdk/tools/mkisofs/reactos/align.h create mode 100644 reactos/sdk/tools/mkisofs/reactos/avoffset.h create mode 100644 reactos/sdk/tools/mkisofs/reactos/xconfig.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/CDDL.Schily.txt create mode 100644 reactos/sdk/tools/mkisofs/schilytools/cdrecord/version.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/align.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/archdefs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/avoffset.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/btorder.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/ccomdefs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/checkerr.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/ctype.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/device.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/dirent.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/dlfcn.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/errno.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/fcntl.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/float.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/fnmatch.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/getargs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/iconv.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/intcvt.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/inttypes.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/io.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/libport.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/limits.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/locale.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/math.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/maxpath.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/mconfig.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/nlsdefs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/param.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/patmatch.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/prototyp.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/schily.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/siconv.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/sigblk.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/standard.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/stat.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/stdint.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/stdio.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/stdlib.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/string.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/time.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/types.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/unistd.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/utypes.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/varargs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/wchar.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/wctype.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/windows.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/include/schily/xconfig.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/astoll.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/checkerr.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/comerr.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/dirent.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/eaccess.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/error.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/fconv.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/fillbytes.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/fnmatch.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/format.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/getargs.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/geterrno.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/getexecpath.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/gettimeofday.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/gid.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/jsprintf.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/jssnprintf.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/match.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/mem.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/movebytes.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/raisecond.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/saveargs.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/searchinpath.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/seterrno.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/cvmod.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/dat.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fcons.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/ffileread.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fgetline.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fileopen.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/filewrite.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/flag.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/niwrite.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/schilyio.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/streql.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/strlcat.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/strlcpy.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/uid.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libschily/zerobytes.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/libsiconv/sic_nls.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/boot.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/bootinfo.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/defaults.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/diskmbr.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/eltorito.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/hash.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/inode.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/iso9660.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/isonum.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/joliet.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/multi.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/name.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/scsi.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/stream.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/sunlabel.h create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/tree.c create mode 100644 reactos/sdk/tools/mkisofs/schilytools/mkisofs/write.c diff --git a/reactos/CMakeLists.txt b/reactos/CMakeLists.txt index 7ca06686eef..0f95bc75827 100644 --- a/reactos/CMakeLists.txt +++ b/reactos/CMakeLists.txt @@ -37,6 +37,10 @@ set(CMAKE_COLOR_MAKEFILE OFF) #set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) set(CMAKE_SKIP_INSTALL_RULES ON) +if(NOT DEFINED USE_MKISOFS) + set(USE_MKISOFS TRUE) +endif() + if(NOT DEFINED NEW_STYLE_BUILD) set(NEW_STYLE_BUILD TRUE) endif() @@ -106,9 +110,9 @@ if(NOT CMAKE_CROSSCOMPILING) if(NOT NEW_STYLE_BUILD) if(NOT MSVC) - export(TARGETS bin2c widl gendib cabman cdmake fatten hpp mkhive obj2bin spec2def geninc rsym mkshelllink utf16le xml2sdb FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake NAMESPACE native- ) + export(TARGETS bin2c widl gendib cabman cdmake fatten hpp mkhive mkisofs obj2bin spec2def geninc rsym mkshelllink utf16le xml2sdb FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake NAMESPACE native- ) else() - export(TARGETS bin2c widl gendib cabman cdmake fatten hpp mkhive obj2bin spec2def geninc mkshelllink utf16le xml2sdb FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake NAMESPACE native- ) + export(TARGETS bin2c widl gendib cabman cdmake fatten hpp mkhive mkisofs obj2bin spec2def geninc mkshelllink utf16le xml2sdb FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake NAMESPACE native- ) endif() endif() diff --git a/reactos/boot/CMakeLists.txt b/reactos/boot/CMakeLists.txt index 2e420261bca..d230ef32839 100644 --- a/reactos/boot/CMakeLists.txt +++ b/reactos/boot/CMakeLists.txt @@ -24,47 +24,87 @@ add_custom_target(efisys #clear it out file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bootcd.lst "") -add_custom_target(bootcd - COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/bootcd.lst REACTOS ${REACTOS_BINARY_DIR}/bootcd.iso - DEPENDS native-cdmake efisys - VERBATIM) +if(USE_MKISOFS) + add_custom_target(bootcd + COMMAND native-mkisofs -o ${REACTOS_BINARY_DIR}/bootcd.iso -iso-level 4 -volid "ReactOS" -path-list ${CMAKE_CURRENT_BINARY_DIR}/bootcd.lst -graft-points -no-cache-inodes -eltorito-boot loader/isoboot.bin -no-emul-boot -boot-load-size 4 -eltorito-alt-boot -eltorito-platform efi -eltorito-boot loader/efisys.bin -hide boot.catalog -publisher "ReactOS Foundation" -preparer "ReactOS Foundation" + DEPENDS native-mkisofs + VERBATIM) +else() + add_custom_target(bootcd + COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/bootcd.lst REACTOS ${REACTOS_BINARY_DIR}/bootcd.iso + DEPENDS native-cdmake efisys + VERBATIM) +endif() ##bootcdregtest #clear it out file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bootcdregtest.lst "") -add_custom_target(bootcdregtest - COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isobtrt.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/bootcdregtest.lst REACTOS ${REACTOS_BINARY_DIR}/bootcdregtest.iso - DEPENDS native-cdmake efisys - VERBATIM) +if(USE_MKISOFS) + add_custom_target(bootcdregtest + COMMAND native-mkisofs -o ${REACTOS_BINARY_DIR}/bootcdregtest.iso -iso-level 4 -volid "ReactOS" -path-list ${CMAKE_CURRENT_BINARY_DIR}/bootcdregtest.lst -graft-points -no-cache-inodes -eltorito-boot loader/isobtrt.bin -no-emul-boot -boot-load-size 4 -eltorito-alt-boot -eltorito-platform efi -eltorito-boot loader/efisys.bin -hide boot.catalog -publisher "ReactOS Foundation" -preparer "ReactOS Foundation" + DEPENDS native-mkisofs + VERBATIM) +else() + add_custom_target(bootcdregtest + COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isobtrt.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/bootcdregtest.lst REACTOS ${REACTOS_BINARY_DIR}/bootcdregtest.iso + DEPENDS native-cdmake efisys + VERBATIM) +endif() ##livecd #clear it out file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "") -#create the empty Desktop, Favorites, and Start Menu folders -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Desktop\n") -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Favorites\n") -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Start Menu/Programs\n") +if(USE_MKISOFS) + #create the empty Desktop, Favorites, and Start Menu folders + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Desktop=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Favorites=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Start Menu/Programs=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") -add_custom_target(livecd - COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/livecd.lst REACTOS ${REACTOS_BINARY_DIR}/livecd.iso - DEPENDS native-cdmake efisys - VERBATIM) + add_custom_target(livecd + COMMAND native-mkisofs -o ${REACTOS_BINARY_DIR}/livecd.iso -iso-level 4 -volid "ReactOS" -path-list ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst -graft-points -no-cache-inodes -eltorito-boot loader/isoboot.bin -no-emul-boot -boot-load-size 4 -eltorito-alt-boot -eltorito-platform efi -eltorito-boot loader/efisys.bin -hide boot.catalog -publisher "ReactOS Foundation" -preparer "ReactOS Foundation" + DEPENDS native-mkisofs + VERBATIM) +else() + #create the empty Desktop, Favorites, and Start Menu folders + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Desktop\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Favorites\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/livecd.lst "Profiles/Default User/Start Menu/Programs\n") + + add_custom_target(livecd + COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/livecd.lst REACTOS ${REACTOS_BINARY_DIR}/livecd.iso + DEPENDS native-cdmake efisys + VERBATIM) +endif() ##hybridcd #clear it out file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "") -#create the empty Desktop, Favorites, and Start Menu folders -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Desktop\n") -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Favorites\n") -file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Start Menu/Programs\n") +if(USE_MKISOFS) + #create the empty Desktop, Favorites, and Start Menu folders + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Desktop=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Favorites=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Start Menu/Programs=${REACTOS_SOURCE_DIR}/boot/bootdata/empty\n") -add_custom_target(hybridcd - COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst REACTOS ${REACTOS_BINARY_DIR}/hybridcd.iso - DEPENDS native-cdmake efisys bootcd livecd - VERBATIM) + add_custom_target(hybridcd + COMMAND native-mkisofs -o ${REACTOS_BINARY_DIR}/hybridcd.iso -iso-level 4 -volid "ReactOS" -path-list ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst -graft-points -no-cache-inodes -eltorito-boot loader/isoboot.bin -no-emul-boot -boot-load-size 4 -eltorito-alt-boot -eltorito-platform efi -eltorito-boot loader/efisys.bin -hide boot.catalog -publisher "ReactOS Foundation" -preparer "ReactOS Foundation" + DEPENDS native-mkisofs bootcd livecd + VERBATIM) + + add_cd_file(TARGET efisys FILE ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin DESTINATION loader NO_CAB FOR bootcd regtest livecd hybridcd) +else() + #create the empty Desktop, Favorites, and Start Menu folders + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Desktop\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Favorites\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst "livecd/Profiles/Default User/Start Menu/Programs\n") + + add_custom_target(hybridcd + COMMAND native-cdmake -j -m -bootdata:2\#p0,e,b${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin\#pEF,e,b${CMAKE_CURRENT_BINARY_DIR}/efisys.bin @${CMAKE_CURRENT_BINARY_DIR}/hybridcd.lst REACTOS ${REACTOS_BINARY_DIR}/hybridcd.iso + DEPENDS native-cdmake efisys bootcd livecd + VERBATIM) +endif() add_subdirectory(freeldr) add_subdirectory(bootdata) diff --git a/reactos/sdk/cmake/host-tools.cmake b/reactos/sdk/cmake/host-tools.cmake index a9d874fa99a..06b48752ca2 100644 --- a/reactos/sdk/cmake/host-tools.cmake +++ b/reactos/sdk/cmake/host-tools.cmake @@ -6,7 +6,7 @@ endif() string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) # List of host tools -list(APPEND host_tools_list bin2c hpp widl gendib cabman cdmake fatten mkhive obj2bin spec2def geninc mkshelllink utf16le xml2sdb) +list(APPEND host_tools_list bin2c hpp widl gendib cabman cdmake fatten mkhive mkisofs obj2bin spec2def geninc mkshelllink utf16le xml2sdb) if(NOT MSVC) list(APPEND host_tools_list rsym) endif() diff --git a/reactos/sdk/tools/CMakeLists.txt b/reactos/sdk/tools/CMakeLists.txt index 8b0121c97f4..b8db360e2f1 100644 --- a/reactos/sdk/tools/CMakeLists.txt +++ b/reactos/sdk/tools/CMakeLists.txt @@ -30,6 +30,7 @@ add_subdirectory(hhpcomp) add_subdirectory(hpp) add_subdirectory(kbdtool) add_subdirectory(mkhive) +add_subdirectory(mkisofs) add_subdirectory(unicode) add_subdirectory(widl) add_subdirectory(wpp) diff --git a/reactos/sdk/tools/mkisofs/CMakeLists.txt b/reactos/sdk/tools/mkisofs/CMakeLists.txt new file mode 100644 index 00000000000..5b0db18226d --- /dev/null +++ b/reactos/sdk/tools/mkisofs/CMakeLists.txt @@ -0,0 +1,87 @@ + +add_definitions( + -DINS_BASE="\\".\\"" + -DSCHILY_BUILD + -DSORTING) + +include_directories( + schilytools/include + reactos + ${REACTOS_BINARY_DIR}/sdk/include) + +# libschily and libsiconv are licensed under CDDL whereas mkisofs is licensed under GPL. +# As such, we cannot mix the library sources with mkisofs sources and have to build them seperately. +# Later on, they may still be linked together though. +# +# Reference: http://opensource.stackexchange.com/questions/2094 + +add_library(libschily + schilytools/libschily/stdio/cvmod.c + schilytools/libschily/stdio/dat.c + schilytools/libschily/stdio/fcons.c + schilytools/libschily/stdio/ffileread.c + schilytools/libschily/stdio/fgetline.c + schilytools/libschily/stdio/fileopen.c + schilytools/libschily/stdio/filewrite.c + schilytools/libschily/stdio/flag.c + schilytools/libschily/stdio/niwrite.c + schilytools/libschily/astoll.c + schilytools/libschily/checkerr.c + schilytools/libschily/comerr.c + schilytools/libschily/dirent.c + schilytools/libschily/eaccess.c + schilytools/libschily/error.c + schilytools/libschily/fconv.c + schilytools/libschily/fillbytes.c + schilytools/libschily/fnmatch.c + schilytools/libschily/format.c + schilytools/libschily/getargs.c + schilytools/libschily/geterrno.c + schilytools/libschily/getexecpath.c + schilytools/libschily/gettimeofday.c + schilytools/libschily/gid.c + schilytools/libschily/jsprintf.c + schilytools/libschily/jssnprintf.c + schilytools/libschily/match.c + schilytools/libschily/mem.c + schilytools/libschily/movebytes.c + schilytools/libschily/raisecond.c + schilytools/libschily/saveargs.c + schilytools/libschily/searchinpath.c + schilytools/libschily/seterrno.c + schilytools/libschily/streql.c + schilytools/libschily/strlcat.c + schilytools/libschily/strlcpy.c + schilytools/libschily/uid.c + schilytools/libschily/zerobytes.c) + +add_library(libsiconv + schilytools/libsiconv/sic_nls.c) +target_link_libraries(libsiconv libschily) + +add_host_tool(mkisofs + schilytools/mkisofs/boot.c + schilytools/mkisofs/eltorito.c + schilytools/mkisofs/hash.c + schilytools/mkisofs/inode.c + schilytools/mkisofs/isonum.c + schilytools/mkisofs/joliet.c + schilytools/mkisofs/match.c + schilytools/mkisofs/mkisofs.c + schilytools/mkisofs/multi.c + schilytools/mkisofs/name.c + schilytools/mkisofs/rock.c + schilytools/mkisofs/stream.c + schilytools/mkisofs/tree.c + schilytools/mkisofs/write.c) +target_link_libraries(mkisofs libschily libsiconv) + +if(MSVC) + # mkisofs uses K&R-style function definitions to support very old compilers. + # MSVC complains about the resulting foo() vs. foo(void) mismatches. + add_target_compile_flags(mkisofs "/wd4113") +else() + # libschily implements an own printf function with support for the %r formatter. + # Silence compilers checking for invalid formatting sequences. + add_target_compile_flags(libschily "-Wno-format") +endif() diff --git a/reactos/sdk/tools/mkisofs/reactos/align.h b/reactos/sdk/tools/mkisofs/reactos/align.h new file mode 100644 index 00000000000..251188c1b26 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/reactos/align.h @@ -0,0 +1,22 @@ +/* + * PROJECT: MKISOFS for the ReactOS Build System + * LICENSE: GNU GPLv2 as published by the Free Software Foundation + * AUTHORS: Colin Finck + */ + +#ifndef __ALIGN_H +#define __ALIGN_H + +#ifdef __LP64__ + #define ALIGN_LMASK 7 +#else + #define ALIGN_LMASK 3 +#endif + +#define xaligned(a, s) ((((UIntptr_t)(a)) & (s)) == 0) +#define x2aligned(a, b, s) (((((UIntptr_t)(a)) | ((UIntptr_t)(b))) & (s)) == 0) + +#define laligned(a) xaligned(a, ALIGN_LMASK) +#define l2aligned(a, b) x2aligned(a, b, ALIGN_LMASK) + +#endif diff --git a/reactos/sdk/tools/mkisofs/reactos/avoffset.h b/reactos/sdk/tools/mkisofs/reactos/avoffset.h new file mode 100644 index 00000000000..263f6715d71 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/reactos/avoffset.h @@ -0,0 +1,2 @@ +/* This file is intentionally left blank. + * libschily depends on a buildsystem-generated avoffset.h, but its content isn't relevant for mkisofs. */ diff --git a/reactos/sdk/tools/mkisofs/reactos/xconfig.h b/reactos/sdk/tools/mkisofs/reactos/xconfig.h new file mode 100644 index 00000000000..b6ce125c716 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/reactos/xconfig.h @@ -0,0 +1,207 @@ +/* + * PROJECT: MKISOFS for the ReactOS Build System + * LICENSE: GNU GPLv2 as published by the Free Software Foundation + * AUTHORS: Colin Finck + */ + +/* + * When mkisofs is part of Schily tools, this file is generated by the Schily Build System + * and checks the existence of hundreds of headers and functions. + * For the ReactOS Build System, we provide a written version of this file with sufficient + * information to build mkisofs and universal among our supported build platforms. + */ + +#ifndef __XCONFIG_H +#define __XCONFIG_H + +/* + * Header Files + */ +#define PROTOTYPES 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STRING_H 1 +#define STDC_HEADERS 1 + +#ifndef WIN32 + #define HAVE_UNISTD_H 1 +#endif + +#define HAVE_LIMITS_H 1 +#define HAVE_FCNTL_H 1 + +#ifdef WIN32 + #define HAVE_IO_H 1 +#endif + +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 + +#ifndef WIN32 + #define HAVE_DIRENT_H 1 + #define HAVE_SYS_TIME_H 1 + #define TIME_WITH_SYS_TIME 1 +#endif + +#define HAVE_SYS_TYPES_H 1 +#define HAVE_MATH_H 1 +#define HAVE_ERRNO_DEF 1 + +#ifdef WIN32 + #define HAVE_WINDOWS_H 1 + #define WBOOL WINBOOL +#endif + +#define HAVE_LOCALE_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_WCTYPE_H 1 +#define HAVE_WCHAR_H 1 + +/* + * Convert to SCHILY name + */ +#define HAVE_STDC_HEADERS + +/* + * Library Functions + */ +#define HAVE_STRERROR 1 +#define HAVE_MEMCHR 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMSET 1 + +#ifndef WIN32 + #define HAVE_GETTIMEOFDAY 1 +#endif + +#define HAVE_TIME 1 +#define HAVE_VA_COPY 1 +#define HAVE_ECVT 1 +#define HAVE_FCVT 1 +#define HAVE_GCVT 1 +#define HAVE_C99_ISINF 1 +#define HAVE_C99_ISNAN 1 + +#define HAVE_SNPRINTF 1 +#ifdef _MSC_VER + #define snprintf _snprintf +#endif + +#define HAVE_STRCAT 1 +#define HAVE_STRNCAT 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCPY 1 + +#ifdef __APPLE__ + #define HAVE_STRLCAT 1 + #define HAVE_STRLCPY 1 +#endif + +#define HAVE_STRNCPY 1 +#define HAVE_STRDUP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 + +#ifndef WIN32 + #define HAVE_USLEEP 1 +#endif + +#define HAVE_WCSCAT 1 +#define HAVE_WCSNCAT 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_WCSCPY 1 + +#ifdef __APPLE__ + #define HAVE_WCSLCAT 1 + #define HAVE_WCSLCPY 1 +#endif + +#define HAVE_WCSNCPY 1 +#define HAVE_WCSDUP 1 +#define HAVE_WCSNDUP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSNLEN 1 +#define HAVE_WCSCHR 1 +#define HAVE_WCSRCHR 1 +#define HAVE_WCSSTR 1 + +#ifndef WIN32 + #define HAVE_WCWIDTH 1 +#endif + +#define HAVE_SETVBUF 1 +#define HAVE_ISWPRINT 1 +#define HAVE_MBSINIT 1 +#define HAVE_MBTOWC 1 +#define HAVE_WCTOMB 1 +#define HAVE_MBRTOWC 1 +#define HAVE_WCRTOMB 1 + +#if !defined(WIN32) && !defined(__APPLE__) + #define HAVE_RAW_FEXECVE 1 +#endif + +/* + * Misc OS stuff + */ +#ifndef WIN32 + #define HAVE__DEV_NULL 1 +#endif + +/* + * Structures + */ +#ifndef WIN32 + #define HAVE_STRUCT_TIMEVAL 1 +#endif + +#define HAVE_STRUCT_TIMEZONE 1 +#define HAVE_STRUCT_TIMESPEC 1 + +/* + * Types/Keywords + */ +#define HAVE_LONGLONG 1 + +#ifndef WIN32 + #define VA_LIST_IS_ARRAY 1 +#endif + +#ifdef WIN32 + #define uid_t int + #define gid_t int + #define nlink_t unsigned long + + #ifdef _MSC_VER + #define mode_t int + #endif +#endif + +#define HAVE_TYPE_INTMAX_T 1 +#define HAVE_TYPE_UINTMAX_T 1 + +/* + * ReactOS additions + */ +#ifdef _MSC_VER + #define ssize_t int +#endif + +/* Would need additional fprformat.c, less portable */ +#define NO_FPRFORMAT + +/* For a nice "mkisofs -version" :) */ +#include +#define HOST_CPU "ReactOS" +#define HOST_VENDOR KERNEL_VERSION_BUILD_STR +#define HOST_OS REACTOS_COMPILER_NAME "-" REACTOS_COMPILER_VERSION + +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/CDDL.Schily.txt b/reactos/sdk/tools/mkisofs/schilytools/CDDL.Schily.txt new file mode 100644 index 00000000000..08aa1284477 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/CDDL.Schily.txt @@ -0,0 +1,376 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates + or contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), + and the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing + Original Software with files containing Modifications, in + each case including portions thereof. + + 1.4. "Executable" means the Covered Software in any form other + than Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this + License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed + herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original + Software or previous Modifications; + + B. Any new file that contains any part of the Original + Software or previous Modifications; or + + C. Any new file that is contributed or otherwise made + available under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable + form of computer software code that is originally released + under this License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, + process, and apparatus claims, in any patent Licensable by + grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms + of, this License. For legal entities, "You" includes any + entity which controls, is controlled by, or is under common + control with You. For purposes of this definition, + "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty + percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, the Initial + Developer hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, + reproduce, modify, display, perform, sublicense and + distribute the Original Software (or portions thereof), + with or without Modifications, and/or as part of a Larger + Work; and + + (b) under Patent Claims infringed by the making, using or + selling of Original Software, to make, have made, use, + practice, sell, and offer for sale, and/or otherwise + dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are + effective on the date Initial Developer first distributes + or otherwise makes the Original Software available to a + third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original + Software, or (2) for infringements caused by: (i) the + modification of the Original Software, or (ii) the + combination of the Original Software with other software + or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, + modify, display, perform, sublicense and distribute the + Modifications created by such Contributor (or portions + thereof), either on an unmodified basis, with other + Modifications, as Covered Software and/or as part of a + Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either + alone and/or in combination with its Contributor Version + (or portions of such combination), to make, use, sell, + offer for sale, have made, and/or otherwise dispose of: + (1) Modifications made by that Contributor (or portions + thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions + of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first distributes or + otherwise makes the Modifications available to a third + party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted + from the Contributor Version; (2) for infringements caused + by: (i) third party modifications of Contributor Version, + or (ii) the combination of Modifications made by that + Contributor with other software (except as part of the + Contributor Version) or other devices; or (3) under Patent + Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make + available in Executable form must also be made available in Source + Code form and that Source Code form must be distributed only under + the terms of this License. You must include a copy of this + License with every copy of the Source Code form of the Covered + Software You distribute or otherwise make available. You must + inform recipients of any such Covered Software in Executable form + as to how they can obtain such Covered Software in Source Code + form in a reasonable manner on or through a medium customarily + used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or + You have sufficient rights to grant the rights conveyed by this + License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may + not remove or alter any copyright, patent or trademark notices + contained within the Covered Software, or any notices of licensing + or any descriptive text giving attribution to any Contributor or + the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version + of this License or the recipients' rights hereunder. You may + choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of + Covered Software. However, you may do so only on Your own behalf, + and not on behalf of the Initial Developer or any Contributor. + You must make it absolutely clear that any such warranty, support, + indemnity or liability obligation is offered by You alone, and You + hereby agree to indemnify the Initial Developer and every + Contributor for any liability incurred by the Initial Developer or + such Contributor as a result of warranty, support, indemnity or + liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software + under the terms of this License or under the terms of a license of + Your choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the + Covered Software in Executable form under a different license, You + must make it absolutely clear that any terms which differ from + this License are offered by You alone, not by the Initial + Developer or Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred + by the Initial Developer or such Contributor as a result of any + such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and + distribute the Larger Work as a single product. In such a case, + You must make sure the requirements of this License are fulfilled + for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Sun Microsystems, Inc. is the initial license steward and may + publish revised and/or new versions of this License from time to + time. Each version will be given a distinguishing version number. + Except as provided in Section 4.3, no one other than the license + steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. + If the Initial Developer includes a notice in the Original + Software prohibiting it from being distributed or otherwise made + available under any subsequent version of the License, You must + distribute and make the Covered Software available under the terms + of the version of the License under which You originally received + the Covered Software. Otherwise, You may also choose to use, + distribute or otherwise make the Covered Software available under + the terms of any subsequent version of the License published by + the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license + and remove any references to the name of the license steward + (except to note that the license differs from this License); and + (b) otherwise make it clear that the license contains terms which + differ from this License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED + SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR + PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND + PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY + COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE + INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY + NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF + WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS + DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond + the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that + the Participant Software (meaning the Contributor Version where + the Participant is a Contributor or the Original Software where + the Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if + the Initial Developer is not the Participant) and all Contributors + under Sections 2.1 and/or 2.2 of this License shall, upon 60 days + notice from Participant terminate prospectively and automatically + at the expiration of such 60 day notice period, unless if within + such 60 day period You withdraw Your claim with respect to the + Participant Software against such Participant either unilaterally + or pursuant to a written agreement with Participant. + + 6.3. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE + LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK + STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL + INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO + NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR + CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT + APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is + defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial + computer software" (as that term is defined at 48 + C.F.R. 252.227-7014(a)(1)) and "commercial computer software + documentation" as such terms are used in 48 C.F.R. 12.212 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 + C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all + U.S. Government End Users acquire Covered Software with only those + rights set forth herein. This U.S. Government Rights clause is in + lieu of, and supersedes, any other FAR, DFAR, or other clause or + provision that addresses Government rights in computer software + under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed + by the law of the jurisdiction specified in a notice contained + within the Original Software (except to the extent applicable law, + if any, provides otherwise), excluding such jurisdiction's + conflict-of-law provisions. Any litigation relating to this + License shall be subject to the jurisdiction of the courts located + in the jurisdiction and venue specified in a notice contained + within the Original Software, with the losing party responsible + for costs, including, without limitation, court costs and + reasonable attorneys' fees and expenses. The application of the + United Nations Convention on Contracts for the International Sale + of Goods is expressly excluded. Any law or regulation which + provides that the language of a contract shall be construed + against the drafter shall not apply to this License. You agree + that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, + distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or + indirectly, out of its utilization of rights under this License + and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission + of liability. + +-------------------------------------------------------------------- + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND +DISTRIBUTION LICENSE (CDDL) + +For Covered Software in this distribution, this License shall +be governed by the laws of Germany (excluding conflict-of-law +provisions). + +Any litigation relating to this License shall be subject to the +jurisdiction and the courts of Berlin Germany, with venue lying +in Berlin Germany. diff --git a/reactos/sdk/tools/mkisofs/schilytools/cdrecord/version.h b/reactos/sdk/tools/mkisofs/schilytools/cdrecord/version.h new file mode 100644 index 00000000000..3161c33436a --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/cdrecord/version.h @@ -0,0 +1,6 @@ +/* @(#)version.h 1.92 16/01/26 Copyright 2007-2016 J. Schilling */ + +/* + * The version for cdrtools programs + */ +#define VERSION "3.02a06" diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/align.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/align.h new file mode 100644 index 00000000000..455d7ec16c8 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/align.h @@ -0,0 +1,173 @@ +/* @(#)align.h 1.11 13/07/23 Copyright 1995-2013 J. Schilling */ +/* + * Platform dependent definitions for aligning data. + * + * Copyright (c) 1995-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +/* + * The automatically created included file defines the following macros: + * + * saligned(a) One parameter aligned for a "short int" + * s2aligned(a, b) Both parameters aligned for a "short int" + * ialigned(a) One parameter aligned for a "int" + * i2aligned(a, b) Both parameters aligned for a "int" + * laligned(a) One parameter aligned for a "long" + * l2aligned(a, b) Both parameters aligned for a "long" + * llaligned(a) One parameter aligned for a "long long" + * ll2aligned(a, b) Both parameters aligned for a "long long" + * faligned(a) One parameter aligned for a "float" + * f2aligned(a, b) Both parameters aligned for a "float" + * daligned(a) One parameter aligned for a "double" + * d2aligned(a, b) Both parameters aligned for a "double" + * paligned(a) One parameter aligned for a "pointer" + * p2aligned(a, b) Both parameters aligned for a "pointe" + * + * salign(x) Align for a "short int" + * ialign(x) Align for a "int" + * lalign(x) Align for a "long" + * llalign(x) Align for a "long long" + * falign(x) Align for a "float" + * dalign(x) Align for a "double" + * palign(x) Align for a "pointer" + */ +#ifndef _SCHILY_ALIGN_H +#define _SCHILY_ALIGN_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_UTYPES_H +#include +#endif + +#ifdef SCHILY_BUILD /* #defined by Schily makefile system */ + /* + * Include $(SRCROOT)/incs/$(OARCH)/align.h via + * -I$(SRCROOT)/incs/$(OARCH)/ + */ +# include +#else /* !SCHILY_BUILD */ +/* + * The stuff for static compilation. Include files from a previous + * dynamic autoconfiguration. + */ +#ifdef __SUNOS5_SPARC_CC32 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_SPARC_CC64 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC32 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC64 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_X86_CC32 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_X86_CC64 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_X86_GCC32 +#include +#define __JS_ARCH_ALIGN_INCL +#endif +#ifdef __SUNOS5_X86_GCC64 +#include +#define __JS_ARCH_ALIGN_INCL +#endif + +#ifdef __HPUX_HPPA_CC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_CC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __LINUX_ARMV6L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5TEJL_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_I386_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_amd64_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __MSWIN_X86_CL32 +#include +#define __JS_ARCH_ALIGN_INCL +#endif + +#ifdef __CYGWIN_X86_GCC +#include +#define __JS_ARCH_ALIGN_INCL +#endif + +#ifndef __JS_ARCH_ALIGN_INCL +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defined. And that's what we want. + */ +Error unconfigured architecture + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#endif /* SCHILY_BUILD */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Fake in order to keep the silly hdrchk(1) quiet. + */ +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_ALIGN_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/archdefs.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/archdefs.h new file mode 100644 index 00000000000..0433328d596 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/archdefs.h @@ -0,0 +1,288 @@ +/* @(#)archdefs.h 1.14 13/07/23 Copyright 2006-2013 J. Schilling */ +/* + * Processor, instruction set and OS architecture specific defines. + * The information is fetched from compiler predefinitions only. + * + * Copyright (c) 2006-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_ARCHDEFS_H +#define _SCHILY_ARCHDEFS_H + +/* + * The code in this file only depends on compiler predefined macros. + * For this reason, it does not need to include schily/mconfig.h + */ + +#if defined(sun) || defined(__sun) || defined(__sun__) +#ifndef __sun +#define __sun +#endif +#endif + +#if defined(sun2) +#ifndef __mc68010 +#define __mc68010 +#endif +#endif + +#if defined(mc68020) || defined(__mc68020) || defined(sun3) +#ifndef __mc68020 +#define __mc68020 +#endif +#endif + +#if defined(__mc68010) || defined(__mc68020) +#ifndef __mc68000 +#define __mc68000 +#endif +#endif + +#if defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86) +#ifndef __i386 +#define __i386 +#endif +#endif + +#if defined(__amd64) || defined(__amd64__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) +#ifndef __amd64 +#define __amd64 +#endif +#endif + +#if defined(__i386) || defined(__amd64) +#ifndef __x86 +#define __x86 +#endif +#endif + +#if defined(sparc) || defined(__sparc) || defined(__sparc__) +#ifndef __sparc +#define __sparc +#endif +#endif + +#if defined(__sparcv9) || defined(__sparcv9__) +#ifndef __sparc +#define __sparc +#endif +#ifndef __sparcv9 +#define __sparcv9 +#endif +#endif + +#if defined(__sparc) && defined(__arch64__) +#ifndef __sparcv9 +#define __sparcv9 +#endif +#endif + +#if defined(SOL2) || defined(SOL2) || \ + defined(S5R4) || defined(__S5R4) || defined(SVR4) +# ifndef __SVR4 +# define __SVR4 +# endif +#endif + +#if defined(sun2) || defined(sun3) || defined(__sun) +#ifndef __sun +#define __sun +#endif +#ifndef __GNUC__ +#ifndef __SUNPRO_C +#ifdef __SVR4 +#define __SUNPRO_C +#else +#define __SUN_C +#endif /* __SVR4 */ +#endif /* !__SUNPRO_C */ +#endif /* !__GNUC__ */ +#endif /* __sun */ + + +/* + * SunOS 4 specific defines + */ +#if defined(__sun) && !defined(__SVR4) + +#define __SUNOS4 + +#if defined(__mc68000) +#define __SUNOS4_MC68000 +#ifdef __GNUC__ +#define __SUNOS4_MC68000_GCC32 +#define __JS_ARCH_DEFINED +#endif +#ifdef __SUN_C +#define __SUNOS4_MC68000_CC32 +#define __JS_ARCH_DEFINED +#endif +#endif /* __mc68000 */ + +#if defined(__sparc) +#define __SUNOS4_SPARC +#ifdef __GNUC__ +#define __SUNOS4_SPARC_GCC32 +#define __JS_ARCH_DEFINED +#endif +#if defined(__SUN_C) || defined(__SUNPRO_C) +#define __SUNOS4_SPARC_CC32 +#define __JS_ARCH_DEFINED +#endif +#endif /* __sparc */ + +#endif /* SunOS 4 */ + + +/* + * SunOS 5 specific defines + */ +#if defined(__sun) && defined(__SVR4) + +#define __SUNOS5 + +#if defined(__sparc) +#ifdef __GNUC__ +#ifdef __sparcv9 +#define __SUNOS5_SPARC_GCC64 +#else +#define __SUNOS5_SPARC_GCC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#if defined(__SUNPRO_C) +#ifdef __sparcv9 +#define __SUNOS5_SPARC_CC64 +#else +#define __SUNOS5_SPARC_CC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#endif /* __sparc */ + +#if defined(__x86) +#ifdef __GNUC__ +#ifdef __amd64 +#define __SUNOS5_X86_GCC64 +#else +#define __SUNOS5_X86_GCC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#if defined(__SUNPRO_C) +#ifdef __amd64 +#define __SUNOS5_X86_CC64 +#else +#define __SUNOS5_X86_CC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#endif /* __x86 */ + +#endif /* SunOS 5 */ + +/* + * HP-UX specific defines + */ +#if defined(__hpux) + +#if defined(__hppa) +#ifdef __GNUC__ +#ifdef __LP64__ /* This may be wrong! */ +#define __HPUX_HPPA_GCC64 +#else +#define __HPUX_HPPA_GCC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#if !defined(__GNUC__) +#ifdef __LP64__ +#define __HPUX_HPPA_CC64 +#else +#define __HPUX_HPPA_CC32 +#endif +#define __JS_ARCH_DEFINED +#endif +#endif /* __hppa */ + +#endif /* HP-UX */ + +/* + * Linux specific defines + */ +#if defined(__linux) + +#if defined(__arm__) +#ifdef __GNUC__ +#ifdef __ARM_ARCH_5TE__ +#define __LINUX_ARMV5TEJL_GCC32 +#define __JS_ARCH_DEFINED +#endif +#ifndef __JS_ARCH_DEFINED +#ifdef __ARM_ARCH_6__ +#define __LINUX_ARMV6L_GCC32 +#define __JS_ARCH_DEFINED +#endif +#endif +#ifndef __JS_ARCH_DEFINED +#ifdef __ARM_ARCH_5__ +#define __LINUX_ARMV5L_GCC32 +#define __JS_ARCH_DEFINED +#endif +#endif +#endif /* __GNUC__ */ +#endif /* __arm__ */ + +#if defined(__i386__) || defined(i386) +#ifdef __GNUC__ +#define __LINUX_I386_GCC32 +#define __JS_ARCH_DEFINED +#endif +#endif /* __i386__ */ +#if defined(__amd64__) || defined(__amd64) +#ifdef __GNUC__ +#define __LINUX_amd64_GCC64 +#define __JS_ARCH_DEFINED +#endif +#endif /* __amd64__ */ + +#endif /* Linux */ + +/* + * MS-WIN specific defines + * + * cl defines one of: + * _M_ALPHA + * _M_IX86 + * _M_AMD64 + * _M_M68K + * _M_PPC PPC in general + * _M_MPPC Power Macintosh + * _M_MRX000 Mips + * _M_IA64 Itanium + */ +#if defined(_MSC_VER) && (defined(_X86_) || defined(_M_IX86)) +#define __MSWIN_X86_CL32 +#define __JS_ARCH_DEFINED +#endif + +#if defined(__CYGWIN32__) || defined(__CYGWIN__) +#define __CYGWIN_X86_GCC +#define __JS_ARCH_DEFINED +#endif + +#endif /* _SCHILY_ARCHDEFS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/avoffset.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/avoffset.h new file mode 100644 index 00000000000..386d9612328 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/avoffset.h @@ -0,0 +1,164 @@ +/* @(#)avoffset.h 1.13 13/08/26 Copyright 1995-2013 J. Schilling */ +/* + * Platform dependent definitions for stack scanning. + * + * Copyright (c) 1995-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +/* + * This file includes definitions for STACK_DIRECTION, + * AV_OFFSET and FP_INDIR. + * + * STACK_DIRECTION: + * +1 -> stack grows to larger addresses + * -1 -> stack "groes" to lower addresses + * + * FP_INDIR: the number of fp chain elements above 'main'. + * + * AV_OFFSET: the offset of &av[0] relative to the frame pointer + * in 'main'. + * + * If getav0() does not work on a specific architecture + * the program which generated this automaticly generated include file + * may dump core. In this case, the generated include file does not include + * definitions for AV_OFFSET and FP_INDIR but ends after the + * STACK_DIRECTION definition. + * If AV_OFFSET or FP_INDIR are missing in the file, all code + * that use the definitions are automatically disabled. + */ +#ifndef _SCHILY_AVOFFSET_H +#define _SCHILY_AVOFFSET_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef SCHILY_BUILD /* #defined by Schily makefile system */ + /* + * Include $(SRCROOT)/incs/$(OARCH)/avoffset.h via + * -I$(SRCROOT)/incs/$(OARCH)/ + */ +# include +#else /* !SCHILY_BUILD */ +/* + * The stuff for static compilation. Include files from a previous + * dynamic autoconfiguration. + */ +#ifdef __SUNOS5_SPARC_CC32 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_SPARC_CC64 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC32 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC64 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_X86_CC32 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_X86_CC64 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_X86_GCC32 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif +#ifdef __SUNOS5_X86_GCC64 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif + +#ifdef __HPUX_HPPA_CC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_CC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __LINUX_ARMV6L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5TEJL_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_I386_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_amd64_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __MSWIN_X86_CL32 +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif + +#ifdef __CYGWIN_X86_GCC +#include +#define __JS_ARCH_AVOFFSET_INCL +#endif + +#ifndef __JS_ARCH_AVOFFSET_INCL +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defined. And that's what we want. + */ +Error unconfigured architecture + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#endif /* SCHILY_BUILD */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Fake in order to keep the silly hdrchk(1) quiet. + */ +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_AVOFFSET_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/btorder.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/btorder.h new file mode 100644 index 00000000000..3ece726d677 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/btorder.h @@ -0,0 +1,124 @@ +/* @(#)btorder.h 1.22 12/12/03 Copyright 1996-2012 J. Schilling */ +/* + * Definitions for Bit and Byte ordering + * + * Copyright (c) 1996-2012 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + + +#ifndef _SCHILY_BTORDER_H +#define _SCHILY_BTORDER_H + +#ifndef _SCHILY_MCONFIG_H +#include /* load bit/byte-oder from xmconfig.h */ +#endif + +#ifndef _SCHILY_TYPES_H +#include /* try to load isa_defs.h on Solaris */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Convert bit-order definitions from xconfig.h into our values + * and verify them. + */ +#if defined(HAVE_C_BITFIELDS) && \ + defined(BITFIELDS_LTOH) +#define _BIT_FIELDS_LTOH +#endif + +#if defined(HAVE_C_BITFIELDS) && \ + defined(BITFIELDS_HTOL) +#define _BIT_FIELDS_HTOL +#endif + +#if defined(HAVE_C_BITFIELDS) && \ + !defined(BITFIELDS_HTOL) +#define BITFIELDS_LTOH +#define _BIT_FIELDS_LTOH +#endif + +#if defined(_BIT_FIELDS_LTOH) && defined(_BIT_FIELDS_HTOL) +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defined. And that's what we want. + */ +error Only one of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL may be defined + +#include /* Avoid "unknown directive" with K&R */ +#endif + + +/* + * Convert byte-order definitions from xconfig.h into our values + * and verify them. + * Note that we cannot use the definitions _LITTLE_ENDIAN and _BIG_ENDIAN + * because they are used on IRIX-6.5 with different meaning. + */ +#if defined(HAVE_C_BIGENDIAN) && \ + !defined(WORDS_BIGENDIAN) +#define WORDS_LITTLEENDIAN +/* #define _LITTLE_ENDIAN */ +#endif + +#if defined(HAVE_C_BIGENDIAN) && \ + defined(WORDS_BIGENDIAN) +#undef WORDS_LITTLEENDIAN +/* #define _BIG_ENDIAN */ +#endif + +#if defined(_BIT_FIELDS_LTOH) || defined(_BIT_FIELDS_HTOL) +/* + * Bitorder is already known. + */ +#else +/* + * Bitorder not yet known. + */ +# if defined(sun3) || defined(mc68000) || \ + defined(sun4) || defined(__sparc) || defined(sparc) || \ + defined(__hppa) || defined(_ARCH_PPC) || defined(_IBMR2) +# define _BIT_FIELDS_HTOL +# endif + +# if defined(__sgi) && defined(__mips) +# define _BIT_FIELDS_HTOL +# endif + +# if defined(__i386__) || defined(__i386) || defined(i386) || \ + defined(__alpha__) || defined(__alpha) || defined(alpha) || \ + defined(__arm__) || defined(__arm) || defined(arm) +# define _BIT_FIELDS_LTOH +# endif + +# if defined(__ppc__) || defined(ppc) || defined(__ppc) || \ + defined(__PPC) || defined(powerpc) || defined(__powerpc__) + +# if defined(__BIG_ENDIAN__) +# define _BIT_FIELDS_HTOL +# else +# define _BIT_FIELDS_LTOH +# endif +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_BTORDER_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/ccomdefs.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/ccomdefs.h new file mode 100644 index 00000000000..0ada8a27092 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/ccomdefs.h @@ -0,0 +1,90 @@ +/* @(#)ccomdefs.h 1.12 11/07/21 Copyright 2000-2011 J. Schilling */ +/* + * Various compiler dependant macros. + * + * Copyright (c) 2000-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_CCOMDEFS_H +#define _SCHILY_CCOMDEFS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Compiler-dependent macros to declare that functions take printf-like + * or scanf-like arguments. They are defined to nothing for versions of gcc + * that are not known to support the features properly (old versions of gcc-2 + * didn't permit keeping the keywords out of the application namespace). + */ +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \ + defined(NO_PRINTFLIKE) + +#define __printflike__(fmtarg, firstvararg) +#define __printf0like__(fmtarg, firstvararg) +#define __scanflike__(fmtarg, firstvararg) + +#else /* We found GCC that supports __attribute__ */ + +#define __printflike__(fmtarg, firstvararg) \ + __attribute__((__format__(__printf__, fmtarg, firstvararg))) +#define __printf0like__(fmtarg, firstvararg) \ + __attribute__((__format__(__printf0__, fmtarg, firstvararg))) + +/* + * FreeBSD GCC implements printf0 that allows the format string to + * be a NULL pointer. + */ +#if __FreeBSD_cc_version < 300001 +#undef __printf0like__ +#define __printf0like__ __printflike__ +#endif + +#define __scanflike__(fmtarg, firstvararg) \ + __attribute__((__format__(__scanf__, fmtarg, firstvararg))) + +#endif /* GNUC */ + +#if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 2 +/* GCC-3.3 or more */ + +/* CSTYLED */ +#define UConst __attribute__ ((__used__)) const + +#else /* less than GNUC 3.3 */ + +#define UConst const + +#endif /* less than GNUC 3.3 */ + +#ifdef __PCC__ +/* + * Hack until pcc supports __attribute__ ((__used__)) + */ +#ifdef UConst +#undef UConst +#define UConst const +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_CCOMDEFS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/checkerr.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/checkerr.h new file mode 100644 index 00000000000..e5209044a3e --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/checkerr.h @@ -0,0 +1,95 @@ +/* @(#)checkerr.h 1.14 12/11/13 Copyright 2003-2012 J. Schilling */ +/* + * Generic error control for programs that do file i/o. + * The error control is usually used by archiving programs. + * + * The current version does not provide a stable interface. + * It does not support multi-threaded programs and it may call + * comerr() from the parser. If you use the code before there is + * an official stable and "library-compliant" interface, be careful + * and watch for changes. + * + * Copyright (c) 2003-2012 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_CHECKERR_H +#define _SCHILY_CHECKERR_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_STANDARD_H +#include +#endif +#ifndef _SCHILY_UTYPES_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Error conditions handled by error control. + */ +#define E_STAT 0x0001 /* Could not stat(2) file */ +#define E_GETACL 0x0002 /* Could not retrieve ACL info */ +#define E_OPEN 0x0004 /* Could not open file */ +#define E_READ 0x0008 /* Could not read file */ +#define E_WRITE 0x0010 /* Could not write file */ +#define E_GROW 0x0020 /* File did grow during backup */ +#define E_SHRINK 0x0040 /* File did shrink during backup */ +#define E_MISSLINK 0x0080 /* Missing hard link(s) for file */ +#define E_NAMETOOLONG 0x0100 /* File name too long for archive */ +#define E_FILETOOBIG 0x0200 /* File too big for archive */ +#define E_SPECIALFILE 0x0400 /* Improper file type for archive */ +#define E_READLINK 0x0800 /* Could not read symbolic link */ +#define E_GETXATTR 0x1000 /* Could not get xattr */ +#define E_CHDIR 0x2000 /* Could not chdir() */ + +/* + * Currently unused: 0x4000 .. 0x8000 + */ + +#define E_SETTIME 0x10000 /* Could not set file times */ +#define E_SETMODE 0x20000 /* Could not set access modes */ +#define E_SECURITY 0x40000 /* Skipped for security reasons */ +#define E_LSECURITY 0x80000 /* Link skipped for security */ +#define E_SAMEFILE 0x100000 /* Skipped from/to identical */ +#define E_BADACL 0x200000 /* ACL string conversion error */ +#define E_SETACL 0x400000 /* Could not set ACL for file */ +#define E_SETXATTR 0x800000 /* Could not set xattr */ + +/* + * Currently unused: 0x1000000 .. 0x8000000 + */ + +#define E_DIFF 0x10000000 /* Diffs encountered */ +#define E_WARN 0x20000000 /* Print this error but do exit(0) */ +#define E_ABORT 0x40000000 /* Abort on this error */ +#define E_EXT 0x80000000 /* Extended (TBD later) */ + +#define E_ALL (~(UInt32_t)(E_DIFF|E_ABORT)) + +extern int errconfig __PR((char *name)); +extern BOOL errhidden __PR((int etype, const char *fname)); +extern BOOL errwarnonly __PR((int etype, const char *fname)); +extern BOOL errabort __PR((int etype, const char *fname, + BOOL doexit)); + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_CHECKERR_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/ctype.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/ctype.h new file mode 100644 index 00000000000..8a477977e45 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/ctype.h @@ -0,0 +1,40 @@ +/* @(#)ctype.h 1.2 16/06/19 Copyright 2009-2016 J. Schilling */ +/* + * Ctype abstraction + * + * Copyright (c) 2009-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_CTYPE_H +#define _SCHILY_CTYPE_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_TYPES_H +#include +#endif + +#ifdef HAVE_CTYPE_H +#ifndef _INCL_CTYPE_H +#include +#define _INCL_CTYPE_H +#endif +#else + +#endif /* ! HAVE_CTYPE_H */ + +#endif /* _SCHILY_CTYPE_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/device.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/device.h new file mode 100644 index 00000000000..8e629d29d58 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/device.h @@ -0,0 +1,153 @@ +/* @(#)device.h 1.19 09/11/16 Copyright 1995-2007 J. Schilling */ +/* + * Generic header for users of major(), minor() and makedev() + * + * Copyright (c) 1995-2007 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_DEVICE_H +#define _SCHILY_DEVICE_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * On generic SVR4, major is a function (defined in sys/mkdev.h). + * On Solaris it is defined ... + * As we cannot just test if major is #define'd, we have to + * define _FOUND_MAJOR_ instead. + * + * WARNING: Do never include in SVR4, it contains + * an old definition for major()/minor() defining 8 minorbits. + * Use instead. + */ +#ifndef _SCHILY_TYPES_H +#include +#endif + +/* + * Some systems define major in . + * We are ready... + */ +#ifdef major +# define _FOUND_MAJOR_ +#endif + +#ifdef MAJOR_IN_MKDEV +# ifndef _INCL_SYS_MKDEV_H +# include +# define _INCL_SYS_MKDEV_H +# endif + /* + * Interix doesn't use makedev(); it uses mkdev() + */ +# if !defined(makedev) && defined(mkdev) +# define makedev(a, b) mkdev((a), (b)) +# endif +# define _FOUND_MAJOR_ +#endif + +#ifndef _FOUND_MAJOR_ +# ifdef MAJOR_IN_SYSMACROS +# ifndef _INCL_SYS_SYSMACROS_H +# include +# define _INCL_SYS_SYSMACROS_H +# endif +# define _FOUND_MAJOR_ +# endif +#endif + +/* + * If we are on HP/UX before HP/UX 8, + * major/minor are not in . + */ +#ifndef _FOUND_MAJOR_ +# if defined(hpux) || defined(__hpux__) || defined(__hpux) +# ifndef _INCL_SYS_MKOD_H +# include +# define _INCL_SYS_MKOD_H +# endif +# define _FOUND_MAJOR_ +# endif +#endif + +#ifndef _FOUND_MAJOR_ +# ifdef VMS +# define major(dev) (((((long)dev) >> 8) & 0xFF)) +# define minor(dev) ((((long)dev) & 0xFF)) +# define makedev(majo, mino) (((majo) << 8) | (mino)) +# define _FOUND_MAJOR_ +# endif /* VMS */ +#endif /* _FOUND_MAJOR_ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * For all other systems define major()/minor() here. + * XXX Check if this definition will be usefull for ms dos too. + */ +#ifndef _FOUND_MAJOR_ +# define major(dev) (((dev) >> 8) & 0xFF) +# define minor(dev) ((dev) & 0xFF) +# define makedev(majo, mino) (((majo) << 8) | (mino)) +#endif + +/* + * Don't pollute namespace... + */ +#undef _FOUND_MAJOR_ + +#ifdef __XDEV__ +/* + * The following defines are currently only needed for 'star'. + * We make it conditional code to avoid to pollute the namespace. + */ +#define XDEV_T unsigned long + +extern int minorbits; +extern XDEV_T minormask; +extern XDEV_T _dev_mask[]; + +#define dev_major(dev) (((XDEV_T)(dev)) >> minorbits) +#define _dev_major(mbits, dev) (((XDEV_T)(dev)) >> (mbits)) + +#define dev_minor(dev) (((XDEV_T)(dev)) & minormask) +#define _dev_minor(mbits, dev) (((XDEV_T)(dev)) & _dev_mask[(mbits)]) + + +#define dev_make(majo, mino) ((((XDEV_T)(majo)) << minorbits) | \ + ((XDEV_T)(mino))) +#define _dev_make(mbits, majo, mino) ((((XDEV_T)(majo)) << (mbits) | \ + ((XDEV_T)(mino))) + +extern void dev_init __PR((BOOL debug)); +#ifndef dev_major +extern XDEV_T dev_major __PR((XDEV_T dev)); +extern XDEV_T _dev_major __PR((int mbits, XDEV_T dev)); +extern XDEV_T dev_minor __PR((XDEV_T dev)); +extern XDEV_T _dev_minor __PR((int mbits, XDEV_T dev)); +extern XDEV_T dev_make __PR((XDEV_T majo, XDEV_T mino)); +extern XDEV_T _dev_make __PR((int mbits, XDEV_T majo, XDEV_T mino)); +#endif + +#endif /* __XDEV__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_DEVICE_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/dirent.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/dirent.h new file mode 100644 index 00000000000..f933b7ceb6e --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/dirent.h @@ -0,0 +1,225 @@ +/* @(#)dirent.h 1.29 11/08/04 Copyright 1987, 1998, 2000-2011 J. Schilling */ +/* + * Copyright (c) 1987, 1998, 2000-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_DIRENT_H +#define _SCHILY_DIRENT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JOS +# ifdef HAVE_SYS_STYPES_H +# ifndef _INCL_SYS_STYPES_H +# include +# define _INCL_SYS_STYPES_H +# endif +# endif +# ifdef HAVE_SYS_FILEDESC_H +# ifndef _INCL_SYS_FILEDESC_H +# include +# define _INCL_SYS_FILEDESC_H +# endif +# endif +# define NEED_READDIR +# define dirent _direct +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# define DIRSIZE 30 +# define FOUND_DIRSIZE + typedef struct _dirent { + char name[DIRSIZE]; + short ino; + } dirent; + +#else /* !JOS */ + +# ifndef _SCHILY_TYPES_H +# include +# endif +# ifndef _SCHILY_STAT_H +# include +# endif +# ifndef _SCHILY_LIMITS_H +# include +# endif +# ifndef _SCHILY_PARAM_H +# include +# endif +# ifndef _SCHILY_STDLIB_H +# include /* MSVC: get _MAX_DIR */ +# endif + +# ifdef HAVE_DIRENT_H /* This a POSIX compliant system */ +# ifndef _INCL_DIRENT_H +# include +# define _INCL_DIRENT_H +# endif +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# define _FOUND_DIR_ +# else /* This is a Pre POSIX system */ + +# define dirent direct +# define DIR_NAMELEN(dirent) (dirent)->d_namlen + +# if defined(HAVE_SYS_DIR_H) +# ifndef _INCL_SYS_DIR_H +# include +# define _INCL_SYS_DIR_H +# endif +# define _FOUND_DIR_ +# endif + +# if defined(HAVE_NDIR_H) && !defined(_FOUND_DIR_) +# ifndef _INCL_NDIR_H +# include +# define _INCL_NDIR_H +# endif +# define _FOUND_DIR_ +# endif + +# if defined(HAVE_SYS_NDIR_H) && !defined(_FOUND_DIR_) +# ifndef _INCL_SYS_NDIR_H +# include +# define _INCL_SYS_NDIR_H +# endif +# define _FOUND_DIR_ +# endif +# endif /* HAVE_DIRENT_H */ + +# if defined(_FOUND_DIR_) +/* + * Don't use defaults here to allow recognition of problems. + */ +# if !defined(FOUND_DIRSIZE) && defined(MAXNAMELEN) +# define DIRSIZE MAXNAMELEN /* From sys/param.h */ +# define FOUND_DIRSIZE +# endif + +# if !defined(FOUND_DIRSIZE) && defined(MAXNAMLEN) +# define DIRSIZE MAXNAMLEN /* From dirent.h */ +# define FOUND_DIRSIZE +# endif + +# ifdef __never__ + /* + * DIRSIZ(dp) is a parameterized macro, we cannot use it here. + */ +# if !defined(FOUND_DIRSIZE) && defined(DIRSIZ) +# define DIRSIZE DIRSIZ /* From sys/dir.h */ +# define FOUND_DIRSIZE +# endif +# endif /* __never__ */ + +# if !defined(FOUND_DIRSIZE) && defined(NAME_MAX) +# define DIRSIZE NAME_MAX /* From limits.h */ +# define FOUND_DIRSIZE +# endif + +# else /* !_FOUND_DIR_ */ + +# if !defined(FOUND_DIRSIZE) && defined(_MAX_DIR) +# if defined(__MINGW32__) || defined(_MSC_VER) +# define DIRSIZE _MAX_DIR /* From stdlib.h */ +# define FOUND_DIRSIZE +# define NEED_READDIR +# undef dirent +# define dirent _direct +# undef DIR_NAMELEN +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# endif +# endif + +# ifndef NEED_READDIR +# define NEED_DIRENT +# define NEED_READDIR +# undef dirent +# define dirent _direct +# undef DIR_NAMELEN +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# endif /* !NEED_READDIR */ + +# endif /* _FOUND_DIR_ */ + + +#ifdef NEED_DIRENT + +#ifndef FOUND_DIRSIZE +#define DIRSIZE 14 /* The old UNIX standard value */ +#define FOUND_DIRSIZE +#endif + +typedef struct _dirent { + short ino; + char name[DIRSIZE]; +} dirent; + +#endif /* NEED_DIRENT */ + +#endif /* !JOS */ + +#ifdef NEED_READDIR + +#ifndef _SCHILY_STDIO_H +#include +#endif +#if defined(__MINGW32__) || defined(_MSC_VER) +#ifndef _SCHILY_IO_H +#include /* for _findfirst() */ +#endif +#ifndef _SCHILY_UTYPES_H +#include +#endif +#endif + + struct _direct { + unsigned long d_ino; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[DIRSIZE +1]; + }; +#define HAVE_DIRENT_D_INO + + typedef struct __dirdesc { + FILE *dd_fd; + +#if defined(__MINGW32__) || defined(_MSC_VER) + struct _direct dd_dir; /* dirent for this dir */ + struct _finddata_t dd_data; /* _findnext() results */ + intptr_t dd_handle; /* _findnext() handle */ + int dd_state; /* Current Dir state */ + char dd_dirname[1]; /* Dir to open */ +#endif + } DIR; + +extern DIR *opendir __PR((const char *)); +extern int closedir __PR((DIR *)); +extern struct dirent *readdir __PR((DIR *)); + +#endif /* NEED_READDIR */ + +#if !defined(HAVE_DIRFD) && defined(HAVE_DIR_DD_FD) +# define dirfd(dirp) ((dirp)->dd_fd) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_DIRENT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/dlfcn.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/dlfcn.h new file mode 100644 index 00000000000..e2b328bdae3 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/dlfcn.h @@ -0,0 +1,110 @@ +/* @(#)dlfcn.h 1.4 15/07/13 Copyright 2015 J. Schilling */ +/* + * Abstraction from dlfcn.h + * + * Copyright (c) 2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_DLFCN_H +#define _SCHILY_DLFCN_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_DLFCN_H +#ifndef _INCL_DLFCN_H +#include /* POSIX */ +#define _INCL_DLFCN_H +#define FOUND_DLFCN_H +#endif +#endif + +#ifdef HAVE_DL_H +#ifndef FOUND_DLFCN_H +#ifndef _INCL_DL_H +#include /* HP-UX */ +#define _INCL_DL_H +#define FOUND_DLFCN_H +#endif +#endif +#endif + +#if defined(HAVE_DLOPEN) && defined(HAVE_DLCLOSE) /* POSIX */ +#define HAVE_LOADABLE_LIBS +#endif + +#if !defined(HAVE_LOADABLE_LIBS) && defined(HAVE_SHL_LOAD) /* HP-UX */ +#define HAVE_LOADABLE_LIBS +#endif + +#if !defined(HAVE_LOADABLE_LIBS) && defined(HAVE_LOADLIBRARY) /* Win-DOS */ +#define HAVE_LOADABLE_LIBS +#endif + +/* + * dlopen() modes + */ +#ifndef RTLD_LAZY /* The only mode in SunOS-4.0 */ +#define RTLD_LAZY 0x00001 +#define RTLD_NOW 0x00002 +#define RTLD_GLOBAL 0x00100 +#define RTLD_LOCAL 0x00000 +#endif + +#ifdef __never_ +/* + * dlsym() speudo handles + * These handles are not valid on SunOS-4.0 + */ +#ifndef RTLD_NEXT +#define RTLD_NEXT (void *)-1 +#define RTLD_DEFAULT (void *)-2 +#define RTLD_SELF (void *)-3 +#endif +#endif + +/* + * dlsym() speudo handle for SunOS-4.0 + */ +#if defined(HAVE_DLSYM) && !defined(RTLD_SELF) +#define RTLD_SELF (void *)0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_DLOPEN +extern void *dlopen __PR((const char *__pathname, int mode)); +#endif +#ifndef HAVE_DLCLOSE +extern int dlclose __PR((void *__handle)); +#endif +#ifndef HAVE_DLSYM +extern void *dlsym __PR((void *__handle, const char *name)); +#endif +#ifndef HAVE_DLERROR +extern const char *dlerror __PR((void)); +#endif + +#ifdef __cplusplus +} +#endif + + + +#endif /* _SCHILY_DLFCN_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/errno.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/errno.h new file mode 100644 index 00000000000..9dad3729764 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/errno.h @@ -0,0 +1,62 @@ +/* @(#)errno.h 1.7 10/08/24 Copyright 2006-2010 J. Schilling */ +/* + * Error number related definitions + * + * Copyright (c) 2006-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_ERRNO_H +#define _SCHILY_ERRNO_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef JOS +#include + +#define ENOEXEC EBADHEADER +#define EACCES EACCESS +#define ENOENT ENOFILE +#define EEXIST EEXISTS +#else +#include + +#define EMISSDIR ENOENT +#define ENDOFFILE EFBIG +#endif + +#ifndef HAVE_ERRNO_DEF +extern int errno; +#endif + +#ifndef HAVE_STRERROR +extern char *sys_errlist[]; +extern int sys_nerr; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef seterrno +extern int seterrno __PR((int)); +#endif +extern int geterrno __PR((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_ERRNO_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/fcntl.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/fcntl.h new file mode 100644 index 00000000000..4bcc7c40433 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/fcntl.h @@ -0,0 +1,134 @@ +/* @(#)fcntl.h 1.19 11/10/19 Copyright 1996-2011 J. Schilling */ +/* + * Generic header for users of open(), creat() and chmod() + * + * Copyright (c) 1996-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_FCNTL_H +#define _SCHILY_FCNTL_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_TYPES_H +#include /* Needed for fcntl.h */ +#endif + +#ifndef _SCHILY_STAT_H +#include /* For 3rd arg of open() and chmod() */ +#endif + +#ifdef HAVE_SYS_FILE_H +/* + * Historical systems with flock() only need sys/file.h + */ +# ifndef _INCL_SYS_FILE_H +# include +# define _INCL_SYS_FILE_H +# endif +#endif +#ifdef HAVE_FCNTL_H +# ifndef _INCL_FCNTL_H +# include +# define _INCL_FCNTL_H +#endif +#endif + +/* + * Do not define more than O_RDONLY / O_WRONLY / O_RDWR / O_BINARY + * The values may differ. + * + * O_BINARY is defined here to allow all applications to compile on a non DOS + * environment without repeating this definition. + * O_SEARCH, O_DIRECTORY and NOFOLLOW are defined here to allow to compile on + * older platforms. + * open(name, O_SEARCH) is like UNOS open(name, "") (open neither for read nor + * for write). This allows to call fstat() and to get an fd for openat(fd, ...) + */ +#ifndef O_RDONLY +# define O_RDONLY 0 +#endif +#ifndef O_WRONLY +# define O_WRONLY 1 +#endif +#ifndef O_RDWR +# define O_RDWR 2 +#endif +#ifndef O_BINARY /* Only present on DOS or similar */ +# define O_BINARY 0 +#endif +#ifndef O_NDELAY /* This is undefined on BeOS :-( */ +# define O_NDELAY 0 +#endif +#ifndef O_EXEC /* Open for exec only (non-directory) */ +# define O_EXEC O_RDONLY +#endif +#ifndef O_SEARCH /* Open for search only. */ +# define O_SEARCH O_RDONLY +#endif +#ifndef O_DIRECTORY /* Fail if not a directory */ +# define O_DIRECTORY 0 +#endif +#ifndef O_NOFOLLOW /* Fail if a symlink */ +# define O_NOFOLLOW 0 +#endif + +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR|O_EXEC|O_SEARCH) +#endif + +#ifdef O_NOATIME /* Allow #ifdef O_NOATIME */ +#define _O_NOATIME O_NOATIME +#else +#define _O_NOATIME 0 +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 /* close on exec flag */ +#endif + +/* + * The following definitions are used for emulating the *at() functions. + * We use higher numbers for our definitions, to allow to add emulations + * for missing functions without causing a clash with system definitions. + */ +#ifndef HAVE_OPENAT +#ifndef AT_FDCWD +#define AT_FDCWD 0xffd19553 /* *at() to working dir */ +#endif +#endif +#ifndef HAVE_FSTATAT +#ifndef AT_SYMLINK_NOFOLLOW +#define AT_SYMLINK_NOFOLLOW 0x10000 /* emulate lstat() */ +#endif +#endif +#ifndef HAVE_UNLINKAT +#ifndef AT_REMOVEDIR +#define AT_REMOVEDIR 0x20000 /* emulate rmdir() */ +#endif +#endif +#ifndef HAVE_FACCESSAT +#ifndef AT_EACCESS +#define AT_EACCESS 0x40000 /* EUID access() */ +#endif +#endif +#ifndef HAVE_LINKAT +#ifndef AT_SYMLINK_FOLLOW +#define AT_SYMLINK_FOLLOW 0x80000 /* follow symlinks before link() */ +#endif +#endif + +#endif /* _SCHILY_FCNTL_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/float.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/float.h new file mode 100644 index 00000000000..58dc12ac53b --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/float.h @@ -0,0 +1,56 @@ +/* @(#)float.h 1.1 09/08/08 Copyright 2009 J. Schilling */ +/* + * Abstraction code for float.h + * + * Copyright (c) 2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_FLOAT_H +#define _SCHILY_FLOAT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_FLOAT_H +#ifndef _INCL_FLOAT_H +#define _INCL_FLOAT_H +#include +#endif +#endif + +#ifdef HAVE_VALUES_H +#ifndef _INCL_VALUES_H +#define _INCL_VALUES_H +#include +#endif + +#ifndef FLT_MAX +#define FLT_MAX MAXFLOAT +#endif +#ifndef FLT_MIN +#define FLT_MIN MINFLOAT +#endif +#ifndef DBL_MAX +#define DBL_MAX MAXDOUBLE +#endif +#ifndef DBL_MIN +#define DBL_MIN MINDOUBLE +#endif + +#endif + + + +#endif /* _SCHILY_FLOAT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/fnmatch.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/fnmatch.h new file mode 100644 index 00000000000..8590bc65c69 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/fnmatch.h @@ -0,0 +1,103 @@ +/* @(#)fnmatch.h 8.13 10/10/09 Copyright 2006-2010 J. Schilling from 8.1 (Berkeley) */ + +#ifndef _SCHILY_FNMATCH_H +#define _SCHILY_FNMATCH_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_FNMATCH_H +#include +#else /* !HAVE_FNMATCH_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int fnmatch __PR((const char *, const char *, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* !HAVE_FNMATCH */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)fnmatch.h 8.13 (Berkeley) 10/09/10 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef FNM_NOMATCH +#define FNM_NOMATCH 1 /* Match failed. */ +#endif +#ifndef FNM_ERROR +#define FNM_ERROR 2 /* An error occured */ +#endif +#ifndef FNM_NOSYS +#define FNM_NOSYS 3 /* Function (XPG4) not supported */ +#endif + +#ifndef FNM_NOESCAPE +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#endif +#ifndef FNM_PATHNAME +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#endif +#ifndef FNM_PERIOD +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#endif +#if !defined(FNM_IGNORECASE) && !defined(FNM_CASEFOLD) +#define FNM_IGNORECASE 0x10 /* Ignore case when making comparisons */ +#endif +#if !defined(FNM_IGNORECASE) && defined(FNM_CASEFOLD) +#define FNM_IGNORECASE FNM_CASEFOLD +#endif +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD FNM_IGNORECASE +#endif +#ifndef FNM_LEADING_DIR +#define FNM_LEADING_DIR 0x20 /* Ignore / after Imatch. */ +#endif + +extern int js_fnmatch __PR((const char *, const char *, int)); + +#if !defined(HAVE_FNMATCH_IGNORECASE) +#define fnmatch js_fnmatch +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_SCHILY_FNMATCH_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/getargs.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/getargs.h new file mode 100644 index 00000000000..40087082103 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/getargs.h @@ -0,0 +1,171 @@ +/* @(#)getargs.h 1.22 16/10/23 Copyright 1985-2016 J. Schilling */ +/* + * Definitions for getargs()/getallargs()/getfiles() + * + * Copyright (c) 1985-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_GETARGS_H +#define _SCHILY_GETARGS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_UTYPES_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Return values for get*args()/get*files() + * + * This package calls options "flags", they are returned from get*args(). + * + * Note that NOTAFILE is not returned by the interface functions. + * NOTAFILE is however used as return code from the user's callback functions + * to signal that the current arg may be an option the callback function does + * not know and definitely is no file type argument. + * + * General rules for the return code of the interface functions + * get*args()/get*files(): + * + * > 0 A file type argument was found + * 0 All arguments have been parsed + * < 0 An error occured + * + * Flag and file arg processing should be terminated after getting a return + * code <= 0. + */ +#define FLAGDELIM 2 /* "--" stopped flag processing */ +#define NOTAFLAG 1 /* Not a flag type argument */ +#define NOARGS 0 /* No more args */ +#define BADFLAG (-1) /* Not a valid flag argument */ +#define BADFMT (-2) /* Error in format string */ +#define NOTAFILE (-3) /* Seems to be a flag type */ + +/* + * The callback functions are called with the following parameters: + * + * arg The option argument + * valp A pointer to the related value argument from a get*arg*() call + * pac A pointer to the current argument counter + * pav A pointer to the current argument vector + * opt The option that caused the call + * + * The return value of the callback function may be: + * + * FLAGDELIM Pretend "--" stopped flag processing + * FLAGPARSED A valid flag was found, getallargs() will continue scanning + * ------------ the following codes will interrupt getallargs() processing: + * NOARGS Pretend all arguments have been examined + * BADFLAG Not a valid flag argument + * BADFMT General Error + * NOTAFILE Continue to check the format string for matches with option arg + */ +#define FLAGPARSED 1 /* Flag was sucessfully parsed */ + +typedef int (*getargfun) __PR((const char *__arg, void *__valp)); +typedef int (*getpargfun) __PR((const char *__arg, void *__valp, + int *__pac, char *const **__pav, + const char *__opt)); + +#define NO_ARGFUN (getargpfun)0 + +struct ga_flags { + const char *ga_format; /* Comma separated list for one flag */ + void *ga_arg; /* Ptr. to variable to fill for flag */ + getpargfun ga_funcp; /* Ptr. for function to call (&/~) */ +}; + +struct ga_props { + UInt32_t ga_flags; /* Flags to define behavior */ + UInt32_t ga_oflags; /* State flags */ + size_t ga_size; /* Size of this struct gs_props */ +}; + +/* + * This may be used instead of a struct ga_props * parameter: + */ +#define GA_NO_PROPS (struct ga_props *)0 /* Default behavior */ +#define GA_POSIX_PROPS (struct ga_props *)-1 /* POSIX behavior */ + +/* + * Definitions for ga_flags + */ +#define GAF_DEFAULT 0x00 /* The default behavior */ +#define GAF_NO_PLUS 0x01 /* Options may not start with '+' */ +#define GAF_NO_EQUAL 0x02 /* Disallow '=' between opt and val */ +#define GAF_NEED_DASH 0x04 /* Need dash before (-name=val), */ + /* name=val is not allowed */ +#define GAF_DELIM_DASHDASH 0x08 /* "--" stops even get?allargs() */ +#define GAF_POSIX 0x1000 /* Will be expanded as shown below */ + +/* + * POSIX does not allow options in the form "+option", "-option=value" or + * "option=value". get*files() needs to know what may be a valid option. + * + * If ga_flags == GAF_POSIX, ga_flags is replaced with the value + * of the current definition for GAF_POSIX_DEFAULT. + * + * GAF_NO_PLUS do not allow options to start with a '+' + * GAF_NO_EQUAL do not allow options to contain '=' between name & val + * + * Warning: future versions may need different flags for POSIX, better use the + * GA_POSIX_PROPS "struct" or the GAF_POSIX flag. + */ +#define GAF_POSIX_DEFAULT (GAF_NO_PLUS | GAF_NO_EQUAL) + +/* + * Keep in sync with schily.h + */ +extern int getallargs __PR((int *, char * const**, const char *, ...)); +extern int getargs __PR((int *, char * const**, const char *, ...)); +extern int getfiles __PR((int *, char * const**, const char *)); +extern char *getargerror __PR((int)); + +/* + * The new list versions of the functions need struct ga_props and thus need + * getargs.h + */ +extern int getlallargs __PR((int *, char * const**, struct ga_props *, + const char *, ...)); +extern int getlargs __PR((int *, char * const**, struct ga_props *, + const char *, ...)); +extern int getlfiles __PR((int *, char * const**, struct ga_props *, + const char *)); +extern int _getarginit __PR((struct ga_props *, size_t, UInt32_t)); + +#define getarginit(p, f) _getarginit(p, sizeof (struct ga_props), f) + +/* + * The vector versions of the functions need struct ga_flags and thus need + * getargs.h + */ +extern int getvallargs __PR((int *, char * const**, struct ga_props *, + struct ga_flags *)); +extern int getvargs __PR((int *, char * const**, struct ga_props *, + struct ga_flags *)); +extern int getvfiles __PR((int *, char * const**, struct ga_props *, + struct ga_flags *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_GETARGS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/iconv.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/iconv.h new file mode 100644 index 00000000000..d14b88a4122 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/iconv.h @@ -0,0 +1,72 @@ +/* @(#)iconv.h 1.4 08/01/02 Copyright 2007 J. Schilling */ +/* + * Abstraction from iconv.h + * + * Copyright (c) 2007 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_ICONV_H +#define _SCHILY_ICONV_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_ICONV_H +#ifndef _INCL_ICONV_H +#include +#define _INCL_ICONV_H +#endif +#else +#undef USE_ICONV +#endif + +/* + * Libiconv on Cygwin is not autoconf-friendly. + * iconv.h #defined iconv to libiconv + * We would need a AC_CHECK_FUNC() macro that allows to specify includefiles. + */ +#if defined(HAVE_LIBICONV) && defined(HAVE_LIBICONV_OPEN) && \ + defined(HAVE_LIBICONV_CLOSE) && \ + defined(iconv) && defined(iconv_open) && defined(iconv_close) +# ifndef HAVE_ICONV +# define HAVE_ICONV +# endif +# ifndef HAVE_ICONV_OPEN +# define HAVE_ICONV_OPEN +# endif +# ifndef HAVE_ICONV_CLOSE +# define HAVE_ICONV_CLOSE +# endif +#endif + +#if !defined(HAVE_ICONV_OPEN) || !defined(HAVE_ICONV_CLOSE) +# undef HAVE_ICONV +#endif + +#ifndef HAVE_ICONV +#undef USE_ICONV +#endif + +#ifdef NO_ICONV +#undef USE_ICONV +#endif + +#ifndef USE_ICONV +#undef iconv_t +#define iconv_t char * +#endif + + +#endif /* _SCHILY_ICONV_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/intcvt.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/intcvt.h new file mode 100644 index 00000000000..ec214acef66 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/intcvt.h @@ -0,0 +1,114 @@ +/* @(#)intcvt.h 1.8 13/10/26 Copyright 1986-2013 J. Schilling */ +/* + * Definitions for conversion to/from integer data types of various size. + * + * Copyright (c) 1986-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_INTCVT_H +#define _SCHILY_INTCVT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_UTYPES_H +#include +#endif + +#define i_to_2_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[1] = (i) & 0xFF) + +#define i_to_3_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[2] = (i) & 0xFF) + +#define i_to_4_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[3] = (i) & 0xFF) + + + +#define a_to_byte(a) (((Int8_t *)a)[0]) + +#define a_to_u_byte(a) ((UInt8_t) \ + (((Uchar *)a)[0] & 0xFF)) + +#define a_to_u_2_byte(a) ((UInt16_t) \ + ((((Uchar *)a)[1] & 0xFF) | \ + (((Uchar *)a)[0] << 8 & 0xFF00))) + +#define a_to_2_byte(a) (int)(Int16_t)a_to_u_2_byte(a) + +#define a_to_u_3_byte(a) ((Ulong) \ + ((((Uchar *)a)[2] & 0xFF) | \ + (((Uchar *)a)[1] << 8 & 0xFF00) | \ + (((Uchar *)a)[0] << 16 & 0xFF0000))) + +#define a_to_3_byte(a) a_to_u_3_byte(a) /* XXX signed version? */ + +#ifdef __STDC__ +# define __TOP_4BYTE 0xFF000000UL +#else +# define __TOP_4BYTE 0xFF000000 +#endif + +#define a_to_u_4_byte(a) ((Ulong) \ + ((((Uchar*)a)[3] & 0xFF) | \ + (((Uchar*)a)[2] << 8 & 0xFF00) | \ + (((Uchar*)a)[1] << 16 & 0xFF0000) | \ + (((Uchar*)a)[0] << 24 & __TOP_4BYTE))) + +#define a_to_4_byte(a) (long)(Int32_t)a_to_u_4_byte(a) + +/* + * Little Endian versions of above macros + */ +#define li_to_2_byte(a, i) (((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + +#define li_to_3_byte(a, i) (((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + +#define li_to_4_byte(a, i) (((Uchar *)(a))[3] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + + +#define la_to_u_2_byte(a) ((UInt16_t) \ + ((((Uchar*)a)[0] & 0xFF) | \ + (((Uchar*)a)[1] << 8 & 0xFF00))) + +#define la_to_2_byte(a) (int)(Int16_t)la_to_u_2_byte(a) + +#define la_to_u_3_byte(a) ((Ulong) \ + ((((Uchar*)a)[0] & 0xFF) | \ + (((Uchar*)a)[1] << 8 & 0xFF00) | \ + (((Uchar*)a)[2] << 16 & 0xFF0000))) + +#define la_to_3_byte(a) la_to_u_3_byte(a) /* XXX signed version? */ + +#define la_to_u_4_byte(a) ((Ulong) \ + ((((Uchar*)a)[0] & 0xFF) | \ + (((Uchar*)a)[1] << 8 & 0xFF00) | \ + (((Uchar*)a)[2] << 16 & 0xFF0000) | \ + (((Uchar*)a)[3] << 24 & __TOP_4BYTE))) + +#define la_to_4_byte(a) (long)(Int32_t)la_to_u_4_byte(a) + +#endif /* _SCHILY_INTCVT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/inttypes.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/inttypes.h new file mode 100644 index 00000000000..a73621e255e --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/inttypes.h @@ -0,0 +1,38 @@ +/* @(#)inttypes.h 1.35 12/01/22 Copyright 1997-2012 J. Schilling */ +/* + * Abstraction from inttypes.h + * + * Copyright (c) 1997-2012 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_INTTYPES_H +#define _SCHILY_INTTYPES_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * inttypes.h is based on stdint.h + */ +#ifndef _SCHILY_STDINT_H +#include +#endif + +/* + * inttypes.h inaddition to stdint.h defines printf() format strings. + * As we have a portable printf() in libschily, we do not need these #defines. + */ + +#endif /* _SCHILY_INTTYPES_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/io.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/io.h new file mode 100644 index 00000000000..61bf3c69125 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/io.h @@ -0,0 +1,46 @@ +/* @(#)io.h 1.1 09/07/13 Copyright 2009 J. Schilling */ +/* + * DOS io.h abstraction + * + * Copyright (c) 2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_IO_H +#define _SCHILY_IO_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_FCNTL_H +#include +#endif + +#ifndef NEED_O_BINARY +#if O_BINARY != 0 +#define NEED_O_BINARY +#endif +#endif + +#if defined(HAVE_IO_H) && defined(NEED_O_BINARY) +#ifndef _INCL_IO_H +#include +#define _INCL_IO_H +#endif +#else /* ! defined(HAVE_IO_H) && defined(NEED_O_BINARY) */ + +#define setmode(f, m) + +#endif + +#endif /* _SCHILY_IO_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/libport.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/libport.h new file mode 100644 index 00000000000..38bac7f3dae --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/libport.h @@ -0,0 +1,416 @@ +/* @(#)libport.h 1.44 15/05/09 Copyright 1995-2015 J. Schilling */ +/* + * Prototypes for POSIX standard functions that may be missing on the + * local platform and thus are implemented inside libschily. + * + * Copyright (c) 1995-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + + +#ifndef _SCHILY_LIBPORT_H +#define _SCHILY_LIBPORT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_TYPES_H +#include +#endif + +#ifndef _SCHILY_UNISTD_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_INCL_SYS_TYPES_H) || defined(_INCL_TYPES_H) || defined(size_t) +# ifndef FOUND_SIZE_T +# define FOUND_SIZE_T +# endif +#endif +#if defined(_MSC_VER) && !defined(_SIZE_T_DEFINED) +# undef FOUND_SIZE_T +#endif + +#ifdef OPENSERVER +/* + * Don't use the usleep() from libc on SCO's OPENSERVER. + * It will kill our processes with SIGALRM. + */ +/* + * Don't #undef HAVE_USLEEP in this file, SCO has a + * usleep() prototype in unistd.h + */ +/* #undef HAVE_USLEEP */ +#endif + +#ifdef FOUND_SIZE_T +/* + * We currently cannot define this here because there IRIX has a definition + * than violates the standard. + */ +#ifndef HAVE_SNPRINTF +/*PRINTFLIKE3*/ +extern int snprintf __PR((char *, size_t, const char *, ...)) + __printflike__(3, 4); +#endif +#endif + +#ifdef EOF /* stdio.h has been included */ +#ifdef FOUND_SIZE_T +#ifndef HAVE_GETDELIM +extern ssize_t getdelim __PR((char **, size_t *, int, FILE *)); +#endif +#endif +#endif + +#ifndef HAVE_GETHOSTID +extern long gethostid __PR((void)); +#endif +#ifndef HAVE_GETPAGESIZE +extern int getpagesize __PR((void)); +#endif +#ifndef HAVE_USLEEP +extern int usleep __PR((int usec)); +#endif + +#ifndef HAVE_STRCASECMP +extern int strcasecmp __PR((const char *, const char *)); +#endif +#ifdef FOUND_SIZE_T +#ifndef HAVE_STRNCASECMP +extern int strncasecmp __PR((const char *, const char *, + size_t)); +#endif +#endif + +#ifndef HAVE_STRCAT +extern char *strcat __PR((char *s1, const char *s2)); +#endif +#ifndef HAVE_STRCHR +extern char *strchr __PR((const char *s1, int c)); +#endif +#ifndef HAVE_STRCMP +extern int strcmp __PR((const char *s1, const char *s2)); +#endif +#ifndef HAVE_STRCPY +extern char *strcpy __PR((char *s1, const char *s2)); +#endif +#if !defined(HAVE_STRDUP) || defined(__SVR4) +extern char *strdup __PR((const char *s)); +#endif +#ifdef FOUND_SIZE_T +#ifndef HAVE_STRNDUP +extern char *strndup __PR((const char *s, size_t len)); +#endif +#ifndef HAVE_STRLEN +extern size_t strlen __PR((const char *s)); +#endif +#ifndef HAVE_STRNLEN +extern size_t strnlen __PR((const char *s, size_t len)); +#endif +#ifndef HAVE_STRLCAT +extern size_t strlcat __PR((char *s1, const char *s2, + size_t len)); +#endif +#ifndef HAVE_STRLCPY +extern size_t strlcpy __PR((char *s1, const char *s2, + size_t len)); +#endif +#ifndef HAVE_STRNCAT +extern char *strncat __PR((char *s1, const char *s2, + size_t len)); +#endif +#ifndef HAVE_STRNCMP +extern int strncmp __PR((const char *s1, const char *s2, + size_t len)); +#endif +#ifndef HAVE_STRNCPY +extern char *strncpy __PR((char *s1, const char *s2, + size_t len)); +#endif +#endif /* FOUND_SIZE_T */ +#ifndef HAVE_STRRCHR +extern char *strrchr __PR((const char *s1, int c)); +#endif + +#ifndef HAVE_STRSTR +extern char *strstr __PR((const char *s1, const char *s2)); +#endif + +#ifdef _SCHILY_WCHAR_H +#ifndef HAVE_WCSCAT +extern wchar_t *wcscat __PR((wchar_t *s1, const wchar_t *s2)); +#endif +#ifndef HAVE_WCSCHR +extern wchar_t *wcschr __PR((const wchar_t *s1, wchar_t c)); +#endif +#ifndef HAVE_WCSCMP +extern int wcscmp __PR((const wchar_t *s1, + const wchar_t *s2)); +#endif +#ifndef HAVE_WCSCPY +extern wchar_t *wcscpy __PR((wchar_t *s1, const wchar_t *s2)); +#endif +#ifndef HAVE_WCSDUP +extern wchar_t *wcsdup __PR((const wchar_t *s)); +#endif +#ifdef FOUND_SIZE_T +#ifndef HAVE_WCSNDUP +extern wchar_t *wcsndup __PR((const wchar_t *s, size_t len)); +#endif +#ifndef HAVE_WCSLEN +extern size_t wcslen __PR((const wchar_t *s)); +#endif +#ifndef HAVE_WCSNLEN +extern size_t wcsnlen __PR((const wchar_t *s, size_t len)); +#endif +#ifndef HAVE_WCSLCAT +extern size_t wcslcat __PR((wchar_t *s1, const wchar_t *s2, + size_t len)); +#endif +#ifndef HAVE_WCSLCPY +extern size_t wcslcpy __PR((wchar_t *s1, const wchar_t *s2, + size_t len)); +#endif +#ifndef HAVE_WCSNCAT +extern wchar_t *wcsncat __PR((wchar_t *s1, const wchar_t *s2, + size_t len)); +#endif +#ifndef HAVE_WCSNCMP +extern int wcsncmp __PR((const wchar_t *s1, + const wchar_t *s2, + size_t len)); +#endif +#ifndef HAVE_WCSNCPY +extern wchar_t *wcsncpy __PR((wchar_t *s1, const wchar_t *s2, + size_t len)); +#endif +#endif /* FOUND_SIZE_T */ +#ifndef HAVE_WCSRCHR +extern wchar_t *wcsrchr __PR((const wchar_t *s1, wchar_t c)); +#endif + +#ifndef HAVE_WCSSTR +extern wchar_t *wcsstr __PR((const wchar_t *s1, + const wchar_t *s2)); +#endif +#endif /* _SCHILY_WCHAR_H */ + +#ifndef HAVE_RENAME +extern int rename __PR((const char *old, + const char *new)); +#endif + +/* + * XXX Note: libgen.h / -lgen on Solaris contain eaccess() + */ +#ifndef HAVE_EACCESS +extern int eaccess __PR((const char *name, int mode)); +#endif + +/* + * See also libgen.h + */ +#ifndef HAVE_BASENAME +extern char *basename __PR((char *name)); +#endif +#ifndef HAVE_DIRNAME +extern char *dirname __PR((char *name)); +#endif + +#ifndef HAVE_TIMEGM +#if defined(_SCHILY_TIME_H) +extern time_t timegm __PR((struct tm *)); +#endif +#endif + +#ifndef HAVE_GETUID +extern uid_t getuid __PR((void)); +#endif +#ifndef HAVE_GETEUID +extern uid_t geteuid __PR((void)); +#endif +#ifndef HAVE_SETUID +extern int setuid __PR((uid_t uid)); +#endif +#ifndef HAVE_SETEUID +extern int seteuid __PR((uid_t uid)); +#endif + +#ifndef HAVE_GETGID +extern gid_t getgid __PR((void)); +#endif +#ifndef HAVE_GETEGID +extern gid_t getegid __PR((void)); +#endif +#ifndef HAVE_SETGID +extern int setgid __PR((gid_t gid)); +#endif +#ifndef HAVE_SETEGID +extern int setegid __PR((gid_t gid)); +#endif + +#ifndef HAVE_GETPWNAM +extern struct passwd *getpwnam __PR((const char *name)); +#endif +#ifndef HAVE_GETPWENT +extern struct passwd *getpwent __PR((void)); +#endif +#ifndef HAVE_GETPWUID +extern struct passwd *getpwuid __PR((uid_t uid)); +#endif +#ifndef HAVE_SETPWENT +extern void setpwent __PR((void)); +#endif +#ifndef HAVE_ENDPWENT +extern void endpwent __PR((void)); +#endif + + +#ifndef HAVE_GETGRNAM +extern struct group *getgrnam __PR((const char *name)); +#endif +#ifndef HAVE_GETGRENT +extern struct group *getgrent __PR((void)); +#endif +#ifndef HAVE_GETGRGID +extern struct group *getgrgid __PR((gid_t gid)); +#endif +#ifndef HAVE_SETGRENT +extern void setgrent __PR((void)); +#endif +#ifndef HAVE_ENDGRENT +extern void endgrent __PR((void)); +#endif + +#ifndef HAVE_FCHDIR +extern int fchdir __PR((int fd)); +#endif +#ifndef HAVE_OPENAT +extern int openat __PR((int fd, const char *name, int oflag, ...)); +#endif + + +#ifndef HAVE_GETTIMEOFDAY +#ifdef _SCHILY_TIME_H +extern int gettimeofday __PR((struct timeval *__tp, void *__tzp)); +#endif +#endif + +#ifndef HAVE_FACCESSAT +extern int faccessat __PR((int fd, const char *name, + int amode, int flag)); +#endif +#ifndef HAVE_FCHMODAT +extern int fchmodat __PR((int fd, const char *name, + mode_t mode, int flag)); +#endif +#ifndef HAVE_LCHMOD +extern int lchmod __PR((const char *name, mode_t mode)); +#endif + +#ifndef HAVE_FCHOWNAT +extern int fchownat __PR((int fd, const char *name, + uid_t owner, gid_t group, int flag)); +#endif + +#ifndef HAVE_FDOPENDIR +#ifdef _SCHILY_DIRENT_H +extern DIR *fdopendir __PR((int fd)); +#endif +#endif + +#ifdef _SCHILY_STAT_H +#ifndef HAVE_FSTATAT +extern int fstatat __PR((int fd, const char *name, + struct stat *sbuf, int flag)); +#endif +#endif /* _SCHILY_STAT_H */ +#ifdef _SCHILY_TIME_H +#ifndef HAVE_FUTIMENS +extern int futimens __PR((int fd, + const struct timespec __times[2])); +#endif +#ifndef HAVE_FUTIMESAT +extern int futimesat __PR((int fd, const char *name, + const struct timeval __times[2])); +#endif +#ifndef HAVE_LUTIMENS +extern int lutimens __PR((const char *name, + const struct timespec __times[2])); +#endif +#endif /* _SCHILY_TIME_H */ +#ifndef HAVE_LINKAT +extern int linkat __PR((int fd1, const char *name1, + int fd2, const char *name2, int flag)); +#endif +#ifndef HAVE_MKDIRAT +extern int mkdirat __PR((int fd, const char *name, mode_t mode)); +#endif +#ifndef HAVE_MKFIFO +extern int mkfifo __PR((const char *name, mode_t mode)); +#endif +#ifndef HAVE_MKFIFOAT +extern int mkfifoat __PR((int fd, const char *name, mode_t mode)); +#endif +#ifndef HAVE_MKNODAT +extern int mknodat __PR((int fd, const char *name, + mode_t mode, dev_t dev)); +#endif +#ifndef HAVE_READLINKAT +extern ssize_t readlinkat __PR((int fd, const char *name, + char *lbuf, size_t lbufsize)); +#endif +#ifndef HAVE_RENAMEAT +extern int renameat __PR((int oldfd, const char *old, + int newfd, const char *new)); +#endif +#ifndef HAVE_SYMLINKAT +extern int symlinkat __PR((const char *content, + int fd, const char *name)); +#endif +#ifndef HAVE_UNLINKAT +extern int unlinkat __PR((int fd, const char *name, int flag)); +#endif +#ifdef _SCHILY_TIME_H +#ifndef HAVE_UTIMENS +extern int utimens __PR((const char *name, + const struct timespec __times[2])); +#endif +#ifndef HAVE_UTIMENSAT +extern int utimensat __PR((int fd, const char *name, + const struct timespec __times[2], + int flag)); +#endif +#endif /* _SCHILY_TIME_H */ + +#ifdef __SUNOS4 +/* + * Define prototypes for POSIX standard functions that are missing on SunOS-4.x + * to make compilation smooth. + */ +#include + +#endif /* __SUNOS4 */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_LIBPORT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/limits.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/limits.h new file mode 100644 index 00000000000..0ed3b539948 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/limits.h @@ -0,0 +1,54 @@ +/* @(#)limits.h 1.7 11/08/13 Copyright 2011 J. Schilling */ +/* + * Copyright (c) 2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_LIMITS_H +#define _SCHILY_LIMITS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_LIMITS_H +#ifndef _INCL_LIMITS_H +#include +#define _INCL_LIMITS_H +#endif +#endif + +#ifndef COLL_WEIGHTS_MAX +#define COLL_WEIGHTS_MAX 2 +#endif + +#ifndef _POSIX2_LINE_MAX +#define _POSIX2_LINE_MAX 2048 +#endif + +/* + * Include sys/param.h for PIPE_BUF + */ +#ifndef _SCHILY_PARAM_H +#include +#endif + +#ifndef PIPE_BUF +#if defined(__MINGW32__) || defined(_MSC_VER) +#define PIPE_BUF 5120 +#else +#define PIPE_BUF 512 +#endif +#endif /* PIPE_BUF */ + +#endif /* _SCHILY_LIMITS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/locale.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/locale.h new file mode 100644 index 00000000000..40d1f960350 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/locale.h @@ -0,0 +1,50 @@ +/* @(#)locale.h 1.2 09/05/24 Copyright 2009 J. Schilling */ +/* + * Copyright (c) 2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_LOCALE_H +#define _SCHILY_LOCALE_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_LOCALE_H +#ifndef _INCL_LOCALE_H +#include /* LC_* definitions */ +#define _INCL_LOCALE_H +#endif +#ifndef USE_LOCALE +#define USE_LOCALE +#endif +#else +#undef USE_LOCALE +#endif + +#ifndef HAVE_SETLOCALE +#undef USE_LOCALE +#endif + +#ifdef NO_LOCALE +#undef USE_LOCALE +#endif + +#ifndef USE_LOCALE +#undef setlocale +#define setlocale(n, s) ((void *)0) +#endif + + +#endif /* _SCHILY_LOCALE_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/math.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/math.h new file mode 100644 index 00000000000..0a7395b4b4e --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/math.h @@ -0,0 +1,34 @@ +/* @(#)math.h 1.1 09/08/26 Copyright 2009 J. Schilling */ +/* + * Abstraction from math.h + * + * Copyright (c) 2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_MATH_H +#define _SCHILY_MATH_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_MATH_H +#ifndef _INCL_MATH_H +#define _INCL_MATH_H +#include +#endif +#endif + + +#endif /* _SCHILY_MATH_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/maxpath.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/maxpath.h new file mode 100644 index 00000000000..356a8757f02 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/maxpath.h @@ -0,0 +1,113 @@ +/* @(#)maxpath.h 1.12 10/08/27 Copyright 1985, 1995, 1998, 2001-2010 J. Schilling */ +/* + * Definitions for dealing with statically limitations on pathnames + * + * Copyright (c) 1985, 1995, 1998, 2001-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_MAXPATH_H +#define _SCHILY_MAXPATH_H + +#ifndef _SCHILY_DIRENT_H +#include /* Includes mconfig.h if needed */ +#endif + +#ifdef JOS +#ifndef _SCHILY_JOS_MAXP_H +# include +#endif +# ifndef FOUND_MAXPATHNAME +# define FOUND_MAXPATHNAME +# endif +# ifndef FOUND_MAXFILENAME +# define FOUND_MAXFILENAME +# endif +#endif /* JOS */ + +#if !defined(FOUND_MAXPATHNAME) && defined(MAXPATHLEN) +# define MAXPATHNAME MAXPATHLEN /* From sys/param.h */ +# define FOUND_MAXPATHNAME +#endif + +#if !defined(FOUND_MAXPATHNAME) && defined(PATH_MAX) +# define MAXPATHNAME PATH_MAX /* From limits.h */ +# define FOUND_MAXPATHNAME +#endif + +#if !defined(FOUND_MAXPATHNAME) +#include +#endif +#if !defined(FOUND_MAXPATHNAME) && defined(_MAX_PATH) +# define MAXPATHNAME _MAX_PATH /* From MS stdlib.h */ +# define FOUND_MAXPATHNAME +#endif + +#if !defined(FOUND_MAXPATHNAME) +# define MAXPATHNAME 256 /* Is there a limit? */ +#endif + +#ifndef PATH_MAX +#define PATH_MAX MAXPATHNAME +#endif + + +/* + * Don't use defaults here to allow recognition of problems. + */ +#if !defined(FOUND_MAXFILENAME) && defined(MAXNAMELEN) +# define MAXFILENAME MAXNAMELEN /* From sys/param.h */ +# define FOUND_MAXFILENAME +#endif + +#if !defined(FOUND_MAXFILENAME) && defined(MAXNAMLEN) +# define MAXFILENAME MAXNAMLEN /* From dirent.h */ +# define FOUND_MAXFILENAME +#endif + +#ifdef __never__ +/* + * DIRSIZ(dp) is a parameterized macro, we cannot use it here. + */ +#if !defined(FOUND_MAXFILENAME) && defined(DIRSIZ) +# define MAXFILENAME DIRSIZ /* From sys/dir.h */ +# define FOUND_MAXFILENAME +#endif +#endif /* __never__ */ + +#if !defined(FOUND_MAXFILENAME) && defined(NAME_MAX) +# define MAXFILENAME NAME_MAX /* From limits.h */ +# define FOUND_MAXFILENAME +#endif + +#if !defined(FOUND_MAXFILENAME) && defined(FOUND_DIRSIZE) +# define MAXFILENAME DIRSIZE /* From schily/dirent.h */ +# define FOUND_MAXFILENAME +#endif + +#if !defined(FOUND_MAXPATHNAME) +#include +#endif +#if !defined(FOUND_MAXFILENAME) && defined(_MAX_FNAME) +# define MAXFILENAME _MAX_FNAME /* From MS stdlib.h */ +# define FOUND_MAXFILENAME +#endif + +#ifndef NAME_MAX +#define NAME_MAX MAXFILENAME +#endif +#ifndef MAXNAMLEN +#define MAXNAMLEN MAXFILENAME +#endif + +#endif /* _SCHILY_MAXPATH_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/mconfig.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/mconfig.h new file mode 100644 index 00000000000..90a9a5f6f47 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/mconfig.h @@ -0,0 +1,559 @@ +/* @(#)mconfig.h 1.71 15/08/14 Copyright 1995-2015 J. Schilling */ +/* + * definitions for machine configuration + * + * Copyright (c) 1995-2015 J. Schilling + * + * This file must be included before any other file. + * If this file is not included before stdio.h you will not be + * able to get LARGEFILE support + * + * Use only cpp instructions. + * + * NOTE: SING: (Schily Is Not Gnu) + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_MCONFIG_H +#define _SCHILY_MCONFIG_H + +/* + * Tell our users that this is a Schily SING compile environment. + */ +#define IS_SCHILY + +/* + * We need to do this before we include xconfig.h + */ +#ifdef NO_LARGEFILES +#undef USE_LARGEFILES +#endif +#ifdef NO_ACL +#undef USE_ACL +#endif + +/* + * Inside we get architecture specific Processor defines + * fetched from compiler predefinitions only. + */ +#include + +/* + * Inside we decide whether to use static or dynamic + * autoconf stuff. + */ +#include + +/* + * Make sure that neither HAVE_LARGEFILES nor USE_LARGEFILES is defined + * if the platform does not support large files. + */ +#ifndef HAVE_LARGEFILES +#undef USE_LARGEFILES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The NetBSD people want to bother us. + * They removed the definition for 'unix' and are bleating for every test + * for #if defined(unix). So we need to check for NetBSD early. + */ +#ifndef IS_UNIX +# if defined(__NetBSD__) +# define IS_UNIX +# endif +#endif + +#ifndef IS_UNIX +# if (defined(unix) || defined(__unix) || defined(__unix__)) && \ + !defined(__DJGPP__) +# define IS_UNIX +# endif +#endif + +#ifdef __MSDOS__ +# define IS_MSDOS +#endif + +#if defined(tos) || defined(__tos) +# define IS_TOS +#endif + +#ifdef THINK_C +# define IS_MAC +#endif + +#if defined(sun) || defined(__sun) || defined(__sun__) +# define IS_SUN +#endif + +#if defined(__CYGWIN32__) || defined(__CYGWIN__) +# define IS_GCC_WIN32 +# define IS_CYGWIN + +#if defined(unix) || defined(_X86) +# define IS_CYGWIN_1 +#endif +#endif + +/* ------------------------------------------------------------------------- */ +/* + * Some magic that cannot (yet) be figured out with autoconf. + */ + +#if defined(sun3) || defined(mc68000) || defined(mc68020) +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif +#ifdef sparc +# ifndef HAVE_LDSTUB +# define HAVE_LDSTUB +# endif +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif +#if defined(__i386_) || defined(i386) +# ifndef HAVE_XCHG +# define HAVE_XCHG +# endif +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif + +/* + * Use of SCANSTACK is disabled by default + */ +#ifndef USE_SCANSTACK +# undef HAVE_SCANSTACK +#else +/* + * But .... + * The tests are much better now, so always give it a chance. + */ +#ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +#endif +#endif + +/* + * Allow to overwrite the defines in the makefiles by calling + * + * make COPTX=-DFORCE_SCANSTACK + */ +#ifdef FORCE_SCANSTACK +# undef NO_SCANSTACK +#ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +#endif +#ifndef USE_SCANSTACK +# define USE_SCANSTACK +#endif +#endif + +/* + * This is the global switch to deactivate stack scanning + */ +#ifdef NO_SCANSTACK +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +/* + * This is the global switch to deactivate using #pragma weak + */ +#ifdef NO_PRAGMA_WEAK +# ifdef HAVE_PRAGMA_WEAK +# undef HAVE_PRAGMA_WEAK +# endif +#endif + +#ifdef NO_FORK +# ifdef HAVE_FORK +# undef HAVE_FORK +# endif +# ifdef HAVE_VFORK +# undef HAVE_VFORK +# endif +#endif +#ifdef NO_VFORK +# ifdef HAVE_VFORK +# undef HAVE_VFORK +# endif +#endif + +#if defined(SOL2) || defined(SOL2) || \ + defined(S5R4) || defined(__S5R4) || defined(SVR4) +# ifndef __SVR4 +# define __SVR4 +# endif +#endif + +#ifdef __SVR4 +# ifndef SVR4 +# define SVR4 +# endif +#endif + +/* + * SunOS 4.x / SunOS 5.x + */ +#if defined(IS_SUN) +# define HAVE_GETAV0 +#endif + +/* + * AIX + */ +#if defined(_IBMR2) || defined(_AIX) +# ifndef IS_UNIX +# define IS_UNIX /* ??? really ??? */ +# endif +#endif + +/* + * QNX + */ +#if defined(__QNX__) +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * Silicon Graphics (must be before SVR4) + */ +#if defined(sgi) || defined(__sgi) +# define __NOT_SVR4__ /* Not a real SVR4 implementation */ +#endif + +/* + * Data General + */ +#if defined(__DGUX__) +#ifdef XXXXXXX +# undef HAVE_MTGET_DSREG +# undef HAVE_MTGET_RESID +# undef HAVE_MTGET_FILENO +# undef HAVE_MTGET_BLKNO +#endif +# define mt_type mt_model +# define mt_dsreg mt_status1 +# define mt_erreg mt_status2 + /* + * DGUX hides its flock as dg_flock. + */ +# define HAVE_FLOCK +# define flock dg_flock + /* + * Use the BSD style wait on DGUX to get the resource usages of child + * processes. + */ +# define _BSD_WAIT_FLAVOR +#endif + +/* + * Apple Rhapsody (This is the name for Mac OS X beta) + */ +#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody +# define HAVE_OSDEF /* prevent later definitions to overwrite current */ +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * NextStep + */ +#if defined(__NeXT__) && !defined(HAVE_OSDEF) +#define NO_PRINT_OVR +#undef HAVE_USG_STDIO + /* + * NeXT Step 3.x uses + * __flsbuf(unsigned char, FILE *) + * instead of __flsbuf(int, FILE *) + */ +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * Mac OS X + */ +#if defined(__APPLE__) && defined(__MACH__) +# ifndef IS_UNIX +# define IS_UNIX +# endif +# define IS_MACOS_X +#endif + +/* + * NextStep 3.x has a broken linker that does not allow us to override + * these functions. + */ +#ifndef __OPRINTF__ + +#ifdef NO_PRINT_OVR +# define printf Xprintf +# define fprintf Xfprintf +# define sprintf Xsprintf +#endif + +#endif /* __OPRINTF__ */ + +/* ------------------------------------------------------------------------- */ + +#ifndef _SCHILY_PROTOTYP_H +#include +#endif + +/* + * We use HAVE_LONGLONG as generalized test on whether "long long", "__in64" or + * something similar exist. + * + * In case that HAVE_LONGLONG is defined here, this is an indication that + * "long long" works. We define HAVE_LONG_LONG to keep this knowledge. + */ +#ifdef HAVE_LONGLONG +# define HAVE_LONG_LONG +#endif + +/* + * Microsoft C defines _MSC_VER + * use __int64 instead of long long and use 0i64 for a signed long long const + * and 0ui64 for an unsigned long long const. + * + * #if defined(HAVE___INT64) + * use __int64 + * #elif defined(HAVE_LONGLONG) + * use long long + * #endif + * + * Be very careful here as older MSVC versions do not implement long long but + * rather __int64 and once someone makes 'long long' 128 bits on a 64 bit + * machine, we may need to check for a MSVC __int128 type. + */ +#ifndef HAVE_LONGLONG +# if defined(HAVE___INT64) +# define HAVE_LONGLONG +# endif +#endif + +/* + * gcc 2.x generally implements the "long long" type. + */ +#ifdef __GNUC__ +# if __GNUC__ > 1 +# ifndef HAVE_LONGLONG +# define HAVE_LONGLONG +# endif +# ifndef HAVE_LONG_LONG +# define HAVE_LONG_LONG +# endif +# endif +#endif + +#ifdef __CHAR_UNSIGNED__ /* GNU GCC define (dynamic) */ +#ifndef CHAR_IS_UNSIGNED +#define CHAR_IS_UNSIGNED /* Sing Schily define (static) */ +#endif +#endif + +/* + * Convert to GNU name + */ +#ifdef HAVE_STDC_HEADERS +# ifndef STDC_HEADERS +# define STDC_HEADERS +# endif +#endif +/* + * Convert to SCHILY name + */ +#ifdef STDC_HEADERS +# ifndef HAVE_STDC_HEADERS +# define HAVE_STDC_HEADERS +# endif +#endif + +#ifdef IS_UNIX +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +/* + * Win32 with Gygwin + */ +#ifdef IS_GCC_WIN32 +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +/* + * Win32 with Mingw32 + */ +#ifdef __MINGW32__ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +/* + * OS/2 EMX + */ +#ifdef __EMX__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +#ifdef __BEOS__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +/* + * DOS with DJGPP + */ +#ifdef __DJGPP__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER + +# define NEED_O_BINARY +#endif + +/* + * Vanilla DOS + */ +#if defined(IS_MSDOS) && !defined(__DJGPP__) +# define HAVE_PATH_DELIM +# define PATH_DELIM '\\' +# define PATH_DELIM_STR "\\" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER + +# define NEED_O_BINARY +#endif + +/* + * ATARI TOS + */ +#ifdef IS_TOS +# define HAVE_PATH_DELIM +# define PATH_DELIM '\\' +# define PATH_DELIM_STR "\\" +# define PATH_ENV_DELIM ',' +# define PATH_ENV_DELIM_STR "," +# define HAVE_DOS_DRIVELETTER +# define far +# define near +#endif + +/* + * Mac OS 9 + */ +#ifdef IS_MAC +# define HAVE_PATH_DELIM +# define PATH_DELIM ':' +# define PATH_DELIM_STR ":" +# define PATH_ENV_DELIM ';' /* ??? */ +# define PATH_ENV_DELIM_STR ";" /* ??? */ +# define far +# define near +#endif + +/* + * I hope this will make compilation on unknown OS easier. + */ +#ifndef HAVE_PATH_DELIM /* Default to POSIX rules */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +/* + * Is there a solution for /dev/tty and similar? + */ +#ifdef HAVE__DEV_NULL +# define DEV_NULL "/dev/null" +#else +#if defined(_MSC_VER) || defined(__MINGW32__) +# define DEV_NULL "NUL" +#else +/* + * What to do here? + */ +#endif +#endif + +#ifdef DBG_MALLOC +/* + * We need to include this here already in order to make sure that + * every program that is based on mconfig.h will include schily/dbgmalloc.h + * in case that we specify -DDBG_MALLOC + */ +#include +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_MCONFIG_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/nlsdefs.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/nlsdefs.h new file mode 100644 index 00000000000..42028814424 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/nlsdefs.h @@ -0,0 +1,103 @@ +/* @(#)nlsdefs.h 1.5 10/12/19 Copyright 2004-2010 J. Schilling */ +/* + * Native language support + * + * Copyright (c) 2004-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_NLSDEFS_H +#define _SCHILY_NLSDEFS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef NO_NLS +#ifndef USE_NLS +#define USE_NLS /* Make nls the default */ +#endif +#endif + +#ifdef HAVE_LIBINTL_H +#ifndef _INCL_LIBINTL_H +#include /* gettext() */ +#define _INCL_LIBINTL_H +#endif +#else +#undef USE_NLS +#endif + +#ifndef _SCHILY_LOCALE_H +#include /* LC_* definitions */ +#endif +#ifndef _INCL_LOCALE_H +#undef USE_NLS +#endif + +#ifdef HAVE_LANGINFO_H +#ifndef _INCL_LAGINFO_H +#include /* YESSTR amnd similar */ +#define _INCL_LANGINFO_H +#endif +#else +#undef USE_NLS +#endif + +#ifndef HAVE_GETTEXT +#undef USE_NLS +#endif + +#ifdef NO_NLS +#undef USE_NLS +#endif + +#ifdef NO_TEXT_DOMAIN +#undef TEXT_DOMAIN +#endif + +#ifndef USE_NLS +#undef gettext +#define gettext(s) s +#undef dgettext +#define dgettext(d, s) s +#undef dcgettext +#define dcgettext(d, s, c) s + +#undef textdomain +#define textdomain(a) ((char *)0) +#undef bindtextdomain +#define bindtextdomain(d, dir) ((char *)0) +#undef bind_textdomain_codeset +#define bind_textdomain_codeset(d, c) ((char *)0) +#endif + +#ifdef lint +/* + * Allow lint to check printf() format strings. + */ +#define _(s) s +#else /* lint */ + +#ifdef USE_DGETTEXT /* e.g. in a library */ +#define _(s) dgettext(TEXT_DOMAIN, s) +#else +#define _(s) gettext(s) +#endif +#endif /* lint */ +/* + * Allow to mark strings for xgettext(1) + */ +#define __(s) s + +#endif /* _SCHILY_NLSDEFS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/param.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/param.h new file mode 100644 index 00000000000..4010e639675 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/param.h @@ -0,0 +1,76 @@ +/* @(#)param.h 1.7 12/01/22 Copyright 2006-2011 J. Schilling */ +/* + * Abstraction from sys/param.h + * + * Copyright (c) 2006-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_PARAM_H +#define _SCHILY_PARAM_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * Let us include system defined types first. + */ +#ifndef _SCHILY_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#ifndef _INCL_SYS_PARAM_H +#include /* Must be before limits.h */ +#define _INCL_SYS_PARAM_H +#endif +#endif +#ifndef _SCHILY_LIMITS_H +#include /* For _SC_CLK_TCK */ +#endif +#ifndef _SCHILY_UNISTD_H +#include /* For _SC_CLK_TCK */ +#endif + +#ifndef NBBY +#define NBBY 8 /* Number of bits per byte */ +#endif + +#ifndef DEV_BSIZE +#define DEV_BSIZE 512 /* UNIX Device Block size */ +#endif + +/* + * NODEV may be in sys/param.h keep this definition past the include. + */ +#ifndef NODEV +#define NODEV ((dev_t)-1L) +#endif + +#ifndef HZ +#if defined(_SC_CLK_TCK) +#define HZ ((clock_t)sysconf(_SC_CLK_TCK)) +#else +#define HZ 100 +#endif +#endif + +/* + * Do we need to define _XOPEN_SOURCE to get NZERO? + * On Linux, it is needed but on Linux NZERO is 20. + */ +#ifndef NZERO /* for nice(2) */ +#define NZERO 20 +#endif + +#endif /* _SCHILY_PARAM_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/patmatch.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/patmatch.h new file mode 100644 index 00000000000..320f695d59e --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/patmatch.h @@ -0,0 +1,130 @@ +/* @(#)patmatch.h 1.15 10/08/27 Copyright 1985,1993-2010 J. Schilling */ + +#ifndef _SCHILY_PATMATCH_H +#define _SCHILY_PATMATCH_H +/* + * Definitions for the pattern matching functions. + * + * Copyright (c) 1985,1993-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ +/* + * The pattern matching functions are based on the algorithm + * presented by Martin Richards in: + * + * "A Compact Function for Regular Expression Pattern Matching", + * Software-Practice and Experience, Vol. 9, 527-534 (1979) + * + * Several changes have been made to the original source which has been + * written in BCPL: + * + * '/' is replaced by '!' (to allow UNIX filenames) + * '(',')' are replaced by '{', '}' + * '\'' is replaced by '\\' (UNIX compatible quote) + * + * Character classes have been added to allow "[]" + * to be used. + * Start of line '^' and end of line '$' have been added. + * + * Any number in the following comment is zero or more occurrencies + */ +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALT '!' /* Alternation in match i.e. this!that!the_other */ +#define REP '#' /* Any number of occurrences of the following expr */ +#define NIL '%' /* Empty string (exactly nothing) */ +#define STAR '*' /* Any number of any character (equivalent of #?) */ +#define ANY '?' /* Any one character */ +#define QUOTE '\\' /* Quotes the next character */ +#define LBRACK '{' /* Begin of precedence grouping */ +#define RBRACK '}' /* End of precedence grouping */ +#define LCLASS '[' /* Begin of character set */ +#define RCLASS ']' /* End of character set */ +#define NOT '^' /* If first in set: invert set content */ +#define RANGE '-' /* Range notation in sets */ +#define START '^' /* Begin of a line */ +#define END '$' /* End of a line */ + +/* + * A list of case statements that may be used for a issimple() or ispattern() + * funtion that checks whether a string conrtains characters that need the + * pattern matcher. + * + * Note that this list does not contain NOT or RANGE because you need + * LCLASS and RCLASS in addition. + */ +#define casePAT case ALT: case REP: case NIL: case STAR: case ANY: \ + case QUOTE: case LBRACK: case RBRACK: \ + case LCLASS: case RCLASS: case START: case END: + + +#define MAXPAT 128 /* Max length of pattern for opatmatch()/opatlmatch() */ + +extern int patcompile __PR((const unsigned char *__pat, int __patlen, + int *__aux)); + +extern unsigned char *opatmatch __PR((const unsigned char *__pat, + const int *__aux, + const unsigned char *__str, + int __soff, int __slen, + int __alt)); +extern unsigned char *opatlmatch __PR((const unsigned char *__pat, + const int *__aux, + const unsigned char *__str, + int __soff, int __slen, + int __alt)); +extern unsigned char *patmatch __PR((const unsigned char *__pat, + const int *__aux, + const unsigned char *__str, + int __soff, int __slen, + int __alt, int __state[])); +extern unsigned char *patlmatch __PR((const unsigned char *__pat, + const int *__aux, + const unsigned char *__str, + int __soff, int __slen, + int __alt, int __state[])); + +#ifdef __cplusplus +} +#endif + +#ifdef _SCHILY_WCHAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int patwcompile __PR((const wchar_t *__pat, int __patlen, + int *__aux)); +extern wchar_t *patwmatch __PR((const wchar_t *__pat, const int *__aux, + const wchar_t *__str, + int __soff, int __slen, + int __alt, int __state[])); +extern wchar_t *patwlmatch __PR((const wchar_t *__pat, const int *__aux, + const wchar_t *__str, + int __soff, int __slen, + int __alt, int __state[])); + + +#ifdef __cplusplus +} +#endif +#endif /* _SCHILY_WCHAR_H */ + +#endif /* _SCHILY_PATMATCH_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/prototyp.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/prototyp.h new file mode 100644 index 00000000000..77655cadd9c --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/prototyp.h @@ -0,0 +1,132 @@ +/* @(#)prototyp.h 1.17 15/12/26 Copyright 1995-2015 J. Schilling */ +/* + * Definitions for dealing with ANSI / KR C-Compilers + * + * Copyright (c) 1995-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +/* + * includes + * To be correct, we need to include before we test + * for _SCHILY_PROTOTYP_H + * + * In order to keep the silly Solaris hdrchk(1) quiet, we are forced to + * have the _SCHILY_PROTOTYP_H first in . + * To keep hdrchk(1) quiet and be correct, we need to introduce a second + * guard _SCHILY_PROTOTYP_X_H. + */ +#ifndef _SCHILY_PROTOTYP_H +#define _SCHILY_PROTOTYP_H + +#ifndef _SCHILY_MCONFIG_H +#undef _SCHILY_PROTOTYP_H +#include +#endif + +#ifndef _SCHILY_PROTOTYP_X_H +#define _SCHILY_PROTOTYP_X_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PROTOTYPES + /* + * If this has already been defined, + * someone else knows better than us... + */ +# ifdef __STDC__ +# if __STDC__ /* ANSI C */ +# define PROTOTYPES +# endif +# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ +# define PROTOTYPES +# endif +# endif +#endif /* PROTOTYPES */ + +#if !defined(PROTOTYPES) && (defined(__cplusplus) || defined(_MSC_VER)) + /* + * C++ always supports prototypes. + * Define PROTOTYPES so we are not forced to make + * a separtate autoconf run for C++ + * + * Microsoft C has prototypes but does not define __STDC__ + */ +# define PROTOTYPES +#endif + +/* + * If we have prototypes, we should have stdlib.h string.h stdarg.h + */ +#ifdef PROTOTYPES +#if !(defined(SABER) && defined(sun)) +# ifndef HAVE_STDARG_H +# define HAVE_STDARG_H +# endif +#endif +#ifndef JOS +# ifndef HAVE_STDLIB_H +# define HAVE_STDLIB_H +# endif +# ifndef HAVE_STRING_H +# define HAVE_STRING_H +# endif +# ifndef HAVE_STDC_HEADERS +# define HAVE_STDC_HEADERS +# endif +# ifndef STDC_HEADERS +# define STDC_HEADERS /* GNU name */ +# endif +#endif +#endif + +#ifdef NO_PROTOTYPES /* Force not to use prototypes */ +# undef PROTOTYPES +#endif + +#ifdef PROTOTYPES +# define __PR(a) a +#else +# define __PR(a) () +#endif + +#if !defined(PROTOTYPES) && !defined(NO_CONST_DEFINE) +# ifndef const +# define const +# endif +# ifndef signed +# define signed +# endif +# ifndef volatile +# define volatile +# endif +#endif + +#ifdef PROTOTYPES +#define ALERT '\a' +#else +#define ALERT '\07' +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_PROTOTYP_X_H */ +#endif /* _SCHILY_PROTOTYP_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/schily.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/schily.h new file mode 100644 index 00000000000..4aca72d3b3b --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/schily.h @@ -0,0 +1,658 @@ +/* @(#)schily.h 1.120 16/09/28 Copyright 1985-2016 J. Schilling */ +/* + * Definitions for libschily + * + * This file should be included past: + * + * schily/mconfig.h / config.h + * schily/standard.h + * stdio.h + * stdlib.h (better use schily/stdlib.h) + * unistd.h (better use schily/unistd.h) needed f. LARGEFILE support + * schily/string.h + * sys/types.h + * + * If you need stdio.h, you must include it before schily/schily.h + * + * NOTE: If you need ctype.h and did not include stdio.h you need to + * include ctype.h past schily/schily.h as OpenBSD does not follow POSIX + * and defines EOF in ctype.h + * + * Copyright (c) 1985-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_SCHILY_H +#define _SCHILY_SCHILY_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_STANDARD_H +#include +#endif +#ifndef _SCHILY_CCOMDEFS_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_INCL_SYS_TYPES_H) || defined(_INCL_TYPES_H) || defined(off_t) +# ifndef FOUND_OFF_T +# define FOUND_OFF_T +# endif +#endif +#if defined(_INCL_SYS_TYPES_H) || defined(_INCL_TYPES_H) || defined(size_t) +# ifndef FOUND_SIZE_T +# define FOUND_SIZE_T +# endif +#endif +#if defined(_MSC_VER) && !defined(_SIZE_T_DEFINED) +# undef FOUND_SIZE_T +#endif + +#ifdef __never_def__ +/* + * It turns out that we cannot use the folloginw definition because there are + * some platforms that do not behave application friendly. These are mainly + * BSD-4.4 based systems (which #undef a definition when size_t is available. + * We actually removed this code because of a problem with QNX Neutrino. + * For this reason, it is important not to include directly but + * via the Schily SING include files so we know whether it has been included + * before we come here. + */ +#if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ + defined(__SIZE_T) || defined(_SIZE_T_) || \ + defined(_GCC_SIZE_T) || defined(_SIZET_) || \ + defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) + +#ifndef FOUND_SIZE_T +# define FOUND_SIZE_T /* We already included a size_t definition */ +#endif +#endif +#endif /* __never_def__ */ + +#if defined(HAVE_LARGEFILES) +# define _fcons _fcons64 +# define fdup fdup64 +# define fileluopen fileluopen64 +# define fileopen fileopen64 +# define filemopen filemopen64 +# define filepos filepos64 +# define filereopen filereopen64 +# define fileseek fileseek64 +# define filesize filesize64 +# define filestat filestat64 +# define _openfd _openfd64 +#endif + +/* + * The official POSIX rule is not to define "new" interfaces that + * are in conflict with older interfaces of the same name. + * Our interfaces fexec*() have been defined and published in 1982. + * The new POSIX interfaces define a different interface and the + * new POSIX interfaces even use names that are not compatible with + * POSIX rules. The new POSIX interfaces in question should be called + * fdexec*() to follow the rules of other similar POSIX functions. + * Simiar problems exist with getline()/fgetline(). + */ +#if defined(HAVE_RAW_FEXECL) || defined(HAVE_RAW_FEXECLE) || \ + defined(HAVE_RAW_FEXECV) || defined(HAVE_RAW_FEXECVE) +#define RENAME_FEXEC +#endif +#if defined(HAVE_RAW_FSPAWNV) || defined(HAVE_RAW_FSPAWNL) || \ + defined(HAVE_RAW_FSPAWNV_NOWAIT) +#define RENAME_FSPAWN +#endif +#if defined(HAVE_RAW_GETLINE) || defined(HAVE_RAW_FGETLINE) +#define RENAME_GETLINE +#endif + +#ifdef __needed__ +#define RENAME_FEXEC +#define RENAME_FSPAWN +#define RENAME_GETLINE +#endif + +#if defined(RENAME_FEXEC) || defined(RENAME_FSPAWN) +#ifndef _SCHILY_UNISTD_H +#include /* Need to incl. before fexec*() protoypes */ +#endif +#endif + +#if defined(RENAME_GETLINE) +#ifndef _SCHILY_STDIO_H +#include /* Need to incl. before *getline() protoypes */ +#endif + +#endif + +#ifdef EOF /* stdio.h has been included */ + +extern int _cvmod __PR((const char *, int *, int *)); +extern FILE *_fcons __PR((FILE *, int, int)); +extern FILE *fdup __PR((FILE *)); +#if !defined(fdown) || defined(PROTOTYPES) +/* + * We cannot declare fdown() with K&R in case that fdown() has been #define'd + */ +extern int fdown __PR((FILE *)); +#endif +extern int js_fexecl __PR((const char *, FILE *, FILE *, FILE *, + const char *, ...)); +extern int js_fexecle __PR((const char *, FILE *, FILE *, FILE *, + const char *, ...)); + /* 6th arg not const, fexecv forces av[ac] = NULL */ +extern int js_fexecv __PR((const char *, FILE *, FILE *, FILE *, int, + char **)); +extern int js_fexecve __PR((const char *, FILE *, FILE *, FILE *, + char * const *, char * const *)); +extern int js_fspawnv __PR((FILE *, FILE *, FILE *, int, char * const *)); +extern int js_fspawnl __PR((FILE *, FILE *, FILE *, const char *, ...)); +extern int js_fspawnv_nowait __PR((FILE *, FILE *, FILE *, + const char *, int, char *const*)); +extern int js_fgetline __PR((FILE *, char *, int)); +#ifdef FOUND_SIZE_T +extern ssize_t fgetaline __PR((FILE *, char **, size_t *)); +extern ssize_t getaline __PR((char **, size_t *)); +#endif +extern int fgetstr __PR((FILE *, char *, int)); +extern int file_getraise __PR((FILE *)); +extern void file_raise __PR((FILE *, int)); +extern int fileclose __PR((FILE *)); +extern FILE *fileluopen __PR((int, const char *)); +extern FILE *fileopen __PR((const char *, const char *)); +#ifdef _SCHILY_TYPES_H +extern FILE *filemopen __PR((const char *, const char *, mode_t)); +#endif +#ifdef FOUND_OFF_T +extern off_t filepos __PR((FILE *)); +#endif +#ifdef FOUND_SIZE_T +extern ssize_t fileread __PR((FILE *, void *, size_t)); +extern ssize_t ffileread __PR((FILE *, void *, size_t)); +#endif +extern FILE *filereopen __PR((const char *, const char *, FILE *)); +#ifdef FOUND_OFF_T +extern int fileseek __PR((FILE *, off_t)); +extern off_t filesize __PR((FILE *)); +#endif +#ifdef S_IFMT +extern int filestat __PR((FILE *, struct stat *)); +#endif +#ifdef FOUND_SIZE_T +extern ssize_t filewrite __PR((FILE *, void *, size_t)); +extern ssize_t ffilewrite __PR((FILE *, void *, size_t)); +#endif +extern int flush __PR((void)); +extern int fpipe __PR((FILE **)); +#ifdef __never__ +extern int fprintf __PR((FILE *, const char *, ...)) __printflike__(2, 3); +#endif +extern int getbroken __PR((FILE *, char *, char, char **, int)); +extern int ofindline __PR((FILE *, char, const char *, int, + char **, int)); +extern int peekc __PR((FILE *)); + +#ifdef __never_def__ +/* + * We cannot define this or we may get into problems with DOS based systems. + */ +extern int spawnv __PR((FILE *, FILE *, FILE *, int, char * const *)); +extern int spawnl __PR((FILE *, FILE *, FILE *, const char *, ...)); +extern int spawnv_nowait __PR((FILE *, FILE *, FILE *, + const char *, int, char *const*)); +#endif /* __never_def__ */ +#endif /* EOF */ + +/* + * Flags for absfpath() and resolvefpath(): + */ +#define RSPF_EXIST 0x01 /* All path components must exist */ +#define RSPF_NOFOLLOW_LAST 0x02 /* Don't follow link in last pathcomp */ + +#ifdef FOUND_SIZE_T +extern char *abspath __PR((const char *relp, char *absp, size_t asize)); +extern char *absnpath __PR((const char *relp, char *absp, size_t asize)); +extern char *absfpath __PR((const char *relp, char *absp, size_t asize, + int __flags)); +#ifndef HAVE_RESOLVEPATH +extern int resolvepath __PR((const char *__path, + char *__buf, size_t __bufsiz)); +#endif +extern int resolvenpath __PR((const char *__path, + char *__buf, size_t __bufsiz)); +extern int resolvefpath __PR((const char *__path, + char *__buf, size_t __bufsiz, int __flags)); +#endif + +#ifdef _SCHILY_TYPES_H +extern int mkdirs __PR((char *, mode_t)); +extern int makedirs __PR((char *, mode_t, int __striplast)); +#endif + +extern int lxchdir __PR((char *)); +#ifdef HAVE_FCHDIR +#define fdsetname(fd, name) (0) +#define fdclosename(fd) (0) +#else +extern int fdsetname __PR((int fd, const char *name)); +extern int fdclosename __PR((int fd)); +#endif +extern int diropen __PR((const char *)); +extern int dirrdopen __PR((const char *)); +extern int dirclose __PR((int)); + +struct save_wd { + int fd; + char *name; +}; + +extern int savewd __PR((struct save_wd *sp)); +extern void closewd __PR((struct save_wd *sp)); +extern int restorewd __PR((struct save_wd *sp)); + + +#ifdef _SCHILY_UTYPES_H +typedef struct gnmult { + char key; + Llong mult; +} gnmult_t; + +extern int getllnum __PR((char *arg, Llong *lvalp)); +extern int getxnum __PR((char *arg, long *valp, gnmult_t *mult)); +extern int getllxnum __PR((char *arg, Llong *lvalp, gnmult_t *mult)); + +extern int getlltnum __PR((char *arg, Llong *lvalp)); +extern int getxtnum __PR((char *arg, time_t *valp, gnmult_t *mult)); +extern int getllxtnum __PR((char *arg, Llong *lvalp, gnmult_t *mult)); +#endif +extern int getnum __PR((char *arg, long *valp)); +#ifdef _SCHILY_TIME_H +extern int gettnum __PR((char *arg, time_t *valp)); +#endif + +#ifdef _SCHILY_TIME_H + +extern int getnstimeofday __PR((struct timespec *__tp)); +extern int setnstimeofday __PR((struct timespec *__tp)); + +#ifdef _SCHILY_UTYPES_H +extern Llong mklgmtime __PR((struct tm *)); +#endif +extern time_t mkgmtime __PR((struct tm *)); +#endif + + +#ifdef EOF /* stdio.h has been included */ +#ifdef _SCHILY_TYPES_H +/* + * getperm() flags: + */ +#define GP_NOX 0 /* This is not a dir and 'X' is not valid */ +#define GP_DOX 1 /* 'X' perm character is valid */ +#define GP_XERR 2 /* 'X' perm characters are invalid */ +#define GP_FPERM 4 /* TRUE if we implement find -perm */ +#define GP_UMASK 8 /* TRUE if we implement umask */ + +extern int getperm __PR((FILE *f, char *perm, char *opname, \ + mode_t *modep, int smode, int flag)); +extern void permtostr __PR((mode_t mode, char *)); +#endif +#endif + +#ifdef FOUND_SIZE_T +extern ssize_t _niread __PR((int, void *, size_t)); +extern ssize_t _niwrite __PR((int, void *, size_t)); +extern ssize_t _nixread __PR((int, void *, size_t)); +extern ssize_t _nixwrite __PR((int, void *, size_t)); +#endif +extern int _openfd __PR((const char *, int)); +extern int on_comerr __PR((void (*fun)(int, void *), void *arg)); +/*PRINTFLIKE1*/ +extern void comerr __PR((const char *, ...)) __printflike__(1, 2); +/*PRINTFLIKE2*/ +extern void xcomerr __PR((int, const char *, ...)) __printflike__(2, 3); +/*PRINTFLIKE2*/ +extern void comerrno __PR((int, const char *, ...)) __printflike__(2, 3); +/*PRINTFLIKE3*/ +extern void xcomerrno __PR((int, int, const char *, ...)) __printflike__(3, 4); +/*PRINTFLIKE1*/ +extern int errmsg __PR((const char *, ...)) __printflike__(1, 2); +/*PRINTFLIKE2*/ +extern int errmsgno __PR((int, const char *, ...)) __printflike__(2, 3); +#ifdef FOUND_SIZE_T +/*PRINTFLIKE3*/ +extern int serrmsg __PR((char *, size_t, const char *, ...)) + __printflike__(3, 4); +/*PRINTFLIKE4*/ +extern int serrmsgno __PR((int, char *, size_t, const char *, ...)) + __printflike__(4, 5); +#endif +extern void comexit __PR((int)); +extern char *errmsgstr __PR((int)); + +#ifdef EOF /* stdio.h has been included */ +/*PRINTFLIKE2*/ +extern void fcomerr __PR((FILE *, const char *, ...)) + __printflike__(2, 3); +/*PRINTFLIKE3*/ +extern void fxcomerr __PR((FILE *, int, const char *, ...)) + __printflike__(3, 4); +/*PRINTFLIKE3*/ +extern void fcomerrno __PR((FILE *, int, const char *, ...)) + __printflike__(3, 4); +/*PRINTFLIKE4*/ +extern void fxcomerrno __PR((FILE *, int, int, const char *, ...)) + __printflike__(4, 5); +/*PRINTFLIKE2*/ +extern int ferrmsg __PR((FILE *, const char *, ...)) + __printflike__(2, 3); +/*PRINTFLIKE3*/ +extern int ferrmsgno __PR((FILE *, int, const char *, ...)) + __printflike__(3, 4); +#ifdef _SCHILY_VARARGS_H +#define COMERR_RETURN 0 +#define COMERR_EXIT 1 +#define COMERR_EXCODE 2 +/*PRINTFLIKE5*/ +extern int _comerr __PR((FILE *, int, int, int, + const char *, va_list)); +#endif +#endif + +/*PRINTFLIKE1*/ +extern int error __PR((const char *, ...)) __printflike__(1, 2); +#ifdef FOUND_SIZE_T +extern char *fillbytes __PR((void *, ssize_t, char)); +extern char *zerobytes __PR((void *, ssize_t)); +extern char *findbytes __PR((const void *, ssize_t, char)); +#endif +extern char *findinpath __PR((char *__name, int __mode, + BOOL __plain_file, char *__path)); +extern int findline __PR((const char *, char, const char *, + int, char **, int)); +extern int js_getline __PR((char *, int)); +extern int getstr __PR((char *, int)); +extern int breakline __PR((char *, char, char **, int)); +extern int getallargs __PR((int *, char * const**, const char *, ...)); +extern int getargs __PR((int *, char * const**, const char *, ...)); +extern int getfiles __PR((int *, char * const**, const char *)); +extern char *astoi __PR((const char *, int *)); +extern char *astol __PR((const char *, long *)); +extern char *astolb __PR((const char *, long *, int base)); +#ifdef _SCHILY_UTYPES_H +extern char *astoll __PR((const char *, Llong *)); +extern char *astollb __PR((const char *, Llong *, int)); +extern char *astoull __PR((const char *, Ullong *)); +extern char *astoullb __PR((const char *, Ullong *, int)); +#endif + +extern int patcompile __PR((const unsigned char *, int, int *)); +extern unsigned char *patmatch __PR((const unsigned char *, const int *, + const unsigned char *, + int, int, int, int[])); +extern unsigned char *patlmatch __PR((const unsigned char *, const int *, + const unsigned char *, + int, int, int, int[])); + +#ifdef __never__ +extern int printf __PR((const char *, ...)) __printflike__(1, 2); +#endif +#ifdef FOUND_SIZE_T +extern char *movebytes __PR((const void *, void *, ssize_t)); +#endif + +extern void save_args __PR((int, char **)); +extern int saved_ac __PR((void)); +extern char **saved_av __PR((void)); +extern char *saved_av0 __PR((void)); +extern char *searchfileinpath __PR((char *__name, int __mode, + int __file_mode, char *__path)); +#define SIP_ANY_FILE 0x00 /* Search for any file type */ +#define SIP_PLAIN_FILE 0x01 /* Search for plain files - not dirs */ +#define SIP_NO_PATH 0x10 /* Do not do PATH search */ +#define SIP_ONLY_PATH 0x20 /* Do only PATH search */ +#define SIP_NO_STRIPBIN 0x40 /* Do not strip "/bin" from PATH elem. */ +#define SIP_TYPE_MASK 0x0F /* Mask file type related bits */ + +#ifndef seterrno +extern int seterrno __PR((int)); +#endif +extern void set_progname __PR((const char *)); +extern char *get_progname __PR((void)); +extern char *get_progpath __PR((void)); +extern char *getexecpath __PR((void)); + +extern void setfp __PR((void * const *)); +extern int wait_chld __PR((int)); /* for fspawnv_nowait() */ +extern int geterrno __PR((void)); +extern void raisecond __PR((const char *, long)); +#ifdef __never__ +/* + * sprintf() may be declared incorrectly somewhere else + * e.g. in old BSD include files + */ +extern int sprintf __PR((char *, const char *, ...)); +#endif +extern char *strcatl __PR((char *, ...)); +#ifdef FOUND_SIZE_T +extern size_t strlcatl __PR((char *, size_t, ...)); +#endif +extern int streql __PR((const char *, const char *)); +#ifdef _SCHILY_WCHAR_H +extern wchar_t *wcscatl __PR((wchar_t *, ...)); +#ifdef FOUND_SIZE_T +extern size_t wcslcatl __PR((wchar_t *, size_t, ...)); +#endif +extern int wcseql __PR((const wchar_t *, const wchar_t *)); +#endif +#ifdef va_arg +extern int format __PR((void (*)(char, long), long, const char *, + va_list)); +extern int fprformat __PR((long, const char *, va_list)); +#else +extern int format __PR((void (*)(char, long), long, const char *, void *)); +extern int fprformat __PR((long, const char *, void *)); +#endif + +extern int ftoes __PR((char *, double, int, int)); +extern int ftofs __PR((char *, double, int, int)); +#ifdef HAVE_LONGDOUBLE +extern int qftoes __PR((char *, long double, int, int)); +extern int qftofs __PR((char *, long double, int, int)); +#endif + +/*PRINTFLIKE1*/ +extern int js_error __PR((const char *, ...)) __printflike__(1, 2); +/*PRINTFLIKE2*/ +extern int js_dprintf __PR((int, const char *, ...)) + __printflike__(2, 3); +#ifdef EOF /* stdio.h has been included */ +/*PRINTFLIKE2*/ +extern int js_fprintf __PR((FILE *, const char *, ...)) + __printflike__(2, 3); +#endif /* EOF */ +/*PRINTFLIKE1*/ +extern int js_printf __PR((const char *, ...)) __printflike__(1, 2); +#ifdef FOUND_SIZE_T +/*PRINTFLIKE3*/ +extern int js_snprintf __PR((char *, size_t, const char *, ...)) + __printflike__(3, 4); +#endif +/*PRINTFLIKE2*/ +extern int js_sprintf __PR((char *, const char *, ...)) + __printflike__(2, 3); + +#ifdef FOUND_SIZE_T +extern void swabbytes __PR((void *, ssize_t)); +#endif +extern char **getmainfp __PR((void)); +extern char **getavp __PR((void)); +extern char *getav0 __PR((void)); +extern void **getfp __PR((void)); +extern int flush_reg_windows __PR((int)); +#ifdef FOUND_SIZE_T +extern ssize_t cmpbytes __PR((const void *, const void *, ssize_t)); +extern int cmpmbytes __PR((const void *, const void *, ssize_t)); +extern ssize_t cmpnullbytes __PR((const void *, ssize_t)); +#endif + +#ifdef nonono +#if defined(HAVE_LARGEFILES) +/* + * To allow this, we need to figure out how to do autoconfiguration for off64_t + */ +extern FILE *_fcons64 __PR((FILE *, int, int)); +extern FILE *fdup64 __PR((FILE *)); +extern FILE *fileluopen64 __PR((int, const char *)); +extern FILE *fileopen64 __PR((const char *, const char *)); +#ifdef FOUND_OFF_T +extern off64_t filepos64 __PR((FILE *)); +#endif +extern FILE *filereopen64 __PR((const char *, const char *, FILE *)); +#ifdef FOUND_OFF_T +extern int fileseek64 __PR((FILE *, off64_t)); +extern off64_t filesize64 __PR((FILE *)); +#endif +#ifdef S_IFMT +extern int filestat64 __PR((FILE *, struct stat *)); +#endif +extern int _openfd64 __PR((const char *, int)); +#endif +#endif + +#ifndef NO_SCHILY_PRINT /* Define to disable *printf() redirects */ +#ifdef SCHILY_PRINT +#ifdef __never__ +#undef error +#define error js_error +#endif +#undef dprintf +#define dprintf js_dprintf +#undef fprintf +#define fprintf js_fprintf +#undef printf +#define printf js_printf +#undef snprintf +#define snprintf js_snprintf +#undef sprintf +#define sprintf js_sprintf +#else +#ifndef HAVE_SNPRINTF +#undef snprintf +#define snprintf js_snprintf +#endif +#endif +#endif + +#ifndef NO_SCHILY_GETLINE /* Define to disable *getline() redirect */ +#undef getline +#define getline js_getline +#undef fgetline +#define fgetline js_fgetline +#endif + +#ifndef NO_SCHILY_FEXEC /* Define to disable fexec*() redirect */ +#undef fexecl +#define fexecl js_fexecl +#undef fexecle +#define fexecle js_fexecle +#undef fexecv +#define fexecv js_fexecv +#undef fexecve +#define fexecve js_fexecve +#endif + +#ifndef NO_SCHILY_FSPAWN /* Define to disable fspawn*() redirect */ +#undef fspawnv +#define fspawnv js_fspawnv +#undef fspawnv_nowait +#define fspawnv_nowait js_fspawnv_nowait +#undef fspawnl +#define fspawnl js_fspawnl +#endif + +extern int js_mexval __PR((int exval)); +#ifdef FOUND_SIZE_T +extern void *js_malloc __PR((size_t size, char *msg)); +extern void *js_realloc __PR((void *ptr, size_t size, char *msg)); +#endif +extern char *js_savestr __PR((const char *s)); + +#ifdef _SCHILY_JMPDEFS_H + +/* + * Special values for the "jmp" parameter. + * + * Control how the siglongjmp() should be handled: + */ +#define JM_EXIT ((sigjmps_t *)-1) /* Call comexit(errno) instead */ +#define JM_RETURN ((sigjmps_t *)0) /* Return instead */ + +extern int js_jmexval __PR((int exval)); +#ifdef FOUND_SIZE_T +extern void *js_jmalloc __PR((size_t size, char *msg, sigjmps_t *jmp)); +extern void *js_jrealloc __PR((void *ptr, size_t size, char *msg, + sigjmps_t *jmp)); +#endif +extern char *js_jsavestr __PR((const char *s, sigjmps_t *jmp)); + +extern int js_fjmexval __PR((int exval)); +#ifdef EOF /* stdio.h has been included */ +#ifdef FOUND_SIZE_T +extern void *js_fjmalloc __PR((FILE *f, size_t size, char *msg, + sigjmps_t *jmp)); +extern void *js_fjrealloc __PR((FILE *f, void *ptr, size_t size, + char *msg, sigjmps_t *jmp)); +#endif +extern char *js_fjsavestr __PR((FILE *f, const char *s, sigjmps_t *jmp)); +#endif /* EOF */ +#endif /* _SCHILY_JMPDEFS_H */ + +#define ___mexval js_mexval +#define ___malloc js_malloc +#define ___realloc js_realloc +#define ___savestr js_savestr +#define __jmexval js_jmexval +#define __jmalloc js_jmalloc +#define __jrealloc js_jrealloc +#define __jsavestr js_jsavestr +#define __fjmalloc js_fjmalloc +#define __fjmexval js_fjmexval +#define __fjrealloc js_fjrealloc +#define __fjsavestr js_fjsavestr + +#ifdef __cplusplus +} +#endif + +#if defined(_JOS) || defined(JOS) +# ifndef _SCHILY_JOS_IO_H +# include +# endif +#endif + +#if !defined(_SCHILY_LIBPORT_H) && !defined(NO_LIBPORT_H) +#include +#endif +#if !defined(_SCHILY_HOSTNAME_H) && defined(USE_HOSTNAME_H) +#include +#endif + +#endif /* _SCHILY_SCHILY_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/siconv.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/siconv.h new file mode 100644 index 00000000000..370cf3b8a89 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/siconv.h @@ -0,0 +1,63 @@ +/* @(#)siconv.h 1.5 10/12/20 Copyright 2007-2010 J. Schilling */ +/* + * Definitions fur users of libsiconv + * + * Copyright (c) 2007-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_SICONV_H +#define _SCHILY_SICONV_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif +#ifndef _SCHILY_UTYPES_H +#include +#endif +#ifndef _SCHILY_ICONV_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct siconv_table siconvt_t; +struct siconv_table { + char *sic_name; /* SICONV charset name */ + UInt16_t *sic_cs2uni; /* Charset -> Unicode */ + UInt8_t **sic_uni2cs; /* Unicode -> Charset */ + iconv_t sic_cd2uni; /* iconv Charset -> Unicode */ + iconv_t sic_uni2cd; /* iconv Unicode -> Charset */ + siconvt_t *sic_alt; /* alternate iconv tab */ + siconvt_t *sic_next; /* Next table */ + int sic_refcnt; /* Reference count */ +}; + +#define use_iconv(t) ((t)->sic_cd2uni != NULL) + +#define sic_c2uni(t, c) ((t)->sic_cs2uni[c]) +#define sic_uni2c(t, c) ((t)->sic_uni2cs[((c) >> 8) & 0xFF][(c) & 0xFF]) + +extern int sic_list __PR((FILE *)); +extern siconvt_t *sic_open __PR((char *)); +extern const char *sic_base __PR((void)); +extern int sic_close __PR((siconvt_t *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_SICONV_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/sigblk.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/sigblk.h new file mode 100644 index 00000000000..418abd7223c --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/sigblk.h @@ -0,0 +1,62 @@ +/* @(#)sigblk.h 1.12 08/12/24 Copyright 1985, 1995-2008 J. Schilling */ +/* + * software signal block definition + * + * Copyright (c) 1985, 1995-2008 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_SIGBLK_H +#define _SCHILY_SIGBLK_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sigblk { + long **sb_savfp; /* Real saved framepointer */ + struct sigblk *sb_signext; /* Next sw signal blk for this func */ + short sb_siglen; /* Strlen for sb_signame */ + const char *sb_signame; /* Name of software signal */ + + /* sb_sigfun: function to call */ + int (*sb_sigfun) __PR((const char *, long, long)); + + long sb_sigarg; /* Second arg for sb_sigfun */ +} SIGBLK; + +/* + * The handler function is called with three arguments: + * + * 1) The name of the software signal + * 2) The argument from the handlecond() call + * 3) The argument from the raisecond() call + */ +typedef int (*handlefunc_t) __PR((const char *, long, long)); + +extern void handlecond __PR((const char *, SIGBLK *, + int(*)(const char *, long, long), + long)); +extern void raisecond __PR((const char *, long)); +extern void starthandlecond __PR((SIGBLK *)); +extern void unhandlecond __PR((SIGBLK *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_SIGBLK_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/standard.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/standard.h new file mode 100644 index 00000000000..e8101843613 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/standard.h @@ -0,0 +1,159 @@ +/* @(#)standard.h 1.40 13/05/01 Copyright 1985-2013 J. Schilling */ +/* + * standard definitions + * + * This file should be included past: + * + * mconfig.h / config.h + * stdio.h + * stdlib.h (better use schily/stdlib.h) + * unistd.h (better use schily/unistd.h) needed f. LARGEFILE support + * + * If you need stdio.h, you must include it before standard.h + * + * Copyright (c) 1985-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STANDARD_H +#define _SCHILY_STANDARD_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef M68000 +# ifndef tos +# define JOS 1 +# endif +#endif + +/* + * fundamental constants + */ +#ifndef NULL +# define NULL 0 +#endif +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +/* + * Program exit codes used with comerr(), comexit() and similar. + * + * Exit codes between -2 and -63 are currently available to flag + * program specific error conditions. + */ +#define EX_BAD (-1) /* Default error exit code */ +#define EX_CLASH (-64) /* Exit code used with exit clashes */ + +/* + * standard storage class definitions + */ +#define GLOBAL extern +#define IMPORT extern +#define EXPORT +#define INTERN static +#define LOCAL static +#define FAST register + +#ifndef PROTOTYPES +# ifndef const +# define const +# endif +# ifndef signed +# define signed +# endif +# ifndef volatile +# define volatile +# endif +#endif /* PROTOTYPES */ + +/* + * standard type definitions + * + * The hidden Schily BOOL definition is used in case we need to deal + * with other BOOL defines on systems we like to port to. + */ +typedef int __SBOOL; +typedef int BOOL; +#ifdef JOS +# ifndef __GNUC__ +# define NO_VOID +# endif +#endif +#ifdef NO_VOID +# ifndef lint + typedef int void; +# endif +#endif + +#if defined(_INCL_SYS_TYPES_H) || defined(_INCL_TYPES_H) || defined(off_t) +# ifndef FOUND_OFF_T +# define FOUND_OFF_T +# endif +#endif +#if defined(_INCL_SYS_TYPES_H) || defined(_INCL_TYPES_H) || defined(size_t) +# ifndef FOUND_SIZE_T +# define FOUND_SIZE_T +# endif +#endif +#if defined(_MSC_VER) && !defined(_SIZE_T_DEFINED) +# undef FOUND_SIZE_T +#endif + +#ifdef __never_def__ +/* + * It turns out that we cannot use the folloginw definition because there are + * some platforms that do not behave application friendly. These are mainly + * BSD-4.4 based systems (which #undef a definition when size_t is available. + * We actually removed this code because of a problem with QNX Neutrino. + * For this reason, it is important not to include directly but + * via the Schily SING include files so we know whether it has been included + * before we come here. + */ +#if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ + defined(__SIZE_T) || defined(_SIZE_T_) || \ + defined(_GCC_SIZE_T) || defined(_SIZET_) || \ + defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) + +#ifndef FOUND_SIZE_T +# define FOUND_SIZE_T /* We already included a size_t definition */ +#endif +#endif +#endif /* __never_def__ */ + +#ifdef __cplusplus +} +#endif + +#if defined(_JOS) || defined(JOS) +# ifndef _SCHILY_SCHILY_H +# include +# endif + +# ifndef _SCHILY_JOS_DEFS_H +# include +# endif + +# ifndef _SCHILY_JOS_IO_H +# include +# endif +#endif + +#endif /* _SCHILY_STANDARD_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/stat.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stat.h new file mode 100644 index 00000000000..52dcfe6338f --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stat.h @@ -0,0 +1,402 @@ +/* @(#)stat.h 1.20 15/08/23 Copyright 1998-2015 J. Schilling */ +/* + * Definitions for stat() file mode + * + * Copyright (c) 1998-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STAT_H +#define _SCHILY_STAT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_TYPES_H +#include /* Needed for sys/stat.h */ +#endif +#ifndef _INCL_SYS_STAT_H +#include /* For S_IS* and S_IF* */ +#define _INCL_SYS_STAT_H +#endif + +#if !defined(HAVE_LSTAT) || !defined(S_IFLNK) +#define lstat stat +#endif + +/* + * Apollo Domain/OS has a broken sys/stat.h that defines + * S_IFIFO == S_IFSOCK and creates trouble if the constants + * are used as case labels. + */ +#if S_IFIFO == S_IFSOCK +# undef S_IFSOCK +#endif + +#ifdef STAT_MACROS_BROKEN +#undef S_ISFIFO /* Named pipe */ +#undef S_ISCHR /* Character special */ +#undef S_ISMPC /* UNUSED multiplexed c */ +#undef S_ISDIR /* Directory */ +#undef S_ISNAM /* Named file (XENIX) */ +#undef S_ISBLK /* Block special */ +#undef S_ISMPB /* UNUSED multiplexed b */ +#undef S_ISREG /* Regular file */ +#undef S_ISCTG /* Contiguous file */ +#undef S_ISLNK /* Symbolic link */ +#undef S_ISSHAD /* Solaris shadow inode */ +#undef S_ISSOCK /* UNIX domain socket */ +#undef S_ISDOOR /* Solaris DOOR */ +#undef S_ISPORT /* Solaris event port */ +#undef S_ISWHT /* BSD whiteout */ +#undef S_ISEVC /* UNOS eventcount */ +#endif + +#ifndef S_ISFIFO /* 1 Named pipe */ +# ifdef S_IFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(m) (0) +# endif +#endif +#ifndef S_ISCHR /* 2 Character special */ +# ifdef S_IFCHR +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# else +# define S_ISCHR(m) (0) +# endif +#endif +#ifndef S_ISMPC /* 3 UNUSED multiplexed char */ +# ifdef S_IFMPC +# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) +# else +# define S_ISMPC(m) (0) +# endif +#endif +#ifndef S_ISDIR /* 4 Directory */ +# ifdef S_IFDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# else +# define S_ISDIR(m) (0) +# endif +#endif +#ifndef S_ISNAM /* 5 Named file (XENIX) */ +# ifdef S_IFNAM +# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) +# else +# define S_ISNAM(m) (0) +# endif +#endif +#ifndef S_ISBLK /* 6 Block special */ +# ifdef S_IFBLK +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(m) (0) +# endif +#endif +#ifndef S_ISMPB /* 7 UNUSED multiplexed block */ +# ifdef S_IFMPB +# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) +# else +# define S_ISMPB(m) (0) +# endif +#endif +#ifndef S_ISREG /* 8 Regular file */ +# ifdef S_IFREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +# else +# define S_ISREG(m) (0) +# endif +#endif +#ifndef S_ISCTG /* 9 Contiguous file */ +# ifdef S_IFCTG +# define S_ISCTG(m) (((m) & S_IFMT) == S_IFCTG) +# else +# define S_ISCTG(m) (0) +# endif +#endif +#ifndef S_ISLNK /* 10 Symbolic link */ +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# else +# define S_ISLNK(m) (0) +# endif +#endif +#ifndef S_ISSHAD /* 11 Solaris shadow inode */ +# ifdef S_IFSHAD +# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) +# else +# define S_ISSHAD(m) (0) +# endif +#endif +#ifndef S_ISSOCK /* 12 UNIX domain socket */ +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# else +# define S_ISSOCK(m) (0) +# endif +#endif +#ifndef S_ISDOOR /* 13 Solaris DOOR */ +# ifdef S_IFDOOR +# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) +# else +# define S_ISDOOR(m) (0) +# endif +#endif +#ifndef S_ISPORT /* 14 Solaris event port */ +# ifdef S_IFPORT +# define S_ISPORT(m) (((m) & S_IFMT) == S_IFPORT) +# else +# define S_ISPORT(m) (0) +# endif +#endif +#ifndef S_ISWHT /* 14 BSD whiteout */ +# ifdef S_IFWHT +# define S_ISWHT(m) (((m) & S_IFMT) == S_ISWHT) +# else +# define S_ISWHT(m) (0) +# endif +#endif +#ifndef S_IFEVC /* 15 UNOS eventcount */ +# ifdef S_IFEVC +# define S_ISEVC(m) (((m) & S_IFMT) == S_IFEVC) +# else +# define S_ISEVC(m) (0) +# endif +#endif + +#ifndef S_TYPEISMQ +/* + * XXX ??? where is a definition of a message queue ??? + */ +# define S_TYPEISMQ(_stbuf) (0) +#endif +#ifndef S_TYPEISSEM +# ifdef S_INSEM +# define S_TYPEISSEM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && \ + (_stbuf)->st_rdev == S_INSEM) +# else +# define S_TYPEISSEM(_stbuf) (0) +# endif +#endif +#ifndef S_TYPEISSHM +# ifdef S_INSHD +# define S_TYPEISSHM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && \ + (_stbuf)->st_rdev == S_INSHD) +# else +# define S_TYPEISSHM(_stbuf) (0) +# endif +#endif + +/* + * Mode permission bits. + * UNIX V.7 has only S_ISUID/S_ISGID/S_ISVTX and S_IREAD/S_IWRITE/S_IEXEC + * + * S_ISUID/S_ISGID/S_ISVTX is available on UNIX V.7 and POSIX + */ +#ifndef S_ISUID /* Set-user-ID on execution */ +#define S_ISUID 0 /* If it is not defined, it is not supported */ +#endif +#ifndef S_ISGID /* Set-group-ID on execution */ +#define S_ISGID 0 /* If it is not defined, it is not supported */ +#endif +#ifndef S_ISVTX /* On directories, restricted deletion flag */ +#define S_ISVTX 0 /* If it is not defined, it is not supported */ +#endif + +/* + * S_IREAD/S_IWRITE/S_IEXEC is only available on UNIX V.7 but not on POSIX + * Emulate these definitions to support compilation of programs like + * SCCS and the Bourne Shell and to make the other definitions simpler. + */ +#ifndef S_IREAD +#ifdef S_IRUSR +#define S_IREAD S_IRUSR /* Use POSIX name */ +#else +#define S_IREAD 0400 /* Very old UNIX, use own definition */ +#endif +#endif +#ifndef S_IWRITE +#ifdef S_IWUSR +#define S_IWRITE S_IWUSR /* Use POSIX name */ +#else +#define S_IWRITE 0200 /* Very old UNIX, use own definition */ +#endif +#endif +#ifndef S_IEXEC +#ifdef S_IXUSR +#define S_IEXEC S_IXUSR /* Use POSIX name */ +#else +#define S_IEXEC 0100 /* Very old UNIX, use own definition */ +#endif +#endif + +#ifndef S_IRUSR /* Read permission, owner */ +#define S_IRUSR S_IREAD /* Needed on old UNIX systems */ +#endif +#ifndef S_IWUSR /* Write permission, owner */ +#define S_IWUSR S_IWRITE /* Needed on old UNIX systems */ +#endif +#ifndef S_IXUSR /* Execute/search permission, owner */ +#define S_IXUSR S_IEXEC /* Needed on old UNIX systems */ +#endif +#ifndef S_IRGRP /* Read permission, group */ +#define S_IRGRP (S_IREAD >> 3) /* Needed on old UNIX systems */ +#endif +#ifndef S_IWGRP /* Write permission, group */ +#define S_IWGRP (S_IWRITE >> 3) /* Needed on old UNIX systems */ +#endif +#ifndef S_IXGRP /* Execute/search permission, group */ +#define S_IXGRP (S_IEXEC >> 3) /* Needed on old UNIX systems */ +#endif +#ifndef S_IROTH /* Read permission, others */ +#define S_IROTH (S_IREAD >> 6) /* Needed on old UNIX systems */ +#endif +#ifndef S_IWOTH /* Write permission, others */ +#define S_IWOTH (S_IWRITE >> 6) /* Needed on old UNIX systems */ +#endif +#ifndef S_IXOTH /* Execute/search permission, others */ +#define S_IXOTH (S_IEXEC >> 6) /* Needed on old UNIX systems */ +#endif + +#ifndef S_IRWXU /* Read, write, execute/search by owner */ +#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR) +#endif +#ifndef S_IRWXG /* Read, write, execute/search by group */ +#define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP) +#endif +#ifndef S_IRWXO /* Read, write, execute/search by others */ +#define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH) +#endif + +/* + * SCO UnixWare has st_atim.st__tim.tv_nsec but the st_atim.tv_nsec tests also + * succeeds. If we use st_atim.tv_nsec on UnixWare, we get a warning about + * illegal structure usage. For this reason, our code needs to have + * #ifdef HAVE_ST__TIM before #ifdef HAVE_ST_NSEC. + */ +#if defined(HAVE_ST_ATIMENSEC) + +/* + * Found e.g. on NetBSD and OpenBSD. + */ +#define stat_ansecs(s) ((s)->st_atimensec) +#define stat_mnsecs(s) ((s)->st_mtimensec) +#define stat_cnsecs(s) ((s)->st_ctimensec) + +#define stat_set_ansecs(s, n) ((s)->st_atimensec = n) +#define stat_set_mnsecs(s, n) ((s)->st_mtimensec = n) +#define stat_set_cnsecs(s, n) ((s)->st_ctimensec = n) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_ATIME_N) + +/* + * Found e.g. on AIX. + */ +#define stat_ansecs(s) ((s)->st_atime_n) +#define stat_mnsecs(s) ((s)->st_mtime_n) +#define stat_cnsecs(s) ((s)->st_ctime_n) + +#define stat_set_ansecs(s, n) ((s)->st_atime_n = n) +#define stat_set_mnsecs(s, n) ((s)->st_mtime_n = n) +#define stat_set_cnsecs(s, n) ((s)->st_ctime_n = n) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST__TIM) && !defined(_FOUND_STAT_NSECS_) + +/* + * Found e.g. on UnixWare. + */ +#define stat_ansecs(s) ((s)->st_atim.st__tim.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtim.st__tim.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctim.st__tim.tv_nsec) + +#define stat_set_ansecs(s, n) ((s)->st_atim.st__tim.tv_nsec = n) +#define stat_set_mnsecs(s, n) ((s)->st_mtim.st__tim.tv_nsec = n) +#define stat_set_cnsecs(s, n) ((s)->st_ctim.st__tim.tv_nsec = n) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_NSEC) && !defined(_FOUND_STAT_NSECS_) + +/* + * Found e.g. on SunOS-5.x and IRIX. + */ +#define stat_ansecs(s) ((s)->st_atim.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtim.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctim.tv_nsec) + +#define stat_set_ansecs(s, n) ((s)->st_atim.tv_nsec = n) +#define stat_set_mnsecs(s, n) ((s)->st_mtim.tv_nsec = n) +#define stat_set_cnsecs(s, n) ((s)->st_ctim.tv_nsec = n) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_ATIMESPEC) && !defined(_FOUND_STAT_NSECS_) + +/* + * Found e.g. on FreeBSD and Mac OS X. + */ +#define stat_ansecs(s) ((s)->st_atimespec.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtimespec.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctimespec.tv_nsec) + +#define stat_set_ansecs(s, n) ((s)->st_atimespec.tv_nsec = n) +#define stat_set_mnsecs(s, n) ((s)->st_mtimespec.tv_nsec = n) +#define stat_set_cnsecs(s, n) ((s)->st_ctimespec.tv_nsec = n) + +#define _FOUND_STAT_NSECS_ +#endif + +/* + * st_spare1 is last as some implementations keep backwards + * compatibility although there is one of the nsec implementations. + */ +#if defined(HAVE_ST_SPARE1) && !defined(_FOUND_STAT_NSECS_) + +/* + * Found e.g. on SunOS-4.x and HP-UX. + */ +#define stat_ansecs(s) ((s)->st_spare1 * 1000) +#define stat_mnsecs(s) ((s)->st_spare2 * 1000) +#define stat_cnsecs(s) ((s)->st_spare3 * 1000) + +#define stat_set_ansecs(s, n) ((s)->st_spare1 = n / 1000) +#define stat_set_mnsecs(s, n) ((s)->st_spare2 = n / 1000) +#define stat_set_cnsecs(s, n) ((s)->st_spare3 = n / 1000) + +#define _FOUND_STAT_USECS_ +#define _FOUND_STAT_NSECS_ +#endif + +#if !defined(_FOUND_STAT_NSECS_) +#define stat_ansecs(s) (0) +#define stat_mnsecs(s) (0) +#define stat_cnsecs(s) (0) + +#define stat_set_ansecs(s, n) (0) +#define stat_set_mnsecs(s, n) (0) +#define stat_set_cnsecs(s, n) (0) +#endif + +#endif /* _SCHILY_STAT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdint.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdint.h new file mode 100644 index 00000000000..0fdf9acc27d --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdint.h @@ -0,0 +1,488 @@ +/* @(#)stdint.h 1.37 15/12/10 Copyright 1997-2015 J. Schilling */ +/* + * Abstraction from stdint.h + * + * Copyright (c) 1997-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STDINT_H +#define _SCHILY_STDINT_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * Let us include system defined types too. + */ +#ifndef _SCHILY_TYPES_H +#include +#endif + +/* + * Include sys/param.h for NBBY - needed in case that CHAR_BIT is missing + */ +#ifndef _SCHILY_PARAM_H +#include /* Must be before limits.h */ +#endif + +/* + * Include limits.h for CHAR_BIT - needed by TYPE_MINVAL(t) and TYPE_MAXVAL(t) + */ +#ifndef _SCHILY_LIMITS_H +#include +#endif + +#ifndef CHAR_BIT +#ifdef NBBY +#define CHAR_BIT NBBY +#endif +#endif + +/* + * Last resort: define CHAR_BIT by hand + */ +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* + * These macros may not work on all platforms but as we depend + * on two's complement in many places, they do not reduce portability. + * The macros below work with 2s complement and ones complement machines. + * Verify with this table... + * + * Bits 1's c. 2's complement. + * 100 -3 -4 + * 101 -2 -3 + * 110 -1 -2 + * 111 -0 -1 + * 000 +0 0 + * 001 +1 +1 + * 010 +2 +2 + * 011 +3 +3 + * + * Computing -TYPE_MINVAL(type) will not work on 2's complement machines + * if 'type' is int or more. Use: + * ((unsigned type)(-1 * (TYPE_MINVAL(type)+1))) + 1; + * it works for both 1's complement and 2's complement machines. + */ +#define TYPE_ISSIGNED(t) (((t)-1) < ((t)0)) +#define TYPE_ISUNSIGNED(t) (!TYPE_ISSIGNED(t)) +#define TYPE_MSBVAL(t) ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1))) +#define TYPE_MINVAL(t) (TYPE_ISSIGNED(t) \ + ? TYPE_MSBVAL(t) \ + : ((t)0)) +#define TYPE_MAXVAL(t) ((t)(~((t)0) - TYPE_MINVAL(t))) + +/* + * MSVC has size_t in stddef.h + */ +#ifdef HAVE_STDDEF_H +#ifndef _INCL_STDDEF_H +#include +#define _INCL_STDDEF_H +#endif +#endif + +/* + * CHAR_IS_UNSIGNED is needed to define int8_t + */ +#ifdef __CHAR_UNSIGNED__ /* GNU GCC define (dynamic) */ +#ifndef CHAR_IS_UNSIGNED +#define CHAR_IS_UNSIGNED /* Sing Schily define (static) */ +#endif +#endif + +/* + * This is a definition for a compiler dependant 64 bit type. + * There is currently a silently fallback to a long if the compiler does not + * support it. Check if this is the right way. + * + * Be very careful here as MSVC does not implement long long but rather __int64 + * and once someone makes 'long long' 128 bits on a 64 bit machine, we need to + * check for a MSVC __int128 type. + */ +#ifndef NO_LONGLONG +# if !defined(USE_LONGLONG) && defined(HAVE_LONGLONG) +# define USE_LONGLONG +# endif +# if !defined(USE_LONGLONG) && defined(HAVE___INT64) +# define USE_LONGLONG +# endif +#endif + +#ifdef USE_LONGLONG + +# if defined(HAVE___INT64) + +typedef __int64 Llong; +typedef unsigned __int64 Ullong; /* We should avoid this */ +typedef unsigned __int64 ULlong; + +#define SIZEOF_LLONG SIZEOF___INT64 +#define SIZEOF_ULLONG SIZEOF_UNSIGNED___INT64 + +# else /* We must have HAVE_LONG_LONG */ + +typedef long long Llong; +typedef unsigned long long Ullong; /* We should avoid this */ +typedef unsigned long long ULlong; + +#define SIZEOF_LLONG SIZEOF_LONG_LONG +#define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG_LONG + +# endif /* HAVE___INT64 / HAVE_LONG_LONG */ + +#else /* !USE_LONGLONG */ + +typedef long Llong; +typedef unsigned long Ullong; /* We should avoid this */ +typedef unsigned long ULlong; + +#define SIZEOF_LLONG SIZEOF_LONG +#define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG + +#endif /* USE_LONGLONG */ + +#ifndef LLONG_MIN +#define LLONG_MIN TYPE_MINVAL(Llong) +#endif +#ifndef LLONG_MAX +#define LLONG_MAX TYPE_MAXVAL(Llong) +#endif +#ifndef ULLONG_MAX +#define ULLONG_MAX TYPE_MAXVAL(Ullong) +#endif + +/* + * Start inttypes.h emulation. + * + * Thanks to Solaris 2.4 and even recent 1999 Linux versions, we + * cannot use the official UNIX-98 names here. Old Solaris versions + * define parts of the types in some exotic include files. + * Linux even defines incompatible types in . + */ + +#if defined(HAVE_INTTYPES_H) || defined(HAVE_STDINT_H) +#if defined(HAVE_INTTYPES_H) +# ifndef _INCL_INTTYPES_H +# include +# define _INCL_INTTYPES_H +# endif +#else +#if defined(HAVE_STDINT_H) +# ifndef _INCL_STDINT_H +# include +# define _INCL_STDINT_H +# endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * On VMS on VAX, these types are present but non-scalar. + * Thus we may not be able to use them + */ +#ifdef HAVE_LONGLONG +# define HAVE_INT64_T +# define HAVE_UINT64_T +#endif + +#define Int8_t int8_t +#define Int16_t int16_t +#define Int32_t int32_t +#ifdef HAVE_LONGLONG +#define Int64_t int64_t +#endif +#define Intmax_t intmax_t +#define UInt8_t uint8_t +#define UInt16_t uint16_t +#define UInt32_t uint32_t +#ifdef HAVE_LONGLONG +#define UInt64_t uint64_t +#endif +#define UIntmax_t uintmax_t + +#define Intptr_t intptr_t +#define UIntptr_t uintptr_t + +/* + * If we only have a UNIX-98 inttypes.h but no SUSv3 + * + * Beware not to use int64_t / uint64_t as VMS on a VAX defines + * them as non-scalar (structure) based types. + */ +#ifndef HAVE_TYPE_INTMAX_T +#define intmax_t Llong +#endif +#ifndef HAVE_TYPE_UINTMAX_T +#define uintmax_t ULlong +#endif + +#ifdef __cplusplus +} +#endif + +#else /* !HAVE_INTTYPES_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if SIZEOF_CHAR != 1 || SIZEOF_UNSIGNED_CHAR != 1 +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if the above is true. And that's what we want. + */ +error Sizeof char is not equal 1 + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#if defined(__STDC__) || defined(CHAR_IS_UNSIGNED) + typedef signed char Int8_t; +#else + typedef char Int8_t; +#endif + +#if SIZEOF_SHORT_INT == 2 + typedef short Int16_t; +#else + error No int16_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#if SIZEOF_INT == 4 +#if defined(_MSC_VER) && SIZEOF_LONG_INT == 4 + typedef long Int32_t; +#else + typedef int Int32_t; +#endif +#else + error No int32_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#if SIZEOF_LONG_INT == 8 + typedef long Int64_t; +# define HAVE_INT64_T +#else +#if SIZEOF_LONG_LONG == 8 + typedef long long Int64_t; +# define HAVE_INT64_T +#else +#if SIZEOF___INT64 == 8 + typedef __int64 Int64_t; +# define HAVE_INT64_T +#else +/* + * Tolerate platforms without 64-Bit support. + */ +/* error No int64_t found */ +#endif +#endif +#endif + +#if SIZEOF_CHAR_P == SIZEOF_INT + typedef int Intptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_LONG_INT + typedef long Intptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_LLONG + typedef Llong Intptr_t; +#else + error No intptr_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif +#endif +#endif + +typedef unsigned char UInt8_t; + +#if SIZEOF_UNSIGNED_SHORT_INT == 2 + typedef unsigned short UInt16_t; +#else + error No uint16_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#if SIZEOF_UNSIGNED_INT == 4 +#if defined(_MSC_VER) && SIZEOF_UNSIGNED_LONG_INT == 4 + typedef unsigned long UInt32_t; +#else + typedef unsigned int UInt32_t; +#endif +#else + error No int32_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#if SIZEOF_UNSIGNED_LONG_INT == 8 + typedef unsigned long UInt64_t; +# define HAVE_UINT64_T +#else +#if SIZEOF_UNSIGNED_LONG_LONG == 8 + typedef unsigned long long UInt64_t; +# define HAVE_UINT64_T +#else +#if SIZEOF_UNSIGNED___INT64 == 8 + typedef unsigned __int64 UInt64_t; +# define HAVE_UINT64_T +#else +/* + * Tolerate platforms without 64-Bit support. + */ +/* error No uint64_t found */ +#endif +#endif +#endif + +#define Intmax_t Llong +#define UIntmax_t Ullong + +#if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_INT + typedef unsigned int UIntptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG_INT + typedef unsigned long UIntptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_ULLONG + typedef ULlong UIntptr_t; +#else + error No uintptr_t found + +#include /* Avoid "unknown directive" with K&R */ +#endif +#endif +#endif + +#ifdef _MSC_VER +/* + * All recent platforms define the POSIX/C-99 compliant types from inttypes.h + * except Microsoft. With these #defines, we may also use official types on a + * Microsoft environment. + * + * Warning: Linux-2.2 and before do not have inttypes.h and define some of the + * types in an incmpatible way. + */ +#undef int8_t +#define int8_t Int8_t +#undef int16_t +#define int16_t Int16_t +#undef int32_t +#define int32_t Int32_t +#undef int64_t +#define int64_t Int64_t +#undef intmax_t +#define intmax_t Intmax_t +#undef uint8_t +#define uint8_t UInt8_t +#undef uint16_t +#define uint16_t UInt16_t +#undef uint32_t +#define uint32_t UInt32_t +#undef uint64_t +#define uint64_t UInt64_t +#undef uintmax_t +#define uintmax_t UIntmax_t + +#undef intptr_t +#define intptr_t Intptr_t +#undef uintptr_t +#define uintptr_t UIntptr_t +#endif /* _MSC_VER */ + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_INTTYPES_H */ + +#ifndef INT8_MIN +#define INT8_MIN TYPE_MINVAL(Int8_t) +#endif +#ifndef INT8_MAX +#define INT8_MAX TYPE_MAXVAL(Int8_t) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX TYPE_MAXVAL(UInt8_t) +#endif + +#ifndef INT16_MIN +#define INT16_MIN TYPE_MINVAL(Int16_t) +#endif +#ifndef INT16_MAX +#define INT16_MAX TYPE_MAXVAL(Int16_t) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX TYPE_MAXVAL(UInt16_t) +#endif + +#ifndef INT32_MIN +#define INT32_MIN TYPE_MINVAL(Int32_t) +#endif +#ifndef INT32_MAX +#define INT32_MAX TYPE_MAXVAL(Int32_t) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX TYPE_MAXVAL(UInt32_t) +#endif + +#ifdef HAVE_INT64_T +#ifndef INT64_MIN +#define INT64_MIN TYPE_MINVAL(Int64_t) +#endif +#ifndef INT64_MAX +#define INT64_MAX TYPE_MAXVAL(Int64_t) +#endif +#endif +#ifdef HAVE_UINT64_T +#ifndef UINT64_MAX +#define UINT64_MAX TYPE_MAXVAL(UInt64_t) +#endif +#endif + +#ifndef INTMAX_MIN +#define INTMAX_MIN TYPE_MINVAL(Intmax_t) +#endif +#ifndef INTMAX_MAX +#define INTMAX_MAX TYPE_MAXVAL(Intmax_t) +#endif +#ifndef UINTMAX_MAX +#define UINTMAX_MAX TYPE_MAXVAL(UIntmax_t) +#endif + +#define SIZE_T_MIN TYPE_MINVAL(size_t) +#ifdef SIZE_T_MAX +#undef SIZE_T_MAX /* FreeBSD has a similar #define */ +#endif +#define SIZE_T_MAX TYPE_MAXVAL(size_t) + +#define SSIZE_T_MIN TYPE_MINVAL(ssize_t) +#define SSIZE_T_MAX TYPE_MAXVAL(ssize_t) + +#endif /* _SCHILY_STDINT_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdio.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdio.h new file mode 100644 index 00000000000..cb1b6a61c56 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdio.h @@ -0,0 +1,124 @@ +/* @(#)stdio.h 1.12 16/09/11 Copyright 2009-2016 J. Schilling */ +/* + * Abstraction from stdio.h + * + * Copyright (c) 2009-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STDIO_H +#define _SCHILY_STDIO_H +#ifndef NO_SCHILY_STDIO_H /* We #undef _SCHILY_STDIO_H later because */ + /* of the ill designed "hdrchk" program */ + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef INCL_MYSTDIO +#ifndef _INCL_MYSTDIO_H +#include +#define _INCL_MYSTDIO_H +#endif + +#else /* INCL_MYSTDIO */ + +#ifndef _INCL_STDIO_H +#include +#define _INCL_STDIO_H +#endif +#endif /* INCL_MYSTDIO */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_LARGEFILES +/* + * If HAVE_LARGEFILES is defined, it is guaranteed that fseeko()/ftello() + * both are available. + */ +#define fseek fseeko +#define ftell ftello +#else /* !HAVE_LARGEFILES */ + +/* + * If HAVE_LARGEFILES is not defined, we depend on specific tests for + * fseeko()/ftello() which must have been done before the tests for + * Large File support have been done. + * Note that this only works if the tests used below are really done before + * the Large File autoconf test is run. This is because autoconf does no + * clean testing but instead cumulatively modifes the envivonment used for + * testing. + */ +#ifdef HAVE_FSEEKO +# define fseek fseeko +#endif +#ifdef HAVE_FTELLO +# define ftell ftello +#endif +#endif + +#if !defined(HAVE_POPEN) && defined(HAVE__POPEN) +#define popen(c, m) _popen((c), (m)) +#endif + +#if !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE) +#define pclose(fp) _pclose(fp) +#endif + +#ifdef FAST_GETC_PUTC +/* + * The following code partially allows libschily to access FILE * as fast as + * from inside libc on Solaris. + * This makes it possible to implement js_printf() from libschily aprox. + * 33% faster than printf() from libc on Solaris. To do this, we + * partially unhide the FILE structure in a 64 bit environment on Solaris + * to allow to run putc_unlocked() as a marcro. + * + * If you believe you can do this on onther platforms, send a note. + */ +#if defined(__SVR4) && defined(__sun) && defined(_LP64) + +/* + * This is how the 64 bit FILE * begins on Solaris. + */ +struct SCHILY__FILE_TAG { + unsigned char *_ptr; /* next character from/to here in buffer */ + unsigned char *_base; /* the buffer */ + unsigned char *_end; /* the end of the buffer */ + ssize_t _cnt; /* number of available characters in buffer */ +}; + +#define __putc_unlocked(x, p) (--(p)->_cnt < 0 \ + ? __flsbuf((x), (FILE *)(p)) \ + : (int)(*(p)->_ptr++ = \ + (unsigned char) (x))) + +#define putc_unlocked(x, p) __putc_unlocked(x, (struct SCHILY__FILE_TAG *)p) + +extern int __flsbuf __PR((int, FILE *)); + +#endif /* defined(__SVR4) && defined(__sun) && defined(_LP64) */ +#endif /* FAST_GETC_PUTC */ + +#ifdef __cplusplus +} +#endif + +#else /* !NO_SCHILY_STDIO_H */ +#undef _SCHILY_STDIO_H /* #undef here to pass "hdrchk" */ +#endif /* NO_SCHILY_STDIO_H */ +#endif /* _SCHILY_STDIO_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdlib.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdlib.h new file mode 100644 index 00000000000..99813731fd2 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/stdlib.h @@ -0,0 +1,72 @@ +/* @(#)stdlib.h 1.11 15/11/28 Copyright 1996-2015 J. Schilling */ +/* + * Definitions for stdlib + * + * Copyright (c) 1996-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STDLIB_H +#define _SCHILY_STDLIB_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#ifndef _INCL_STDLIB_H +#include +#define _INCL_STDLIB_H +#endif +#endif /* HAVE_STDLIB_H */ + + +#ifdef HAVE_POSIX_MALLOC_H /* Haiku */ +#ifndef _INCL_POSIX_MALLOC_H +#include +#define _INCL_POSIX_MALLOC_H +#endif +#endif /* HAVE_POSIX_MALLOC_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_INCL_STDLIB_H) && !defined(_INCL_POSIX_MALLOC_H) +extern char *malloc(); +extern char *realloc(); +#endif + +#ifndef _INCL_STDLIB_H +extern double atof(); +#endif + +#ifdef __cplusplus +} +#endif + + + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef RAND_MAX +#define RAND_MAX 32767 +#endif + +#endif /* _SCHILY_STDLIB_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/string.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/string.h new file mode 100644 index 00000000000..08b51b6902d --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/string.h @@ -0,0 +1,108 @@ +/* @(#)string.h 1.12 11/11/24 Copyright 1996-2011 J. Schilling */ +/* + * Definitions for strings + * + * Copyright (c) 1996-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_STRING_H +#define _SCHILY_STRING_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_TYPES_H +#include /* Try to get size_t */ +#endif + +/* + * It may be that IBM's AIX has problems when doing + * #include + * #include + * So I moved the #include to the top. As the file strings.h + * defines strcasecmp() we may need it... + * + * Note that the only real problem appears if we use rubbish FSF based code that + * #defines _NO_PROTO + */ +#ifdef HAVE_STRINGS_H +#ifndef _INCL_STRINGS_H +#include +#define _INCL_STRINGS_H +#endif +#endif /* HAVE_STRINGS_H */ + + +#ifdef HAVE_STRING_H +#ifndef _INCL_STRING_H +#include +#define _INCL_STRING_H +#endif +#else /* HAVE_STRING_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#define NULL 0 +#endif + +extern void *memcpy __PR((void *, const void *, int)); +extern void *memmove __PR((void *, const void *, int)); +extern char *strcpy __PR((char *, const char *)); +extern char *strncpy __PR((char *, const char *, int)); + +extern char *strcat __PR((char *, const char *)); +extern char *strncat __PR((char *, const char *, int)); + +extern int memcmp __PR((const void *, const void *, int)); +extern int strcmp __PR((const char *, const char *)); +extern int strcoll __PR((const char *, const char *)); +extern int strncmp __PR((const char *, const char *, int)); +extern int strxfrm __PR((char *, const char *, int)); + +extern void *memchr __PR((const void *, int, int)); +extern char *strchr __PR((const char *, int)); + +extern int strcspn __PR((const char *, const char *)); +/* #pragma int_to_unsigned strcspn */ + +extern char *strpbrk __PR((const char *, const char *)); +extern char *strrchr __PR((const char *, int)); + +extern int strspn __PR((const char *, const char *)); +/* #pragma int_to_unsigned strspn */ + +extern char *strstr __PR((const char *, const char *)); +extern char *strtok __PR((char *, const char *)); +extern void *memset __PR((void *, int, int)); +extern char *strerror __PR((int)); + +extern int strlen __PR((const char *)); +/* #pragma int_to_unsigned strlen */ + +extern void *memccpy __PR((void *, const void *, int, int)); + +extern int strcasecmp __PR((const char *, const char *)); +extern int strncasecmp __PR((const char *, const char *, size_t)); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_STRING_H */ + +#endif /* _SCHILY_STRING_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/time.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/time.h new file mode 100644 index 00000000000..3218235c285 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/time.h @@ -0,0 +1,164 @@ +/* @(#)time.h 1.20 13/10/01 Copyright 1996-2013 J. Schilling */ +/* + * Generic header for users of time(), gettimeofday() ... + * + * It includes definitions for time_t, struct timeval, ... + * + * Copyright (c) 1996-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_TIME_H +#define _SCHILY_TIME_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_TYPES_H +#include /* Needed for time_t */ +#endif + +#ifdef TIME_WITH_SYS_TIME +# ifndef _INCL_SYS_TIME_H +# include +# define _INCL_SYS_TIME_H +# endif +# ifndef _INCL_TIME_H +# include +# define _INCL_TIME_H +# endif +#else +#ifdef HAVE_SYS_TIME_H +# ifndef _INCL_SYS_TIME_H +# include +# define _INCL_SYS_TIME_H +# endif +#else +# ifndef _INCL_TIME_H +# include +# define _INCL_TIME_H +# endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef timerclear +/* + * With MSVC timerclear / struct timeval present in case that + * winsock2.h has been included before. + */ +#undef HAVE_STRUCT_TIMEVAL +#define HAVE_STRUCT_TIMEVAL 1 +#endif + +#ifndef HAVE_STRUCT_TIMEVAL + +struct timeval { + long tv_sec; + long tv_usec; +}; +#endif + +#ifndef HAVE_STRUCT_TIMEZONE + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; +#endif + +#ifndef HAVE_STRUCT_TIMESPEC + +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif + + +#undef timerclear +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 + +#undef timerfix +#define timerfix1(tvp) while ((tvp)->tv_usec < 0) { \ + (tvp)->tv_sec--; \ + (tvp)->tv_usec += 1000000; \ + } + +#define timerfix2(tvp) while ((tvp)->tv_usec > 1000000) { \ + (tvp)->tv_sec++; \ + (tvp)->tv_usec -= 1000000; \ + } + +#define timerfix(tvp) do { timerfix1(tvp); timerfix2(tvp); } while (0) + +/* + * timersub() and timeradd() are defined on FreeBSD with a different + * interface (3 parameters). + */ +#undef timersub +#define timersub(tvp1, tvp2) do { \ + (tvp1)->tv_sec -= (tvp2)->tv_sec; \ + (tvp1)->tv_usec -= (tvp2)->tv_usec; \ + timerfix1(tvp1); timerfix2(tvp1); \ + } while (0) + +#undef timeradd +#define timeradd(tvp1, tvp2) do { \ + (tvp1)->tv_sec += (tvp2)->tv_sec; \ + (tvp1)->tv_usec += (tvp2)->tv_usec; \ + timerfix1(tvp1); timerfix2(tvp1); \ + } while (0) + + +#undef timespecclear +#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0 + +#undef timespecfix +#define timespecfix1(tsp) while ((tsp)->tv_nsec < 0) { \ + (tsp)->tv_sec--; \ + (tsp)->tv_nsec += 1000000000; \ + } + +#define timespecfix2(tsp) while ((tsp)->tv_nsec > 1000000000) { \ + (tsp)->tv_sec++; \ + (tsp)->tv_nsec -= 1000000000; \ + } + +#define timespecfix(tsp) do { timespecfix1(tsp); timespecfix2(tsp); } while (0) + +#undef timespecsub +#define timespecsub(tsp1, tsp2) do { \ + (tsp1)->tv_sec -= (tsp2)->tv_sec; \ + (tsp1)->tv_nsec -= (tsp2)->tv_nsec; \ + timespecfix1(tsp1); timespecfix2(tsp1); \ + } while (0) + +#undef timespecadd +#define timespecadd(tsp1, tsp2) do { \ + (tsp1)->tv_sec += (tsp2)->tv_sec; \ + (tsp1)->tv_nsec += (tsp2)->tv_nsec; \ + timespecfix1(tsp1); timespecfix2(tsp1); \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_TIME_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/types.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/types.h new file mode 100644 index 00000000000..5331d50513a --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/types.h @@ -0,0 +1,47 @@ +/* @(#)types.h 1.5 09/10/22 Copyright 2006-2009 J. Schilling */ +/* + * Abstraction from sys/types.h + * + * Copyright (c) 2006-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_TYPES_H +#define _SCHILY_TYPES_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#ifndef _INCL_SYS_TYPES_H +#include +#define _INCL_SYS_TYPES_H +#endif +#else +#ifdef HAVE_TYPES_H +#ifndef _INCL_TYPES_H +#include +#define _INCL_TYPES_H +#endif +#endif +#endif + +#ifdef HAVE_STDDEF_H +#ifndef _INCL_STDDEF_H +#include /* For offsetof(), ptrdiff_t, wchar_t, size_t */ +#define _INCL_STDDEF_H +#endif +#endif + +#endif /* _SCHILY_TYPES_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/unistd.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/unistd.h new file mode 100644 index 00000000000..46d2e3be7ab --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/unistd.h @@ -0,0 +1,183 @@ +/* @(#)unistd.h 1.27 14/06/19 Copyright 1996-2014 J. Schilling */ +/* + * Definitions for unix system interface + * + * Copyright (c) 1996-2014 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_UNISTD_H +#define _SCHILY_UNISTD_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * unistd.h grants things like off_t to be typedef'd. + */ +#ifndef _SCHILY_TYPES_H +#include +#endif + +/* + * inttypes.h grants things like Intptr_t to be typedef'd. + */ +#ifndef _SCHILY_INTTYPES_H +#include +#endif + +#ifdef HAVE_UNISTD_H + +#ifndef _INCL_UNISTD_H +#include +#define _INCL_UNISTD_H +#endif + +#ifndef _SC_PAGESIZE +#ifdef _SC_PAGE_SIZE /* HP/UX & OSF */ +#define _SC_PAGESIZE _SC_PAGE_SIZE +#endif +#endif + +#else /* !HAVE_UNISTD_H */ +#ifndef _SCHILY_STDLIB_H +#include /* MSVC: no unistd.h environ is in stdlib.h */ +#endif +#endif /* !HAVE_UNISTD_H */ + +/* + * MSVC has getcwd()/chdir()/mkdir()/rmdir() in direct.h + */ +#if defined(_MSC_VER) && defined(HAVE_DIRECT_H) +#ifndef _INCL_DIRECT_H +#include +#define _INCL_DIRECT_H +#endif +#endif + +/* + * MSVC has size_t in stddef.h + */ +#ifdef HAVE_STDDEF_H +#ifndef _INCL_STDDEF_H +#include +#define _INCL_STDDEF_H +#endif +#endif + +#ifndef STDIN_FILENO +# ifdef JOS +# ifndef _SCHILY_JOS_IO_H +# include +# endif +# else +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 +# endif +#endif + +#ifndef R_OK +/* Symbolic constants for the "access" routine: */ +#define R_OK 4 /* Test for Read permission */ +#define W_OK 2 /* Test for Write permission */ +#define X_OK 1 /* Test for eXecute permission */ +#define F_OK 0 /* Test for existence of File */ +#endif +#ifndef E_OK +#ifdef HAVE_ACCESS_E_OK +#ifdef EFF_ONLY_OK +#define E_OK EFF_ONLY_OK /* Irix */ +#else +#ifdef EUID_OK +#define E_OK EUID_OK /* UNICOS (0400) */ +#else +#define E_OK 010 /* Test effective uids */ +#endif /* EUID_OK */ +#endif /* EFF_ONLY_OK */ +#else +#define E_OK 0 +#endif /* HAVE_ACCESS_E_OK */ +#endif /* !E_OK */ + +/* Symbolic constants for the "lseek" routine: */ +#ifndef SEEK_SET +#define SEEK_SET 0 /* Set file pointer to "offset" */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* Set file pointer to current plus "offset" */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef HAVE_ENVIRON_DEF +extern char **environ; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(HAVE_UNISTD_H) || !defined(_POSIX_VERSION) +/* + * Maybe we need a lot more definitions here... + * It is not clear whether we should have prototyped definitions. + */ +#if !defined(_MSC_VER) && !defined(__MINGW32__) +/* + * MS C comes with broken prototypes in wrong header files (in our case, the + * wrong prototype is in io.h). Avoid to redefine the broken MS stuff with + * correct prototypes. + */ +extern int access __PR((const char *, int)); +extern int close __PR((int)); +extern int dup __PR((int)); +extern int dup2 __PR((int, int)); +extern int link __PR((const char *, const char *)); +extern int read __PR((int, void *, size_t)); +extern int unlink __PR((const char *)); +extern int write __PR((int, const void *, size_t)); +#endif +#if !defined(_MSC_VER) && !defined(__MINGW32__) +/* + * MS C comes with broken prototypes in wrong header files (in our case, the + * wrong prototype is in stdlib.h). Avoid to redefine the broken MS stuff with + * correct prototypes. + */ +extern void _exit __PR((int)); +#endif +#endif + +#if !defined(HAVE_PIPE) && defined(HAVE__PIPE) && defined(HAVE_IO_H) +#ifndef _SCHILY_LIMITS_H +#include /* for PIPE_BUF */ +#endif +#ifndef _SCHILY_FCNTL_H +#include /* for O_BINARY */ +#endif +#ifndef _SCHILY_IO_H +#include /* for _pipe() */ +#endif + +#define pipe(pp) _pipe(pp, PIPE_BUF, O_BINARY) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_UNISTD_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/utypes.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/utypes.h new file mode 100644 index 00000000000..d723d95e201 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/utypes.h @@ -0,0 +1,158 @@ +/* @(#)utypes.h 1.36 13/09/14 Copyright 1997-2013 J. Schilling */ +/* + * Definitions for some user defined types + * + * Copyright (c) 1997-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_UTYPES_H +#define _SCHILY_UTYPES_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +/* + * uypes.h is based on inttypes.h + */ +#ifndef _SCHILY_INTTYPES_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Several unsigned cardinal types + */ +typedef unsigned long Ulong; +typedef unsigned int Uint; +typedef unsigned short Ushort; +typedef unsigned char Uchar; + +/* + * The IBM AIX C-compiler seems to be the only compiler on the world + * which does not allow to use unsigned char bit fields as a hint + * for packed bit fields. Define a pesical type to avoid warnings. + * The packed attribute is honored wit unsigned int in this case too. + */ +#if defined(_AIX) && !defined(__GNUC__) + +typedef unsigned int Ucbit; + +#else + +typedef unsigned char Ucbit; + +#endif + +#ifndef CHAR_MIN +#define CHAR_MIN TYPE_MINVAL(char) +#endif +#ifndef CHAR_MAX +#define CHAR_MAX TYPE_MAXVAL(char) +#endif +#ifndef UCHAR_MAX +#define UCHAR_MAX TYPE_MAXVAL(unsigned char) +#endif + +#ifndef SHRT_MIN +#define SHRT_MIN TYPE_MINVAL(short) +#endif +#ifndef SHRT_MAX +#define SHRT_MAX TYPE_MAXVAL(short) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX TYPE_MAXVAL(unsigned short) +#endif + +#ifndef INT_MIN +#define INT_MIN TYPE_MINVAL(int) +#endif +#ifndef INT_MAX +#define INT_MAX TYPE_MAXVAL(int) +#endif +#ifndef UINT_MAX +#define UINT_MAX TYPE_MAXVAL(unsigned int) +#endif + +#ifndef LONG_MIN +#define LONG_MIN TYPE_MINVAL(long) +#endif +#ifndef LONG_MAX +#define LONG_MAX TYPE_MAXVAL(long) +#endif +#ifndef ULONG_MAX +#define ULONG_MAX TYPE_MAXVAL(unsigned long) +#endif + +#define OFF_T_MIN TYPE_MINVAL(off_t) +#define OFF_T_MAX TYPE_MAXVAL(off_t) + +#define UID_T_MIN TYPE_MINVAL(uid_t) +#define UID_T_MAX TYPE_MAXVAL(uid_t) + +#define GID_T_MIN TYPE_MINVAL(gid_t) +#define GID_T_MAX TYPE_MAXVAL(gid_t) + +#define PID_T_MIN TYPE_MINVAL(pid_t) +#define PID_T_MAX TYPE_MAXVAL(pid_t) + +#define MODE_T_MIN TYPE_MINVAL(mode_t) +#define MODE_T_MAX TYPE_MAXVAL(mode_t) + +#define TIME_T_MIN TYPE_MINVAL(time_t) +#define TIME_T_MAX TYPE_MAXVAL(time_t) + +#define CADDR_T_MIN TYPE_MINVAL(caddr_t) +#define CADDR_T_MAX TYPE_MAXVAL(caddr_t) + +#define DADDR_T_MIN TYPE_MINVAL(daddr_t) +#define DADDR_T_MAX TYPE_MAXVAL(daddr_t) + +#define DEV_T_MIN TYPE_MINVAL(dev_t) +#define DEV_T_MAX TYPE_MAXVAL(dev_t) + +#define MAJOR_T_MIN TYPE_MINVAL(major_t) +#define MAJOR_T_MAX TYPE_MAXVAL(major_t) + +#define MINOR_T_MIN TYPE_MINVAL(minor_t) +#define MINOR_T_MAX TYPE_MAXVAL(minor_t) + +#define INO_T_MIN TYPE_MINVAL(ino_t) +#define INO_T_MAX TYPE_MAXVAL(ino_t) + +#define NLINK_T_MIN TYPE_MINVAL(nlink_t) +#define NLINK_T_MAX TYPE_MAXVAL(nlink_t) + +#define BLKSIZE_T_MIN TYPE_MINVAL(blksize_t) +#define BLKSIZE_T_MAX TYPE_MAXVAL(blksize_t) + +#define BLKCNT_T_MIN TYPE_MINVAL(blkcnt_t) +#define BLKCNT_T_MAX TYPE_MAXVAL(blkcnt_t) + +#define CLOCK_T_MIN TYPE_MINVAL(clock_t) +#define CLOCK_T_MAX TYPE_MAXVAL(clock_t) + +#define SOCKLEN_T_MIN TYPE_MINVAL(socklen_t) +#define SOCKLEN_T_MAX TYPE_MAXVAL(socklen_t) + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_UTYPES_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/varargs.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/varargs.h new file mode 100644 index 00000000000..e2618180ea2 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/varargs.h @@ -0,0 +1,140 @@ +/* @(#)varargs.h 1.8 14/01/06 Copyright 1998-2014 J. Schilling */ +/* + * Generic header for users of var args ... + * + * Includes a default definition for va_copy() + * and some magic know how about the SVr4 Power PC var args ABI + * to create a __va_arg_list() macro. + * + * The __va_arg_list() macro is needed to fetch a va_list type argument + * from a va_list. This is needed to implement a recursive "%r" printf. + * + * Copyright (c) 1998-2014 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_VARARGS_H +#define _SCHILY_VARARGS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PROTOTYPES +/* + * For ANSI C-compilers prefer stdarg.h + */ +# ifdef HAVE_STDARG_H +# ifndef _INCL_STDARG_H +# include +# define _INCL_STDARG_H +# endif +# else +# ifndef _INCL_VARARGS_H +# include +# define _INCL_VARARGS_H +# endif +# endif +#else +/* + * For K&R C-compilers prefer varargs.h + */ +# ifdef HAVE_VARARGS_H +# ifndef _INCL_VARARGS_H +# include +# define _INCL_VARARGS_H +# endif +# else +# ifndef _INCL_STDARG_H +# include +# define _INCL_STDARG_H +# endif +# endif +#endif + +#if (defined(__linux__) || defined(__linux) || defined(sun)) && \ + (defined(__ppc) || defined(__PPC) || \ + defined(powerpc) || defined(__powerpc__)) + +# ifndef VA_LIST_IS_ARRAY +# define VA_LIST_IS_ARRAY +# endif +#endif + + +/* + * __va_copy() is used by GCC 2.8 or newer until va_copy() becomes + * a final ISO standard. + */ +#if !defined(va_copy) && !defined(HAVE_VA_COPY) +# if defined(__va_copy) +# define va_copy(to, from) __va_copy(to, from) +# endif +#endif + +/* + * va_copy() is a Solaris extension to provide a portable way to perform a + * variable argument list "bookmarking" function. + * If it is not available via stdarg.h, use a simple assignement for backward + * compatibility. + */ +#if !defined(va_copy) && !defined(HAVE_VA_COPY) +#ifdef VA_LIST_IS_ARRAY +# define va_copy(to, from) ((to)[0] = (from)[0]) +#else +# define va_copy(to, from) ((to) = (from)) +#endif +#endif + +/* + * I don't know any portable way to get an arbitrary + * C object from a var arg list so I use a + * system-specific routine __va_arg_list() that knows + * if 'va_list' is an array. You will not be able to + * assign the value of __va_arg_list() but it works + * to be used as an argument of a function. + * It is a requirement for recursive printf to be able + * to use this function argument. If your system + * defines va_list to be an array you need to know this + * via autoconf or another mechanism. + * It would be nice to have something like + * __va_arg_list() in stdarg.h + */ + +#ifdef VA_LIST_IS_ARRAY +# define __va_arg_list(list) va_arg(list, void *) +#else +# define __va_arg_list(list) va_arg(list, va_list) +#endif + +/* + * This structure allows to work around the C limitation that a variable of + * type array cannot appear at the left side of an assignement operator. + * By putting va_list inside a struture, the assignement will work even in case + * that va_list is an array2. + */ +typedef struct { + va_list ap; +} va_lists_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_VARARGS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/wchar.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/wchar.h new file mode 100644 index 00000000000..f27dec57f88 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/wchar.h @@ -0,0 +1,180 @@ +/* @(#)wchar.h 1.21 11/07/19 Copyright 2007-2011 J. Schilling */ +/* + * Abstraction from wchar.h + * + * Copyright (c) 2007-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_WCHAR_H +#define _SCHILY_WCHAR_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_STDLIB_H +#include /* for MB_CUR_MAX, mbtowc()/wctomb() */ +#endif +#ifndef _SCHILY_TYPES_H +#include +#endif +#ifdef HAVE_STDDEF_H +#ifndef _INCL_STDDEF_H +#include /* Needed for e.g. size_t (POSIX) */ +#define _INCL_STDDEF_H +#endif +#endif +#ifndef _SCHILY_STDIO_H +#include /* Needed for e.g. FILE (POSIX) */ +#endif +#ifndef _SCHILY_VARARGS_H +#include /* Needed for e.g. va_list (POSIX) */ +#endif + + +#if !defined(HAVE_MBTOWC) || !defined(HAVE_WCTOMB) +#if defined(HAVE_MBRTOWC) && defined(HAVE_WCRTOMB) +# define mbtowc(wp, cp, len) mbrtowc(wp, cp, len, (mbstate_t *)0) +# define wctomb(cp, wc) wcrtomb(cp, wc, (mbstate_t *)0) +#else +# define NO_WCHAR +#endif +#endif + +#ifdef HAVE_WCHAR_H + +#ifndef _INCL_WCHAR_H +#include +#define _INCL_WCHAR_H +#endif + +#ifndef HAVE_MBSINIT +#define mbsinit(sp) ((int)((sp) == 0)) +#endif +#ifndef HAVE_MBRTOWC +#define mbrtowc(wp, cp, len, sp) mbtowc(wp, cp, len) +#endif +#ifndef HAVE_WCRTOMB +#define wcrtomb(cp, wc, sp) wctomb(cp, wc) +#endif + +#ifndef USE_WCHAR +#define USE_WCHAR +#endif + +#else /* HAVE_WCHAR_H */ + +#undef USE_WCHAR +#endif /* !HAVE_WCHAR_H */ + +#if !defined(HAVE_WCTYPE_H) && !defined(HAVE_ISWPRINT) +#undef USE_WCHAR +#undef USE_WCTYPE +#endif + +#ifdef NO_WCTYPE +#undef USE_WCHAR +#undef USE_WCTYPE +#endif + +#ifdef NO_WCHAR +#undef USE_WCHAR +#undef USE_WCTYPE +#endif + +#ifndef USE_WCHAR + +/* + * We either don't have wide chars or we don't use them... + */ +#undef wchar_t +#define wchar_t char +#undef wint_t +#define wint_t int +/* + * We cannot define wctype_t here because of a bug in Linux (missing xctype_t + * definition in wchar.h + */ +#ifdef __never__ +#undef wctype_t +#define wctype_t int +#endif + +#undef WEOF +#define WEOF ((wint_t)-1) + +#ifndef _SCHILY_UTYPES_H +#include /* For TYPE_MAXVAL() */ +#endif + +#undef WCHAR_MAX +#define WCHAR_MAX TYPE_MAXVAL(wchar_t) +#undef WCHAR_MIN +#define WCHAR_MIN TYPE_MINVAL(wchar_t) + +#undef WINT_MAX +#define WINT_MAX TYPE_MAXVAL(wint_t) +#undef WINT_MIN +#define WINT_MIN TYPE_MINVAL(wint_t) + +#undef WCTYPE_MAX +#define WCTYPE_MAX TYPE_MAXVAL(wctype_t) +#undef WCTYPE_MIN +#define WCTYPE_MIN TYPE_MINVAL(wctype_t) + +#undef SIZEOF_WCHAR_T +#define SIZEOF_WCHAR_T SIZEOF_CHAR + +#undef MB_CUR_MAX +#define MB_CUR_MAX 1 +#undef MB_LEN_MAX +#define MB_LEN_MAX 1 + +/* + * The mbtowc() for the non-multibyte case could be as simple as + * + * #define mbtowc(wp, cp, len) (*(wp) = *(cp), 1) + * + * but Mac OS X forces us to do many mbtowc(NULL, NULL, 0) calls in order + * to reset the internal state. On other platforms that do not support + * wide chars, NULL may be defined as (void *)0, so we need to check + * for "wp" != NULL and to cast "wp" and "cp" to their expected types. + */ +#undef mbtowc +#define mbtowc(wp, cp, len) ((void)((wp) ? \ + *(wchar_t *)(wp) = *(char *)(cp) : 1), 1) +#undef mbrtowc +#define mbrtowc(wp, cp, len, sp) ((void)((wp) ? \ + *(wchar_t *)(wp) = *(char *)(cp) : 1), 1) +#undef wctomb +#define wctomb(cp, wc) (*(cp) = wc, 1) +#undef wcrtomb +#define wcrtomb(cp, wc, sp) (*(cp) = wc, 1) + +#undef mbsinit +#define mbsinit(sp) ((int)((sp) == 0)) + +#undef wcwidth +#define wcwidth(wc) (1) + +#else /* USE_WCHAR */ + +#ifndef HAVE_WCWIDTH +#undef wcwidth +#define wcwidth(wc) (1) +#endif + +#endif /* USE_WCHAR */ + +#endif /* _SCHILY_WCHAR_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/wctype.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/wctype.h new file mode 100644 index 00000000000..d8298794cbf --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/wctype.h @@ -0,0 +1,99 @@ +/* @(#)wctype.h 1.8 13/07/08 Copyright 2009-2013 J. Schilling */ +/* + * Abstraction from wctype.h + * + * Copyright (c) 2009-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_WCTYPE_H +#define _SCHILY_WCTYPE_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifndef _SCHILY_WCHAR_H +#include +#endif + +#ifdef HAVE_WCTYPE_H +/* + * Include wctype.h if wchars have been enabled in schily/wchar.h + */ +#ifdef USE_WCHAR +#ifndef _INCL_WCTYPE_H +#include +#define _INCL_WCTYPE_H +#endif +#ifndef USE_WCTYPE +#define USE_WCTYPE +#endif +#endif /* USE_WCHAR */ +#endif /* HAVE_WCTYPE_H */ + +#if defined(HAVE_ISWPRINT) && defined(USE_WCHAR) +#ifndef USE_WCTYPE +#undef USE_WCTYPE +#endif +#endif + +#if !defined(HAVE_WCTYPE_H) && !defined(HAVE_ISWPRINT) +#undef USE_WCTYPE +#endif + +#ifdef NO_WCTYPE +#undef USE_WCTYPE +#endif + +#ifndef USE_WCTYPE + +#ifndef _SCHILY_CTYPE_H +#include +#endif + +#undef iswalnum +#define iswalnum(c) isalnum(c) +#undef iswalpha +#define iswalpha(c) isalpha(c) +#undef iswcntrl +#define iswcntrl(c) iscntrl(c) +#undef iswcntrl +#define iswcntrl(c) iscntrl(c) +#undef iswdigit +#define iswdigit(c) isdigit(c) +#undef iswgraph +#define iswgraph(c) isgraph(c) +#undef iswlower +#define iswlower(c) islower(c) +#undef iswprint +#define iswprint(c) isprint(c) +#undef iswpunct +#define iswpunct(c) ispunct(c) +#undef iswspace +#define iswspace(c) isspace(c) +#undef iswupper +#define iswupper(c) isupper(c) +#undef iswxdigit +#define iswxdigit(c) isxdigit(c) + +#undef towlower +#define towlower(c) tolower(c) +#undef towupper +#define towupper(c) toupper(c) + +#endif /* !USE_WCTYPE */ + +#endif /* _SCHILY_WCTYPE_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/windows.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/windows.h new file mode 100644 index 00000000000..5f78997d4dc --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/windows.h @@ -0,0 +1,88 @@ +/* @(#)windows.h 1.4 13/10/26 Copyright 2011-2013 J. Schilling */ +/* + * Definitions for windows.h + * + * Copyright (c) 2011-2013 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_WINDOWS_H +#define _SCHILY_WINDOWS_H + +#ifndef _SCHILY_MCONFIG_H +#include +#endif + +#ifdef HAVE_WINDOWS_H +#ifndef _INCL_WINDOWS_H + +/* + * configure believes they are missing and #define's them: + */ +#if defined(_MSC_VER) || defined(__MINGW32__) +/* BEGIN CSTYLED */ +#undef u_char +#undef u_short +#undef u_int +#undef u_long +/* END CSTYLED */ +#endif + +#if defined(__CYGWIN32__) || defined(__CYGWIN__) + +/* + * Cygwin-1.7.17 (Autumn 2012) makes life hard as it prevents to rename + * the Cygwin BOOL definition. Note that we have our own BOOL definition + * in schily/standard.h that exists since 1982 which happened before Microsoft + * introduced their BOOL. + * + * Previous Cygwin versions have been compatible to the original MS include + * files and allowed to rename the BOOL from windows.h (windef.h) by just using + * #define BOOL WBOOL before #include . + * + * Recent Cygwin version are unfriendly to us and prevent this. + * We now need a two level #define to redirect the BOOL from windows.h to the + * Cygwin specific WINBOOL typedef. + * + * If we do not include schily/standard.h with newer Cygwin, we cannot get + * working typedefs for "PBOOL" and "LPBOOL". + */ +#include /* Get our BOOL typedef */ + +#define _NO_BOOL_TYPEDEF /* Avoid 2nd BOOL typedef on Cygwin-1.7.17 */ + +#define WBOOL WINBOOL /* Cygwin-1.7.17 prevents to avoid BOOL */ +#endif /* defined(__CYGWIN32__) || defined(__CYGWIN__) */ + + +#define BOOL WBOOL /* This is the Win BOOL */ +#define format __ms_format /* Avoid format parameter hides global ... */ + +#ifdef timerclear /* struct timeval has already been declared */ +#define timeval __ms_timeval +#endif + +#include + +#undef BOOL /* MS Code uses WBOOL or #define BOOL WBOOL */ +#undef format /* Return to previous definition */ +#undef timeval + +#define _INCL_WINDOWS_H +#endif + +#endif /* HAVE_WINDOWS_H */ + +#endif /* _SCHILY_WINDOWS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/include/schily/xconfig.h b/reactos/sdk/tools/mkisofs/schilytools/include/schily/xconfig.h new file mode 100644 index 00000000000..83f7f2c13f5 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/include/schily/xconfig.h @@ -0,0 +1,180 @@ +/* @(#)xconfig.h 1.13 13/07/23 Copyright 1995-2013 J. Schilling */ +/* + * This file either includes the dynamic or manual autoconf stuff. + * + * Copyright (c) 1995-2013 J. Schilling + * + * This file is included from and usually + * includes $(SRCROOT)/incs/$(OARCH)/xconfig.h via + * -I$(SRCROOT)/incs/$(OARCH)/ + * + * Use only cpp instructions. + * + * NOTE: SING: (Schily Is Not Gnu) + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _SCHILY_XCONFIG_H +#define _SCHILY_XCONFIG_H + +/* + * This hack that is needed as long as VMS has no POSIX shell. + * It will go away soon. VMS users: in future you need to specify: + * cc -DUSE_STATIC_CONF + */ +#ifdef VMS +# define USE_STATIC_CONF +#endif + +#ifdef NO_STATIC_CONF +#undef USE_STATIC_CONF +#endif + +#ifdef USE_STATIC_CONF +# include /* The static autoconf stuff */ +#else /* USE_STATIC_CONF */ + + +#ifdef SCHILY_BUILD /* #defined by Schily makefile system */ + /* + * Include $(SRCROOT)/incs/$(OARCH)/xconfig.h via + * -I$(SRCROOT)/incs/$(OARCH)/ + */ +# include /* The current dynamic autoconf stuff */ +#else /* !SCHILY_BUILD */ +/* + * The stuff for static compilation. Include files from a previous + * dynamic autoconfiguration. + */ +#ifdef __SUNOS5_SPARC_CC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_SPARC_CC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_SPARC_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_X86_CC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_X86_CC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_X86_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __SUNOS5_X86_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __SUNOS4_MC68000_CC32 +#ifdef __mc68020 +#include +#define __JS_ARCH_CONF_INCL +#endif +#endif +#ifdef __SUNOS4_MC68000_GCC32 +#ifdef __mc68020 +#include +#define __JS_ARCH_CONF_INCL +#endif +#endif + +#ifdef __HPUX_HPPA_CC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_CC64 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __HPUX_HPPA_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __LINUX_ARMV6L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5L_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_ARMV5TEJL_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_I386_GCC32 +#include +#define __JS_ARCH_CONF_INCL +#endif +#ifdef __LINUX_amd64_GCC64 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __MSWIN_X86_CL32 +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifdef __CYGWIN_X86_GCC +#include +#define __JS_ARCH_CONF_INCL +#endif + +#ifndef __JS_ARCH_CONF_INCL +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defined. And that's what we want. + */ +Error unconfigured architecture + +#include /* Avoid "unknown directive" with K&R */ +#endif + +#endif /* SCHILY_BUILD */ + +#endif /* USE_STATIC_CONF */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Fake in order to keep the silly hdrchk(1) quiet. + */ +#ifdef __cplusplus +} +#endif + +#endif /* _SCHILY_XCONFIG_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/astoll.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/astoll.c new file mode 100644 index 00000000000..db1e97612d1 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/astoll.c @@ -0,0 +1,164 @@ +/* @(#)astoll.c 1.5 15/12/10 Copyright 1985, 2000-2015 J. Schilling */ +/* + * astoll() converts a string to long long + * + * Leading tabs and spaces are ignored. + * Both return pointer to the first char that has not been used. + * Caller must check if this means a bad conversion. + * + * leading "+" is ignored + * leading "0" makes conversion octal (base 8) + * leading "0x" makes conversion hex (base 16) + * + * Llong is silently reverted to long if the compiler does not + * support long long. + * + * Copyright (c) 1985, 2000-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include + +#define is_space(c) ((c) == ' ' || (c) == '\t') +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define is_hex(c) (\ + ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) + +#define is_lower(c) ((c) >= 'a' && (c) <= 'z') +#define is_upper(c) ((c) >= 'A' && (c) <= 'Z') +#define to_lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c)) + +#if ('i' + 1) < 'j' +#define BASE_MAX ('i' - 'a' + 10 + 1) /* This is EBCDIC */ +#else +#define BASE_MAX ('z' - 'a' + 10 + 1) /* This is ASCII */ +#endif + + +char * +astoll(s, l) + register const char *s; + Llong *l; +{ + return (astollb(s, l, 0)); +} + +char * +astollb(s, l, base) + register const char *s; + Llong *l; + register int base; +{ + int neg = 0; + register ULlong ret = (ULlong)0; + ULlong maxmult; + ULlong maxval; + register int digit; + register char c; + + if (base > BASE_MAX || base == 1 || base < 0) { + seterrno(EINVAL); + return ((char *)s); + } + + while (is_space(*s)) + s++; + + if (*s == '+') { + s++; + } else if (*s == '-') { + s++; + neg++; + } + + if (base == 0) { + if (*s == '0') { + base = 8; + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } + } else { + base = 10; + } + } + if (neg) { + /* + * Portable way to compute the positive value of "min-Llong" + * as -TYPE_MINVAL(Llong) does not work. + */ + maxval = ((ULlong)(-1 * (TYPE_MINVAL(Llong)+1))) + 1; + } else { + maxval = TYPE_MAXVAL(Llong); + } + maxmult = maxval / base; + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; + } else if (is_lower(c)) { + digit = c - 'a' + 10; + } else if (is_upper(c)) { + digit = c - 'A' + 10; + } else { + break; + } + + if (digit < base) { + if (ret > maxmult) + goto overflow; + ret *= base; + if (maxval - ret < digit) + goto overflow; + ret += digit; + } else { + break; + } + } + if (neg) { + *l = (Llong)-1 * ret; + } else { + *l = (Llong)ret; + } + return ((char *)s); +overflow: + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; + } else if (is_lower(c)) { + digit = c - 'a' + 10; + } else if (is_upper(c)) { + digit = c - 'A' + 10; + } else { + break; + } + if (digit >= base) + break; + } + if (neg) { + *l = TYPE_MINVAL(Llong); + } else { + *l = TYPE_MAXVAL(Llong); + } + seterrno(ERANGE); + return ((char *)s); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/checkerr.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/checkerr.c new file mode 100644 index 00000000000..520b9bb3bad --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/checkerr.c @@ -0,0 +1,323 @@ +/* @(#)checkerr.c 1.24 09/07/08 Copyright 2003-2009 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)checkerr.c 1.24 09/07/08 Copyright 2003-2009 J. Schilling"; +#endif +/* + * Generic error control for programs that do file i/o. + * The error control is usually used by archiving programs. + * + * The current version does not provide a stable interface. + * It does not support multi-threaded programs and it may call + * comerr() from the parser. If you use the code before there is + * an official stable and "library-compliant" interface, be careful + * and watch for changes. + * + * Copyright (c) 2003-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include +#include +#include + +typedef struct errconf { + struct errconf *ec_next; /* Next in list */ + const Uchar *ec_pat; /* File name pattern */ + int *ec_aux; /* Aux array from pattern compiler */ + int ec_alt; /* Alt return from pattern compiler */ + int ec_plen; /* String length of pattern */ + UInt32_t ec_flags; /* Error condition flags */ +} ec_t; + +LOCAL int *ec_state; /* State array for pattern compiler */ +LOCAL ec_t *ec_root; /* Root node of error config list */ +LOCAL ec_t **ec_last = &ec_root; /* Last pointer in root node list */ +LOCAL int maxplen; +LOCAL BOOL _errflag = TRUE; /* Abort on all errors */ + +EXPORT int errconfig __PR((char *name)); +LOCAL char *_endword __PR((char *p)); +LOCAL void parse_errctl __PR((char *line)); +LOCAL UInt32_t errflags __PR((char *eflag, BOOL doexit)); +LOCAL ec_t *_errptr __PR((int etype, const char *fname)); +EXPORT BOOL errhidden __PR((int etype, const char *fname)); +EXPORT BOOL errwarnonly __PR((int etype, const char *fname)); +EXPORT BOOL errabort __PR((int etype, const char *fname, BOOL doexit)); + +/* + * Read and parse error configuration file + */ +EXPORT int +errconfig(name) + char *name; +{ + char line[8192]; + FILE *f; + int omaxplen = maxplen; + + if ((f = fileopen(name, "r")) == NULL) { + if (errflags(name, FALSE) != 0) + parse_errctl(name); + else + comerr("Cannot open '%s'.\n", name); + } else { + while (fgetline(f, line, sizeof (line)) >= 0) { + parse_errctl(line); + } + fclose(f); + } + if (maxplen > omaxplen) { + ec_state = ___realloc(ec_state, (maxplen+1)*sizeof (int), + "pattern state"); + } + return (1); +} + +LOCAL char * +_endword(p) + char *p; +{ + /* + * Find end of word. + */ + for (; *p != '\0' && + *p != '\t' && + *p != ' '; + p++) { + ; + /* LINTED */ + } + return (p); +} + +LOCAL void +parse_errctl(line) + char *line; +{ + int plen; + char *pattern; + ec_t *ep; + + /* + * Find end of word. + */ + pattern = _endword(line); + + if (pattern == line || *pattern == '\0') { + comerrno(EX_BAD, + "Bad error configuration line '%s'.\n", line); + } + /* + * Find end of white space after word. + */ + for (pattern++; *pattern != '\0' && + (*pattern == '\t' || *pattern == ' '); + pattern++) { + ; + /* LINTED */ + } + ep = ___malloc(sizeof (ec_t), "errcheck node"); + ep->ec_flags = errflags(line, TRUE); + ep->ec_plen = plen = strlen(pattern); + if (ep->ec_plen > maxplen) + maxplen = ep->ec_plen; + ep->ec_pat = (const Uchar *)___savestr(pattern); + ep->ec_aux = ___malloc(plen*sizeof (int), "compiled pattern"); + if ((ep->ec_alt = patcompile((const Uchar *)pattern, + plen, ep->ec_aux)) == 0) + comerrno(EX_BAD, "Bad errctl pattern: '%s'.\n", pattern); + + ep->ec_next = NULL; + *ec_last = ep; + ec_last = &ep->ec_next; +} + +LOCAL struct eflags { + char *fname; + UInt32_t fval; +} eflags[] = { + { "STAT", E_STAT }, + { "GETACL", E_GETACL }, + { "OPEN", E_OPEN }, + { "READ", E_READ }, + { "WRITE", E_WRITE }, + { "GROW", E_GROW }, + { "SHRINK", E_SHRINK }, + { "MISSLINK", E_MISSLINK }, + { "NAMETOOLONG", E_NAMETOOLONG }, + { "FILETOOBIG", E_FILETOOBIG }, + { "SPECIALFILE", E_SPECIALFILE }, + { "READLINK", E_READLINK }, + { "GETXATTR", E_GETXATTR }, + { "CHDIR", E_CHDIR }, + + { "SETTIME", E_SETTIME }, + { "SETMODE", E_SETMODE }, + { "SECURITY", E_SECURITY }, + { "LSECURITY", E_LSECURITY }, + { "SAMEFILE", E_SAMEFILE }, + { "BADACL", E_BADACL }, + { "SETACL", E_SETACL }, + { "SETXATTR", E_SETXATTR }, + + { "ALL", E_ALL }, + + { "DIFF", E_DIFF }, + { "WARN", E_WARN }, + { "ABORT", E_ABORT }, + + { NULL, 0 } +}; + +/* + * Convert error condition string into flag word + */ +LOCAL UInt32_t +errflags(eflag, doexit) + char *eflag; + BOOL doexit; +{ + register char *p = eflag; + char *ef = _endword(eflag); + register struct eflags *ep; + register int slen; + register UInt32_t nflags = 0; + + do { + for (ep = eflags; ep->fname; ep++) { + slen = strlen(ep->fname); + if ((strncmp(ep->fname, p, slen) == 0) && + (p[slen] == '|' || p[slen] == ' ' || + p[slen] == '\0')) { + nflags |= ep->fval; + break; + } + } + if (ep->fname == NULL) { + if (doexit) + comerrno(EX_BAD, "Bad flag '%s'\n", p); + return (0); + } + p = strchr(p, '|'); + } while (p < ef && p && *p++ == '|'); + + if ((nflags & ~(UInt32_t)(E_ABORT|E_WARN)) == 0) { + if (doexit) + comerrno(EX_BAD, "Bad error condition '%s'.\n", eflag); + return (0); + } + return (nflags); +} + +LOCAL ec_t * +_errptr(etype, fname) + int etype; + const char *fname; +{ + ec_t *ep = ec_root; + char *ret; + const Uchar *name = (const Uchar *)fname; + int nlen; + + if (fname == NULL) { + errmsgno(EX_BAD, + "Implementation botch for errhidden(0x%X, NULL)\n", + etype); + errmsgno(EX_BAD, "Please report this bug!\n"); + errmsgno(EX_BAD, "Error cannot be ignored.\n"); + return ((ec_t *)NULL); + } + nlen = strlen(fname); + while (ep) { + if ((ep->ec_flags & etype) != 0) { + ret = (char *)patmatch(ep->ec_pat, ep->ec_aux, + name, 0, + nlen, ep->ec_alt, ec_state); + if (ret != NULL && *ret == '\0') + return (ep); + } + ep = ep->ec_next; + } + return ((ec_t *)NULL); +} + +/* + * Check whether error condition should be ignored for file name. + */ +EXPORT BOOL +errhidden(etype, fname) + int etype; + const char *fname; +{ + ec_t *ep; + + if ((ep = _errptr(etype, fname)) != NULL) { + if ((ep->ec_flags & (E_ABORT|E_WARN)) != 0) + return (FALSE); + return (TRUE); + } + return (FALSE); +} + +/* + * Check whether error condition should not affect exit code for file name. + */ +EXPORT BOOL +errwarnonly(etype, fname) + int etype; + const char *fname; +{ + ec_t *ep; + + if ((ep = _errptr(etype, fname)) != NULL) { + if ((ep->ec_flags & E_WARN) != 0) + return (TRUE); + return (FALSE); + } + return (FALSE); +} + +/* + * Check whether error condition should be fatal for file name. + */ +EXPORT BOOL +errabort(etype, fname, doexit) + int etype; + const char *fname; + BOOL doexit; +{ + ec_t *ep; + + if ((ep = _errptr(etype, fname)) == NULL) { + if (!_errflag) + return (FALSE); + } else if ((ep->ec_flags & E_ABORT) == 0) + return (FALSE); + + if (doexit) { + errmsgno(EX_BAD, "Error is considered fatal, aborting.\n"); +#ifdef CALL_OTHER_FUNCTION + if (other_func != NULL) + (*other_func)(); + else +#endif + comexit(-3); + } + return (TRUE); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/comerr.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/comerr.c new file mode 100644 index 00000000000..cb72f0fc7ff --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/comerr.c @@ -0,0 +1,373 @@ +/* @(#)comerr.c 1.43 15/07/01 Copyright 1985-1989, 1995-2015 J. Schilling */ +/* + * Routines for printing command errors + * + * Copyright (c) 1985-1989, 1995-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include /* include try to get size_t */ +#include /* Try again for size_t */ +#include /* Try again for size_t */ +#include +#include +#include +#include +#include + +EXPORT int on_comerr __PR((void (*fun)(int, void *), void *arg)); +EXPORT void comerr __PR((const char *, ...)); +EXPORT void xcomerr __PR((int, const char *, ...)); +EXPORT void comerrno __PR((int, const char *, ...)); +EXPORT void xcomerrno __PR((int, int, const char *, ...)); +EXPORT int errmsg __PR((const char *, ...)); +EXPORT int errmsgno __PR((int, const char *, ...)); +EXPORT int _comerr __PR((FILE *, int, int, int, + const char *, va_list)); +LOCAL int _ex_clash __PR((int)); +EXPORT void comexit __PR((int)); +EXPORT char *errmsgstr __PR((int)); + +typedef struct ex { + struct ex *next; + void (*func) __PR((int, void *)); + void *arg; +} ex_t; + +LOCAL ex_t *exfuncs; + +/* + * Set list of callback functions to call with *comerr() and comexit(). + * The function set up last with on_comerr() is called first on exit; + * in other words: call order is the reverse order of registration. + */ +EXPORT int +on_comerr(func, arg) + void (*func) __PR((int, void *)); + void *arg; +{ + ex_t *fp; + + fp = malloc(sizeof (*fp)); + if (fp == NULL) + return (-1); + + fp->func = func; + fp->arg = arg; + fp->next = exfuncs; + exfuncs = fp; + return (0); +} + +/* + * Fetch current errno, print a related message and exit(errno). + */ +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT void +comerr(const char *msg, ...) +#else +EXPORT void +comerr(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(stderr, COMERR_EXIT, 0, geterrno(), msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* + * Fetch current errno, print a related message and exit(exc). + */ +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT void +xcomerr(int exc, const char *msg, ...) +#else +EXPORT void +xcomerr(exc, msg, va_alist) + int exc; + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(stderr, COMERR_EXCODE, exc, geterrno(), msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* + * Print a message related to err and exit(err). + */ +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT void +comerrno(int err, const char *msg, ...) +#else +EXPORT void +comerrno(err, msg, va_alist) + int err; + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(stderr, COMERR_EXIT, 0, err, msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* + * Print a message related to err and exit(exc). + */ +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT void +xcomerrno(int exc, int err, const char *msg, ...) +#else +EXPORT void +xcomerrno(exc, err, msg, va_alist) + int exc; + int err; + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(stderr, COMERR_EXCODE, exc, err, msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* + * Fetch current errno, print a related message and return(errno). + */ +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +errmsg(const char *msg, ...) +#else +EXPORT int +errmsg(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + ret = _comerr(stderr, COMERR_RETURN, 0, geterrno(), msg, args); + va_end(args); + return (ret); +} + +/* + * Print a message related to err and return(err). + */ +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +errmsgno(int err, const char *msg, ...) +#else +EXPORT int +errmsgno(err, msg, va_alist) + int err; + char *msg; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + ret = _comerr(stderr, COMERR_RETURN, 0, err, msg, args); + va_end(args); + return (ret); +} + +#if defined(__BEOS__) || defined(__HAIKU__) + /* + * On BeOS errno is a big negative number (0x80000000 + small number). + * We assume that small negative numbers are safe to be used as special + * values that prevent printing the errno text. + * + * We tried to use #if EIO < 0 but this does not work because EIO is + * defined to a enum. ENODEV may work as ENODEV is defined to a number + * directly. + */ +#define silent_error(e) ((e) < 0 && (e) >= -1024) +#else + /* + * On UNIX errno is a small non-negative number, so we assume that + * negative values cannot be a valid errno and don't print the error + * string in this case. However the value may still be used as exit() + * code if 'exflg' is set. + */ +#define silent_error(e) ((e) < 0) +#endif +EXPORT int +_comerr(f, exflg, exc, err, msg, args) + FILE *f; /* FILE * to print to */ + int exflg; /* COMERR_RETURN, COMERR_EXIT, COMERR_EXCODE */ + int exc; /* Use for exit() if exflg & COMERR_EXCODE */ + int err; /* Errno for text, exit(err) if !COMERR_EXIT*/ + const char *msg; /* printf() format */ + va_list args; /* printf() args for format */ +{ + char errbuf[20]; + char *errnam; + char *prognam = get_progname(); + + if (silent_error(err)) { + js_fprintf(f, "%s: %r", prognam, msg, args); + } else { + errnam = errmsgstr(err); + if (errnam == NULL) { + (void) js_snprintf(errbuf, sizeof (errbuf), + "Error %d", err); + errnam = errbuf; + } + js_fprintf(f, "%s: %s. %r", prognam, errnam, msg, args); + } + if (exflg) { + if (exflg & COMERR_EXCODE) + err = exc; + else + err = _ex_clash(err); + comexit(err); + /* NOTREACHED */ + } + return (err); +} + +LOCAL int +_ex_clash(exc) + int exc; +{ + int exmod = exc % 256; + + /* + * On a recent POSIX System that supports waitid(), siginfo.si_status + * holds the exit(2) value as an int. So if waitid() is used to wait + * for the process, we do not have problems from folded exit codes. + * All other wait*() functions fold the exit code by masking it + * with 0377. + * + * Exit codes used with comerr*()/comexit() are frequently errno values + * that have been in the range 0..31 with UNIX.V5 in the mid 1970s and + * that now are in the range 0..151 on Solaris. These values do not + * cause problems from folding to 8 bits, but "sysexits.h" contains + * definitions in the range 64..79 that cause (even unfolded) clashes + * with errno values. + * + * To avoid clashes with errno values, "schily/standard.h" defines + * EX_BAD (-1) as default error exit code and + * EX_CLASH (-64) as marker for clashes. + * Exit codes in the range -2..-63 (254..193 seen as unsigned two's + * complement) are available as software specific exit codes. + * We map all other negative exit codes to EX_CLASH if they would fold + * to -2..-63. + */ + if (exc != exmod && exmod <= 0 && exmod >= EX_CLASH) + exc = EX_CLASH; + return (exc); +} + +/* + * Do a program exit() with previously calling functions registered via + * on_comerr(). + */ +EXPORT void +comexit(err) + int err; +{ + while (exfuncs) { + (*exfuncs->func)(err, exfuncs->arg); + exfuncs = exfuncs->next; + } + exit(err); + /* NOTREACHED */ +} + +/* + * Wrapper around the strange POSIX strerror(). + * If there is a problem with retrieving the correct error text, + * return NULL. + */ +EXPORT char * +errmsgstr(err) + int err; +{ +#ifdef HAVE_STRERROR + /* + * POSIX compliance may look strange... + */ + int errsav = geterrno(); + char *ret; + + seterrno(0); + ret = strerror(err); + err = geterrno(); + seterrno(errsav); + + if (ret == NULL || err) + return (NULL); + return (ret); +#else + if (err < 0 || err >= sys_nerr) { + return (NULL); + } else { + return (sys_errlist[err]); + } +#endif +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/dirent.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/dirent.c new file mode 100644 index 00000000000..aa358304513 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/dirent.c @@ -0,0 +1,157 @@ +/* @(#)dirent.c 1.3 12/03/20 Copyright 2011 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)dirent.c 1.3 12/03/20 Copyright 2011 J. Schilling"; +#endif +/* + * Copyright (c) 2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#ifdef NEED_READDIR + +#if defined(__MINGW32__) || defined(_MSC_VER) + +#include +#include +#include + +EXPORT DIR *opendir __PR((const char *)); +EXPORT int closedir __PR((DIR *)); +EXPORT struct dirent *readdir __PR((DIR *)); + +EXPORT DIR * +opendir(dname) + const char *dname; +{ + char path[PATH_MAX]; + size_t len; + uint32_t attr; + DIR *dp; + + if (dname == NULL) { + seterrno(EFAULT); + return ((DIR *)0); + } + len = strlen(dname); + if (len > PATH_MAX) { + seterrno(ENAMETOOLONG); + return ((DIR *)0); + } + if (len == 0) { + seterrno(ENOENT); + return ((DIR *)0); + } + + attr = GetFileAttributes(dname); + if (attr == INVALID_FILE_ATTRIBUTES || + (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { + seterrno(ENOTDIR); + return ((DIR *)0); + } + path[0] = '\0'; + _fullpath(path, dname, PATH_MAX); + len = strlen(path); + if (len == 0) { + seterrno(ENOENT); + return ((DIR *)0); + } + + dp = malloc(sizeof (*dp) + len + 2); /* Add 2 for "/ *" */ + if (dp == NULL) { + seterrno(ENOMEM); + return ((DIR *)0); + } + strcpy(dp->dd_dirname, path); + if (dp->dd_dirname[len-1] != '/' && + dp->dd_dirname[len-1] != '\\') { + dp->dd_dirname[len] = '\\'; + len++; + } + dp->dd_dirname[len] = '*'; + dp->dd_handle = -1; + dp->dd_state = 0; + + dp->dd_dir.d_ino = 0; + dp->dd_dir.d_reclen = 0; + dp->dd_dir.d_namlen = 0; + zerobytes(dp->dd_dir.d_name, sizeof (dp->dd_dir.d_name)); + + return (dp); +} + +EXPORT int +closedir(dp) + DIR *dp; +{ + int ret = 0; + + if (dp == NULL) { + seterrno(EFAULT); + return (-1); + } + if (dp->dd_handle != -1) { + ret = _findclose(dp->dd_handle); + } + free(dp); + + return (ret); +} + +EXPORT struct dirent * +readdir(dp) + DIR *dp; +{ + if (dp == NULL) { + seterrno(EFAULT); + return ((struct dirent *)0); + } + if (dp->dd_state == (char)-1) { + return ((struct dirent *)0); + } else if (dp->dd_state == (char)0) { + dp->dd_handle = _findfirst(dp->dd_dirname, &(dp->dd_data)); + if (dp->dd_handle != -1) + dp->dd_state = 1; + else + dp->dd_state = -1; + } else { + if (_findnext(dp->dd_handle, &(dp->dd_data))) { + uint32_t werrno = GetLastError(); + + if (werrno == ERROR_NO_MORE_FILES) + seterrno(0); + _findclose(dp->dd_handle); + dp->dd_handle = -1; + dp->dd_state = -1; + } else { + dp->dd_state = 1; /* state++ to support seekdir */ + } + } + if (dp->dd_state > 0) { + strlcpy(dp->dd_dir.d_name, dp->dd_data.name, + sizeof (dp->dd_dir.d_name)); + + return (&dp->dd_dir); + } + return ((struct dirent *)0); +} + +#endif /* defined(__MINGW32__) || defined(_MSC_VER) */ + +#endif /* NEED_READDIR */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/eaccess.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/eaccess.c new file mode 100644 index 00000000000..e7c4c8f5e15 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/eaccess.c @@ -0,0 +1,56 @@ +/* @(#)eaccess.c 1.6 14/05/15 Copyright 2004-2014 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)eaccess.c 1.6 14/05/15 Copyright 2004-2014 J. Schilling"; +#endif +/* + * Implement the best possible emulation for eaccess() + * + * Copyright 2004-2014 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#ifndef HAVE_EACCESS +EXPORT int eaccess __PR((const char *name, int mode)); + +EXPORT int +eaccess(name, mode) + const char *name; + int mode; +{ +#ifdef HAVE_EUIDACCESS + return (euidaccess(name, mode)); +#else +#ifdef HAVE_ACCESS_E_OK + return (access(name, E_OK|mode)); +#else + if (getuid() == geteuid() && getgid() == getegid()) + return (access(name, mode)); +#ifdef EOPNOTSUPP + seterrno(EOPNOTSUPP); +#else + seterrno(EINVAL); +#endif + return (-1); +#endif +#endif +} +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/error.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/error.c new file mode 100644 index 00000000000..f608d53d9fa --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/error.c @@ -0,0 +1,88 @@ +/* @(#)error.c 1.18 15/08/01 Copyright 1985, 1989, 1995-2015 J. Schilling */ +/* + * fprintf() on standard error stdio stream + * + * Copyright (c) 1985, 1989, 1995-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include + +#undef error + +#ifndef NO_WEAK_SYMBOLS +/* + * The Cygwin compile environment incorrectly implements #pragma weak. + * The weak symbols are only defined as local symbols making it impossible + * to use them from outside the scope of this source file. + * A platform that allows linking with global symbols has HAVE_LINK_WEAK + * defined. + */ +#if defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK) +#pragma weak error = js_error +#else +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +error(const char *fmt, ...) +#else +EXPORT int +error(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = js_fprintf(stderr, "%r", fmt, args); + va_end(args); + return (ret); +} +#endif +#endif /* NO_WEAK_SYMBOLS */ + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +js_error(const char *fmt, ...) +#else +EXPORT int +js_error(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = js_fprintf(stderr, "%r", fmt, args); + va_end(args); + return (ret); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/fconv.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/fconv.c new file mode 100644 index 00000000000..6e1fee8d743 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/fconv.c @@ -0,0 +1,416 @@ +/* @(#)fconv.c 1.45 10/11/06 Copyright 1985, 1995-2010 J. Schilling */ +/* + * Convert floating point numbers to strings for format.c + * Should rather use the MT-safe routines [efg]convert() + * + * Copyright (c) 1985, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include /* <- may define NO_FLOATINGPOINT */ +#ifndef NO_FLOATINGPOINT + +#ifndef __DO_LONG_DOUBLE__ +#include +#include +#include +#include +#include /* The default place for isinf()/isnan() */ +#include + +#if !defined(HAVE_STDLIB_H) || defined(HAVE_DTOA) +extern char *ecvt __PR((double, int, int *, int *)); +extern char *fcvt __PR((double, int, int *, int *)); +#endif + +#if defined(HAVE_ISNAN) && defined(HAVE_ISINF) +/* + * *BSD alike libc + */ +#define FOUND_ISNAN +#define FOUND_ISINF +#define FOUND_ISXX +#endif + +#if defined(HAVE_C99_ISNAN) && defined(HAVE_C99_ISINF) +#ifndef FOUND_ISXX +#define FOUND_ISXX +#endif +#define FOUND_C99_ISNAN +#define FOUND_C99_ISINF +#define FOUND_C99_ISXX +#endif + +#if defined(HAVE_FP_H) && !defined(FOUND_ISXX) +/* + * WAS: + * #if defined(__osf__) || defined(_IBMR2) || defined(_AIX) + */ +/* + * Moved before HAVE_IEEEFP_H for True64 due to a hint + * from Bert De Knuydt + * + * True64 has both fp.h & ieeefp.h but the functions + * isnand() & finite() seem to be erreneously not implemented + * as a macro and the function lives in libm. + * Let's hope that we will not get problems with the new order. + */ +#include +#if !defined(isnan) && defined(IS_NAN) +#define isnan IS_NAN +#define FOUND_ISNAN +#endif +#if !defined(isinf) && defined(FINITE) +#define isinf !FINITE +#define FOUND_ISINF +#endif +#if defined(FOUND_ISNAN) && defined(FOUND_ISINF) +#define FOUND_ISXX +#endif +#endif + +#if defined(HAVE_IEEEFP_H) && !defined(FOUND_ISXX) && \ + !defined(FOUND_C99_ISXX) +/* + * SVR4 + */ +#include +#ifdef HAVE_ISNAND +#ifndef isnan +#define isnan isnand +#define FOUND_ISNAN +#endif +#endif +#ifdef HAVE_FINITE +#ifndef isinf +#define isinf !finite +#define FOUND_ISINF +#endif +#endif +#if defined(FOUND_ISNAN) && defined(FOUND_ISINF) +#define FOUND_ISXX +#endif +#endif + +/* + * WAS: + * #if defined(__hpux) || defined(VMS) || defined(_SCO_DS) || defined(__QNX__) + */ +#ifdef __nneded__ +#if defined(__hpux) || defined(__QNX__) || defined(__DJGPP__) +#ifndef FOUND_C99_ISXX +#undef isnan +#undef isinf +#endif +#endif +#endif /* __needed__ */ + +/* + * As we no longer check for defined(isnan)/defined(isinf), the next block + * should also handle the problems with DJGPP, HP-UX, QNX and VMS. + */ +#if !defined(FOUND_ISNAN) && !defined(HAVE_C99_ISNAN) +#undef isnan +#define isnan(val) (0) +#define NO_ISNAN +#endif +#if !defined(FOUND_ISINF) && !defined(HAVE_C99_ISINF) +#undef isinf +#define isinf(val) (0) +#define NO_ISINF +#endif + +#if defined(NO_ISNAN) || defined(NO_ISINF) +#include /* For values.h */ +#if (_IEEE - 0) > 0 /* We know that there is IEEE FP */ +/* + * Note that older HP-UX versions have different #defines for MAXINT in + * values.h and sys/param.h + */ +#include +#include + +#ifdef WORDS_BIGENDIAN +#define fpw_high(x) ((UInt32_t *)&x)[0] +#define fpw_low(x) ((UInt32_t *)&x)[1] +#else +#define fpw_high(x) ((UInt32_t *)&x)[1] +#define fpw_low(x) ((UInt32_t *)&x)[0] +#endif +#define FP_EXP 0x7FF00000 +#define fp_exp(x) (fpw_high(x) & FP_EXP) +#define fp_exc(x) (fp_exp(x) == FP_EXP) + +#ifdef NO_ISNAN +#undef isnan +#define isnan(val) (fp_exc(val) && \ + (fpw_low(val) != 0 || (fpw_high(val) & 0xFFFFF) != 0)) +#endif +#ifdef NO_ISINF +#undef isinf +#define isinf(val) (fp_exc(val) && \ + fpw_low(val) == 0 && (fpw_high(val) & 0xFFFFF) == 0) +#endif +#endif /* We know that there is IEEE FP */ +#endif /* defined(NO_ISNAN) || defined(NO_ISINF) */ + + +#if !defined(HAVE_ECVT) || !defined(HAVE_FCVT) || !defined(HAVE_GCVT) + +#ifdef NO_USER_XCVT + /* + * We cannot define our own ecvt()/fcvt()/gcvt() so we need to use + * local names instead. + */ +#ifndef HAVE_ECVT +#define ecvt js_ecvt +#endif +#ifndef HAVE_FCVT +#define fcvt js_fcvt +#endif +#ifndef HAVE_GCVT +#define gcvt js_gcvt +#endif +#endif + +#include "cvt.c" +#endif + +static char _js_nan[] = "(NaN)"; +static char _js_inf[] = "(Infinity)"; + +static int _ferr __PR((char *, double)); +#endif /* __DO_LONG_DOUBLE__ */ + +#ifdef __DO_LONG_DOUBLE__ +#undef MDOUBLE +#define MDOUBLE long double +#else +#undef MDOUBLE +#define MDOUBLE double +#endif + +#ifdef abs +#undef abs +#endif +#define abs(i) ((i) < 0 ? -(i) : (i)) + +EXPORT int +ftoes(s, val, fieldwidth, ndigits) + register char *s; + MDOUBLE val; + register int fieldwidth; + register int ndigits; +{ + register char *b; + register char *rs; + register int len; + register int rdecpt; + int decpt; + int sign; + +#ifndef __DO_LONG_DOUBLE__ + if ((len = _ferr(s, val)) > 0) + return (len); +#endif + rs = s; +#ifdef V7_FLOATSTYLE + b = ecvt(val, ndigits, &decpt, &sign); + rdecpt = decpt; +#else + b = ecvt(val, ndigits+1, &decpt, &sign); + rdecpt = decpt-1; +#endif +#ifdef __DO_LONG_DOUBLE__ + len = *b; + if (len < '0' || len > '9') { /* Inf/NaN */ + strcpy(s, b); + return (strlen(b)); + } +#endif + len = ndigits + 6; /* Punkt e +/- nnn */ + if (sign) + len++; + if (fieldwidth > len) + while (fieldwidth-- > len) + *rs++ = ' '; + if (sign) + *rs++ = '-'; +#ifndef V7_FLOATSTYLE + if (*b) + *rs++ = *b++; +#endif +#if defined(HAVE_LOCALECONV) && defined(USE_LOCALE) + *rs++ = *(localeconv()->decimal_point); +#else + *rs++ = '.'; +#endif + while (*b && ndigits-- > 0) + *rs++ = *b++; + *rs++ = 'e'; + *rs++ = rdecpt >= 0 ? '+' : '-'; + rdecpt = abs(rdecpt); +#ifdef __DO_LONG_DOUBLE__ + if (rdecpt >= 1000) { /* Max-Exp is > 4000 */ + *rs++ = rdecpt / 1000 + '0'; + rdecpt %= 1000; + } +#endif +#ifndef V7_FLOATSTYLE + if (rdecpt >= 100) +#endif + { + *rs++ = rdecpt / 100 + '0'; + rdecpt %= 100; + } + *rs++ = rdecpt / 10 + '0'; + *rs++ = rdecpt % 10 + '0'; + *rs = '\0'; + return (rs - s); +} + +/* + * fcvt() from Cygwin32 is buggy. + */ +#if !defined(HAVE_FCVT) && defined(HAVE_ECVT) +#define USE_ECVT +#endif + +EXPORT int +ftofs(s, val, fieldwidth, ndigits) + register char *s; + MDOUBLE val; + register int fieldwidth; + register int ndigits; +{ + register char *b; + register char *rs; + register int len; + register int rdecpt; + int decpt; + int sign; + +#ifndef __DO_LONG_DOUBLE__ + if ((len = _ferr(s, val)) > 0) + return (len); +#endif + rs = s; +#ifdef USE_ECVT + /* + * Needed on systems with broken fcvt() implementation + * (e.g. Cygwin32) + */ + b = ecvt(val, ndigits, &decpt, &sign); + /* + * The next call is needed to force higher precision. + */ + if (decpt > 0) + b = ecvt(val, ndigits+decpt, &decpt, &sign); +#else + b = fcvt(val, ndigits, &decpt, &sign); +#endif +#ifdef __DO_LONG_DOUBLE__ + len = *b; + if (len < '0' || len > '9') { /* Inf/NaN */ + strcpy(s, b); + return (strlen(b)); + } +#endif + rdecpt = decpt; + len = rdecpt + ndigits + 1; + if (rdecpt < 0) + len -= rdecpt; + if (sign) + len++; + if (fieldwidth > len) + while (fieldwidth-- > len) + *rs++ = ' '; + if (sign) + *rs++ = '-'; + if (rdecpt > 0) { + len = rdecpt; + while (*b && len-- > 0) + *rs++ = *b++; +#ifdef USE_ECVT + while (len-- > 0) + *rs++ = '0'; +#endif + } +#ifndef V7_FLOATSTYLE + else { + *rs++ = '0'; + } +#endif +#if defined(HAVE_LOCALECONV) && defined(USE_LOCALE) + *rs++ = *(localeconv()->decimal_point); +#else + *rs++ = '.'; +#endif + if (rdecpt < 0) { + len = rdecpt; + while (len++ < 0 && ndigits-- > 0) + *rs++ = '0'; + } + while (*b && ndigits-- > 0) + *rs++ = *b++; +#ifdef USE_ECVT + while (ndigits-- > 0) + *rs++ = '0'; +#endif + *rs = '\0'; + return (rs - s); +} + +#ifndef __DO_LONG_DOUBLE__ + +#ifdef HAVE_LONGDOUBLE +#ifdef HAVE__LDECVT +#define qecvt(ld, n, dp, sp) _ldecvt(*(long_double *)&ld, n, dp, sp) +#endif +#ifdef HAVE__LDFCVT +#define qfcvt(ld, n, dp, sp) _ldfcvt(*(long_double *)&ld, n, dp, sp) +#endif + +#if (defined(HAVE_QECVT) || defined(HAVE__LDECVT)) && \ + (defined(HAVE_QFCVT) || defined(HAVE__LDFCVT)) +#define __DO_LONG_DOUBLE__ +#define ftoes qftoes +#define ftofs qftofs +#define ecvt qecvt +#define fcvt qfcvt +#include "fconv.c" +#undef __DO_LONG_DOUBLE__ +#endif +#endif /* HAVE_LONGDOUBLE */ + +LOCAL int +_ferr(s, val) + char *s; + double val; +{ + if (isnan(val)) { + strcpy(s, _js_nan); + return (sizeof (_js_nan) - 1); + } + + /* + * Check first for NaN because finite() will return 1 on Nan too. + */ + if (isinf(val)) { + strcpy(s, _js_inf); + return (sizeof (_js_inf) - 1); + } + return (0); +} +#endif /* __DO_LONG_DOUBLE__ */ +#endif /* NO_FLOATINGPOINT */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/fillbytes.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/fillbytes.c new file mode 100644 index 00000000000..ade1f4dfaec --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/fillbytes.c @@ -0,0 +1,99 @@ +/* @(#)fillbytes.c 1.18 10/08/21 Copyright 1987, 1995-2010 J. Schilling */ +/* + * fill memory with data + * + * Copyright (c) 1987, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#define DO8(a) a; a; a; a; a; a; a; a; + +#define cval ((char)lval) + +/* + * fillbytes(to, cnt, val) is the same as memset(to, val, cnt) + */ +#ifdef PROTOTYPES +EXPORT char * +fillbytes(void *tov, ssize_t cnt, char val) +#else +EXPORT char * +fillbytes(tov, cnt, val) + void *tov; + ssize_t cnt; + char val; +#endif +{ + register char *to = (char *)tov; + register ssize_t n; + register long lval; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (to); + + lval = val & 0xFF; + + /* + * Assign byte-wise until properly aligned for a long pointer. + */ + while (--n >= 0 && !laligned(to)) { + *to++ = cval; + } + n++; + + if (n >= (ssize_t)(8 * sizeof (long))) { + register ssize_t rem = n % (8 * sizeof (long)); + + lval |= (lval<<8); + lval |= (lval<<16); +#if SIZE_LONG > SIZE_INT + lval |= (lval<<32); +#endif + + n /= (8 * sizeof (long)); + { + register long *tol = (long *)to; + + do { + DO8 (*tol++ = lval); + } while (--n > 0); + + to = (char *)tol; + } + n = rem; + + if (n >= 8) { + n -= 8; + do { + DO8 (*to++ = cval); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + *to++ = cval; + } while (--n > 0); + return (to); + } + if (n > 0) do { + *to++ = cval; + } while (--n > 0); + return (to); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/fnmatch.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/fnmatch.c new file mode 100644 index 00000000000..53a44ab2797 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/fnmatch.c @@ -0,0 +1,341 @@ +/* @(#)fnmatch.c 8.20 15/07/06 2005-2015 J. Schilling from 8.2 (Berkeley) */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)fnmatch.c 8.20 15/07/06 2005-2015 J. Schilling from 8.2 (Berkeley)"; +#endif +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static UConst char sccsid[] = "@(#)fnmatch.c 8.20 (Berkeley) 07/06/15"; +#endif /* LIBC_SCCS and not lint */ +/* "FBSD src/lib/libc/gen/fnmatch.c,v 1.19 2010/04/16 22:29:24 jilles Exp $" */ + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +/* + * Some notes on multibyte character support: + * 1. Patterns with illegal byte sequences match nothing. + * 2. Illegal byte sequences in the "string" argument are handled by treating + * them as single-byte characters with a value of the first byte of the + * sequence cast to wchar_t. + * 3. Multibyte conversion state objects (mbstate_t) are passed around and + * used for most, but not all, conversions. Further work will be required + * to support state-dependent encodings. + */ + +#include +#include +#include +#include +#include +#include +#include /* Define missing prototypes */ + +#define EOS '\0' + +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) + +static int rangematch __PR((const char *, wchar_t, int, char **, mbstate_t *)); +static int fnmatch1 __PR((const char *, const char *, const char *, int, + mbstate_t, mbstate_t)); + +#ifndef HAVE_FNMATCH +#undef fnmatch + +/* + * The Cygwin compile environment incorrectly implements #pragma weak. + * The weak symbols are only defined as local symbols making it impossible + * to use them from outside the scope of this source file. + * A platform that allows linking with global symbols has HAVE_LINK_WEAK + * defined. + */ +#if defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK) +#pragma weak fnmatch = js_fnmatch +#else +int +fnmatch(pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + return (js_fnmatch(pattern, string, flags)); +} +#endif +#endif + +int +js_fnmatch(pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + /* + * SunPro C gives a warning if we do not initialize an object: + * static const mbstate_t initial; + * GCC gives a warning if we try to initialize it. + * As the POSIX standard forbids mbstate_t from being an array, + * we do not need "const", the var is always copied when used as + * a parapemeter for fnmatch1(); + */ + static mbstate_t initial; + + return (fnmatch1(pattern, string, string, flags, initial, initial)); +} + +static int +fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs) + const char *pattern; + const char *string; + const char *stringstart; + int flags; + mbstate_t patmbs; + mbstate_t strmbs; +{ + char *newp; + char c; + wchar_t pc, sc; + size_t pclen, sclen; + + for (;;) { + pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (FNM_NOMATCH); + pattern += pclen; + sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); + if (sclen == (size_t)-1 || sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof (strmbs)); + } + switch (pc) { + case EOS: + if ((flags & FNM_LEADING_DIR) && sc == '/') + return (0); + return (sc == EOS ? 0 : FNM_NOMATCH); + case '?': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + string += sclen; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) { + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + } else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while (sc != EOS) { + if (!fnmatch1(pattern, string, stringstart, + flags, patmbs, strmbs)) + return (0); + sclen = mbrtowc(&sc, string, MB_LEN_MAX, + &strmbs); + if (sclen == (size_t)-1 || + sclen == (size_t)-2) { + sc = (unsigned char)*string; + sclen = 1; + memset(&strmbs, 0, sizeof (strmbs)); + } + if (sc == '/' && (flags & FNM_PATHNAME)) + break; + string += sclen; + } + return (FNM_NOMATCH); + case '[': + if (sc == EOS) + return (FNM_NOMATCH); + if (sc == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (sc == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + switch (rangematch(pattern, sc, flags, &newp, + &patmbs)) { + case RANGE_ERROR: + goto norm; + case RANGE_MATCH: + pattern = newp; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } + string += sclen; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, + &patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (FNM_NOMATCH); + if (pclen == 0) + pc = '\\'; + pattern += pclen; + } + /* FALLTHROUGH */ + default: + norm: + if (pc == sc) + ; + else if ((flags & FNM_CASEFOLD) && + (towlower(pc) == towlower(sc))) + ; + else + return (FNM_NOMATCH); + string += sclen; + break; + } + } + /* NOTREACHED */ +} + +#ifdef PROTOTYPES +static int +rangematch(const char *pattern, wchar_t test, int flags, char **newp, mbstate_t *patmbs) +#else +static int +rangematch(pattern, test, flags, newp, patmbs) + const char *pattern; + wchar_t test; + int flags; + char **newp; + mbstate_t *patmbs; +#endif +{ + int negate, ok; + wchar_t c, c2; + size_t pclen; + const char *origpat; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ((negate = (*pattern == '!' || *pattern == '^'))) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = towlower(test); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + origpat = pattern; + for (;;) { + if (*pattern == ']' && pattern > origpat) { + pattern++; + break; + } else if (*pattern == '\0') { + return (RANGE_ERROR); + } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { + return (RANGE_NOMATCH); + } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) + pattern++; + pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_NOMATCH); + pattern += pclen; + + if (flags & FNM_CASEFOLD) + c = towlower(c); + + if (*pattern == '-' && *(pattern + 1) != EOS && + *(pattern + 1) != ']') { + if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) + if (*pattern != EOS) + pattern++; + pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); + if (pclen == (size_t)-1 || pclen == (size_t)-2) + return (RANGE_NOMATCH); + pattern += pclen; + if (c2 == EOS) + return (RANGE_ERROR); + + if (flags & FNM_CASEFOLD) + c2 = towlower(c2); + +#ifdef XXX_COLLATE + if (__collate_load_error ? + c <= test && test <= c2 : + __collate_range_cmp(c, test) <= 0 && + __collate_range_cmp(test, c2) <= 0) + ok = 1; +#else + if (c <= test && test <= c2) + ok = 1; +#endif + } else if (c == test) + ok = 1; + } + + *newp = (char *)pattern; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/format.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/format.c new file mode 100644 index 00000000000..ca98ba0d381 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/format.c @@ -0,0 +1,1706 @@ +/* @(#)format.c 1.61 16/08/10 Copyright 1985-2016 J. Schilling */ +/* + * format + * common code for printf fprintf & sprintf + * + * allows recursive printf with "%r", used in: + * error, comerr, comerrno, errmsg, errmsgno and the like + * + * Copyright (c) 1985-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#if !defined(HAVE_STDLIB_H) || !defined(HAVE_GCVT) +extern char *gcvt __PR((double, int, char *)); +#endif +#include +#include +#include + +/* + * As Llong is currently a 'best effort' long long, we usually need to + * include long long print formats. + * This may go away, if we implement maxint_t formats. + */ +#ifndef USE_LONGLONG +#define USE_LONGLONG +#endif + +#ifdef NO_LONGLONG +#undef USE_LONGLONG +#endif + +#ifndef USE_NL_ARGS +#define USE_NL_ARGS +#endif + +#ifdef NO_NL_ARGS +#undef USE_NL_ARGS +#endif + +/* + * Avoid to keep copies of the variable arg list in case that + * format() was compiled without including NL support for + * argument reordering. + */ +#ifdef USE_NL_ARGS +#define args fargs.ap /* Use working copy */ +#else +#define args oargs /* Directly use format() arg */ +#endif + +/* + * We may need to decide whether we should check whether all + * flags occur according to the standard which is either directly past: + * "%" or directly past "%n$". + * + * This however may make printf() slower in some cases. + */ +#ifdef USE_CHECKFLAG +#define CHECKFLAG() if (fa.flags & GOTSTAR) goto flagerror +#else +#define CHECKFLAG() +#endif + +#ifdef NO_USER_XCVT + /* + * We cannot define our own gcvt() so we need to use a + * local name instead. + */ +#ifndef HAVE_GCVT +# define gcvt js_gcvt +EXPORT char *gcvt __PR((double value, int ndigit, char *buf)); +#endif +#endif + +/* + * Some CPU's (e.g. PDP-11) cannot do logical shifts. + * They use rotate instead. Masking the low bits before, + * makes rotate work too. + */ +#define allmask(t) ((unsigned t)~((unsigned t)0)) +#define lowmask(t, x) ((unsigned t)~((unsigned t)((1 << (x))-1))) +#define rshiftmask(t, s)((allmask(t) & lowmask(t, s)) >> (s)) + +#define CHARMASK makemask(char) +#define SHORTMASK makemask(short) +#define INTMASK makemask(int) +#define LONGMASK makemask(long) + +#ifdef DIVLBYS +extern long divlbys(); +extern long modlbys(); +#else +#define divlbys(val, base) ((val)/(base)) +#define modlbys(val, base) ((val)%(base)) +#endif + +/* + * We use macros here to avoid the need to link to the international + * character routines. + * We don't need internationalization for our purpose. + */ +#define is_dig(c) (((c) >= '0') && ((c) <= '9')) +#define is_cap(c) ((c) >= 'A' && (c) <= 'Z') +#define to_cap(c) (is_cap(c) ? c : c - 'a' + 'A') +#define cap_ty(c) (is_cap(c) ? 'L' : 'I') + +#ifdef HAVE_LONGLONG +typedef union { + Ullong ll; + Ulong l[2]; + char c[8]; +} quad_u; +#endif + +typedef struct f_args { +#ifdef FORMAT_BUFFER +#define BFSIZ 256 + char *ptr; /* Current ptr in buf */ + int cnt; /* Free char count in buf */ +#else + void (*outf)__PR((char, long)); /* Func from format(fun, arg) */ +#endif + long farg; /* Arg from format (fun, arg) */ + int minusflag; /* Fieldwidth is negative */ + int flags; /* General flags (+-#) */ + int fldwidth; /* Field width as in %3d */ + int signific; /* Significant chars as in %.4d */ + int lzero; /* Left '0' pad flag */ + char *buf; /* Out print buffer */ + char *bufp; /* Write ptr into buffer */ + char fillc; /* Left fill char (' ' or '0') */ + char *prefix; /* Prefix to print before buf */ + int prefixlen; /* Len of prefix ('+','-','0x') */ +#ifdef FORMAT_BUFFER + /* rarely used members last: */ + char iobuf[BFSIZ]; /* buffer for stdio */ + FILE *fp; /* FILE * for fprformat() */ + int err; /* FILE * I/O error */ +#endif +} f_args; + +#define MINUSFLG 1 /* '-' flag */ +#define PLUSFLG 2 /* '+' flag */ +#define SPACEFLG 4 /* ' ' flag */ +#define HASHFLG 8 /* '#' flag */ +#define APOFLG 16 /* '\'' flag */ +#define GOTDOT 32 /* '.' found */ +#define GOTSTAR 64 /* '*' found */ + +#define FMT_ARGMAX 30 /* Number of fast args */ + +LOCAL void prnum __PR((Ulong, unsigned, f_args *)); +LOCAL void prdnum __PR((Ulong, f_args *)); +LOCAL void pronum __PR((Ulong, f_args *)); +LOCAL void prxnum __PR((Ulong, f_args *)); +LOCAL void prXnum __PR((Ulong, f_args *)); +#ifdef USE_LONGLONG +LOCAL void prlnum __PR((Ullong, unsigned, f_args *)); +LOCAL void prldnum __PR((Ullong, f_args *)); +LOCAL void prlonum __PR((Ullong, f_args *)); +LOCAL void prlxnum __PR((Ullong, f_args *)); +LOCAL void prlXnum __PR((Ullong, f_args *)); +#endif +LOCAL int prbuf __PR((const char *, f_args *)); +LOCAL int prc __PR((char, f_args *)); +LOCAL int prstring __PR((const char *, f_args *)); +#ifdef DEBUG +LOCAL void dbg_print __PR((char *fmt, int a, int b, int c, int d, int e, int f, int g, int h, int i)); +#endif + +#ifdef USE_NL_ARGS +#ifndef FORMAT_FUNC_NAME +#define FORMAT_IMPL +EXPORT void _fmtarglist __PR((const char *fmt, va_lists_t, va_lists_t arglist[])); +EXPORT void _fmtgetarg __PR((const char *fmt, int num, va_lists_t *)); +#else +extern void _fmtarglist __PR((const char *fmt, va_lists_t, va_lists_t arglist[])); +extern void _fmtgetarg __PR((const char *fmt, int num, va_lists_t *)); +#endif +#endif + +#ifdef FORMAT_BUFFER +LOCAL char xflsbuf __PR((int c, f_args *ap)); + +LOCAL char +xflsbuf(c, ap) + int c; + f_args *ap; +{ + *ap->ptr++ = c; + if (filewrite((FILE *)ap->fp, ap->iobuf, ap->ptr - ap->iobuf) < 0) + ap->err = 1; + + ap->cnt = BFSIZ; + ap->ptr = ap->iobuf; + return (c); +} + +#undef ofun +#define ofun(c, xp) (--((f_args *)xp)->cnt <= 0 ? \ + xflsbuf(c, (f_args *)xp) : \ + (*(((f_args *)xp)->ptr)++ = (c))) + +#endif + +#ifndef FORMAT_FUNC_NAME +#define FORMAT_FUNC_NAME format +#define FORMAT_FUNC_PARM + +#define FORMAT_FUNC_PROTO_DECL void (*fun)(char, long), +#define FORMAT_FUNC_KR_DECL register void (*fun)(); +#define FORMAT_FUNC_KR_ARGS fun, + +#define ofun(c, fp) (*fun)(c, fp) +#endif + +#ifdef FORMAT_BUFFER +#define FARG (farg|1) +#else +#define FARG farg +#endif + +#ifdef PROTOTYPES +EXPORT int +FORMAT_FUNC_NAME(FORMAT_FUNC_PROTO_DECL + long farg, + const char *fmt, + va_list oargs) +#else +EXPORT int +FORMAT_FUNC_NAME(FORMAT_FUNC_KR_ARGS farg, fmt, oargs) + FORMAT_FUNC_KR_DECL + register long farg; + register char *fmt; + va_list oargs; +#endif +{ +#ifdef FORMAT_LOW_MEM + char buf[512]; +#else + char buf[8192]; +#endif + const char *sfmt; + register int unsflag; + register long val; + register char type; + register char mode; + register char c; + int count; + int num; + int i; + short sh; + const char *str; + double dval; +#ifdef USE_LONGLONG + Llong llval = 0; +#endif + Ulong res; + char *rfmt; + f_args fa; +#ifdef USE_NL_ARGS + va_lists_t fargs; /* Used to get arguments */ + va_lists_t sargs; /* Saved argument state */ + va_lists_t arglist[FMT_ARGMAX+1]; /* List of fast args */ + const char *ofmt = fmt; /* Saved original format */ + BOOL didlist = FALSE; /* Need to scan arguments */ +#endif + +#ifdef FORMAT_BUFFER + if ((farg & 1) == 0) { /* Called externally */ + fa.cnt = BFSIZ; + fa.ptr = fa.iobuf; + fa.fp = (FILE *)farg; + fa.err = 0; + farg = fa.farg = (long)&fa; + } else { /* recursion */ + farg &= ~1; + } +#endif +#ifdef FORMAT_FUNC_PARM + fa.outf = fun; +#endif + fa.farg = farg; + count = 0; + +#ifdef USE_NL_ARGS + va_copy(sargs.ap, oargs); /* Keep a copy in sargs */ + fargs = sargs; /* Make a working copy */ +#endif + + /* + * Main loop over the format string. + * Increment and check for end of string is made here. + */ + for (; *fmt != '\0'; fmt++) { + c = *fmt; + while (c != '%') { + if (c == '\0') + goto out; + ofun(c, farg); + c = *(++fmt); + count++; + } + + /* + * We reached a '%' sign. + */ + buf[0] = '\0'; + fa.buf = fa.bufp = buf; + fa.minusflag = 0; + fa.flags = 0; + fa.fldwidth = 0; + fa.signific = -1; + fa.lzero = 0; + fa.fillc = ' '; + fa.prefixlen = 0; + sfmt = fmt; + unsflag = FALSE; + type = '\0'; + mode = '\0'; + /* + * %f.s + * %*.* + * %n$f.s + * %n$*n$.*n$ + */ + newflag: + switch (*(++fmt)) { + + case '+': + CHECKFLAG(); + fa.flags |= PLUSFLG; + goto newflag; + + case '-': + CHECKFLAG(); + fa.minusflag++; + fa.flags |= MINUSFLG; + goto newflag; + + case ' ': + CHECKFLAG(); + /* + * If the space and the + flag are present, + * the space flag will be ignored. + */ + fa.flags |= SPACEFLG; + goto newflag; + + case '#': + CHECKFLAG(); + fa.flags |= HASHFLG; + goto newflag; + + case '\'': + CHECKFLAG(); + fa.flags |= APOFLG; + goto newflag; + + case '.': + fa.flags |= GOTDOT; + fa.signific = 0; + goto newflag; + + case '*': + fa.flags |= GOTSTAR; +#ifdef USE_NL_ARGS + if (is_dig(fmt[1])) { /* *n$ */ + fmt++; /* Eat up '*' */ + goto dodig; + } +#endif + if (!(fa.flags & GOTDOT)) { + fa.fldwidth = va_arg(args, int); + /* + * A negative fieldwith is a minus flag with a + * positive fieldwidth. + */ + if (fa.fldwidth < 0) { + fa.fldwidth = -fa.fldwidth; + fa.minusflag = 1; + } + } else { + /* + * A negative significance (precision) is taken + * as if the precision and '.' were omitted. + */ + fa.signific = va_arg(args, int); + if (fa.signific < 0) + fa.signific = -1; + } + goto newflag; + + case '0': + /* + * '0' may be a flag. + */ + if (!(fa.flags & (GOTDOT | GOTSTAR | MINUSFLG))) + fa.fillc = '0'; + /* FALLTHRU */ + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': +#ifdef USE_NL_ARGS + dodig: +#endif + num = *fmt++ - '0'; + while (c = *fmt, is_dig(c)) { + num *= 10; + num += c - '0'; + fmt++; + } +#ifdef USE_NL_ARGS + if (c == '$') + goto doarglist; +#endif + fmt--; /* backup to last digit */ + if (!(fa.flags & GOTDOT)) + fa.fldwidth = num; + else + fa.signific = num; + goto newflag; + +#ifdef USE_NL_ARGS + doarglist: + { + va_lists_t tmp; /* Temporary arg state */ + if (num <= 0) /* Illegal arg offset */ + goto newflag; /* Continue after '$' */ + if (!didlist) { /* Need to init arglist */ + _fmtarglist(ofmt, sargs, arglist); + didlist = TRUE; + } + if (num <= FMT_ARGMAX) { + tmp = arglist[num-1]; + } else { + tmp = arglist[FMT_ARGMAX-1]; + _fmtgetarg(ofmt, num, &tmp); + } + if (!(fa.flags & GOTSTAR)) { + fargs = tmp; + } else { + if (!(fa.flags & GOTDOT)) { + fa.fldwidth = va_arg(tmp.ap, int); + /* + * A negative fieldwith is a minus flag + * with a positive fieldwidth. + */ + if (fa.fldwidth < 0) { + fa.fldwidth = -fa.fldwidth; + fa.minusflag = 1; + } + } else { + /* + * A negative significance (precision) + * is taken as if the precision and '.' + * were omitted. + */ + fa.signific = va_arg(tmp.ap, int); + if (fa.signific < 0) + fa.signific = -1; + } + } + goto newflag; + } +#endif + +#ifdef USE_CHECKFLAG + flagerror: + fmt = ++sfmt; /* Don't print '%' */ + continue; +#endif + } + + if (strchr("UCSIL", *fmt)) { + /* + * Enhancements to K&R and ANSI: + * + * got a type specifyer + * + * XXX 'S' in C99 is %ls, 'S' should become 'H' + */ + if (*fmt == 'U') { + fmt++; + unsflag = TRUE; + } + if (!strchr("CSILZODX", *fmt)) { + /* + * Got only 'U'nsigned specifyer, + * use default type and mode. + */ + type = 'I'; + mode = 'D'; + fmt--; + } else if (!strchr("CSIL", *fmt)) { + /* + * no type, use default + */ + type = 'I'; + mode = *fmt; + } else { + /* + * got CSIL type + */ + type = *fmt++; + if (!strchr("ZODX", mode = *fmt)) { + /* + * Check long double "Le", "Lf" or "Lg" + */ + if (type == 'L' && + (mode == 'e' || + mode == 'f' || + mode == 'g')) + goto checkfmt; + fmt--; + mode = 'D'; /* default mode */ + } + } + } else { + checkfmt: + switch (*fmt) { + + case 'h': + if (!type) + type = 'H'; /* convert to short type */ + goto getmode; + + case 'l': + if (!type) + type = 'L'; /* convert to long type */ + goto getmode; + + case 'j': + if (!type) + type = 'J'; /* convert to intmax_t type */ + goto getmode; + + case 'z': /* size_t */ +#if SIZEOF_SIZE_T == SIZEOF_INT + if (!type) + type = 'I'; /* convert to int type */ +#else +#if SIZEOF_SIZE_T == SIZEOF_LONG_INT + if (!type) + type = 'L'; /* convert to long type */ +#else +#if SIZEOF_SIZE_T == SIZEOF_LLONG + if (!type) + type = 'Q'; /* convert to long long type */ +#else +error sizeof (size_t) is unknown +#endif +#endif +#endif + goto getmode; + + case 't': /* ptrdiff_t */ +#if SIZEOF_PTRDIFF_T == SIZEOF_INT + if (!type) + type = 'I'; /* convert to int type */ +#else +#if SIZEOF_PTRDIFF_T == SIZEOF_LONG_INT + if (!type) + type = 'L'; /* convert to long type */ +#else +#if SIZEOF_PTRDIFF_T == SIZEOF_LLONG + if (!type) + type = 'Q'; /* convert to long long type */ +#else +error sizeof (ptrdiff_t) is unknown +#endif +#endif +#endif + /* + * XXX Future length modifiers: + * XXX 'L' with double: long double + */ + + getmode: + if (!strchr("udioxXn", *(++fmt))) { + /* + * %hhd -> char in decimal + */ + if (type == 'H' && *fmt == 'h') { + type = 'C'; + goto getmode; + } +#ifdef USE_LONGLONG + if (type == 'L' && *fmt == 'l') { + type = 'Q'; + goto getmode; + } +#endif + fmt--; + mode = 'D'; + } else { /* One of "udioxXn": */ + mode = *fmt; + if (mode == 'n') + goto gotn; + if (mode != 'x') + mode = to_cap(mode); + if (mode == 'U') + unsflag = TRUE; + else if (mode == 'I') /* XXX */ + mode = 'D'; + } + break; + case 'x': + mode = 'x'; + goto havemode; + case 'X': + mode = 'X'; + type = 'I'; + goto havemode; + case 'u': + unsflag = TRUE; + /* + * XXX Need to remove uppercase letters for 'long' + * XXX in future for POSIX/C99 compliance. + */ + /* FALLTHRU */ + case 'o': case 'O': + case 'd': case 'D': + case 'i': case 'I': + case 'Z': + mode = to_cap(*fmt); + havemode: + if (!type) + type = cap_ty(*fmt); +#ifdef DEBUG + dbg_print("*fmt: '%c' mode: '%c' type: '%c'\n", + *fmt, mode, type); +#endif + if (mode == 'I') /* XXX kann entfallen */ + mode = 'D'; /* wenn besseres uflg */ + break; + case 'p': + mode = 'P'; + type = 'L'; + break; + + case '%': + count += prc('%', &fa); + continue; + case ' ': + count += prbuf("", &fa); + continue; + case 'c': + c = va_arg(args, int); + count += prc(c, &fa); + continue; + case 's': + str = va_arg(args, char *); + count += prstring(str, &fa); + continue; + case 'b': + str = va_arg(args, char *); + fa.signific = va_arg(args, int); + count += prstring(str, &fa); + continue; + +#ifndef NO_FLOATINGPOINT + case 'e': + if (fa.signific == -1) + fa.signific = 6; + if (type == 'L') { +#ifdef HAVE_LONGDOUBLE + long double ldval = va_arg(args, long double); + +#if (defined(HAVE_QECVT) || defined(HAVE__LDECVT)) + qftoes(buf, ldval, 0, fa.signific); + count += prbuf(buf, &fa); + continue; +#else + dval = ldval; +#endif +#endif + } + dval = va_arg(args, double); + ftoes(buf, dval, 0, fa.signific); + count += prbuf(buf, &fa); + continue; + case 'f': + if (fa.signific == -1) + fa.signific = 6; + if (type == 'L') { +#ifdef HAVE_LONGDOUBLE + long double ldval = va_arg(args, long double); + +#if (defined(HAVE_QFCVT) || defined(HAVE__LDFCVT)) + qftofs(buf, ldval, 0, fa.signific); + count += prbuf(buf, &fa); + continue; +#else + dval = ldval; +#endif +#endif + } + dval = va_arg(args, double); + ftofs(buf, dval, 0, fa.signific); + count += prbuf(buf, &fa); + continue; + case 'g': + if (fa.signific == -1) + fa.signific = 6; + if (fa.signific == 0) + fa.signific = 1; + if (type == 'L') { +#ifdef HAVE_LONGDOUBLE + long double ldval = va_arg(args, long double); + +#if (defined(HAVE_QGCVT) || defined(HAVE__LDGCVT)) + +#ifdef HAVE__LDGCVT +#define qgcvt(ld, n, b) _ldgcvt(*(long_double *)&ld, n, b) +#endif + (void) qgcvt(ldval, fa.signific, buf); + count += prbuf(buf, &fa); + continue; +#else + dval = ldval; +#endif +#endif + } + dval = va_arg(args, double); + (void) gcvt(dval, fa.signific, buf); + count += prbuf(buf, &fa); + continue; +#else +# ifdef USE_FLOATINGARGS + case 'e': + case 'f': + case 'g': + dval = va_arg(args, double); + continue; +# endif +#endif + + case 'r': /* recursive printf */ + case 'R': /* recursive printf */ + rfmt = va_arg(args, char *); + /* + * I don't know any portable way to get an arbitrary + * C object from a var arg list so I use a + * system-specific routine __va_arg_list() that knows + * if 'va_list' is an array. You will not be able to + * assign the value of __va_arg_list() but it works + * to be used as an argument of a function. + * It is a requirement for recursive printf to be able + * to use this function argument. If your system + * defines va_list to be an array you need to know this + * via autoconf or another mechanism. + * It would be nice to have something like + * __va_arg_list() in stdarg.h + */ + count += FORMAT_FUNC_NAME(FORMAT_FUNC_KR_ARGS + FARG, rfmt, __va_arg_list(args)); + continue; + + gotn: + case 'n': + switch (type) { + + case 'C': { + signed char *cp = va_arg(args, signed char *); + + *cp = count; + } + continue; + case 'H': { + short *sp = va_arg(args, short *); + + *sp = count; + } + continue; + case 'L': { + long *lp = va_arg(args, long *); + + *lp = count; + } + continue; +#ifdef USE_LONGLONG + case 'J': /* For now Intmax_t is Llong */ + case 'Q': { + Llong *qp = va_arg(args, Llong *); + + *qp = count; + } + continue; +#endif + default: { + int *ip = va_arg(args, int *); + + *ip = count; + } + continue; + } + + default: /* Unknown '%' format */ + sfmt++; /* Dont't print '%' */ + count += fmt - sfmt; + while (sfmt < fmt) + ofun(*(sfmt++), farg); + if (*fmt == '\0') { + fmt--; + continue; + } else { + ofun(*fmt, farg); + count++; + continue; + } + } + } + /* + * print numbers: + * first prepare type 'C'har, s'H'ort, 'I'nt, or 'L'ong + * or 'Q'ad and 'J'==maxint_t + */ + switch (type) { + + case 'C': + c = va_arg(args, int); + val = c; /* extend sign here */ + if (unsflag || mode != 'D') +#ifdef DO_MASK + val &= CHARMASK; +#else + val = (unsigned char)val; +#endif + break; + case 'H': + case 'S': /* XXX remove 'S' in future */ + sh = va_arg(args, int); + val = sh; /* extend sign here */ + if (unsflag || mode != 'D') +#ifdef DO_MASK + val &= SHORTMASK; +#else + val = (unsigned short)val; +#endif + break; + case 'I': + default: + i = va_arg(args, int); + val = i; /* extend sign here */ + if (unsflag || mode != 'D') +#ifdef DO_MASK + val &= INTMASK; +#else + val = (unsigned int)val; +#endif + break; + case 'P': + case 'L': + val = va_arg(args, long); + break; +#ifdef USE_LONGLONG + case 'J': /* For now Intmax_t is Llong */ + type = 'Q'; /* use 'Q' for processing */ + case 'Q': + llval = va_arg(args, Llong); + val = llval != 0; + break; +#endif + } + + /* + * Final print out, take care of mode: + * mode is one of: 'O'ctal, 'D'ecimal, or he'X' + * oder 'Z'weierdarstellung. + */ + fa.bufp = &buf[sizeof (buf)-1]; + *--fa.bufp = '\0'; + + if (val == 0 && mode != 'D') { + printzero: + /* + * Printing '0' with fieldwidth 0 results in no chars. + */ + fa.lzero = -1; + if (fa.signific >= 0) + fa.fillc = ' '; + count += prstring("0", &fa); + continue; + } else switch (mode) { + + case 'D': +#ifdef USE_LONGLONG + if (type == 'Q') { + if (!unsflag && llval < 0) { + fa.prefix = "-"; + fa.prefixlen = 1; + llval = -llval; + } else if (fa.flags & PLUSFLG) { + fa.prefix = "+"; + fa.prefixlen = 1; + } else if (fa.flags & SPACEFLG) { + fa.prefix = " "; + fa.prefixlen = 1; + } + if (llval == 0) + goto printzero; + goto prunsigned; + } +#endif + if (!unsflag && val < 0) { + fa.prefix = "-"; + fa.prefixlen = 1; + val = -val; + } else if (fa.flags & PLUSFLG) { + fa.prefix = "+"; + fa.prefixlen = 1; + } else if (fa.flags & SPACEFLG) { + fa.prefix = " "; + fa.prefixlen = 1; + } + if (val == 0) + goto printzero; + /* FALLTHRU */ + case 'U': + /* output a long unsigned decimal number */ +#ifdef USE_LONGLONG + prunsigned: + if (type == 'Q') + prldnum(llval, &fa); + else +#endif + prdnum(val, &fa); + break; + case 'O': + /* output a long octal number */ + if (fa.flags & HASHFLG) { + fa.prefix = "0"; + fa.prefixlen = 1; + } +#ifdef USE_LONGLONG + if (type == 'Q') { + prlonum(llval, &fa); + } else +#endif + { + pronum(val & 07, &fa); + if ((res = (val>>3) & rshiftmask(long, 3)) != 0) + pronum(res, &fa); + } + break; + case 'p': + case 'x': + /* output a hex long */ + if (fa.flags & HASHFLG) { + fa.prefix = "0x"; + fa.prefixlen = 2; + } +#ifdef USE_LONGLONG + if (type == 'Q') + prlxnum(llval, &fa); + else +#endif + { + prxnum(val & 0xF, &fa); + if ((res = (val>>4) & rshiftmask(long, 4)) != 0) + prxnum(res, &fa); + } + break; + case 'P': + case 'X': + /* output a hex long */ + if (fa.flags & HASHFLG) { + fa.prefix = "0X"; + fa.prefixlen = 2; + } +#ifdef USE_LONGLONG + if (type == 'Q') + prlXnum(llval, &fa); + else +#endif + { + prXnum(val & 0xF, &fa); + if ((res = (val>>4) & rshiftmask(long, 4)) != 0) + prXnum(res, &fa); + } + break; + case 'Z': + /* output a binary long */ +#ifdef USE_LONGLONG + if (type == 'Q') + prlnum(llval, 2, &fa); + else +#endif + { + prnum(val & 0x1, 2, &fa); + if ((res = (val>>1) & rshiftmask(long, 1)) != 0) + prnum(res, 2, &fa); + } + } + fa.lzero = -1; + /* + * If a precision (fielwidth) is specified + * on diouXx conversions, the '0' flag is ignored. + */ + if (fa.signific >= 0) + fa.fillc = ' '; + count += prbuf(fa.bufp, &fa); + } +out: +#ifdef FORMAT_BUFFER + if (farg == (long)&fa) { /* Top level call, flush buffer */ + if (fa.err) + return (EOF); + if ((fa.ptr != fa.iobuf) && + (filewrite(fa.fp, fa.iobuf, fa.ptr - fa.iobuf) < 0)) + return (EOF); + } +#endif + return (count); +} + +/* + * Routines to print (not negative) numbers in an arbitrary base + */ +LOCAL unsigned char dtab[] = "0123456789abcdef"; +LOCAL unsigned char udtab[] = "0123456789ABCDEF"; + +LOCAL void +prnum(val, base, fa) + register Ulong val; + register unsigned base; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[modlbys(val, base)]; + val = divlbys(val, base); + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prdnum(val, fa) + register Ulong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[modlbys(val, (unsigned)10)]; + val = divlbys(val, (unsigned)10); + } while (val > 0); + + fa->bufp = p; +} + +/* + * We may need to use division here too (PDP-11, non two's complement ...) + */ +LOCAL void +pronum(val, fa) + register Ulong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[val & 7]; + val >>= 3; + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prxnum(val, fa) + register Ulong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[val & 15]; + val >>= 4; + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prXnum(val, fa) + register Ulong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = udtab[val & 15]; + val >>= 4; + } while (val > 0); + + fa->bufp = p; +} + +#ifdef USE_LONGLONG +LOCAL void +prlnum(val, base, fa) + register Ullong val; + register unsigned base; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[modlbys(val, base)]; + val = divlbys(val, base); + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prldnum(val, fa) + register Ullong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[val % (unsigned)10]; + val = val / (unsigned)10; + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prlonum(val, fa) + register Ullong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[val & 7]; + val >>= 3; + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prlxnum(val, fa) + register Ullong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = dtab[val & 15]; + val >>= 4; + } while (val > 0); + + fa->bufp = p; +} + +LOCAL void +prlXnum(val, fa) + register Ullong val; + f_args *fa; +{ + register char *p = fa->bufp; + + do { + *--p = udtab[val & 15]; + val >>= 4; + } while (val > 0); + + fa->bufp = p; +} + +#endif + +/* + * Final buffer print out routine. + */ +LOCAL int +prbuf(s, fa) + register const char *s; + f_args *fa; +{ + register int diff; + register int rfillc; + register long arg = fa->farg; +#ifdef FORMAT_FUNC_PARM + register void (*fun) __PR((char, long)) = fa->outf; +#endif + register int count; + register int lzero = 0; + + count = strlen(s); + + /* + * lzero becomes the number of left fill chars needed to reach signific + */ + if (fa->lzero < 0 && count < fa->signific) + lzero = fa->signific - count; + count += lzero + fa->prefixlen; + diff = fa->fldwidth - count; + if (diff > 0) + count += diff; + + if (fa->prefixlen && fa->fillc != ' ') { + while (*fa->prefix != '\0') + ofun(*fa->prefix++, arg); + } + if (!fa->minusflag) { + rfillc = fa->fillc; + while (--diff >= 0) + ofun(rfillc, arg); + } + if (fa->prefixlen && fa->fillc == ' ') { + while (*fa->prefix != '\0') + ofun(*fa->prefix++, arg); + } + if (lzero > 0) { + rfillc = '0'; + while (--lzero >= 0) + ofun(rfillc, arg); + } + while (*s != '\0') + ofun(*s++, arg); + if (fa->minusflag) { + rfillc = ' '; + while (--diff >= 0) + ofun(rfillc, arg); + } + return (count); +} + +/* + * Print out one char, allowing prc('\0') + * Similar to prbuf() + */ +#ifdef PROTOTYPES + +LOCAL int +prc(char c, f_args *fa) + +#else + +LOCAL int +prc(c, fa) + char c; + f_args *fa; +#endif +{ + register int diff; + register int rfillc; + register long arg = fa->farg; +#ifdef FORMAT_FUNC_PARM + register void (*fun) __PR((char, long)) = fa->outf; +#endif + register int count; + + count = 1; + diff = fa->fldwidth - 1; + if (diff > 0) + count += diff; + + if (!fa->minusflag) { + rfillc = fa->fillc; + while (--diff >= 0) + ofun(rfillc, arg); + } + ofun(c, arg); + if (fa->minusflag) { + rfillc = ' '; + while (--diff >= 0) + ofun(rfillc, arg); + } + return (count); +} + +/* + * String output routine. + * If fa->signific is >= 0, it uses only fa->signific chars. + * If fa->signific is 0, print no characters. + */ +LOCAL int +prstring(s, fa) + register const char *s; + f_args *fa; +{ + register char *bp; + register int signific; + + if (s == NULL) + return (prbuf("(NULL POINTER)", fa)); + + if (fa->signific < 0) + return (prbuf(s, fa)); + + bp = fa->buf; + signific = fa->signific; + + while (--signific >= 0 && *s != '\0') + *bp++ = *s++; + *bp = '\0'; + + return (prbuf(fa->buf, fa)); +} + +#ifdef DEBUG +LOCAL void +dbg_print(fmt, a, b, c, d, e, f, g, h, i) +char *fmt; +{ + char ff[1024]; + + sprintf(ff, fmt, a, b, c, d, e, f, g, h, i); + write(STDERR_FILENO, ff, strlen(ff)); +} +#endif + +#ifdef USE_NL_ARGS +#ifdef FORMAT_IMPL +/* + * The following code is shared between format() and fprformat(). + */ + +/* + * Format argument types. + * As "char" and "short" type arguments are fetched as "int" + * we start with size "int" and ignore the 'h' modifier when + * parsing sizes. + */ +#define AT_NONE 0 +#define AT_INT 1 +#define AT_LONG 2 +#define AT_LONG_LONG 3 +#define AT_DOUBLE 4 +#define AT_LONG_DOUBLE 5 +#define AT_VOID_PTR 6 +#define AT_CHAR_PTR 7 +#define AT_SHORT_PTR 8 +#define AT_INT_PTR 9 +#define AT_LONG_PTR 10 +#define AT_LONG_LONG_PTR 11 +#define AT_R_FMT 12 +#define AT_R_VA_LIST 13 +#define AT_BOUNDS 14 + +#define AF_NONE 0 +#define AF_LONG 1 +#define AF_LONG_LONG 2 +#define AF_LONG_DOUBLE 4 +#define AF_STAR 8 + +static const char skips[] = "+- #'.$h1234567890"; +static const char *digits = &skips[8]; + +/* + * Parse the format string and store the first FMT_ARGMAX args in the arglist + * parameter. + * + * This is done in two stages: + * 1 parse the format string and store the types in argtypes[]. + * 2 use the type list in argtypes[], fetch the args in order and + * store the related va_list state in arglist[] + */ +EXPORT void +_fmtarglist(fmt, fargs, arglist) + const char *fmt; + va_lists_t fargs; + va_lists_t arglist[]; +{ + int i; + int argindex; + int maxindex; + int thistype; + int thisflag; + int argtypes[FMT_ARGMAX+1]; + + for (i = 0; i < FMT_ARGMAX; i++) + argtypes[i] = AT_NONE; + + maxindex = -1; + argindex = 0; + while ((fmt = strchr(fmt, '%')) != NULL) { + fmt++; + i = strspn(fmt, digits); + if (fmt[i] == '$') { + int c; + + argindex = *fmt++ - '0'; + while (c = *fmt, is_dig(c)) { + argindex *= 10; + argindex += c - '0'; + fmt++; + } + argindex -= 1; + } + thistype = AT_NONE; + thisflag = AF_NONE; + newarg: + fmt += strspn(fmt, skips); + switch (*fmt++) { + + case '%': /* %% format no arg */ + continue; + + case 'l': + if (thisflag & AF_LONG) { + thisflag |= AF_LONG_LONG; + } else { + thisflag |= AF_LONG; + } + goto newarg; + case 'j': /* intmax_t for now is long long */ + thisflag |= AF_LONG_LONG; + goto newarg; + case 'z': /* size_t */ +#if SIZEOF_SIZE_T == SIZEOF_INT + if (thistype == AT_NONE) + thistype = AT_INT; +#else +#if SIZEOF_SIZE_T == SIZEOF_LONG_INT + if (thistype == AT_NONE) + thistype = AT_LONG; +#else +#if SIZEOF_SIZE_T == SIZEOF_LLONG + if (thistype == AT_NONE) + thistype = AT_LONG_LONG; +#else +error sizeof (size_t) is unknown +#endif +#endif +#endif + goto newarg; + case 't': /* ptrdiff_t */ +#if SIZEOF_PTRDIFF_T == SIZEOF_INT + if (thistype == AT_NONE) + thistype = AT_INT; +#else +#if SIZEOF_PTRDIFF_T == SIZEOF_LONG_INT + if (thistype == AT_NONE) + thistype = AT_LONG; +#else +#if SIZEOF_PTRDIFF_T == SIZEOF_LLONG + if (thistype == AT_NONE) + thistype = AT_LONG_LONG; +#else +error sizeof (ptrdiff_t) is unknown +#endif +#endif +#endif + goto newarg; +#ifndef NO_UCSIL + /* + * Enhancements to K&R and ANSI: + * + * got a type specifyer + * + * XXX 'S' in C99 is %ls, 'S' should become 'H' + */ + case 'U': + if (!strchr("CSILZODX", *fmt)) { + /* + * Got only 'U'nsigned specifyer, + * use default type and mode. + */ + thistype = AT_INT; + break; + } + if (!strchr("CSIL", *fmt)) { + /* + * Got 'U' and ZODX. + * no type, use default + */ + thistype = AT_INT; + fmt++; /* Skip ZODX */ + break; + } + fmt++; /* Unsigned, skip 'U', get CSIL */ + /* FALLTHRU */ + case 'C': + case 'S': + case 'I': + case 'L': + fmt--; /* Undo fmt++ from switch() */ + { + /* + * got CSIL type + */ + int type = *fmt++; /* Undo above fmt-- */ + int mode = *fmt; + if (!strchr("ZODX", mode)) { + /* + * Check long double "Le", "Lf" or "Lg" + */ + if (type == 'L' && + (mode == 'e' || + mode == 'f' || + mode == 'g')) { + thisflag |= AF_LONG_DOUBLE; + goto newarg; + } + } else { + fmt++; /* Skip ZODX */ + } + if (type == 'L') + thistype = AT_LONG; + else + thistype = AT_INT; + } + break; +#else + case 'L': + thisflag |= AF_LONG_DOUBLE; + goto newarg; +#endif + + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + if (thisflag & AF_LONG_DOUBLE) + thistype = AT_LONG_DOUBLE; + else + thistype = AT_DOUBLE; + break; + + case 'p': + thistype = AT_VOID_PTR; + break; + case 's': + thistype = AT_CHAR_PTR; + break; + case 'b': + thistype = AT_BOUNDS; + break; + case 'n': + if (thisflag & AF_LONG_LONG) + thistype = AT_LONG_LONG_PTR; + else if (thistype & AF_LONG) + thistype = AT_LONG_PTR; + else + thistype = AT_INT_PTR; + break; + case 'r': + thistype = AT_R_FMT; + break; + default: + if (thistype == AT_NONE) { + if (thisflag & AF_LONG_LONG) + thistype = AT_LONG_LONG; + else if (thistype & AF_LONG) + thistype = AT_LONG; + else + thistype = AT_INT; + } + break; + + case '*': + if (is_dig(*fmt)) { + int c; + int starindex; + + starindex = *fmt++ - '0'; + while (c = *fmt, is_dig(c)) { + starindex *= 10; + starindex += c - '0'; + fmt++; + } + starindex -= 1; + if (starindex >= 0 && starindex < FMT_ARGMAX) { + argtypes[starindex] = AT_INT; + if (starindex > maxindex) + maxindex = starindex; + } + goto newarg; + } + thistype = AT_INT; + thisflag |= AF_STAR; /* Make sure to rescan for type */ + break; + } + if (argindex >= 0 && argindex < FMT_ARGMAX) { + argtypes[argindex] = thistype; + if (thistype == AT_R_FMT) + argtypes[++argindex] = AT_R_VA_LIST; + else if (thistype == AT_BOUNDS) + argtypes[++argindex] = AT_INT; + + if (argindex > maxindex) + maxindex = argindex; + } + ++argindex; /* Default to next arg in list */ + if (thisflag & AF_STAR) { /* Found '*', continue for type */ + thisflag &= ~AF_STAR; + goto newarg; + } + } + + for (i = 0; i <= maxindex; i++) { /* Do not fetch more args than known */ + arglist[i] = fargs; /* Save state before fetching this */ + + switch (argtypes[i]) { + + default: + /* FALLTHRU */ + case AT_NONE: /* This matches '*' args */ + /* FALLTHRU */ + case AT_INT: + (void) va_arg(fargs.ap, int); + break; + case AT_LONG: + (void) va_arg(fargs.ap, long); + break; + case AT_LONG_LONG: + (void) va_arg(fargs.ap, Llong); + break; + case AT_DOUBLE: + (void) va_arg(fargs.ap, double); + break; + case AT_LONG_DOUBLE: +#ifdef HAVE_LONGDOUBLE + (void) va_arg(fargs.ap, long double); +#endif + break; + case AT_VOID_PTR: + (void) va_arg(fargs.ap, void *); + break; + case AT_CHAR_PTR: + (void) va_arg(fargs.ap, char *); + break; + case AT_SHORT_PTR: + (void) va_arg(fargs.ap, short *); + break; + case AT_INT_PTR: + (void) va_arg(fargs.ap, int *); + break; + case AT_LONG_PTR: + (void) va_arg(fargs.ap, long *); + break; + case AT_LONG_LONG_PTR: + (void) va_arg(fargs.ap, Llong *); + break; + case AT_R_FMT: + (void) va_arg(fargs.ap, char *); + arglist[++i] = fargs; + (void) __va_arg_list(fargs.ap); + break; + case AT_R_VA_LIST: + break; + case AT_BOUNDS: + (void) va_arg(fargs.ap, char *); + arglist[++i] = fargs; + (void) va_arg(fargs.ap, int); + break; + } + } +} + +/* + * In case that the format references an argument > FMT_ARGMAX, we use this + * implementation. It is slow (n*n - where n is (argno - FMT_ARGMAX)). + * Fortunately, it is most unlikely that there are more positional args than + * the current FMT_ARGMAX definition of 30. + */ +EXPORT void +_fmtgetarg(fmt, num, fargs) + const char *fmt; + int num; + va_lists_t *fargs; +{ + const char *sfmt = fmt; + int i; + + /* + * Hacky preliminary support for all int type args bejond FMT_ARGMAX. + */ + for (i = FMT_ARGMAX; i < num; i++) + (void) va_arg((*fargs).ap, int); +} +#endif /* FORMAT_IMPL */ +#endif /* USE_NL_ARGS */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/getargs.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/getargs.c new file mode 100644 index 00000000000..7f8db12e72c --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/getargs.c @@ -0,0 +1,1339 @@ +/* @(#)getargs.c 2.70 16/10/23 Copyright 1985, 1988, 1994-2016 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)getargs.c 2.70 16/10/23 Copyright 1985, 1988, 1994-2016 J. Schilling"; +#endif +#define NEW +/* + * Copyright (c) 1985, 1988, 1994-2016 J. Schilling + * + * 1.3.88 Start implementation of release 2 + */ +/* + * Parse arguments on a command line. + * Format string type specifier (appearing directly after flag name): + * '' BOOL size int set to TRUE (1) + * '%' Extended format, next char determines the type: + * '%0' BOOL with size modifier set to FALSE (0) + * '%1' BOOL with size modifier set to TRUE(1) + * '*' string + * '?' char + * '#' number + * '&' call function for any type flag + * '~' call function for BOOLEAN flag + * '+' inctype +++ NEU +++ + * + * The format string 'f* ' may be used to disallow -ffoo for f* + * The same behavior is implemented for 'f# ', 'f? ' and 'f& '. + * The ' ' needs to immediately follow the format type specifier. + * + * The format string 'f*_' may be used to disallow -f foo for f* + * The same behavior is implemented for 'f#_', 'f?_' and 'f&_'. + * The '_' needs to immediately follow the format type specifier. + * This also allows to implement optional arguments to options. + * Note: 'f#_' is only implemented for orthogonality, -f will + * be converted to an integer value of 0. + * + * The '#', '+' and '%[01]' types may have size modifiers added: + * 'c'/'C' char + * 's'/'S' short + * 'i'/'I' int (default == no size modifier) + * 'l'/'L' long + * 'll'/'LL' long long + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ +/* LINTLIBRARY */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Various return values + */ +#define RETMAX 2 /* Max. value for getargerror() */ +#define FLAGDELIM 2 /* "--" stopped flag processing */ +#define NOTAFLAG 1 /* Not a flag type argument */ +#define NOARGS 0 /* No more args */ +#define BADFLAG (-1) /* Not a valid flag argument */ +#define BADFMT (-2) /* Error in format string */ +#define NOTAFILE (-3) /* Seems to be a flag type arg */ +#define RETMIN (-3) /* Min. value for getargerror() */ + +LOCAL char *retnames[] = { + "NOTAFILE", + "BADFMT", + "BADFLAG", + "NOARGS", + "NOTAFLAG", + "FLAGDELIM", +}; +#define RNAME(a) (retnames[(a)-RETMIN]) + +#define SCANONLY 0 /* Do not try to set argument values */ +#define SETARGS 1 /* Set argument values from cmdline */ +#define ARGVECTOR 2 /* Use vector instead of list interface */ +#define NOEQUAL 4 /* -opt=val not allowed for -opt val */ + +LOCAL struct ga_props *_getprops __PR((struct ga_props *)); + + int _getargs __PR((int *, char *const **, void *, + int, + struct ga_props *, + va_list)); +LOCAL int dofile __PR((int *, char *const **, const char **, + struct ga_props *)); +LOCAL int doflag __PR((int *, char *const **, const char *, + void *, int, va_list)); +LOCAL int dosflags __PR((const char *, void *, + int *, char *const **, + int, va_list)); +LOCAL int checkfmt __PR((const char *)); +LOCAL int checkeql __PR((const char *)); + +LOCAL va_list va_dummy; + +LOCAL char fmtspecs[] = "#?*&~+%"; + +#define isfmtspec(c) (strchr(fmtspecs, c) != NULL) + +LOCAL struct ga_props props_default = { 0, 0, sizeof (struct ga_props) }; +LOCAL struct ga_props props_posix = { GAF_POSIX_DEFAULT, 0, sizeof (struct ga_props) }; + +EXPORT int +_getarginit(props, size, flags) + struct ga_props *props; + size_t size; + UInt32_t flags; +{ + if (size > sizeof (struct ga_props)) + return (-1); + + /* + * GAF_POSIX may be used as an alias for the flags that currently + * define POSIX behavior. + */ + if (flags == GAF_POSIX) + flags = GAF_POSIX_DEFAULT; + + props->ga_flags = flags; + props->ga_oflags = 0; + props->ga_size = size; + return (0); +} + +LOCAL struct ga_props * +_getprops(props) + struct ga_props *props; +{ + if (props == GA_NO_PROPS) + props = &props_default; + else if (props == GA_POSIX_PROPS) + props = &props_posix; + props->ga_oflags = 0; + /* + * GAF_POSIX may be used as an alias for the flags that currently + * define POSIX behavior. + */ + if (props->ga_flags == GAF_POSIX) + props->ga_flags = GAF_POSIX_DEFAULT; + + return (props); +} + +/* + * get flags until a non flag type argument is reached (old version) + */ +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT int +getargs(int *pac, char *const **pav, const char *fmt, ...) +#else +EXPORT int +getargs(pac, pav, fmt, va_alist) + int *pac; + char **pav[]; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = _getargs(pac, pav, (void *)fmt, SETARGS, GA_NO_PROPS, args); + va_end(args); + return (ret); +} + + +/* + * get flags until a non flag type argument is reached (list version) + */ +/* VARARGS4 */ +#ifdef PROTOTYPES +EXPORT int +getlargs(int *pac, char *const **pav, struct ga_props *props, const char *fmt, ...) +#else +EXPORT int +getlargs(pac, pav, props, fmt, va_alist) + int *pac; + char **pav[]; + struct ga_props *props; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = _getargs(pac, pav, (void *)fmt, SETARGS, props, args); + va_end(args); + return (ret); +} + + +/* + * get flags until a non flag type argument is reached (vector version) + */ +EXPORT int +getvargs(pac, pav, props, vfmt) + int *pac; + char * const *pav[]; + struct ga_props *props; + struct ga_flags *vfmt; +{ + return (_getargs(pac, pav, vfmt, SETARGS | ARGVECTOR, props, va_dummy)); +} + + +/* + * get all flags on the command line, do not stop on files (old version) + */ +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT int +getallargs(int *pac, char *const **pav, const char *fmt, ...) +#else +EXPORT int +getallargs(pac, pav, fmt, va_alist) + int *pac; + char **pav[]; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + for (; ; (*pac)--, (*pav)++) { + if ((ret = _getargs(pac, pav, (void *)fmt, SETARGS, GA_NO_PROPS, args)) < NOTAFLAG) + break; + } + va_end(args); + return (ret); +} + + +/* + * get all flags on the command line, do not stop on files (list version) + */ +/* VARARGS4 */ +#ifdef PROTOTYPES +EXPORT int +getlallargs(int *pac, char *const **pav, struct ga_props *props, const char *fmt, ...) +#else +EXPORT int +getlallargs(pac, pav, props, fmt, va_alist) + int *pac; + char **pav[]; + struct ga_props *props; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + props = _getprops(props); + for (; ; (*pac)--, (*pav)++) { + if ((ret = _getargs(pac, pav, (void *)fmt, SETARGS, props, args)) < NOTAFLAG) + break; + /* + * The default is to parse all options on the command line and + * to let "--" only make the next argument a non-option. + */ + if (ret == FLAGDELIM && (props->ga_flags & GAF_DELIM_DASHDASH)) + break; + } + va_end(args); + return (ret); +} + + +/* + * get all flags on the command line, do not stop on files (vector version) + */ +EXPORT int +getvallargs(pac, pav, props, vfmt) + int *pac; + char * const *pav[]; + struct ga_props *props; + struct ga_flags *vfmt; +{ + int ret; + + props = _getprops(props); + for (; ; (*pac)--, (*pav)++) { + if ((ret = _getargs(pac, pav, vfmt, SETARGS | ARGVECTOR, props, va_dummy)) < NOTAFLAG) + break; + /* + * The default is to parse all options on the command line and + * to let "--" only make the next argument a non-option. + */ + if (ret == FLAGDELIM && (props->ga_flags & GAF_DELIM_DASHDASH)) + break; + } + return (ret); +} + + +/* + * get next non flag type argument (i.e. a file) (old version) + * getfiles() is a dry run getargs() + */ +EXPORT int +getfiles(pac, pav, fmt) + int *pac; + char *const *pav[]; + const char *fmt; +{ + return (_getargs(pac, pav, (void *)fmt, SCANONLY, GA_NO_PROPS, va_dummy)); +} + + +/* + * get next non flag type argument (i.e. a file) (list version) + * getlfiles() is a dry run getlargs() + */ +EXPORT int +getlfiles(pac, pav, props, fmt) + int *pac; + char *const *pav[]; + struct ga_props *props; + const char *fmt; +{ + return (_getargs(pac, pav, (void *)fmt, SCANONLY, props, va_dummy)); +} + + +/* + * get next non flag type argument (i.e. a file) (vector version) + * getvfiles() is a dry run getvargs() + */ +EXPORT int +getvfiles(pac, pav, props, vfmt) + int *pac; + char *const *pav[]; + struct ga_props *props; + struct ga_flags *vfmt; +{ + return (_getargs(pac, pav, vfmt, SCANONLY | ARGVECTOR, props, va_dummy)); +} + + +/* + * check args until the next non flag type argmument is reached + * *pac is decremented, *pav is incremented so that the + * non flag type argument is at *pav[0] + * + * return code: + * +2 FLAGDELIM "--" stopped flag processing + * +1 NOTAFLAG not a flag type argument (is a file) + * 0 NOARGS no more args + * -1 BADFLAG a non-matching flag type argument + * -2 BADFMT bad syntax in format string + */ +/* LOCAL int */ +EXPORT int +_getargs(pac, pav, vfmt, flags, props, args) + register int *pac; + register char *const **pav; + void *vfmt; + int flags; + struct ga_props *props; + va_list args; +{ + const char *argp; + int ret; + + + props = _getprops(props); + + if (props->ga_flags & GAF_NO_EQUAL) + flags |= NOEQUAL; + + for (; *pac > 0; (*pac)--, (*pav)++) { + argp = **pav; + + ret = dofile(pac, pav, &argp, props); + + if (ret != NOTAFILE) + return (ret); + + ret = doflag(pac, pav, argp, vfmt, flags, args); + + if (ret != NOTAFLAG) + return (ret); + } + return (NOARGS); +} + + +/* + * check if *pargp is a file type argument + */ +LOCAL int +dofile(pac, pav, pargp, props) + register int *pac; + register char *const **pav; + const char **pargp; + struct ga_props *props; +{ + register const char *argp = *pargp; + + + if (argp[0] == '-') { + /* + * "-" is a special non flag type argument + * that usually means take stdin instead of a named file + */ + if (argp[1] == '\0') + return (NOTAFLAG); + /* + * "--" is a prefix to take the next argument + * as non flag type argument + * NOTE: POSIX requires "--" to indicate the end of the + * flags on the command line. Programs that like to be + * 100% POSIX compliant call only get[lv]args() once + * and then process the list of files from cav[0]. + */ + if (argp[1] == '-' && argp[2] == '\0') { + if (--(*pac) > 0) { + (*pav)++; + return (FLAGDELIM); + } else { + return (NOARGS); + } + } + } + + /* + * Now check if it may be flag type argument at all. + * Flag type arguments begin with a '-', a '+' or contain a '=' + * i.e. -flag +flag or flag= + * The behavior here may be controlled by props->ga_flags to + * allow getargs() to e.g. behave fully POSIX compliant. + */ + if (argp[0] != '-') { + if (argp[0] == '+' && (props->ga_flags & GAF_NO_PLUS) == 0) + return (NOTAFILE); /* This is a flag type arg */ + + /* + * If 'flag=value' is not allowed at all, speed things up + * and do not call checkeql() to check for '='. + */ + if (props->ga_flags & GAF_NO_EQUAL) + return (NOTAFLAG); + if (checkeql(argp) && (props->ga_flags & GAF_NEED_DASH) == 0) + return (NOTAFILE); /* This is a flag type arg */ + return (NOTAFLAG); + } + return (NOTAFILE); /* This is a flag type arg */ +} + + +/* + * compare argp with the format string + * if a match is found store the result a la scanf in one of the + * arguments pointed to in the va_list + * + * If (flags & SETARGS) == 0, only check arguments for getfiles() + * In case that (flags & SETARGS) == 0 or that (flags & ARGVECTOR) != 0, + * va_list may be a dummy argument. + */ +LOCAL int +doflag(pac, pav, argp, vfmt, flags, oargs) + int *pac; + char *const **pav; + register const char *argp; + void *vfmt; + int flags; + va_list oargs; +{ + register const char *fmt = (const char *)vfmt; + struct ga_flags *flagp = vfmt; + const char *fmtp; + long val; + Llong llval; + int singlecharflag = 0; + BOOL isspec; + BOOL hasdash = FALSE; + BOOL doubledash = FALSE; + BOOL haseql = checkeql(argp); + const char *sargp; + const char *sfmt; + va_list args; + char *const *spav = *pav; + int spac = *pac; + void *curarg = (void *)0; + + sfmt = fmt; + /* + * flags beginning with '-' don't have to include the '-' in + * the format string. + * flags beginning with '+' have to include it in the format string. + */ + if (argp[0] == '-') { + argp++; + hasdash = TRUE; + /* + * Implement legacy support for --longopt + * If we find a double dash, we do not look for combinations + * of boolean single char flags. + */ + if (argp[0] == '-') { + argp++; + doubledash = TRUE; + /* + * Allow -- only for long options. + */ + if (argp[1] == '\0') { + return (BADFLAG); + } + } + } + sargp = argp; + + /* + * Initialize 'args' to the start of the argument list. + * I don't know any portable way to copy an arbitrary + * C object so I use a system-specific routine + * (probably a macro) from stdarg.h. (Remember that + * if va_list is an array, 'args' will be a pointer + * and '&args' won't be what I would need for memcpy.) + * It is a system requirement for SVr4 compatibility + * to be able to do this assgignement. If your system + * defines va_list to be an array but does not define + * va_copy() you are lost. + * This is needed to make sure, that 'oargs' will not + * be clobbered. + */ + va_copy(args, oargs); + + if (flags & ARGVECTOR) { + sfmt = fmt = flagp->ga_format; + if (fmt == NULL) + sfmt = fmt = ""; + if (flags & SETARGS) + curarg = flagp->ga_arg; + } else if (flags & SETARGS) { + curarg = va_arg(args, void *); + } + /* + * check if the first flag in format string is a singlechar flag + */ +again: + if (fmt[0] != '\0' && + (fmt[1] == ',' || fmt[1] == '+' || + fmt[1] == '~' || fmt[1] == '%' || fmt[1] == '\0')) + singlecharflag++; + /* + * check the whole format string for a match + */ + for (;;) { + for (; *fmt; fmt++, argp++) { + if (*fmt == '\\') { + /* + * Allow "#?*&+" to appear inside a flag. + * NOTE: they must be escaped by '\\' only + * inside the the format string. + */ + fmt++; + isspec = FALSE; + } else { + isspec = isfmtspec(*fmt); + } + /* + * If isspec is TRUE, the arg beeing checked starts + * like a valid flag. Argp now points to the rest. + */ + if (isspec) { + /* + * If *argp is '+' and we are on the + * beginning of the arg that is currently + * checked, this cannot be an inc type flag. + */ + if (*argp == '+' && argp == sargp) + continue; + /* + * skip over to arg of flag + */ + if (*argp == '=') { + if (flags & NOEQUAL) + return (BADFLAG); + argp++; + } else if (*argp != '\0' && haseql) { + /* + * Flag and arg are not separated by a + * space. + * Check here for: + * xxxxx=yyyyy match on '&' + * Checked before: + * abc=yyyyy match on 'abc&' + * or 'abc*' + * or 'abc#' + * We come here if 'argp' starts with + * the same sequence as a valid flag + * and contains an equal sign. + * We have tested before if the text + * before 'argp' matches exactly. + * At this point we have no exact match + * and we only allow to match + * the special pattern '&'. + * We need this e.g. for 'make'. + * We allow any flag type argument to + * match the format string "&" to set + * up a function that handles all odd + * stuff that getargs will not grok. + * In addition, to allow getargs to be + * used for CPP type flags we allow to + * match -Dabc=xyz on 'D&'. Note that + * Dabc=xyz will not match 'D&'. + */ + if ((!hasdash && argp != sargp) || *fmt != '&') + goto nextarg; + } + + /* + * The format string 'f* ' may be used + * to disallow -ffoo for f* + * + * The same behavior is implemented for + * 'f# '. 'f? ' and 'f& '. + */ + if (!haseql && *argp != '\0' && + (fmt[0] == '*' || fmt[0] == '#' || + fmt[0] == '?' || fmt[0] == '&') && + fmt[1] == ' ') { + goto nextarg; + } + + /* + * *arpp == '\0' || !haseql + * We come here if 'argp' starts with + * the same sequence as a valid flag. + * This will match on the following args: + * -farg match on 'f*' + * -f12 match on 'f#' + * +12 match on '+#' + * -12 match on '#' + * and all args that are separated from + * their flags. + * In the switch statement below, we check + * if the text after 'argp' (if *argp != 0) or + * the next arg is a valid arg for this flag. + */ + break; + } else if (*fmt == *argp) { + if (argp[1] == '\0' && + (fmt[1] == '\0' || fmt[1] == ',')) { + + if (flags & SETARGS) + *((int *)curarg) = TRUE; + + + return (checkfmt(fmt)); /* XXX */ + } + } else { + /* + * skip over to next format identifier + * & reset arg pointer + */ + nextarg: + while (*fmt != ',' && *fmt != '\0') { + /* function has extra arg on stack */ + if ((*fmt == '&' || *fmt == '~') && + (flags & (SETARGS|ARGVECTOR)) == SETARGS) { + curarg = va_arg(args, void *); + } + fmt++; + } + argp = sargp; + break; + } + } + switch (*fmt) { + + case '\0': + /* + * Boolean type has been tested before. + */ + if (flags & ARGVECTOR) { + if (flagp[1].ga_format != NULL) { + flagp++; + sfmt = fmt = flagp->ga_format; + if (flags & SETARGS) + curarg = flagp->ga_arg; + argp = sargp; + goto again; + } + } + if (singlecharflag && !doubledash && + (val = dosflags(sargp, vfmt, pac, pav, + flags & ~SETARGS, + va_dummy)) == BADFLAG) { + return (val); + } + if (singlecharflag && !doubledash && + (val = dosflags(sargp, vfmt, pac, pav, + flags, + oargs)) != BADFLAG) { + return (val); + } + return (BADFLAG); + + case ',': + fmt++; + if (fmt[0] == '\0') /* Should we allow "a,b,c,"? */ + return (BADFMT); + if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') + singlecharflag++; + if ((flags & (SETARGS|ARGVECTOR)) == SETARGS) + curarg = va_arg(args, void *); + continue; + + case '*': + if (*argp == '\0' && fmt[1] != '_') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + if (fmt[1] == '_') /* To disallow -f foo for f* */ + fmt++; + else if (fmt[1] == ' ') /* To disallow -ffoo for f* */ + fmt++; + + if (flags & SETARGS) + *((const char **)curarg) = argp; + + + return (checkfmt(fmt)); + + case '?': + if (*argp == '\0' && fmt[1] != '_') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + if (fmt[1] == '_') /* To disallow -f c for f? */ + fmt++; + else if (fmt[1] == ' ') /* To disallow -fc for f? */ + fmt++; + + /* + * Allow -f '' to specify a nul character. + * If more than one char arg, it + * cannot be a character argument. + */ + if (argp[0] != '\0' && argp[1] != '\0') + goto nextchance; + + if (flags & SETARGS) + *((char *)curarg) = *argp; + + + return (checkfmt(fmt)); + + case '+': + /* + * inc type is similar to boolean, + * there is no arg in argp to convert. + */ + if (*argp != '\0') + goto nextchance; + /* + * If *fmt is '+' and we are on the beginning + * of the format desciptor that is currently + * checked, this cannot be an inc type flag. + */ + if (fmt == sfmt || fmt[-1] == ',') + goto nextchance; + + fmtp = fmt; + if (fmt[1] == 'l' || fmt[1] == 'L') { + if (fmt[2] == 'l' || fmt[2] == 'L') { + if (flags & SETARGS) + *((Llong *)curarg) += 1; + fmt += 2; + } else { + if (flags & SETARGS) + *((long *)curarg) += 1; + fmt++; + } + } else if (fmt[1] == 's' || fmt[1] == 'S') { + if (flags & SETARGS) + *((short *)curarg) += 1; + fmt++; + } else if (fmt[1] == 'c' || fmt[1] == 'C') { + if (flags & SETARGS) + *((char *)curarg) += 1; + fmt++; + } else { + if (fmt[1] == 'i' || fmt[1] == 'I') + fmt++; + if (flags & SETARGS) + *((int *)curarg) += 1; + } + + + return (checkfmt(fmt)); + + case '%': + /* + * inc type is similar to boolean, + * there is no arg in argp to convert. + */ + if (*argp != '\0') + goto nextchance; + + fmt++; + if (*fmt == '1') + val = TRUE; + else if (*fmt == '0') + val = FALSE; + else + goto nextchance; + + fmtp = fmt; + llval = (Llong)val; + if (fmt[1] == 'l' || fmt[1] == 'L') { + if (fmt[2] == 'l' || fmt[2] == 'L') { + if (flags & SETARGS) + *((Llong *)curarg) = llval; + fmt += 2; + } else { + if (flags & SETARGS) + *((long *)curarg) = val; + fmt++; + } + } else if (fmt[1] == 's' || fmt[1] == 'S') { + if (flags & SETARGS) + *((short *)curarg) = val; + fmt++; + } else if (fmt[1] == 'c' || fmt[1] == 'C') { + if (flags & SETARGS) + *((char *)curarg) = val; + fmt++; + } else { + if (fmt[1] == 'i' || fmt[1] == 'I') + fmt++; + if (flags & SETARGS) + *((int *)curarg) = val; + } + + + return (checkfmt(fmt)); + + case '#': + if (*argp == '\0' && fmt[1] != '_') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + if (fmt[1] == '_') /* To disallow -f 123 for f# */ + fmt++; + else if (fmt[1] == ' ') /* To disallow -f123 for f# */ + fmt++; + + if (*astoll(argp, &llval) != '\0') { + /* + * arg is not a valid number! + * go to next format in the format string + * and check if arg matches any other type + * in the format specs. + */ + nextchance: + while (*fmt != ',' && *fmt != '\0') { + if ((*fmt == '&' || *fmt == '~') && + (flags & (SETARGS|ARGVECTOR)) == SETARGS) { + curarg = va_arg(args, void *); + } + fmt++; + } + argp = sargp; + *pac = spac; + *pav = spav; + continue; + } + fmtp = fmt; + val = (long)llval; + if (fmt[1] == 'l' || fmt[1] == 'L') { + if (fmt[2] == 'l' || fmt[2] == 'L') { + if (flags & SETARGS) + *((Llong *)curarg) = llval; + fmt += 2; + } else { + if (flags & SETARGS) + *((long *)curarg) = val; + fmt++; + } + } else if (fmt[1] == 's' || fmt[1] == 'S') { + if (flags & SETARGS) + *((short *)curarg) = (short)val; + fmt++; + } else if (fmt[1] == 'c' || fmt[1] == 'C') { + if (flags & SETARGS) + *((char *)curarg) = (char)val; + fmt++; + } else { + if (fmt[1] == 'i' || fmt[1] == 'I') + fmt++; + if (flags & SETARGS) + *((int *)curarg) = (int)val; + } + + return (checkfmt(fmt)); + + case '~': + if (*argp != '\0') + goto nextchance; + if (haseql) { + return (BADFLAG); + } + goto callfunc; + + case '&': + if (*argp == '\0' && fmt[1] != '_') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + callfunc: + + if (*fmt == '&' && fmt[1] == '_') /* To disallow -f foo for f& */ + fmt++; + else if (fmt[1] == ' ') /* To disallow -ffoo for f& */ + fmt++; + if ((val = checkfmt(fmt)) != NOTAFLAG) + return (val); + + fmtp = sargp; + if (hasdash) + fmtp--; + if (doubledash) + fmtp--; + if ((flags & (SETARGS|ARGVECTOR)) == (SETARGS|ARGVECTOR)) { + int ret; + + if (flagp->ga_funcp == NULL) + return (BADFMT); + + ret = ((*flagp->ga_funcp) (argp, flagp->ga_arg, + pac, pav, fmtp)); + if (ret != NOTAFILE) + return (ret); + fmt++; + } else + if (flags & SETARGS) { + int ret; + void *funarg = va_arg(args, void *); + + if (curarg == NULL) + return (BADFMT); + ret = ((*(getpargfun)curarg) (argp, funarg, + pac, pav, fmtp)); + if (ret != NOTAFILE) + return (ret); + fmt++; + } else { + return (val); + } + /* + * Called function returns NOTAFILE: try next format. + */ + } + } +} + + +/* + * parse args for combined single char flags + */ +typedef struct { + void *curarg; /* The pointer to the arg to modify */ + void *curfun; /* The pointer to the function to call */ + char c; /* The single char flag character */ + char type; /* The type of the single char flag */ + char fmt; /* The format type of the single char flag */ + char val; /* The value to assign for BOOL flags */ +} sflags; + +LOCAL int +dosflags(argp, vfmt, pac, pav, flags, oargs) + register const char *argp; + void *vfmt; + int *pac; + char *const **pav; + int flags; + va_list oargs; +{ + register const char *fmt = (const char *)vfmt; + struct ga_flags *flagp = vfmt; +#define MAXSF 64 + sflags sf[MAXSF]; + char fl[256]; + va_list args; + register sflags *rsf = sf; + register int nsf = 0; + register const char *p = argp; + register int i; + register void *curarg = (void *)0; + getpargfun curfun = 0; + char type; + + /* + * Initialize 'args' to the start of the argument list. + * I don't know any portable way to copy an arbitrary + * C object so I use a system-specific routine + * (probably a macro) from stdarg.h. (Remember that + * if va_list is an array, 'args' will be a pointer + * and '&args' won't be what I would need for memcpy.) + * It is a system requirement for SVr4 compatibility + * to be able to do this assgignement. If your system + * defines va_list to be an array but does not define + * va_copy() you are lost. + * This is needed to make sure, that 'oargs' will not + * be clobbered. + */ + va_copy(args, oargs); + + if (flags & ARGVECTOR) { + fmt = flagp->ga_format; + if (fmt == NULL) + fmt = ""; + if (flags & SETARGS) { + curarg = flagp->ga_arg; + curfun = flagp->ga_funcp; + } + } else if (flags & SETARGS) { + /* + * We set curfun to curarg. We later get the real + * curarg in case that we see a function callback + * but we need curfun first in this case. + */ + curarg = va_arg(args, void *); + curfun = (getpargfun)curarg; + } + + for (i = 0; i < sizeof (fl); i++) { + fl[i] = 0; + } + while (*p) { + for (i = 0; i < nsf; i++) { + if (rsf[i].c == *p) + break; + } + if (i >= MAXSF) + return (BADFLAG); + if (i == nsf) { + rsf[i].curarg = (void *)0; + rsf[i].curfun = (void *)0; + rsf[i].c = *p; + rsf[i].type = (char)-1; + rsf[i].fmt = '\0'; + rsf[i].val = (char)TRUE; + nsf++; + } + fl[*p & 0xFF] = i; + p++; + } + +again: + while (*fmt) { + if (!isfmtspec(*fmt) && + (fmt[1] == ',' || fmt[1] == '+' || + fmt[1] == '~' || fmt[1] == '%' || fmt[1] == '\0') && + strchr(argp, *fmt)) { + for (i = 0; i < nsf; i++) { + if (rsf[i].c == *fmt) { + if (fmt[1] == '+') { + rsf[i].fmt = '+'; + fmt++; + if (fmt[1] == ',' || + fmt[1] == '\0') { + rsf[i].type = 'i'; + } else if ((fmt[1] == 'l' || + fmt[1] == 'L') && + (fmt[2] == 'l' || + fmt[2] == 'L')) { + /* + * Type 'Q'uad (ll) + */ + rsf[i].type = 'Q'; + fmt++; + } else { + /* + * Type 'l','i','s','c' + */ + rsf[i].type = fmt[1]; + } + } else if (fmt[1] == '%') { + fmt++; + rsf[i].fmt = '%'; + if (fmt[1] == '0') + rsf[i].val = (char)FALSE; + else if (fmt[1] == '1') + rsf[i].val = (char)TRUE; + fmt++; + if (fmt[1] == ',' || + fmt[1] == '\0') { + rsf[i].type = 'i'; + } else if ((fmt[1] == 'l' || + fmt[1] == 'L') && + (fmt[2] == 'l' || + fmt[2] == 'L')) { + /* + * Type 'Q'uad (ll) + */ + rsf[i].type = 'Q'; + fmt++; + } else { + /* + * Type 'l','i','s','c' + */ + rsf[i].type = fmt[1]; + } + } else if (fmt[1] == '~') { + /* + * Let fmt point to ',' to + * prevent to fetch the + * func arg twice. + */ + fmt += 2; + rsf[i].fmt = '~'; + rsf[i].type = '~'; + rsf[i].curfun = (void *)curfun; + if ((flags & (SETARGS|ARGVECTOR)) == SETARGS) + curarg = va_arg(args, void *); + } else { + /* + * ',' or '\0' for BOOL + */ + rsf[i].type = fmt[1]; + } + rsf[i].curarg = curarg; + break; + } + } + } + while (*fmt != ',' && *fmt != '\0') { + /* + * function has extra arg on stack. The code above + * prevents us from fetching this arg twice. + */ + if ((*fmt == '&' || *fmt == '~') && + (flags & (SETARGS|ARGVECTOR)) == SETARGS) { + curarg = va_arg(args, void *); + } + fmt++; + } + if (*fmt != '\0') + fmt++; + else + break; + + if ((flags & (SETARGS|ARGVECTOR)) == SETARGS) { + /* + * We set curfun to curarg. We later get the real + * curarg in case that we see a function callback + * but we need curfun first in this case. + */ + curarg = va_arg(args, void *); + curfun = (getpargfun)curarg; + } + } + if ((flags & ARGVECTOR) && flagp[1].ga_format != NULL) { + flagp++; + fmt = flagp->ga_format; + if (flags & SETARGS) { + curarg = flagp->ga_arg; + curfun = flagp->ga_funcp; + } + goto again; + } + + for (p = argp; *p; p++) { + char tfmt; + + i = fl[*p & 0xFF]; + tfmt = rsf[i].fmt; + type = rsf[i].type; + if (type == (char)-1) { + return (BADFLAG); + } + + if ((flags & SETARGS) && + (rsf[i].curfun || rsf[i].curarg)) { + if (type == ',' || type == '\0') { + *((int *)rsf[i].curarg) = TRUE; + } else if (type == 'i' || type == 'I') { + if (tfmt == '+') + *((int *)rsf[i].curarg) += 1; + else + *((int *)rsf[i].curarg) = rsf[i].val; + } else if (type == 'l' || type == 'L') { + if (tfmt == '+') + *((long *)rsf[i].curarg) += 1; + else + *((long *)rsf[i].curarg) = rsf[i].val; + } else if (type == 'Q') { + if (tfmt == '+') + *((Llong *)rsf[i].curarg) += 1; + else + *((Llong *)rsf[i].curarg) = rsf[i].val; + } else if (type == 's' || type == 'S') { + if (tfmt == '+') + *((short *)rsf[i].curarg) += 1; + else + *((short *)rsf[i].curarg) = rsf[i].val; + } else if (type == 'c' || type == 'C') { + if (tfmt == '+') + *((char *)rsf[i].curarg) += 1; + else + *((char *)rsf[i].curarg) = rsf[i].val; + } else if (type == '~') { + int ret; + char cfmt[3]; + + cfmt[0] = '-'; + cfmt[1] = rsf[i].c; + cfmt[2] = '\0'; + + if (rsf[i].curfun == NULL) + return (BADFMT); + ret = ((*(getpargfun)rsf[i].curfun) ("", + rsf[i].curarg, + pac, pav, cfmt)); + return (ret); + } else { + return (BADFLAG); + } + } + } + return (NOTAFLAG); +} + +/* + * If the next format character is a comma or the string delimiter, + * there are no invalid format specifiers. Return success. + * Otherwise raise the getarg_bad_format condition. + */ +LOCAL int +checkfmt(fmt) + const char *fmt; +{ + char c; + + c = *(++fmt); /* non constant expression */ + + + if (c == ',' || c == '\0') { + return (NOTAFLAG); + } else { + raisecond("getarg_bad_format", (long)fmt); + return (BADFMT); + } +} + +/* + * Parse the string as long as valid characters can be found. + * Valid flag identifiers are chosen from the set of + * alphanumeric characters, '-' and '_'. + * If the next character is an equal sign the string + * contains a valid flag identifier. + */ +LOCAL int +checkeql(str) + register const char *str; +{ + register unsigned char c; + + for (c = (unsigned char)*str; + isalnum(c) || c == '_' || c == '-' || c == '+'; + c = *++str) + /* LINTED */ + ; + return (c == '='); +} + +EXPORT char * +getargerror(err) + int err; +{ + if (err < RETMIN || err > RETMAX) + return ("Illegal arg error"); + return (RNAME(err)); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/geterrno.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/geterrno.c new file mode 100644 index 00000000000..372df96a2b3 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/geterrno.c @@ -0,0 +1,38 @@ +/* @(#)geterrno.c 1.14 10/08/23 Copyright 1985, 1995-2010 J. Schilling */ +/* + * Get error number + * + * Copyright (c) 1985, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _TS_ERRNO +#define _TS_ERRNO /* Solaris: get thread safe errno value */ +#endif +#ifndef _LIBC_REENTRANT +#define _LIBC_REENTRANT /* Linux: get thread safe errno value */ +#endif +#include +#include +#include + +#ifdef geterrno +#undef geterrno +#endif + +EXPORT int +geterrno() + +{ + return (errno); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/getexecpath.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/getexecpath.c new file mode 100644 index 00000000000..87c5af5ae6a --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/getexecpath.c @@ -0,0 +1,80 @@ +/* @(#)getexecpath.c 1.1 10/11/18 Copyright 2006-2010 J. Schilling */ +/* + * Copyright (c) 2006.2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include +#include + +#if (defined(sun) || defined(__sun) || defined(__sun__)) && defined(__SVR4) +#define PATH_IMPL +#define METHOD_SYMLINK +#define SYMLINK_PATH "/proc/self/path/a.out" /* Solaris 10 -> ... */ +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#define PATH_IMPL +#define METHOD_SYMLINK +#define SYMLINK_PATH "/proc/curproc/file" /* /proc may nor be mounted */ +#endif + +#if defined(__linux__) || defined(__linux)|| defined(linux) +#define PATH_IMPL +#define METHOD_SYMLINK +#define SYMLINK_PATH "/proc/self/exe" +#endif + +#if defined(HAVE_PROC_PIDPATH) /* Mac OS X */ +#ifdef HAVE_LIBPROC_H +#include +#endif +#define PATH_IMPL +#endif + +/* + * TODO: AIX: /proc/$$/object/a.out -> plain file, match via st_dev/st_ino + */ + + +EXPORT char * +getexecpath() +{ +#ifdef PATH_IMPL +#ifdef METHOD_SYMLINK + char buf[1024]; + ssize_t len; + + len = readlink(SYMLINK_PATH, buf, sizeof (buf)-1); + if (len == -1) + return (NULL); + buf[len] = '\0'; + return (strdup(buf)); +#endif +#ifdef HAVE_PROC_PIDPATH /* Mac OS X */ + char buf[1024]; + int len; + + len = proc_pidpath(getpid(), buf, sizeof (buf)); + if (len == -1) + return (NULL); + return (strdup(buf)); +#endif +#else + return (NULL); +#endif +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/gettimeofday.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/gettimeofday.c new file mode 100644 index 00000000000..d1d454fa206 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/gettimeofday.c @@ -0,0 +1,89 @@ +/* @(#)gettimeofday.c 1.9 12/11/29 Copyright 2007-2012 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)gettimeofday.c 1.9 12/11/29 Copyright 2007-2012 J. Schilling"; +#endif +/* + * Emulate gettimeofday where it does not exist + * + * Copyright (c) 2007-2012 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#if !defined(HAVE_GETTIMEOFDAY) +#if (defined(_MSC_VER) || defined(__MINGW32__)) +#include +#include +#include +#include + +#ifdef _MSC_VER +const __int64 MS_FTIME_ADD = 0x2b6109100i64; +const __int64 MS_FTIME_SECS = 10000000i64; +#else +const Int64_t MS_FTIME_ADD = 0x2b6109100LL; +const Int64_t MS_FTIME_SECS = 10000000LL; +#endif + +EXPORT int +gettimeofday(tp, dummy) + struct timeval *tp; + void *dummy; /* tzp is unspecified by POSIX */ +{ + FILETIME ft; + Int64_t T; + + if (tp == 0) + return (0); + + GetSystemTimeAsFileTime(&ft); /* 100ns time since 1601 */ + T = ft.dwHighDateTime; + T <<= 32; + T += ft.dwLowDateTime; + + /* + * Cast to avoid a loss of data warning + * MSVC uses long instead of time_t for tv_sec + */ + tp->tv_sec = (long) (T / MS_FTIME_SECS - MS_FTIME_ADD); + tp->tv_usec = (long) (T % MS_FTIME_SECS) / 10; + + return (0); +} +#else /* (defined(_MSC_VER) || defined(__MINGW32__)) */ + +#ifdef HAVE_TIME +#include +#include + +EXPORT int +gettimeofday(tp, dummy) + struct timeval *tp; + void *dummy; /* tzp is unspecified by POSIX */ +{ + time_t t; + + if (tp == 0) + return (0); + + (void) time(&t); + tp->tv_sec = t; + tp->tv_usec = 0; + + return (0); +} +#endif + +#endif /* (defined(_MSC_VER) || defined(__MINGW32__)) */ +#endif /* !defined(HAVE_GETTIMEOFDAY) */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/gid.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/gid.c new file mode 100644 index 00000000000..cbc35d6cb91 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/gid.c @@ -0,0 +1,64 @@ +/* @(#)gid.c 1.1 11/07/11 Copyright 2011 J. Schilling */ +/* + * Dummy functions for gid handling, used e.g. on MINGW + * + * Copyright (c) 2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#ifndef HAVE_GETGID + +EXPORT gid_t +getgid() +{ + return (0); +} + +#endif + +#ifndef HAVE_GETEGID + +EXPORT gid_t +getegid() +{ + return (0); +} + +#endif + +#ifndef HAVE_SETGID + +EXPORT int +setgid(gid) + gid_t gid; +{ + return (0); +} + +#endif + +#ifndef HAVE_SETEGID + +EXPORT int +setegid(gid) + gid_t gid; +{ + return (0); +} + +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/jsprintf.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/jsprintf.c new file mode 100644 index 00000000000..e9192aa78a7 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/jsprintf.c @@ -0,0 +1,198 @@ +/* @(#)jsprintf.c 1.19 16/01/21 Copyright 1985, 1995-2016 J. Schilling */ +/* + * Copyright (c) 1985, 1995-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef NO_FPRFORMAT +#undef USE_FPRFORMAT +#else +#define USE_FPRFORMAT +#endif + +#ifdef USE_FPRFORMAT +/* + * This is the speed-optimized version that currently only has been tested + * on Solaris. + * It is based on fprformat() instead of format() and is faster than the + * the format() based standard implementation, in case that putc() or + * putc_unlocked() is a macro. + */ + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +js_printf(const char *form, ...) +#else +EXPORT int +js_printf(form, va_alist) + char *form; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + ret = fprformat((long)stdout, form, args); + va_end(args); + return (ret); +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +js_fprintf(FILE *file, const char *form, ...) +#else +EXPORT int +js_fprintf(file, form, va_alist) + FILE *file; + char *form; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + ret = fprformat((long)file, form, args); + va_end(args); + return (ret); +} + +#else /* !USE_FPRFORMAT */ +/* + * This is the portable standard implementation that works anywhere. + */ + +#define BFSIZ 256 + +typedef struct { + short cnt; + char *ptr; + char buf[BFSIZ]; + int count; + FILE *f; +} *BUF, _BUF; + +LOCAL void _bflush __PR((BUF)); +LOCAL void _bput __PR((char, long)); +EXPORT int js_fprintf __PR((FILE *, const char *, ...)); +EXPORT int js_printf __PR((const char *, ...)); + +LOCAL void +_bflush(bp) + register BUF bp; +{ + bp->count += bp->ptr - bp->buf; + if (filewrite(bp->f, bp->buf, bp->ptr - bp->buf) < 0) + bp->count = EOF; + bp->ptr = bp->buf; + bp->cnt = BFSIZ; +} + +#ifdef PROTOTYPES +LOCAL void +_bput(char c, long l) +#else +LOCAL void +_bput(c, l) + char c; + long l; +#endif +{ + register BUF bp = (BUF)l; + + *bp->ptr++ = c; + if (--bp->cnt <= 0) + _bflush(bp); +} + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +js_printf(const char *form, ...) +#else +EXPORT int +js_printf(form, va_alist) + char *form; + va_dcl +#endif +{ + va_list args; + _BUF bb; + + bb.ptr = bb.buf; + bb.cnt = BFSIZ; + bb.count = 0; + bb.f = stdout; +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + format(_bput, (long)&bb, form, args); + va_end(args); + if (bb.cnt < BFSIZ) + _bflush(&bb); + return (bb.count); +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +js_fprintf(FILE *file, const char *form, ...) +#else +EXPORT int +js_fprintf(file, form, va_alist) + FILE *file; + char *form; + va_dcl +#endif +{ + va_list args; + _BUF bb; + + bb.ptr = bb.buf; + bb.cnt = BFSIZ; + bb.count = 0; + bb.f = file; +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + format(_bput, (long)&bb, form, args); + va_end(args); + if (bb.cnt < BFSIZ) + _bflush(&bb); + return (bb.count); +} +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/jssnprintf.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/jssnprintf.c new file mode 100644 index 00000000000..37f756e6a8f --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/jssnprintf.c @@ -0,0 +1,89 @@ +/* @(#)jssnprintf.c 1.13 16/08/10 Copyright 1985, 1995-2016 J. Schilling */ +/* + * Copyright (c) 1985, 1995-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include /* include try to get size_t */ +#include /* Try again for size_t */ +#include /* Try again for size_t */ +#include +#include +#include + +EXPORT int js_snprintf __PR((char *, size_t maxcnt, const char *, ...)); + +typedef struct { + char *ptr; + int count; +} *BUF, _BUF; + +#ifdef PROTOTYPES +static void +_cput(char c, long l) +#else +static void +_cput(c, l) + char c; + long l; +#endif +{ + register BUF bp = (BUF)l; + + if (--bp->count > 0) { + *bp->ptr++ = c; + } else { + /* + * Make sure that there will never be a negative overflow. + */ + bp->count++; + } +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +js_snprintf(char *buf, size_t maxcnt, const char *form, ...) +#else +EXPORT int +js_snprintf(buf, maxcnt, form, va_alist) + char *buf; + unsigned maxcnt; + char *form; + va_dcl +#endif +{ + va_list args; + int cnt; + _BUF bb; + + bb.ptr = buf; + bb.count = maxcnt; + +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + cnt = format(_cput, (long)&bb, form, args); + va_end(args); + if (maxcnt > 0) + *(bb.ptr) = '\0'; + if (bb.count < 0) + return (-1); + + return (cnt); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/match.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/match.c new file mode 100644 index 00000000000..addba2db7b4 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/match.c @@ -0,0 +1,470 @@ +/* @(#)match.c 1.24 10/08/21 Copyright 1985, 1995-2010 J. Schilling */ +#include +#include +/* + * Pattern matching functions + * + * Copyright (c) 1985, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ +/* + * The pattern matching functions below are based on the algorithm + * presented by Martin Richards in: + * + * "A Compact Function for Regular Expression Pattern Matching", + * Software-Practice and Experience, Vol. 9, 527-534 (1979) + * + * Several changes have been made to the original source which has been + * written in BCPL: + * + * '/' is replaced by '!' (to allow UNIX filenames) + * '(',')' are replaced by '{', '}' + * '\'' is replaced by '\\' (UNIX compatible quote) + * + * Character classes have been added to allow "[]" + * to be used. + * Start of line '^' and end of line '$' have been added. + */ + +#undef CHAR + +#ifdef __LINE_MATCH +#ifdef __WIDE_CHAR +#define patmatch patwlmatch +#else +#define opatmatch opatlmatch +#define patmatch patlmatch +#endif +#endif + +#ifdef __WIDE_CHAR +#ifndef __LINE_MATCH +#define patcompile patwcompile +#define patmatch patwmatch +#endif +#define CHAR wchar_t +#endif + +#ifndef CHAR +typedef unsigned char Uchar; +#define CHAR Uchar +#endif + +#define ENDSTATE (-1) + +/* + * The Interpreter + */ + + +/* + * put adds a new state to the active list + */ +#define put(ret, state, sp, n) { \ + register int *lstate = state; \ + register int *lsp = sp; \ + register int ln = n; \ + \ + while (lstate < lsp) { \ + if (*lstate++ == ln) { \ + ret = lsp; \ + lsp = 0; \ + break; \ + } \ + } \ + if (lsp) { \ + *lstate++ = ln; \ + ret = lstate; \ + } \ +} + + +/* + * match a character in class + */ +#define in_class(found, pat, c) { \ + register const CHAR *lpat = pat; \ + register int lc = c; \ + int lo_bound; \ + int hi_bound; \ + \ + found = FALSE; \ + \ + if (*lpat == NOT) { \ + lpat++; \ + found = TRUE; \ + } \ + while (*lpat != RCLASS) { \ + if (*lpat == QUOTE) \ + lpat++; \ + lo_bound = *lpat++; \ + if (*lpat == RANGE) { \ + lpat++; \ + if (*lpat == QUOTE) \ + lpat++; \ + hi_bound = *lpat++; \ + } else { \ + hi_bound = lo_bound; \ + } \ + if (lo_bound <= lc && lc <= hi_bound) { \ + found = !found; \ + break; \ + } \ + } \ +} + +/* + * opatmatch - the old external interpreter interface. + * + * Trys to match a string beginning at offset + * against the compiled pattern. + */ +#ifndef __WIDE_CHAR +EXPORT CHAR +*opatmatch(pat, aux, str, soff, slen, alt) + const CHAR *pat; + const int *aux; + const CHAR *str; + int soff; + int slen; + int alt; +{ + int state[MAXPAT]; + + return (patmatch(pat, aux, str, soff, slen, alt, state)); +} +#endif + +/* + * patmatch - the external interpreter interface. + * + * Trys to match a string beginning at offset + * against the compiled pattern. + */ +EXPORT CHAR * +patmatch(pat, aux, str, soff, slen, alt, state) + const CHAR *pat; + const int *aux; + const CHAR *str; + int soff; + int slen; + int alt; + int state[]; +{ + register int *sp; + register int *n; + register int *i; + register int p; + register int q, s, k; + int c; + const CHAR *lastp = (CHAR *)NULL; + +#ifdef __LINE_MATCH +for (; soff <= slen; soff++) { +#endif + + sp = state; + put(sp, state, state, 0); + if (alt != ENDSTATE) + put(sp, state, sp, alt); + + for (s = soff; ; s++) { + /* + * next char from input string + */ + if (s >= slen) + c = 0; + else + c = str[s]; + /* + * first complete the closure + */ + for (n = state; n < sp; ) { + p = *n++; /* next state number */ + if (p == ENDSTATE) + continue; + q = aux[p]; /* get next state for pat */ + k = pat[p]; /* get next char from pat */ + switch (k) { + + case REP: + put(sp, state, sp, p+1); + /* FALLTHRU */ + case NIL: /* NIL matches always */ + case STAR: + put(sp, state, sp, q); + break; + case LBRACK: /* alternations */ + case ALT: + put(sp, state, sp, p+1); + if (q != ENDSTATE) + put(sp, state, sp, q); + break; + case START: + if (s == 0) + put(sp, state, sp, q); + break; + case END: + if (c == '\0') + put(sp, state, sp, q); + break; + } + } + + for (i = state; i < sp; ) { + if (*i++ == ENDSTATE) { + lastp = &str[s]; + break; + } + } + if (c == 0) + return ((CHAR *)lastp); + + /* + * now try to match next character + */ + n = sp; + sp = state; + for (i = sp; i < n; ) { + p = *i++; /* next active state number */ + if (p == ENDSTATE) + continue; + k = pat[p]; + switch (k) { + + case ALT: + case REP: + case NIL: + case LBRACK: + case START: + case END: + continue; + case LCLASS: + in_class(q, &pat[p+1], c); + if (!q) + continue; + break; + case STAR: + put(sp, state, sp, p); + continue; + case QUOTE: + k = pat[p+1]; + default: + if (k != c) + continue; + /* FALLTHRU */ + case ANY: + break; + } + put(sp, state, sp, aux[p]); + } + if (sp == state) { /* if no new states return */ +#ifdef __LINE_MATCH + + if (lastp || (soff == slen - 1)) + return ((CHAR *)lastp); + else + break; +#else + return ((CHAR *)lastp); +#endif + } + } +#ifdef __LINE_MATCH +} +return ((CHAR *)lastp); +#endif +} + + +#ifndef __LINE_MATCH +/* + * The Compiler + */ + +typedef struct args { + const CHAR *pattern; + int *aux; + int patp; + int length; + CHAR Ch; +} arg_t; + +LOCAL void nextitem __PR((arg_t *)); +LOCAL int prim __PR((arg_t *)); +LOCAL int expr __PR((arg_t *, int *)); +LOCAL void setexits __PR((int *, int, int)); +LOCAL int join __PR((int *, int, int)); + +/* + * 'read' the next character from pattern + */ +#define rch(ap) \ +{ \ + if (++(ap)->patp >= (ap)->length) \ + (ap)->Ch = 0; \ + else \ + (ap)->Ch = (ap)->pattern[(ap)->patp]; \ +} + +/* + * get the next item from pattern + */ +LOCAL void +nextitem(ap) + arg_t *ap; +{ + if (ap->Ch == QUOTE) + rch(ap); + rch(ap); +} + +/* + * parse a primary + */ +LOCAL int +prim(ap) + arg_t *ap; +{ + int a = ap->patp; + int op = ap->Ch; + int t; + + nextitem(ap); + switch (op) { + + case '\0': + case ALT: + case RBRACK: + return (ENDSTATE); + case LCLASS: + while (ap->Ch != RCLASS && ap->Ch != '\0') + nextitem(ap); + if (ap->Ch == '\0') + return (ENDSTATE); + nextitem(ap); + break; + case REP: + t = prim(ap); + if (t == ENDSTATE) + return (ENDSTATE); + setexits(ap->aux, t, a); + break; + case LBRACK: + a = expr(ap, &ap->aux[a]); + if (a == ENDSTATE || ap->Ch != RBRACK) + return (ENDSTATE); + nextitem(ap); + break; + } + return (a); +} + +/* + * parse an expression (a sequence of primaries) + */ +LOCAL int +expr(ap, altp) + arg_t *ap; + int *altp; +{ + int exits = ENDSTATE; + int a; + int *aux = ap->aux; + CHAR Ch; + + for (;;) { + a = prim(ap); + Ch = ap->Ch; + if (Ch == ALT || Ch == RBRACK || Ch == '\0') { + exits = join(aux, exits, a); + if (Ch != ALT) + return (exits); + *altp = ap->patp; + altp = &aux[ap->patp]; + nextitem(ap); + } else + setexits(aux, a, ap->patp); + } +} + +/* + * set all exits in a list to a specified value + */ +LOCAL void +setexits(aux, list, val) + int *aux; + int list; + int val; +{ + int a; + + while (list != ENDSTATE) { + a = aux[list]; + aux[list] = val; + list = a; + } +} + +/* + * concatenate two lists + */ +LOCAL int +join(aux, a, b) + int *aux; + int a; + int b; +{ + int t; + + if (a == ENDSTATE) + return (b); + t = a; + while (aux[t] != ENDSTATE) + t = aux[t]; + aux[t] = b; + return (a); +} + +/* + * patcompile - the external compiler interface. + * + * The pattern is compiled into the aux array. + * Return value on success, is the outermost alternate which is != 0. + * Error is indicated by return of 0. + */ +EXPORT int +patcompile(pat, len, aux) + const CHAR *pat; + int len; + int *aux; +{ + arg_t a; + int alt = ENDSTATE; + int i; + + a.pattern = pat; + a.length = len; + a.aux = aux; + a.patp = -1; + + for (i = 0; i < len; i++) + aux[i] = ENDSTATE; + rch(&a); + i = expr(&a, &alt); + if (i == ENDSTATE) + return (0); + setexits(aux, i, ENDSTATE); + return (alt); +} +#endif /* LMATCH */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/mem.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/mem.c new file mode 100644 index 00000000000..b8c9c2a79ff --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/mem.c @@ -0,0 +1,104 @@ +/* @(#)mem.c 1.11 15/05/10 Copyright 1998-2015 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)mem.c 1.11 15/05/10 Copyright 1998-2015 J. Schilling"; +#endif +/* + * Memory handling with error checking + * + * Copyright (c) 1998-2015 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include +#include +#include + +EXPORT int ___mexval __PR((int exval)); +EXPORT void *___malloc __PR((size_t size, char *msg)); +EXPORT void *___realloc __PR((void *ptr, size_t size, char *msg)); +EXPORT char *___savestr __PR((const char *s)); + +LOCAL int mexval; + +EXPORT int +___mexval(exval) + int exval; +{ + int ret = mexval; + + mexval = exval; + + return (ret); +} + +EXPORT void * +___malloc(size, msg) + size_t size; + char *msg; +{ + void *ret; + + ret = malloc(size); + if (ret == NULL) { + int err = geterrno(); + + errmsg(gettext("Cannot allocate memory for %s.\n"), msg); + if (mexval) + err = mexval; + comexit(err); + /* NOTREACHED */ + } + return (ret); +} + +EXPORT void * +___realloc(ptr, size, msg) + void *ptr; + size_t size; + char *msg; +{ + void *ret; + + if (ptr == NULL) + ret = malloc(size); + else + ret = realloc(ptr, size); + if (ret == NULL) { + int err = geterrno(); + + errmsg(gettext("Cannot realloc memory for %s.\n"), msg); + if (mexval) + err = mexval; + comexit(err); + /* NOTREACHED */ + } + return (ret); +} + +EXPORT char * +___savestr(s) + const char *s; +{ + char *ret = ___malloc(strlen(s)+1, "saved string"); + + strcpy(ret, s); + return (ret); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/movebytes.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/movebytes.c new file mode 100644 index 00000000000..74e6db3ccde --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/movebytes.c @@ -0,0 +1,125 @@ +/* @(#)movebytes.c 1.18 09/10/17 Copyright 1985, 1989, 1995-2009 J. Schilling */ +/* + * move data + * + * Copyright (c) 1985, 1989, 1995-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#define DO8(a) a; a; a; a; a; a; a; a; + +/* + * movebytes(from, to, cnt) is the same as memmove(to, from, cnt) + */ +EXPORT char * +movebytes(fromv, tov, cnt) + const void *fromv; + void *tov; + ssize_t cnt; +{ + register const char *from = fromv; + register char *to = tov; + register ssize_t n; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (to); + + if (from >= to) { + /* + * source is on higher addresses than destination: + * move bytes forwards + */ + if (n >= (ssize_t)(8 * sizeof (long))) { + if (l2aligned(from, to)) { + register const long *froml = (const long *)from; + register long *tol = (long *)to; + register ssize_t rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + do { + DO8 (*tol++ = *froml++); + } while (--n > 0); + + from = (const char *)froml; + to = (char *)tol; + n = rem; + } + + if (n >= 8) { + n -= 8; + do { + DO8 (*to++ = *from++); + } while ((n -= 8) >= 0); + n += 8; + } + + if (n > 0) do { + *to++ = *from++; + } while (--n > 0); + return (to); + } + if (n > 0) do { + *to++ = *from++; + } while (--n > 0); + return (to); + } else { + char *ep; + + /* + * source is on lower addresses than destination: + * move bytes backwards + */ + to += n; + from += n; + ep = to; + if (n >= (ssize_t)(8 * sizeof (long))) { + if (l2aligned(from, to)) { + register const long *froml = (const long *)from; + register long *tol = (long *)to; + register ssize_t rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + do { + DO8 (*--tol = *--froml); + } while (--n > 0); + + from = (const char *)froml; + to = (char *)tol; + n = rem; + } + if (n >= 8) { + n -= 8; + do { + DO8 (*--to = *--from); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + *--to = *--from; + } while (--n > 0); + return (ep); + } + if (n > 0) do { + *--to = *--from; + } while (--n > 0); + return (ep); + } +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/raisecond.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/raisecond.c new file mode 100644 index 00000000000..95414023ac4 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/raisecond.c @@ -0,0 +1,172 @@ +/* @(#)raisecond.c 1.22 09/07/10 Copyright 1985, 1989, 1995-2004 J. Schilling */ +/* + * raise a condition (software signal) + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ +/* + * Check for installed condition handlers. + * If a handler is found, the function is called with the appropriate args. + * If no handler is found or no handler signals success, + * the program will be aborted. + * + * Copyright (c) 1985, 1989, 1995-2004 J. Schilling + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +/* + * Macros to print to stderr without stdio, to avoid screwing up. + */ +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif +#define eprints(a) (void)write(STDERR_FILENO, (a), sizeof (a)-1) +#define eprintl(a) (void)write(STDERR_FILENO, (a), strlen(a)) + +#define is_even(p) ((((long)(p)) & 1) == 0) +#define even(p) (((long)(p)) & ~1L) +#ifdef __future__ +#define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */ +#endif + + +LOCAL void raiseabort __PR((const char *)); + +#ifdef HAVE_SCANSTACK +#include +#define next_frame(vp) do { \ + if (((struct frame *)(vp))->fr_savfp == 0) { \ + vp = (void *)0; \ + break; \ + } \ + if (((struct frame *)(vp))->fr_savpc == 0) { \ + vp = (void *)0; \ + break; \ + } \ + vp = \ + (void *)((struct frame *)(vp))->fr_savfp; \ + } while (vp != NULL && is_even(vp)); \ + vp = (struct frame *)even(vp); +#else +#if defined(IS_MACOS_X) +/* + * The MAC OS X linker does not grok "common" varaibles. + * Make __roothandle a "data" variable. + */ +EXPORT SIGBLK *__roothandle = 0; +#else +EXPORT SIGBLK *__roothandle; +#endif + +#define next_frame(vp) vp = (((SIGBLK *)(vp))->sb_savfp); +#endif + +LOCAL BOOL framehandle __PR((SIGBLK *, const char *, const char *, long)); + +/* + * Loop through the chain of procedure frames on the stack. + * + * Frame pointers normally have even values. + * Frame pointers of procedures with an installed handler are marked odd. + * The even base value, in this case actually points to a SIGBLK which + * holds the saved "real" frame pointer. + * The SIGBLK mentioned above may me the start of a chain of SIGBLK's, + * containing different handlers. + */ +EXPORT void +raisecond(signame, arg2) + const char *signame; + long arg2; +{ + register void *vp = NULL; + +#ifdef HAVE_SCANSTACK + /* + * As the SCO OpenServer C-Compiler has a bug that may cause + * the first function call to getfp() been done before the + * new stack frame is created, we call getfp() twice. + */ + (void) getfp(); + vp = getfp(); + next_frame(vp); +#else + vp = __roothandle; +#endif + + while (vp) { + if (framehandle((SIGBLK *)vp, signame, signame, arg2)) + return; + else if (framehandle((SIGBLK *)vp, "any_other", signame, arg2)) + return; +#ifdef HAVE_SCANSTACK + vp = (struct frame *)((SIGBLK *)vp)->sb_savfp; +#endif + next_frame(vp); + } + /* + * No matching handler that signals success found. + * Print error message and abort. + */ + raiseabort(signame); + /* NOTREACHED */ +} + +/* + * Loop through the handler chain for a procedure frame. + * + * If no handler with matching name is found, return FALSE, + * otherwise the first handler with matching name is called. + * The return value in the latter case depends on the called function. + */ +LOCAL BOOL +framehandle(sp, handlename, signame, arg2) + register SIGBLK *sp; + const char *handlename; + const char *signame; + long arg2; +{ + for (; sp; sp = sp->sb_signext) { + if (sp->sb_signame != NULL && + streql(sp->sb_signame, handlename)) { + if (sp->sb_sigfun == NULL) { /* deactivated */ + return (FALSE); + } else { + return (*sp->sb_sigfun)(signame, + sp->sb_sigarg, arg2); + } + } + } + return (FALSE); +} + +LOCAL void +raiseabort(signame) + const char *signame; +{ + eprints("Condition not caught: "); eprintl(signame); eprints(".\n"); + abort(); + /* NOTREACHED */ +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/saveargs.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/saveargs.c new file mode 100644 index 00000000000..230194fc94a --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/saveargs.c @@ -0,0 +1,221 @@ +/* @(#)saveargs.c 1.16 10/11/18 Copyright 1995-2010 J. Schilling */ +/* + * save argc, argv for command error printing routines + * + * Copyright (c) 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +#ifdef HAVE_VAR___PROGNAME +extern char *__progname; +#ifdef HAVE_VAR___PROGNAME_FULL +extern char *__progname_full; +#else +#define __progname_full __progname +#endif +#endif + +static int ac_saved; +static char **av_saved; +static char *av0_saved; +static char *av0_name_saved; +static char *progpath_saved; +static char *progname_saved; + +static char av0_sp[32]; /* av0 space, avoid malloc() in most cases */ +static char prn_sp[32]; /* name space, avoid malloc() in most cases */ +static char dfl_str[] = "?"; + +LOCAL void save_av0 __PR((char *av0)); +LOCAL void init_progname __PR((void)); +LOCAL void init_arginfo __PR((void)); + +EXPORT void +save_args(ac, av) + int ac; + char *av[]; +{ + ac_saved = ac; + av_saved = av; + save_av0(av[0]); +} + +LOCAL void +save_av0(av0) + char *av0; +{ + int slen; + char *p; + + if (av0_saved && av0_saved != av0_sp) + free(av0_saved); + + slen = strlen(av0) + 1; + + if (slen <= (int)sizeof (av0_sp)) + av0_saved = av0_sp; + else + av0_saved = malloc(slen); + + if (av0_saved) { + strcpy(av0_saved, av0); + av0 = av0_saved; + } + + if ((p = strrchr(av0, '/')) == NULL) + av0_name_saved = av0; + else + av0_name_saved = ++p; +} + +EXPORT int +saved_ac() +{ + if (av_saved == NULL) + init_arginfo(); + + return (ac_saved); +} + +EXPORT char ** +saved_av() +{ + if (av_saved == NULL) + init_arginfo(); + + return (av_saved); +} + +EXPORT char * +saved_av0() +{ + if (av0_saved == NULL) + init_arginfo(); + + return (av0_saved); +} + +EXPORT void +set_progname(name) + const char *name; +{ + int slen; + char *p; + + if (progpath_saved && progpath_saved != prn_sp) + free(progpath_saved); + + slen = strlen(name) + 1; + + if (slen <= sizeof (prn_sp)) + progpath_saved = prn_sp; + else + progpath_saved = malloc(slen); + + if (progpath_saved) { + strcpy(progpath_saved, name); + name = progpath_saved; + } + + if ((p = strrchr(name, '/')) == NULL) + progname_saved = (char *)name; + else + progname_saved = ++p; +} + +EXPORT char * +get_progname() +{ + if (progname_saved) + return (progname_saved); + if (av0_name_saved == NULL) + init_progname(); + if (av0_name_saved) + return (av0_name_saved); + return (dfl_str); +} + +EXPORT char * +get_progpath() +{ + if (progpath_saved) + return (progpath_saved); + if (av0_saved == NULL) + init_progname(); + if (av0_saved) + return (av0_saved); + return (dfl_str); +} + +LOCAL void +init_progname() +{ +#if defined(HAVE_SCANSTACK) || defined(HAVE_GETPROGNAME) + char *progname; +#endif + + if (av0_name_saved == NULL) + init_arginfo(); + if (av0_name_saved) + return; +#ifdef HAVE_GETPROGNAME + progname = (char *)getprogname(); + if (progname) { + save_av0(progname); + return; + } +#endif +#ifdef HAVE_VAR___PROGNAME + if (__progname_full) { + save_av0(__progname_full); + return; + } +#endif +#ifdef HAVE_SCANSTACK + progname = getav0(); /* scan stack to get argv[0] */ + if (progname) { + save_av0(progname); + return; + } +#endif +} + +LOCAL void +init_arginfo() +{ +#if defined(HAVE_DLINFO) && defined(HAVE_DLOPEN_IN_LIBC) && defined(RTLD_DI_ARGSINFO) + Dl_argsinfo args; + + if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0 || + args.dla_argc <= 0 || + args.dla_argv[0] == NULL) + return; + + if (av_saved == NULL) + save_args(args.dla_argc, args.dla_argv); +#endif +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/searchinpath.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/searchinpath.c new file mode 100644 index 00000000000..76dbab887d0 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/searchinpath.c @@ -0,0 +1,245 @@ +/* @(#)searchinpath.c 1.5 16/08/01 Copyright 1999-2016 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)searchinpath.c 1.5 16/08/01 Copyright 1999-2016 J. Schilling"; +#endif +/* + * Search a file name in the PATH of the current exeecutable. + * Return the path to the file name in allocated space. + * + * Copyright (c) 1999-2016 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include /* getexecname() */ +#include +#include +#include +#include + + +#define NAMEMAX 4096 + +EXPORT char *searchfileinpath __PR((char *name, int mode, + int file_mode, + char *path)); +LOCAL char *searchonefile __PR((char *name, int mode, + BOOL plain_file, + char *xn, + char *nbuf, + char *np, char *ep)); +#if defined(__DJGPP__) +LOCAL char *strbs2s __PR((char *s)); +#endif + +#ifdef JOS +#define enofile(t) ((t) == EMISSDIR || \ + (t) == ENOFILE || \ + (t) == EISADIR || \ + (t) == EIOERR) +#else +#define enofile(t) ((t) == ENOENT || \ + (t) == ENOTDIR || \ + (t) == EISDIR || \ + (t) == EIO) +#endif + +/* + * Search for the "name" file in the PATH of the user. + * Assume that the file is ... bin/../name. + */ +EXPORT char * +searchfileinpath(name, mode, file_mode, path) + char *name; /* Find /../name in PATH */ + int mode; /* Mode for access() e.g. X_OK */ + int file_mode; /* How to check files */ + char *path; /* PATH to use if not NULL */ +{ + char pbuf[NAMEMAX]; + char *nbuf = pbuf; + char *np; + char *ep; + char *xn; + int nlen = strlen(name); + int oerrno = geterrno(); + int err = 0; +#ifdef HAVE_GETEXECNAME + char *pn = (char *)getexecname(); /* pn is on the stack */ +#else + char *pn = getexecpath(); /* pn is from strdup() */ + char ebuf[NAMEMAX]; + + if (pn) { + strlcpy(ebuf, pn, sizeof (ebuf)); + free(pn); + pn = ebuf; + } +#endif + + if (pn == NULL) + xn = get_progname(); + else + xn = pn; + if ((np = strrchr(xn, '/')) != NULL) + xn = ++np; + + /* + * getexecname() is the best choice for our seach. getexecname() + * returns either "foo" (if called from the current directory) or + * an absolute path after symlinks have been resolved. + * If getexecname() returns a path with slashes, try to search + * first relatively to the known location of the current binary. + */ + if ((file_mode & SIP_ONLY_PATH) == 0 && + pn != NULL && strchr(pn, '/') != NULL) { + strlcpy(nbuf, pn, sizeof (pbuf)); + np = nbuf + strlen(nbuf); + + while (np > nbuf && np[-1] != '/') + *--np = '\0'; + pn = &nbuf[sizeof (pbuf) - 1]; + if ((np = searchonefile(name, mode, + file_mode & (SIP_PLAIN_FILE|SIP_NO_STRIPBIN), + xn, + nbuf, np, pn)) != NULL) { + seterrno(oerrno); + return (np); + } + } + + if (file_mode & SIP_NO_PATH) + return (NULL); + + if (path == NULL) + path = getenv("PATH"); + if (path == NULL) + return (NULL); + + +#ifdef __DJGPP__ + path = strdup(path); + if (path == NULL) + return (NULL); + strbs2s(path); /* PATH under DJGPP can contain both slashes */ +#endif + + /* + * A PATH name search should lead us to the path under which we + * called the binary, but not necessarily to the install path as + * we may have been called thorugh a symlink or hardlink. In case + * of a symlink, we can follow the link. In case of a hardlink, we + * are lost. + */ + ep = &nbuf[sizeof (pbuf) - 1]; + for (;;) { + np = nbuf; + while (*path != PATH_ENV_DELIM && *path != '\0' && + np < &nbuf[sizeof (pbuf) - nlen]) + *np++ = *path++; + *np = '\0'; + if ((np = searchonefile(name, mode, + file_mode & (SIP_PLAIN_FILE|SIP_NO_STRIPBIN), + xn, + nbuf, np, ep)) != NULL) { +#ifdef __DJGPP__ + free(path); +#endif + seterrno(oerrno); + return (np); + } + if (err == 0) { + err = geterrno(); + if (enofile(err)) + err = 0; + } + if (*path == '\0') + break; + path++; + } +#ifdef __DJGPP__ + free(path); +#endif + if (err) + seterrno(err); + else + seterrno(oerrno); + return (NULL); +} + +LOCAL char * +searchonefile(name, mode, plain_file, xn, nbuf, np, ep) + register char *name; /* Find /../name in PATH */ + int mode; /* Mode for access() e.g. X_OK */ + BOOL plain_file; /* Whether to check only plain files */ + char *xn; /* The basename of the executable */ + register char *nbuf; /* Name buffer base */ + register char *np; /* Where to append name to path */ + register char *ep; /* Point to last valid char in nbuf */ +{ + struct stat sb; + + while (np > nbuf && np[-1] == '/') + *--np = '\0'; + if (xn) { + *np++ = '/'; + strlcpy(np, xn, ep - np); + if (stat(nbuf, &sb) < 0) + return (NULL); + if (!S_ISREG(sb.st_mode)) + return (NULL); + *--np = '\0'; + } + if ((plain_file & SIP_NO_STRIPBIN) == 0) { + if (np >= &nbuf[4] && streql(&np[-4], "/bin")) + np = &np[-4]; + } + plain_file &= SIP_PLAIN_FILE; + *np++ = '/'; + *np = '\0'; + strlcpy(np, name, ep - np); + + seterrno(0); + if (stat(nbuf, &sb) >= 0) { + if ((!plain_file || S_ISREG(sb.st_mode)) && + (eaccess(nbuf, mode) >= 0)) { + return (strdup(nbuf)); + } + if (geterrno() == 0) + seterrno(EACCES); + } + return (NULL); +} + +#ifdef __DJGPP__ +LOCAL char * +strbs2s(s) + char *s; +{ + char *tmp = s; + + if (tmp) { + while (*tmp) { + if (*tmp == '\\') + *tmp = '/'; + tmp++; + } + } + return (s); +} +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/seterrno.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/seterrno.c new file mode 100644 index 00000000000..046c9133bc0 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/seterrno.c @@ -0,0 +1,41 @@ +/* @(#)seterrno.c 1.13 10/08/23 Copyright 1985, 1995-2010 J. Schilling */ +/* + * Set error number + * + * Copyright (c) 1985, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _TS_ERRNO +#define _TS_ERRNO /* Solaris: get thread safe errno value */ +#endif +#ifndef _LIBC_REENTRANT +#define _LIBC_REENTRANT /* Linux: get thread safe errno value */ +#endif +#include +#include +#include + +#ifdef seterrno +#undef seterrno +#endif + +EXPORT int +seterrno(err) + int err; +{ + int old = errno; + + errno = err; + return (old); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/cvmod.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/cvmod.c new file mode 100644 index 00000000000..eb886565343 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/cvmod.c @@ -0,0 +1,59 @@ +/* @(#)cvmod.c 2.9 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +EXPORT int +_cvmod(mode, omode, flag) + const char *mode; + int *omode; + int *flag; +{ + while (*mode) { + switch (*mode) { + + case 'r': *omode |= O_RDONLY; *flag |= FI_READ; break; + case 'w': *omode |= O_WRONLY; *flag |= FI_WRITE; break; + case 'e': *omode |= O_EXCL; break; + case 'c': *omode |= O_CREAT; *flag |= FI_CREATE; break; + case 't': *omode |= O_TRUNC; *flag |= FI_TRUNC; break; + case 'a': *omode |= O_APPEND; *flag |= FI_APPEND; break; + case 'u': *flag |= FI_UNBUF; break; + /* dummy on UNIX */ + case 'b': *omode |= O_BINARY; *flag |= FI_BINARY; break; + /* + * XXX do we need this ? + * XXX May this be a problem? + */ + case 'l': *omode |= O_LARGEFILE; break; + default: raisecond(_badmode, 0L); + return (0); + } + mode++; + } + if (*flag & FI_READ && *flag & FI_WRITE) { + *omode &= ~(O_RDONLY|O_WRONLY); + *omode |= O_RDWR; + } + return (1); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/dat.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/dat.c new file mode 100644 index 00000000000..b0554ca10db --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/dat.c @@ -0,0 +1,19 @@ +/* @(#)dat.c 1.3 03/06/15 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +char _badfile[] = "bad_file"; +char _badmode[] = "bad_file_mode"; +char _badop[] = "bad_file_op"; diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fcons.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fcons.c new file mode 100644 index 00000000000..a389adde0a1 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fcons.c @@ -0,0 +1,79 @@ +/* @(#)fcons.c 2.20 10/11/06 Copyright 1986, 1995-2010 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using + * fseeko()/ftello() instead of fseek()/ftell() if available. + */ + +LOCAL char *fmtab[] = { + "", /* 0 FI_NONE */ + "r", /* 1 FI_READ */ + "w", /* 2 FI_WRITE **1) */ + "r+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "wb", /* 6 FI_WRITE | FI_BINARY **1) */ + "r+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + +/* + FI_APPEND */ "", /* 0 FI_NONE */ +/* ... */ "r", /* 1 FI_READ */ + "a", /* 2 FI_WRITE **1) */ + "a+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "ab", /* 6 FI_WRITE | FI_BINARY **1) */ + "a+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + }; +/* + * NOTES: + * 1) fdopen() guarantees not to create/trunc files in this case + * + * "w" will create/trunc files with fopen() + * "a" will create files with fopen() + */ + + +EXPORT FILE * +_fcons(fd, f, flag) + register FILE *fd; + int f; + int flag; +{ + int my_gflag = _io_glflag; + + if (fd == (FILE *)NULL) + fd = fdopen(f, + fmtab[flag&(FI_READ|FI_WRITE|FI_BINARY | FI_APPEND)]); + + if (fd != (FILE *)NULL) { + if (flag & FI_APPEND) { + (void) fseek(fd, (off_t)0, SEEK_END); + } + if (flag & FI_UNBUF) { + setbuf(fd, NULL); + my_gflag |= _JS_IOUNBUF; + } + set_my_flag(fd, my_gflag); /* must clear it if fd is reused */ + return (fd); + } + if (flag & FI_CLOSE) + close(f); + + return ((FILE *)NULL); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/ffileread.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/ffileread.c new file mode 100644 index 00000000000..18081285822 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/ffileread.c @@ -0,0 +1,40 @@ +/* @(#)ffileread.c 1.13 09/06/30 Copyright 1986, 1996-2009 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +EXPORT ssize_t +ffileread(f, buf, len) + register FILE *f; + void *buf; + size_t len; +{ + register int fd; + register ssize_t ret; + int oerrno = geterrno(); + + down2(f, _IOREAD, _IORW); + fd = fileno(f); + + while ((ret = read(fd, buf, len)) < 0 && geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the errno visible + * to the outside if we did not fail. + */ + seterrno(oerrno); + } + return (ret); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fgetline.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fgetline.c new file mode 100644 index 00000000000..c222390ea23 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fgetline.c @@ -0,0 +1,138 @@ +/* @(#)fgetline.c 1.13 14/03/27 Copyright 1986, 1996-2014 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2014 J. Schilling + * + * This is an interface that exists in the public since 1982. + * The POSIX.1-2008 standard did ignore POSIX rules not to + * redefine existing public interfaces and redefined the interfaces + * forcing us to add a js_*() prefix to the original functions. + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#define fgetline __no__fgetline__ +#define getline __no__getline__ + +#include "schilyio.h" + +#ifndef NO_GETLINE_COMPAT /* Define to disable backward compatibility */ +#undef fgetline +#undef getline +#ifdef HAVE_PRAGMA_WEAK +#pragma weak fgetline = js_fgetline +#pragma weak getline = js_getline +#else + +EXPORT int fgetline __PR((FILE *, char *, int)); +EXPORT int getline __PR((char *, int)); + +EXPORT int +fgetline(f, buf, len) + FILE *f; + char *buf; + int len; +{ + return (js_fgetline(f, buf, len)); +} + +EXPORT int +getline(buf, len) + char *buf; + int len; +{ + return (js_fgetline(stdin, buf, len)); +} +#endif +#endif + +/* + * XXX should we check if HAVE_USG_STDIO is defined and + * XXX use something line memccpy to speed things up ??? + * XXX On Solaris 64 bits, we may use #define FAST_GETC_PUTC + * XXX and getc_unlocked() + */ +#if !defined(getc) && defined(USE_FGETS_FOR_FGETLINE) +#include + +EXPORT int +js_fgetline(f, buf, len) + register FILE *f; + char *buf; + register int len; +{ + char *bp = fgets(buf, len, f); + + if (bp) { + len = strlen(bp); + + if (len > 0) { + if (bp[len-1] == '\n') + bp[--len] = '\0'; + } + return (len); + } + buf[0] = '\0'; + return (-1); +} + +#else +EXPORT int +js_fgetline(f, buf, len) + register FILE *f; + char *buf; + register int len; +{ + register int c = '\0'; + register char *bp = buf; + register int nl = '\n'; + + down2(f, _IOREAD, _IORW); + + for (;;) { + if ((c = getc(f)) < 0) + break; + if (c == nl) + break; + if (--len > 0) { + *bp++ = (char)c; + } else { +#ifdef __never__ + /* + * Read up to end of line + */ + while ((c = getc(f)) >= 0 && c != nl) + /* LINTED */ + ; +#endif + break; + } + } + *bp = '\0'; + /* + * If buffer is empty and we hit EOF, return EOF + */ + if (c < 0 && bp == buf) + return (c); + + return (bp - buf); +} +#endif + +EXPORT int +js_getline(buf, len) + char *buf; + int len; +{ + return (js_fgetline(stdin, buf, len)); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fileopen.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fileopen.c new file mode 100644 index 00000000000..6b2658f4c07 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/fileopen.c @@ -0,0 +1,35 @@ +/* @(#)fileopen.c 1.12 10/08/21 Copyright 1986, 1995-2010 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +EXPORT FILE * +fileopen(name, mode) + const char *name; + const char *mode; +{ + int ret; + int omode = 0; + int flag = 0; + + if (!_cvmod(mode, &omode, &flag)) + return ((FILE *)NULL); + + if ((ret = _openfd(name, omode)) < 0) + return ((FILE *)NULL); + + return (_fcons((FILE *)0, ret, flag | FI_CLOSE)); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/filewrite.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/filewrite.c new file mode 100644 index 00000000000..225fac14343 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/filewrite.c @@ -0,0 +1,92 @@ +/* @(#)filewrite.c 1.18 12/02/26 Copyright 1986, 1995-2012 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2012 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +static char _writeerr[] = "file_write_err"; + +#ifdef HAVE_USG_STDIO + +EXPORT ssize_t +filewrite(f, vbuf, len) + register FILE *f; + void *vbuf; + size_t len; +{ + register int n; + ssize_t cnt; + char *buf = vbuf; + + down2(f, _IOWRT, _IORW); + + if (f->_flag & _IONBF) { + cnt = _niwrite(fileno(f), buf, len); + if (cnt < 0) { + f->_flag |= _IOERR; + if (!(my_flag(f) & _JS_IONORAISE)) + raisecond(_writeerr, 0L); + } + return (cnt); + } + cnt = 0; + while (len > 0) { + if (f->_cnt <= 0) { + if (usg_flsbuf((unsigned char) *buf++, f) == EOF) + break; + cnt++; + if (--len == 0) + break; + } + if ((n = f->_cnt >= len ? len : f->_cnt) > 0) { + f->_ptr = (unsigned char *)movebytes(buf, f->_ptr, n); + buf += n; + f->_cnt -= n; + cnt += n; + len -= n; + } + } + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _JS_IONORAISE) && !(_io_glflag & _JS_IONORAISE)) + raisecond(_writeerr, 0L); + return (-1); +} + +#else + +EXPORT ssize_t +filewrite(f, vbuf, len) + register FILE *f; + void *vbuf; + size_t len; +{ + ssize_t cnt; + char *buf = vbuf; + + down2(f, _IOWRT, _IORW); + + if (my_flag(f) & _JS_IOUNBUF) + return (_niwrite(fileno(f), buf, len)); + cnt = fwrite(buf, 1, len, f); + + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _JS_IONORAISE) && !(_io_glflag & _JS_IONORAISE)) + raisecond(_writeerr, 0L); + return (-1); +} + +#endif /* HAVE_USG_STDIO */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/flag.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/flag.c new file mode 100644 index 00000000000..bbd58d49578 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/flag.c @@ -0,0 +1,135 @@ +/* @(#)flag.c 2.14 10/11/06 Copyright 1986-2010 J. Schilling */ +/* + * Copyright (c) 1986-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" +#include + +#ifdef DO_MYFLAG + +#define FL_INIT 10 + +#if defined(IS_MACOS_X) +/* + * The MAC OS X linker does not grok "common" varaibles. + * Make _io_glflag a "data" variable. + */ +EXPORT int _io_glflag = 0; /* global default flag */ +#else +EXPORT int _io_glflag; /* global default flag */ +#endif +LOCAL int _fl_inc = 10; /* increment to expand flag struct */ +EXPORT int _fl_max = FL_INIT; /* max fd currently in _io_myfl */ +LOCAL _io_fl _io_smyfl[FL_INIT]; /* initial static space */ +EXPORT _io_fl *_io_myfl = _io_smyfl; /* init to static space */ + +LOCAL int _more_flags __PR((FILE *)); + +LOCAL int +_more_flags(fp) + FILE *fp; +{ + register int f = fileno(fp); + register int n = _fl_max; + register _io_fl *np; + + while (n <= f) + n += _fl_inc; + + if (_io_myfl == _io_smyfl) { + np = (_io_fl *) malloc(n * sizeof (*np)); + fillbytes(np, n * sizeof (*np), '\0'); + movebytes(_io_smyfl, np, sizeof (_io_smyfl)/sizeof (*np)); + } else { + np = (_io_fl *) realloc(_io_myfl, n * sizeof (*np)); + if (np) + fillbytes(&np[_fl_max], (n-_fl_max)*sizeof (*np), '\0'); + } + if (np) { + _io_myfl = np; + _fl_max = n; + return (_io_get_my_flag(fp)); + } else { + return (_JS_IONORAISE); + } +} + +EXPORT int +_io_get_my_flag(fp) + register FILE *fp; +{ + register int f = fileno(fp); + register _io_fl *fl; + + if (f >= _fl_max) + return (_more_flags(fp)); + + fl = &_io_myfl[f]; + + if (fl->fl_io == 0 || fl->fl_io == fp) + return (fl->fl_flags); + + while (fl && fl->fl_io != fp) + fl = fl->fl_next; + + if (fl == 0) + return (0); + + return (fl->fl_flags); +} + +EXPORT void +_io_set_my_flag(fp, flag) + FILE *fp; + int flag; +{ + register int f = fileno(fp); + register _io_fl *fl; + register _io_fl *fl2; + + if (f >= _fl_max) + (void) _more_flags(fp); + + fl = &_io_myfl[f]; + + if (fl->fl_io != (FILE *)0) { + fl2 = fl; + + while (fl && fl->fl_io != fp) + fl = fl->fl_next; + if (fl == 0) { + if ((fl = (_io_fl *) malloc(sizeof (*fl))) == 0) + return; + fl->fl_next = fl2->fl_next; + fl2->fl_next = fl; + } + } + fl->fl_io = fp; + fl->fl_flags = flag; +} + +EXPORT void +_io_add_my_flag(fp, flag) + FILE *fp; + int flag; +{ + int oflag = _io_get_my_flag(fp); + + oflag |= flag; + + _io_set_my_flag(fp, oflag); +} + +#endif /* DO_MYFLAG */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/niwrite.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/niwrite.c new file mode 100644 index 00000000000..835667e85ac --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/niwrite.c @@ -0,0 +1,42 @@ +/* @(#)niwrite.c 1.7 09/06/30 Copyright 1986, 2001-2009 J. Schilling */ +/* + * Non interruptable write + * + * Copyright (c) 1986, 2001-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include "schilyio.h" + +EXPORT ssize_t +_niwrite(f, buf, count) + int f; + void *buf; + size_t count; +{ + ssize_t ret; + int oerrno = geterrno(); + + if ((ret = (ssize_t)count) < 0) { + seterrno(EINVAL); + return ((ssize_t)-1); + } + while ((ret = write(f, buf, count)) < 0 && geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the errno visible + * to the outside if we did not fail. + */ + seterrno(oerrno); + } + return (ret); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/schilyio.h b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/schilyio.h new file mode 100644 index 00000000000..427b8aebd61 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/stdio/schilyio.h @@ -0,0 +1,233 @@ +/* @(#)schilyio.h 2.28 10/08/23 Copyright 1986, 1995-2010 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#ifndef _STDIO_SCHILYIO_H +#define _STDIO_SCHILYIO_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NO_USG_STDIO +# ifdef HAVE_USG_STDIO +# undef HAVE_USG_STDIO +# endif +#endif + +#ifdef HAVE_LARGEFILES +/* + * XXX We may need to put this code to a more global place to allow all + * XXX users of fseek()/ftell() to automaticaly use fseeko()/ftello() + * XXX if the latter are available. + * + * If HAVE_LARGEFILES is defined, it is guaranteed that fseeko()/ftello() + * both are available. + */ +# define fseek fseeko +# define ftell ftello + +#else /* !HAVE_LARGEFILES */ +/* + * If HAVE_LARGEFILES is not defined, we depend on specific tests for + * fseeko()/ftello() which must have been done before the tests for + * Large File support have been done. + * Note that this only works if the tests used below are really done before + * the Large File autoconf test is run. This is because autoconf does no + * clean testing but instead cumulatively modifes the envivonment used for + * testing. + */ +#ifdef HAVE_FSEEKO +# define fseek fseeko +#endif +#ifdef HAVE_FTELLO +# define ftell ftello +#endif + +#endif + +/* + * speed things up... + */ +#ifndef _OPENFD_SRC +#ifdef _openfd +#undef _openfd +#endif +#define _openfd(name, omode) (open(name, omode, (mode_t)0666)) +#endif + +#define DO_MYFLAG /* use local flags */ + +/* + * Flags used during fileopen(), ... by _fcons()/ _cvmod() + */ +#define FI_NONE 0x0000 /* no flags defined */ + +#define FI_READ 0x0001 /* open for reading */ +#define FI_WRITE 0x0002 /* open for writing */ +#define FI_BINARY 0x0004 /* open in binary mode */ +#define FI_APPEND 0x0008 /* append on each write */ + +#define FI_CREATE 0x0010 /* create if nessecary */ +#define FI_TRUNC 0x0020 /* truncate file on open */ +#define FI_UNBUF 0x0080 /* dont't buffer io */ +#define FI_CLOSE 0x1000 /* close file on error */ + +/* + * Additional Schily FILE * flags that are not present with the + * standard stdio implementation. + */ +#define _JS_IONORAISE 01 /* do no raisecond() on errors */ +#define _JS_IOUNBUF 02 /* do unbuffered i/o */ + + +#ifdef DO_MYFLAG + +struct _io_flags { + FILE *fl_io; /* file pointer */ + struct _io_flags /* pointer to next struct */ + *fl_next; /* if more file pointer to same fd */ + int fl_flags; /* my flags */ +}; + +typedef struct _io_flags _io_fl; + +extern int _io_glflag; /* global default flag */ +extern _io_fl *_io_myfl; /* array of structs to hold my flags */ +extern int _fl_max; /* max fd currently in _io_myfl */ + +/* + * if fileno > max + * expand + * else if map[fileno].pointer == 0 + * return 0 + * else if map[fileno].pointer == p + * return map[fileno].flags + * else + * search list + */ +#define flp(p) (&_io_myfl[fileno(p)]) + +#ifdef MY_FLAG_IS_MACRO +#define my_flag(p) ((int)fileno(p) >= _fl_max ? \ + _io_get_my_flag(p) : \ + ((flp(p)->fl_io == 0 || flp(p)->fl_io == p) ? \ + flp(p)->fl_flags : \ + _io_get_my_flag(p))) +#else +#define my_flag(p) _io_get_my_flag(p) +#endif + +#define set_my_flag(p, v) _io_set_my_flag(p, v) +#define add_my_flag(p, v) _io_add_my_flag(p, v) + +extern int _io_get_my_flag __PR((FILE *)); +extern void _io_set_my_flag __PR((FILE *, int)); +extern void _io_add_my_flag __PR((FILE *, int)); + +#else /* DO_MYFLAG */ + +#define my_flag(p) _JS_IONORAISE /* Always noraise */ +#define set_my_flag(p, v) /* Ignore */ +#define add_my_flag(p, v) /* Ignore */ + +#endif /* DO_MYFLAG */ + +#ifdef HAVE_USG_STDIO + +/* + * Use the right filbuf()/flsbuf() function. + */ +#ifdef HAVE___FILBUF +# define usg_filbuf(fp) __filbuf(fp) +# define usg_flsbuf(c, fp) __flsbuf(c, fp) +/* + * Define prototypes to verify if our interface is right + */ +extern int __filbuf __PR((FILE *)); +#else +# ifdef HAVE__FILBUF +# define usg_filbuf(fp) _filbuf(fp) +# define usg_flsbuf(c, fp) _flsbuf(c, fp) +/* + * Define prototypes to verify if our interface is right + */ +extern int _filbuf __PR((FILE *)); +# else +/* + * no filbuf() but this will not happen on USG_STDIO systems. + */ +# endif +#endif +/* + * Do not check this because flsbuf()'s 1st parameter may be + * int SunOS + * unsigned int Apollo + * unsigned char HP-UX-11 + * + * Note that the interface is now checked by autoconf. + */ +#else +/* + * If we are on a non USG system we cannot down file pointers + */ +#undef DO_DOWN +#endif + +#ifndef DO_DOWN +/* + * No stream checking + */ +#define down(f) +#define down1(f, fl1) +#define down2(f, fl1, fl2) +#else +/* + * Do stream checking (works only on USG stdio) + * + * New version of USG stdio. + * _iob[] holds only a small amount of pointers. + * Aditional space is allocated. + * We may check only if the file pointer is != NULL + * and if iop->_flag refers to a stream with appropriate modes. + * If _iob[] gets expanded by malloc() we cannot check upper bound. + */ +#define down(f) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : (f)) + +#define down1(f, fl1) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : \ + (((f)->_flag & fl1) != fl1 ? \ + (raisecond(_badop, 0L), (FILE *)0) : \ + (f))) + +#define down2(f, fl1, fl2) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : \ + (((f)->_flag & fl1) != fl1 && \ + ((f)->_flag & fl2) != fl2 ? \ + (raisecond(_badop, 0L), (FILE *)0) : \ + (f))) +#endif /* DO_DOWN */ + +extern char _badfile[]; +extern char _badmode[]; +extern char _badop[]; + +#endif /* _STDIO_SCHILYIO_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/streql.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/streql.c new file mode 100644 index 00000000000..5ff2cf095fa --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/streql.c @@ -0,0 +1,41 @@ +/* @(#)streql.c 1.10 09/06/07 Copyright 1985, 1995-2009 J. Schilling */ +/* + * Check if two strings are equal + * + * Copyright (c) 1985, 1995-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include + +EXPORT int +streql(a, b) + const char *a; + const char *b; +{ + register const char *s1 = a; + register const char *s2 = b; + + if (s1 == NULL || s2 == NULL) + return (FALSE); + + if (s1 == s2) + return (TRUE); + + while (*s1 == *s2++) + if (*s1++ == '\0') + return (TRUE); + + return (FALSE); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcat.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcat.c new file mode 100644 index 00000000000..73e35f2d8ab --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcat.c @@ -0,0 +1,59 @@ +/* @(#)strlcat.c 1.1 10/04/26 Copyright 2010 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)strlcat.c 1.1 10/04/26 Copyright 2010 J. Schilling"; +#endif +/* + * strlcat() to be used if missing in libc + * + * Copyright (c) 2010 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#ifndef HAVE_STRLCAT + +EXPORT size_t +strlcat(s1, s2, len) + register char *s1; + register const char *s2; + register size_t len; +{ + const char *os1 = s1; + size_t olen = len; + + if (len > 0) { + while (--len > 0 && *s1++ != '\0') + ; + + if (len == 0) + return (olen + strlen(s2)); + + s1--; + len++; + while (--len > 0 && (*s1++ = *s2++) != '\0') + ; + if (len == 0) { + *s1 = '\0'; + return (s1 - os1 + strlen(s2)); + } + return (--s1 - os1); + } + return (strlen(s2)); +} +#endif /* HAVE_STRLCAT */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcpy.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcpy.c new file mode 100644 index 00000000000..a0d64600710 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/strlcpy.c @@ -0,0 +1,52 @@ +/* @(#)strlcpy.c 1.4 09/07/08 Copyright 2006-2009 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)strlcpy.c 1.4 09/07/08 Copyright 2006-2009 J. Schilling"; +#endif +/* + * strlcpy() to be used if missing in libc + * + * Copyright (c) 2006-2009 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include + +#ifndef HAVE_STRLCPY + +EXPORT size_t +strlcpy(s1, s2, len) + register char *s1; + register const char *s2; + register size_t len; +{ + const char *os2 = s2; + + if (len > 0) { + while (--len > 0 && (*s1++ = *s2++) != '\0') + ; + if (len == 0) { + *s1 = '\0'; + while (*s2++ != '\0') + ; + } + } else { + while (*s2++ != '\0') + ; + } + return (--s2 - os2); +} +#endif /* HAVE_STRLCPY */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/uid.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/uid.c new file mode 100644 index 00000000000..b93faef0e1a --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/uid.c @@ -0,0 +1,64 @@ +/* @(#)uid.c 1.1 11/07/11 Copyright 2011 J. Schilling */ +/* + * Dummy functions for uid handling, used e.g. on MINGW + * + * Copyright (c) 2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#ifndef HAVE_GETUID + +EXPORT uid_t +getuid() +{ + return (0); +} + +#endif + +#ifndef HAVE_GETEUID + +EXPORT uid_t +geteuid() +{ + return (0); +} + +#endif + +#ifndef HAVE_SETUID + +EXPORT int +setuid(uid) + uid_t uid; +{ + return (0); +} + +#endif + +#ifndef HAVE_SETEUID + +EXPORT int +seteuid(uid) + uid_t uid; +{ + return (0); +} + +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/libschily/zerobytes.c b/reactos/sdk/tools/mkisofs/schilytools/libschily/zerobytes.c new file mode 100644 index 00000000000..9525aa44a68 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libschily/zerobytes.c @@ -0,0 +1,90 @@ +/* @(#)zerobytes.c 1.2 11/07/30 Copyright Copyright 1987, 1995-2011 J. Schilling */ +/* + * fill memory with null bytes + * + * Copyright (c) 1987, 1995-2011 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include + +#define DO8(a) a; a; a; a; a; a; a; a; + +/* + * zero(to, cnt) + */ +EXPORT char * +zerobytes(tov, cnt) + void *tov; + ssize_t cnt; +{ + register char *to = (char *)tov; + register ssize_t n; + register long lval = 0L; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (to); + + if (n < 8 * sizeof (long)) { /* Simple may be faster... */ + do { /* n is always > 0 */ + *to++ = '\0'; + } while (--n > 0); + return (to); + } + + /* + * Assign byte-wise until properly aligned for a long pointer. + */ + while (--n >= 0 && !laligned(to)) { + *to++ = '\0'; + } + n++; + + if (n >= (ssize_t)(8 * sizeof (long))) { + register ssize_t rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + { + register long *tol = (long *)to; + + do { + DO8 (*tol++ = lval); + } while (--n > 0); + + to = (char *)tol; + } + n = rem; + + if (n >= 8) { + n -= 8; + do { + DO8 (*to++ = '\0'); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + *to++ = '\0'; + } while (--n > 0); + return (to); + } + if (n > 0) do { + *to++ = '\0'; + } while (--n > 0); + return (to); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/libsiconv/sic_nls.c b/reactos/sdk/tools/mkisofs/schilytools/libsiconv/sic_nls.c new file mode 100644 index 00000000000..0c1678c338b --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/libsiconv/sic_nls.c @@ -0,0 +1,551 @@ +/* @(#)sic_nls.c 1.18 14/01/15 Copyright 2007-2014 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)sic_nls.c 1.18 14/01/15 Copyright 2007-2014 J. Schilling"; +#endif +/* + * This code reads translation files in the format used by + * the Unicode Organization (www.unicode.org). + * + * The current implementation is only useful to create translations + * from single byte character sets to unicode. + * We use this code on systems that do not provide the iconv() function. + * + * Copyright 2007-2014 J. Schilling + */ +/* + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * See the file CDDL.Schily.txt in this distribution for details. + * A copy of the CDDL is also available via the Internet at + * http://www.opensource.org/licenses/cddl1.txt + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file CDDL.Schily.txt from this distribution. + */ + +#include +#include +#include +#include /* For strdup() */ +#include /* For R_OK */ +#include +#include +#include + +#define TAB_SIZE (UINT8_MAX+1) +#define __CAN_TAB_SIZE__ + +#ifndef PROTOTYPES +#undef __CAN_TAB_SIZE__ +#endif +#if (!defined(__STDC__) || __STDC__ < 1) && \ + !defined(__SUNPRO_C) /* Sun Compilers are OK even with __STDC__ 0 */ +/* + * C-preprocessors from K&R compilers cannot do the computation for TAB_SIZE + * in the next line We need to disable this test in case of a K&R compiler. + */ +#undef __CAN_TAB_SIZE__ +#endif +#ifdef __GNUC__ +#if __GNUC__ < 2 +#undef __CAN_TAB_SIZE__ +#endif +#if __GNUC__ < 3 && __GNUC_MINOR__ < 95 +#undef __CAN_TAB_SIZE__ +#endif +#endif +#if defined(VMS) && !defined(__GNUC__) +#undef __CAN_TAB_SIZE__ +#endif + +#ifdef __CAN_TAB_SIZE__ +#if TAB_SIZE < 256 +Error Table size too small +#endif +#endif + +LOCAL UInt8_t nullpage[TAB_SIZE] = { 0 }; +LOCAL char *ins_base; + +LOCAL siconvt_t *insert_sic __PR((siconvt_t *sip)); +LOCAL int remove_sic __PR((siconvt_t *sip)); +EXPORT siconvt_t *sic_open __PR((char *name)); +EXPORT const char *sic_base __PR((void)); +EXPORT int sic_close __PR((siconvt_t *sip)); +EXPORT int sic_list __PR((FILE *f)); +LOCAL void freetbl __PR((UInt8_t **uni2cs)); +LOCAL FILE *pfopen __PR((char *name)); +LOCAL siconvt_t *create_sic __PR((char *name)); +#ifdef USE_ICONV +LOCAL siconvt_t *create_iconv_sic __PR((char *name)); +LOCAL siconvt_t *dup_iconv_sic __PR((siconvt_t *sip)); +#endif + +/* + * Global list for translation tables + */ +LOCAL siconvt_t *glist = (siconvt_t *) NULL; + +/* + * Insert a table into the global list and allow to reuse it + */ +LOCAL siconvt_t * +insert_sic(sip) + siconvt_t *sip; +{ + siconvt_t **sp = &glist; + + if (sip == (siconvt_t *)NULL) /* No table arg */ + return ((siconvt_t *)NULL); + if (sip->sic_next) /* Already in list */ + return (sip); + + while (*sp) { + if (sip == *sp) { /* Already in list */ + return (sip); + } + sp = &(*sp)->sic_next; + } + sip->sic_next = glist; + glist = sip; + return (sip); +} + +/* + * Remove a table from the global list + */ +LOCAL int +remove_sic(sip) + siconvt_t *sip; +{ + siconvt_t **sp = &glist; + + while (*sp) { +#ifdef USE_ICONV + if (strcmp(sip->sic_name, (*sp)->sic_name) == 0) { + siconvt_t *sap = *sp; + + if (sip == *sp) { + *sp = sip->sic_next; + return (0); + } + while (sap->sic_alt != NULL) { + if (sap->sic_alt == sip) { + sap->sic_alt = sip->sic_alt; + sip->sic_name = NULL; /* No free() */ + return (0); + } + sap = sap->sic_alt; + } + } +#endif + if (sip == *sp) { + *sp = sip->sic_next; + return (0); + } + sp = &(*sp)->sic_next; + } + return (-1); +} + +/* + * Open a new translation + */ +EXPORT siconvt_t * +sic_open(charset) + char *charset; +{ + siconvt_t *sip = glist; + + if (charset == NULL || *charset == '\0') + return ((siconvt_t *)NULL); + + while (sip) { + if (strcmp(sip->sic_name, charset) == 0) { +#ifdef USE_ICONV + if (sip->sic_cd2uni != 0) + return (dup_iconv_sic(sip)); +#endif + sip->sic_refcnt++; + return (sip); + } + sip = sip->sic_next; + } + return (create_sic(charset)); +} + +/* + * Open a new translation + */ +EXPORT const char * +sic_base() +{ + if (ins_base == NULL) { + ins_base = searchfileinpath("lib/siconv/iso8859-1", R_OK, + SIP_PLAIN_FILE, NULL); + if (ins_base != NULL) { + int len = strlen(ins_base); + + ins_base[len - 9] = '\0'; + } + } + return (ins_base); +} + +/* + * Close a translation + */ +EXPORT int +sic_close(sip) + siconvt_t *sip; +{ + if (remove_sic(sip) < 0) + return (-1); + + if (--sip->sic_refcnt > 0) + return (0); + + if (sip->sic_name) + free(sip->sic_name); + if (sip->sic_uni2cs) + freetbl(sip->sic_uni2cs); + if (sip->sic_cs2uni) + free(sip->sic_cs2uni); +#ifdef USE_ICONV + if (sip->sic_cd2uni) + iconv_close(sip->sic_cd2uni); + if (sip->sic_uni2cd) + iconv_close(sip->sic_uni2cd); +#endif + + return (0); +} + +/* + * List all possible translation files in the install directory. + */ +EXPORT int +sic_list(f) + FILE *f; +{ + char path[1024]; + DIR *d; + struct dirent *dp; + int i = 0; + + if (ins_base == NULL) + (void) sic_base(); + + if (ins_base != NULL) + snprintf(path, sizeof (path), "%s", ins_base); + else + snprintf(path, sizeof (path), "%s/lib/siconv/", INS_BASE); + if ((d = opendir(path)) == NULL) + return (-1); + + while ((dp = readdir(d)) != NULL) { + if (dp->d_name[0] == '.') { + if (dp->d_name[1] == '\0') + continue; + if (dp->d_name[1] == '.' && dp->d_name[2] == '\0') + continue; + } + fprintf(f, "%s\n", dp->d_name); + i++; + } + return (i); +} + +/* + * Free a reverse (uncode -> char) translation table + */ +LOCAL void +freetbl(uni2cs) + UInt8_t **uni2cs; +{ + int i; + + for (i = 0; i < TAB_SIZE; i++) { + if (uni2cs[i] != nullpage) { + free(uni2cs[i]); + } + } + free(uni2cs); +} + +/* + * Search a tranlation table, first in the current directory and then + * in the install directory. + */ +LOCAL FILE * +pfopen(name) + char *name; +{ + char path[1024]; + char *p; + + if (strchr(name, '/')) + return (fopen(name, "r")); + + if (ins_base == NULL) + (void) sic_base(); + + p = ins_base; + if (p != NULL) { + snprintf(path, sizeof (path), "%s%s", p, name); + return (fopen(path, "r")); + } + snprintf(path, sizeof (path), "%s/lib/siconv/%s", INS_BASE, name); + return (fopen(path, "r")); +} + + +/* + * Create a new translation either from a file or from iconv_open() + */ +LOCAL siconvt_t * +create_sic(name) + char *name; +{ + UInt16_t *cs2uni = NULL; + UInt8_t **uni2cs = NULL; + siconvt_t *sip; + char line[1024]; + FILE *f; + unsigned ch; + unsigned uni; + int i; + int numtrans = 0; + + if (name == NULL || *name == '\0') + return ((siconvt_t *)NULL); + +#ifdef USE_ICONV + /* + * Explicitly search for an iconv based translation + */ + if (strncmp("iconv:", name, 6) == 0) { + return (create_iconv_sic(name)); + } +#else + if (strncmp("iconv:", name, 6) == 0) { + return ((siconvt_t *)NULL); + } +#endif + + if ((f = pfopen(name)) == (FILE *)NULL) { + if (strcmp(name, "default") == 0) { + if ((cs2uni = (UInt16_t *) + malloc(sizeof (UInt16_t) * TAB_SIZE)) == NULL) { + return ((siconvt_t *)NULL); + } + /* + * Set up a 1:1 translation table like ISO-8859-1 + */ + for (i = 0; i < TAB_SIZE; i++) + cs2uni[i] = i; + goto do_reverse; + } +#ifdef USE_ICONV + return (create_iconv_sic(name)); +#else + return ((siconvt_t *)NULL); +#endif + } + + if ((cs2uni = (UInt16_t *) + malloc(sizeof (UInt16_t) * TAB_SIZE)) == NULL) { + fclose(f); + return ((siconvt_t *)NULL); + } + + /* + * Set up mapping base. + * Always map the control characters 0x00 .. 0x1F + */ + for (i = 0; i < 32; i++) + cs2uni[i] = i; + + for (i = 32; i < TAB_SIZE; i++) + cs2uni[i] = '\0'; /* nul marks an illegal character */ + + cs2uni[0x7f] = 0x7F; /* Always map DELETE character 0x7F */ + + while (fgets(line, sizeof (line), f) != NULL) { + char *p; + + if ((p = strchr(line, '#')) != NULL) + *p = '\0'; + + if (sscanf(line, "%x%x", &ch, &uni) == 2) { + /* + * Only accept exactly two values in the right range. + */ + if (ch > 0xFF || uni > 0xFFFF) + continue; + + cs2uni[ch] = uni; /* Set up unicode translation */ + numtrans++; + } + } + fclose(f); + + if (numtrans == 0) { /* No valid translations found */ + free(cs2uni); + return ((siconvt_t *)NULL); + } + +do_reverse: + if ((uni2cs = (UInt8_t **) + malloc(sizeof (unsigned char *) * TAB_SIZE)) == NULL) { + free(cs2uni); + return ((siconvt_t *)NULL); + } + for (i = 0; i < TAB_SIZE; i++) /* Map all pages to the nullpage */ + uni2cs[i] = nullpage; + + /* + * Create a reversed table from the forward table read from the file. + */ + for (i = 0; i < TAB_SIZE; i++) { + UInt8_t high; + UInt8_t low; + UInt8_t *page; + + uni = cs2uni[i]; + high = (uni >> 8) & 0xFF; + low = uni & 0xFF; + page = uni2cs[high]; + + if (page == nullpage) { + int j; + + /* + * Do not write to the nullpage but replace it by + * new and specific memory. + */ + if ((page = (UInt8_t *) malloc(TAB_SIZE)) == NULL) { + free(cs2uni); + freetbl(uni2cs); + return ((siconvt_t *)NULL); + } + for (j = 0; j < TAB_SIZE; j++) + page[j] = '\0'; + uni2cs[high] = page; + } + page[low] = i; /* Set up the reverse translation */ + } + + if ((sip = (siconvt_t *)malloc(sizeof (siconvt_t))) == NULL) { + free(cs2uni); + freetbl(uni2cs); + return ((siconvt_t *)NULL); + } + + sip->sic_name = strdup(name); + sip->sic_uni2cs = uni2cs; + sip->sic_cs2uni = cs2uni; + sip->sic_cd2uni = NULL; + sip->sic_uni2cd = NULL; + sip->sic_alt = NULL; + sip->sic_next = NULL; + sip->sic_refcnt = 1; + + return (insert_sic(sip)); +} + + +#ifdef USE_ICONV + +/* + * Create a new translation from iconv_open() + */ +LOCAL siconvt_t * +create_iconv_sic(name) + char *name; +{ + siconvt_t *sip; + iconv_t to; + iconv_t from; + char *nm; + +/*cerror("init_unls_iconv(%s)\n", name);*/ + if (name == NULL || *name == '\0') + return ((siconvt_t *)NULL); + + nm = name; + if (strncmp("iconv:", name, 6) == 0) + nm = &name[6]; + + if ((sip = (siconvt_t *)malloc(sizeof (siconvt_t))) + == NULL) { + return ((siconvt_t *)NULL); + } + if ((from = iconv_open("UCS-2BE", nm)) == (iconv_t)-1) { + free(sip); + return ((siconvt_t *)NULL); + } + if ((to = iconv_open(nm, "UCS-2BE")) == (iconv_t)-1) { + free(sip); + iconv_close(from); + return ((siconvt_t *)NULL); + } + + sip->sic_name = strdup(name); + sip->sic_uni2cs = NULL; + sip->sic_cs2uni = NULL; + sip->sic_cd2uni = from; + sip->sic_uni2cd = to; + sip->sic_alt = NULL; + sip->sic_next = NULL; + sip->sic_refcnt = 1; + return (insert_sic(sip)); +} + +/* + * As the iconv conversion is stateful, we need to create a new translation + * if we like to get the same translation again. + */ +LOCAL siconvt_t * +dup_iconv_sic(sip) + siconvt_t *sip; +{ + siconvt_t *sp; + iconv_t to; + iconv_t from; + char *nm; + + if ((sp = (siconvt_t *)malloc(sizeof (siconvt_t))) + == NULL) { + return ((siconvt_t *)NULL); + } + nm = sip->sic_name; + if (strncmp("iconv:", nm, 6) == 0) + nm = &nm[6]; + if ((from = iconv_open("UCS-2BE", nm)) == (iconv_t)-1) { + free(sp); + return ((siconvt_t *)NULL); + } + if ((to = iconv_open(nm, "UCS-2BE")) == (iconv_t)-1) { + free(sp); + iconv_close(from); + return ((siconvt_t *)NULL); + } + sp->sic_name = sip->sic_name; /* Allow to compare name pointers */ + sp->sic_uni2cs = NULL; + sp->sic_cs2uni = NULL; + sp->sic_cd2uni = from; + sp->sic_uni2cd = to; + sp->sic_alt = NULL; + sp->sic_next = NULL; + sp->sic_refcnt = 1; + sip->sic_alt = sp; + return (sp); +} + +#endif /* USE_UNLS */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/boot.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/boot.c new file mode 100644 index 00000000000..f8ec10b1c70 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/boot.c @@ -0,0 +1,542 @@ +/* @(#)boot.c 1.28 16/10/23 Copyright 1999-2016 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)boot.c 1.28 16/10/23 Copyright 1999-2016 J. Schilling"; +#endif +/* + * Support for generic boot (sector 0..16) + * and to boot Sun sparc and Sun x86 systems. + * + * Copyright (c) 1999-2016 J. Schilling + */ +/*@@C@@*/ + +#include "mkisofs.h" +#include +#include +#include +#include +#include "sunlabel.h" + +extern int use_sunx86boot; + +LOCAL struct sun_label cd_label; +LOCAL struct x86_label sx86_label; +LOCAL struct pc_part fdisk_part; +LOCAL char *boot_files[NDKMAP]; /* Change this for > 8 x86 parts */ + +LOCAL void init_sparc_label __PR((void)); +LOCAL void init_sunx86_label __PR((void)); +EXPORT int sparc_boot_label __PR((char *label)); +EXPORT int sunx86_boot_label __PR((char *label)); +EXPORT int scan_sparc_boot __PR((char *files)); +EXPORT int scan_sunx86_boot __PR((char *files)); +EXPORT int make_sun_label __PR((void)); +EXPORT int make_sunx86_label __PR((void)); +LOCAL void dup_sun_label __PR((int part)); +LOCAL int sunboot_write __PR((FILE *outfile)); +LOCAL int sunlabel_size __PR((UInt32_t starting_extent)); +LOCAL int sunlabel_write __PR((FILE *outfile)); +LOCAL int genboot_size __PR((UInt32_t starting_extent)); +LOCAL int genboot_write __PR((FILE *outfile)); + +/* + * Set the virtual geometry in the disk label. + * If we like to make the geometry variable, we may change + * dkl_ncyl and dkl_pcyl later. + */ +LOCAL void +init_sparc_label() +{ + i_to_4_byte(cd_label.dkl_vtoc.v_version, V_VERSION); + i_to_2_byte(cd_label.dkl_vtoc.v_nparts, NDKMAP); + i_to_4_byte(cd_label.dkl_vtoc.v_sanity, VTOC_SANE); + + i_to_2_byte(cd_label.dkl_rpm, CD_RPM); + i_to_2_byte(cd_label.dkl_pcyl, CD_PCYL); + i_to_2_byte(cd_label.dkl_apc, CD_APC); + i_to_2_byte(cd_label.dkl_intrlv, CD_INTRLV); + i_to_2_byte(cd_label.dkl_ncyl, CD_NCYL); + i_to_2_byte(cd_label.dkl_acyl, CD_ACYL); + i_to_2_byte(cd_label.dkl_nhead, CD_NHEAD); + i_to_2_byte(cd_label.dkl_nsect, CD_NSECT); + + cd_label.dkl_magic[0] = DKL_MAGIC_0; + cd_label.dkl_magic[1] = DKL_MAGIC_1; +} + +LOCAL void +init_sunx86_label() +{ + li_to_4_byte(sx86_label.dkl_vtoc.v_sanity, VTOC_SANE); + li_to_4_byte(sx86_label.dkl_vtoc.v_version, V_VERSION); + li_to_2_byte(sx86_label.dkl_vtoc.v_sectorsz, 512); + li_to_2_byte(sx86_label.dkl_vtoc.v_nparts, NX86MAP); + + li_to_4_byte(sx86_label.dkl_pcyl, CD_PCYL); + li_to_4_byte(sx86_label.dkl_ncyl, CD_NCYL); + li_to_2_byte(sx86_label.dkl_acyl, CD_ACYL); + li_to_2_byte(sx86_label.dkl_bcyl, 0); + + li_to_4_byte(sx86_label.dkl_nhead, CD_NHEAD); + li_to_4_byte(sx86_label.dkl_nsect, CD_NSECT); + li_to_2_byte(sx86_label.dkl_intrlv, CD_INTRLV); + li_to_2_byte(sx86_label.dkl_skew, 0); + li_to_2_byte(sx86_label.dkl_apc, CD_APC); + li_to_2_byte(sx86_label.dkl_rpm, CD_RPM); + + li_to_2_byte(sx86_label.dkl_write_reinstruct, 0); + li_to_2_byte(sx86_label.dkl_read_reinstruct, 0); + + li_to_2_byte(sx86_label.dkl_magic, DKL_MAGIC); +} + +/* + * For command line parser: set ASCII label. + */ +EXPORT int +sparc_boot_label(label) + char *label; +{ + strncpy(cd_label.dkl_ascilabel, label, 127); + cd_label.dkl_ascilabel[127] = '\0'; + return (1); +} + +EXPORT int +sunx86_boot_label(label) + char *label; +{ + strncpy(sx86_label.dkl_vtoc.v_asciilabel, label, 127); + sx86_label.dkl_vtoc.v_asciilabel[127] = '\0'; + return (1); +} + +/* + * Parse the command line argument for boot images. + */ +EXPORT int +scan_sparc_boot(files) + char *files; +{ + char *p; + int i = 1; + struct stat statbuf; + int status; +extern int use_sparcboot; +extern int use_sunx86boot; + + if (use_sunx86boot) + comerrno(EX_BAD, + _("-sparc-boot and -sunx86-boot are mutual exclusive.\n")); + use_sparcboot++; + + init_sparc_label(); + + do { + if (i >= NDKMAP) + comerrno(EX_BAD, _("Too many boot partitions.\n")); + boot_files[i++] = files; + if ((p = strchr(files, ',')) != NULL) + *p++ = '\0'; + files = p; + } while (p); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[0].p_tag, V_USR); + i_to_2_byte(cd_label.dkl_vtoc.v_part[0].p_flag, V_RONLY); + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (strcmp(p, "...") == '\0') + break; + + status = stat_filter(p, &statbuf); + if (status < 0 || access(p, R_OK) < 0) + comerr(_("Cannot access '%s'.\n"), p); + + i_to_4_byte(cd_label.dkl_map[i].dkl_nblk, + roundup(statbuf.st_size, CD_CYLSIZE)/512); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_tag, V_ROOT); + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } + return (1); +} + +EXPORT int +scan_sunx86_boot(files) + char *files; +{ + char *p; + int i = 0; + struct stat statbuf; + int status; +extern int use_sparcboot; +extern int use_sunx86boot; + + if (use_sparcboot) + comerrno(EX_BAD, + _("-sparc-boot and -sunx86-boot are mutual exclusive.\n")); + use_sunx86boot++; + + + init_sunx86_label(); + + do { + if (i >= NDKMAP) + comerrno(EX_BAD, _("Too many boot partitions.\n")); + boot_files[i++] = files; + if ((p = strchr(files, ',')) != NULL) + *p++ = '\0'; + files = p; + } while (p); + + li_to_2_byte(sx86_label.dkl_vtoc.v_part[0].p_tag, V_ROOT); /* UFS */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[0].p_flag, V_RONLY); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[1].p_tag, V_USR); /* ISO */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[1].p_flag, V_RONLY); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[2].p_tag, 0); /* ALL */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[2].p_flag, 0); + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (i == 1 || i == 2) { + comerrno(EX_BAD, + _("Partition %d may not have a filename.\n"), i); + } + + status = stat_filter(p, &statbuf); + if (status < 0 || access(p, R_OK) < 0) + comerr(_("Cannot access '%s'.\n"), p); + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size, + roundup(statbuf.st_size, CD_CYLSIZE)/512); + + if (i > 2) { + li_to_2_byte(sx86_label.dkl_vtoc.v_part[i].p_tag, V_USR); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } + } + return (1); +} + +/* + * Finish the Sun disk label and compute the size of the additional data. + */ +EXPORT int +make_sun_label() +{ + int last; + int cyl = 0; + int nblk; + int bsize; + int i; + char *p; + + /* + * Compute the size of the padding for the iso9660 image + * to allow the next partition to start on a cylinder boundary. + */ + last = roundup(last_extent, (CD_CYLSIZE/SECTOR_SIZE)); + + i_to_4_byte(cd_label.dkl_map[0].dkl_nblk, last*4); + bsize = 0; + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p != NULL && strcmp(p, "...") == '\0') { + dup_sun_label(i); + break; + } + if ((nblk = a_to_4_byte(cd_label.dkl_map[i].dkl_nblk)) == 0) + continue; + + i_to_4_byte(cd_label.dkl_map[i].dkl_cylno, cyl); + cyl += nblk / (CD_CYLSIZE/512); + if (i > 0) + bsize += nblk; + } + bsize /= 4; + return (last-last_extent+bsize); +} + +/* + * A typical Solaris boot/install CD from a Sun CD set looks + * this way: + * + * UFS Part 0 tag 2 flag 10 start 3839 size 1314560 + * ISO Part 1 tag 4 flag 10 start 0 size 3839 + * ALL Part 2 tag 0 flag 0 start 0 size 1318400 + */ +EXPORT int +make_sunx86_label() +{ + int last; + int cyl = 0; + int nblk; + int bsize; + int i; + int partoff = 1; /* The offset of the Solaris 0x82 partition */ + + /* + * Compute the size of the padding for the iso9660 image + * to allow the next partition to start on a cylinder boundary. + */ + last = roundup(last_extent, (CD_CYLSIZE/SECTOR_SIZE)); + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_size, last*4); + + /* + * Note that the Solaris fdisk partition with fdisk signature 0x82 + * is created at fixed offset 1 sector == 512 Bytes by this + * implementation. + * We need subtract this partition offset from all absolute + * partition offsets in order to get offsets relative to the + * Solaris primary partition. + */ + bsize = 0; + for (i = 0; i < NDKMAP; i++) { + if (i == 2) /* Never include the whole disk in */ + continue; /* size/offset computations */ + + if ((nblk = la_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size)) == 0) + continue; + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_start, + cyl*(CD_CYLSIZE/512)-partoff); + cyl += nblk / (CD_CYLSIZE/512); + if (i == 0 || i > 2) + bsize += nblk; + } + li_to_4_byte(sx86_label.dkl_vtoc.v_part[0].p_start, last*4-partoff); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_start, 0); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_size, last*4-partoff); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[2].p_start, 0); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[2].p_size, last*4+bsize); + + fdisk_part.part[0].pr_status = STATUS_ACTIVE; + fdisk_part.part[0].pr_type = TYPE_SOLARIS; + li_to_4_byte(fdisk_part.part[0].pr_partoff, partoff); + li_to_4_byte(fdisk_part.part[0].pr_nsect, last*4+bsize-partoff); + fdisk_part.magic[0] = 0x55; + fdisk_part.magic[1] = 0xAA; + + bsize /= 4; + return (last-last_extent+bsize); +} + +/* + * Duplicate a partition of the Sun disk label until all partitions are filled up. + */ +LOCAL void +dup_sun_label(part) + int part; +{ + int cyl; + int nblk; + int i; + + + if (part < 1 || part >= NDKMAP) + part = 1; + cyl = a_to_4_byte(cd_label.dkl_map[part-1].dkl_cylno); + nblk = a_to_4_byte(cd_label.dkl_map[part-1].dkl_nblk); + + for (i = part; i < NDKMAP; i++) { + i_to_4_byte(cd_label.dkl_map[i].dkl_cylno, cyl); + i_to_4_byte(cd_label.dkl_map[i].dkl_nblk, nblk); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_tag, V_ROOT); + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } +} + +/* + * Write out Sun boot partitions. + */ +LOCAL int +sunboot_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int i; + int n; + int nblk; + int amt; + int f; + char *p; + + memset(buffer, 0, sizeof (buffer)); + + /* + * Write padding to the iso9660 image to allow the + * boot partitions to start on a cylinder boundary. + */ + amt = roundup(last_extent_written, (CD_CYLSIZE/SECTOR_SIZE)) - last_extent_written; + for (n = 0; n < amt; n++) { + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + if (use_sunx86boot) + i = 0; + else + i = 1; + for (; i < NDKMAP; i++) { + if (use_sunx86boot && (i == 1 || i == 2)) + continue; + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (p != NULL && strcmp(p, "...") == '\0') + break; + if (use_sunx86boot) { + if ((nblk = la_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size)) == 0) + continue; + } else { + if ((nblk = a_to_4_byte(cd_label.dkl_map[i].dkl_nblk)) == 0) + continue; + } + if ((f = open(boot_files[i], O_RDONLY| O_BINARY)) < 0) + comerr(_("Cannot open '%s'.\n"), boot_files[i]); + + amt = nblk / 4; + for (n = 0; n < amt; n++) { + memset(buffer, 0, sizeof (buffer)); + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr(_("Read error on '%s'.\n"), boot_files[i]); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + close(f); + } + fprintf(stderr, _("Total extents including %s boot = %u\n"), + use_sunx86boot ? "Solaris x86":"sparc", + last_extent_written - session_start); + return (0); +} + +/* + * Do size management for the Sun disk label that is located in the first + * sector of a disk. + */ +LOCAL int +sunlabel_size(starting_extent) + UInt32_t starting_extent; +{ + if (last_extent != session_start) + comerrno(EX_BAD, _("Cannot create sparc boot on offset != 0.\n")); + last_extent++; + return (0); +} + +/* + * Compute the checksum and write a Sun disk label to the first sector + * of the disk. + * If the -generic-boot option has been specified too, overlay the + * Sun disk label on the first 512 bytes of the generic boot code. + */ +LOCAL int +sunlabel_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + register char *p; + register short count = (512/2) - 1; + int f; + + memset(buffer, 0, sizeof (buffer)); + if (genboot_image) { + if ((f = open(genboot_image, O_RDONLY| O_BINARY)) < 0) + comerr(_("Cannot open '%s'.\n"), genboot_image); + + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr(_("Read error on '%s'.\n"), genboot_image); + close(f); + } + + if (use_sunx86boot) { + if (sx86_label.dkl_vtoc.v_asciilabel[0] == '\0') + strcpy(sx86_label.dkl_vtoc.v_asciilabel, CD_X86LABEL); + + p = (char *)&sx86_label; + sx86_label.dkl_cksum[0] = 0; + sx86_label.dkl_cksum[1] = 0; + while (count-- > 0) { + sx86_label.dkl_cksum[0] ^= *p++; + sx86_label.dkl_cksum[1] ^= *p++; + } + memcpy(&buffer[0x1BE], fdisk_part.part, sizeof (fdisk_part.part)); + p = &buffer[510]; + *p++ = 0x55; + *p = 0xAA; + memcpy(&buffer[1024], &sx86_label, 512); + } else { + /* + * If we don't already have a Sun disk label text + * set up the default. + */ + if (cd_label.dkl_ascilabel[0] == '\0') + strcpy(cd_label.dkl_ascilabel, CD_DEFLABEL); + + p = (char *)&cd_label; + cd_label.dkl_cksum[0] = 0; + cd_label.dkl_cksum[1] = 0; + while (count--) { + cd_label.dkl_cksum[0] ^= *p++; + cd_label.dkl_cksum[1] ^= *p++; + } + memcpy(buffer, &cd_label, 512); + } + + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Do size management for the generic boot code on sectors 0..16. + */ +LOCAL int +genboot_size(starting_extent) + UInt32_t starting_extent; +{ + if (last_extent > (session_start + 1)) + comerrno(EX_BAD, _("Cannot create generic boot on offset != 0.\n")); + last_extent = session_start + 16; + return (0); +} + +/* + * Write the generic boot code to sectors 0..16. + * If there is a Sun disk label, start writing at sector 1. + */ +LOCAL int +genboot_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int i; + int f; + + if ((f = open(genboot_image, O_RDONLY| O_BINARY)) < 0) + comerr(_("Cannot open '%s'.\n"), genboot_image); + + for (i = 0; i < 16; i++) { + memset(buffer, 0, sizeof (buffer)); + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr(_("Read error on '%s'.\n"), genboot_image); + + if (i != 0 || last_extent_written == session_start) { + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + } + close(f); + return (0); +} + +struct output_fragment sunboot_desc = {NULL, NULL, NULL, sunboot_write, "Sun Boot" }; +struct output_fragment sunlabel_desc = {NULL, sunlabel_size, NULL, sunlabel_write, "Sun Disk Label" }; +struct output_fragment genboot_desc = {NULL, genboot_size, NULL, genboot_write, "Generic Boot" }; diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/bootinfo.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/bootinfo.h new file mode 100644 index 00000000000..309f24d620c --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/bootinfo.h @@ -0,0 +1,34 @@ +/* @(#)bootinfo.h 1.3 04/03/02 Copyright 1999, 2004 J. Schilling */ +/* + * Header file bootinfo.h - mkisofs-defined boot information table + * useful for an El Torito-loaded disk image. + * + * Copyright (c) 1999, 2004 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BOOTINFO_H +#define _BOOTINFO_H + +struct mkisofs_boot_info { + char bi_pvd [ISODCL(1, 4)]; /* LBA of PVD */ + char bi_file [ISODCL(5, 8)]; /* LBA of boot image */ + char bi_length [ISODCL(9, 12)]; /* Length of boot image */ + char bi_csum [ISODCL(13, 16)]; /* Checksum of boot image */ + char bi_reserved [ISODCL(17, 56)]; /* Reserved */ +}; + +#endif /* _BOOTINFO_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/defaults.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/defaults.h new file mode 100644 index 00000000000..db3dd47d1c9 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/defaults.h @@ -0,0 +1,150 @@ +/* @(#)defaults.h 1.25 13/02/14 joerg */ +/* + * Header file defaults.h - assorted default values for character strings in + * the volume descriptor. + * + * Copyright (c) 1999-2013 J. Schilling + */ + +#define PREPARER_DEFAULT NULL +#define PUBLISHER_DEFAULT NULL +#ifndef APPID_DEFAULT +#ifdef APPLE_HYB +#define APPID_DEFAULT "MKISOFS ISO9660/HFS/UDF FILESYSTEM BUILDER (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING" +#else +#define APPID_DEFAULT "MKISOFS ISO9660/UDF FILESYSTEM BUILDER (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING" +#endif /* APPLE_HYB */ +#endif +#define COPYRIGHT_DEFAULT NULL +#define BIBLIO_DEFAULT NULL +#define ABSTRACT_DEFAULT NULL +#define VOLSET_ID_DEFAULT NULL +#define VOLUME_ID_DEFAULT "CDROM" +#define BOOT_CATALOG_DEFAULT "boot.catalog" +#define BOOT_IMAGE_DEFAULT NULL +#ifdef APPLE_HYB +#define APPLE_TYPE_DEFAULT "TEXT" +#define APPLE_CREATOR_DEFAULT "unix" +#endif /* APPLE_HYB */ + +#ifdef __QNX__ +#define SYSTEM_ID_DEFAULT "QNX" +#endif + +#ifdef __osf__ +#define SYSTEM_ID_DEFAULT "OSF" +#endif + +#ifdef __sun +#ifdef __SVR4 +#define SYSTEM_ID_DEFAULT "Solaris" +#else +#define SYSTEM_ID_DEFAULT "SunOS" +#endif +#endif + +#ifdef __hpux +#define SYSTEM_ID_DEFAULT "HP-UX" +#endif + +#ifdef __sgi +#define SYSTEM_ID_DEFAULT "SGI" +#endif + +#if defined(_IBMR2) || defined(_AIX) +#define SYSTEM_ID_DEFAULT "AIX" +#endif + +#if defined(_WIN) || defined(__CYGWIN32__) || defined(__CYGWIN__) +#define SYSTEM_ID_DEFAULT "Win32" +#endif /* _WIN */ + +#if !defined(SYSTEM_ID_DEFAULT) && defined(__MINGW32__) +#define SYSTEM_ID_DEFAULT "Win32/MinGW" +#endif /* __MINGW32__ */ + +#ifdef __EMX__ +#define SYSTEM_ID_DEFAULT "OS/2" +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#define SYSTEM_ID_DEFAULT "FreeBSD" +#endif + +#ifdef __DragonFly__ +#define SYSTEM_ID_DEFAULT "DragonFly" +#endif + +#ifdef __NetBSD__ +#define SYSTEM_ID_DEFAULT "NetBSD" +#endif + +#ifdef __OpenBSD__ +#define SYSTEM_ID_DEFAULT "OpenBSD" +#endif + +#ifdef __bsdi__ +#define SYSTEM_ID_DEFAULT "BSD/OS" +#endif + +#ifdef __NeXT__ +#define SYSTEM_ID_DEFAULT "NeXT" +#endif + +#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody +#undef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "Rhapsody" +#endif + +#if defined(__APPLE__) && defined(__MACH__) +#undef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "Mac OS X" +#endif + +#ifdef __BEOS__ +#define SYSTEM_ID_DEFAULT "BeOS" +#endif + +#ifdef __HAIKU__ +#define SYSTEM_ID_DEFAULT "Haiku" +#endif + +#ifdef __OS2 +#define SYSTEM_ID_DEFAULT "OS/2" +#endif + +#ifdef VMS +#define SYSTEM_ID_DEFAULT "VMS" +#endif + +#ifdef OPENSERVER +#define SYSTEM_ID_DEFAULT "SCO-OPENSERVER" +#endif + +#ifdef UNIXWARE +#define SYSTEM_ID_DEFAULT "SCO-UNIXWARE" +#endif + +#ifdef linux +#define SYSTEM_ID_DEFAULT "LINUX" +#endif + +#ifdef __DJGPP__ +#define SYSTEM_ID_DEFAULT "DOS" +#endif + +#ifdef __MINT__ +#define SYSTEM_ID_DEFAULT "ATARI-MiNT" +#endif + +#ifdef __SYLLABLE__ +#define SYSTEM_ID_DEFAULT "Syllable" +#endif + +#ifdef AMIGA +#define SYSTEM_ID_DEFAULT "AMIGA" +#endif + +#ifndef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "UNIX" +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/diskmbr.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/diskmbr.h new file mode 100644 index 00000000000..903adc6db48 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/diskmbr.h @@ -0,0 +1,53 @@ +/* @(#)diskmbr.h 1.2 04/03/02 Copyright 1999-2004 J. Schilling */ +/* + * Header file diskmbr.h - assorted structure definitions and macros + * describing standard PC partition table + * + * Copyright (c) 1999-2004 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DISKMBR_H +#define _DISKMBR_H + +#define MBR_MAGIC 0xAA55 + +#define PARTITION_UNUSED 0x00 +#define PARTITION_ACTIVE 0x80 + +#define PARTITION_COUNT 4 + +#define MBR_SECTOR(x) ((x)&0x3F) +#define MBR_CYLINDER(x) ((x)>>8|((x)<<2&0x300)) + +struct disk_partition { + unsigned char status; + unsigned char s_head; + unsigned char s_cyl_sec[2]; + unsigned char type; + unsigned char e_head; + unsigned char e_cyl_sec[2]; + unsigned char boot_sec[4]; + unsigned char size[4]; +}; + +struct disk_master_boot_record { + char pad[0x1BE]; + struct disk_partition partition[PARTITION_COUNT]; + unsigned char magic[2]; +}; + +#endif /* _DISKMBR_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/eltorito.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/eltorito.c new file mode 100644 index 00000000000..32456cd4cf6 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/eltorito.c @@ -0,0 +1,686 @@ +/* @(#)eltorito.c 1.52 15/11/23 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)eltorito.c 1.52 15/11/23 joerg"; + +#endif +/* + * Program eltorito.c - Handle El Torito specific extensions to iso9660. + * + * + * Written by Michael Fulbright (1996). + * + * Copyright 1996 RedHat Software, Incorporated + * Copyright (c) 1999-2015 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "mkisofs.h" +#include +#include +#include +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include + +#undef MIN +#define MIN(a, b) (((a) < (b))? (a): (b)) + +EXPORT void init_boot_catalog __PR((const char *path)); +EXPORT void insert_boot_cat __PR((void)); +LOCAL void get_torito_desc __PR((struct eltorito_boot_descriptor *boot_desc)); +LOCAL void fill_boot_shdr __PR((struct eltorito_sectionheader_entry *boot_shdr_entry, + int arch)); +LOCAL void fill_boot_desc __PR((struct eltorito_defaultboot_entry *boot_desc_entry, + struct eltorito_boot_entry_info *boot_entry)); +EXPORT void get_boot_entry __PR((void)); +EXPORT int new_boot_entry __PR((void)); +EXPORT void ex_boot_enoent __PR((char *msg, char *pname)); +LOCAL int tvd_write __PR((FILE *outfile)); + + +LOCAL struct eltorito_validation_entry valid_desc; +LOCAL struct eltorito_boot_descriptor gboot_desc; +LOCAL struct disk_master_boot_record disk_mbr; +LOCAL unsigned int bcat_de_flags; +LOCAL char *bootcat_path; /* name of bootcatalog */ + +/* + * Make sure any existing boot catalog is excluded + */ +EXPORT void +init_boot_catalog(path) + const char *path; +{ +#ifdef SORTING + struct eltorito_boot_entry_info *cbe; + + for (cbe = first_boot_entry; + cbe != NULL; + cbe = cbe->next) { + char *p; + + if (cbe->boot_image == NULL) + comerrno(EX_BAD, _("Missing boot image name, use -eltorito-boot option.\n")); + p = (char *)e_malloc(strlen(cbe->boot_image) + strlen(path) + 2); + strcpy(p, path); + if (p[strlen(p) - 1] != '/') { + strcat(p, "/"); + } + strcat(p, cbe->boot_image); + add_sort_match(p, sort_matches(p, 1)); + free(p); + } +#endif + bootcat_path = (char *)e_malloc(strlen(boot_catalog) + strlen(path) + 2); + strcpy(bootcat_path, path); + if (bootcat_path[strlen(bootcat_path) - 1] != '/') { + strcat(bootcat_path, "/"); + } + strcat(bootcat_path, boot_catalog); + + /* + * we are going to create a virtual catalog file + * - so make sure any existing is excluded + */ + add_match(bootcat_path); + + /* flag the file as a memory file */ + bcat_de_flags = MEMORY_FILE; + + /* find out if we want to "hide" this file */ + if (i_matches(boot_catalog) || i_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_ISO9660_ENTRY; + + if (j_matches(boot_catalog) || j_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_JOLIET_ENTRY; + + if (u_matches(boot_catalog) || u_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_UDF_ENTRY; + +} /* init_boot_catalog(... */ + +/* + * Create a boot catalog file in memory - mkisofs already uses this type of + * file for the TRANS.TBL files. Therefore the boot catalog is set up in + * similar way + */ +EXPORT void +insert_boot_cat() +{ + struct directory_entry *de; + struct directory_entry *s_entry; + char *p1; + char *p2; + char *p3; + struct directory *this_dir; + struct directory *dir; + char *buffer; + + init_fstatbuf(); + + buffer = (char *)e_malloc(SECTOR_SIZE); + memset(buffer, 0, SECTOR_SIZE); + + /* + * try to find the directory that will contain the boot.cat file + * - not very neat, but I can't think of a better way + */ + p1 = e_strdup(boot_catalog); + + /* get dirname (p1) and basename (p2) of boot.cat */ + if ((p2 = strrchr(p1, '/')) != NULL) { + *p2 = '\0'; + p2++; + + /* find the dirname directory entry */ + de = search_tree_file(root, p1); + if (!de) { + ex_boot_enoent(_("catalog directory"), p1); + /* NOTREACHED */ + } + this_dir = 0; + + /* get the basename (p3) of the directory */ + if ((p3 = strrchr(p1, '/')) != NULL) + p3++; + else + p3 = p1; + + /* find the correct sub-directory entry */ + for (dir = de->filedir->subdir; dir; dir = dir->next) + if (strcmp(dir->de_name, p3) == 0) + this_dir = dir; + + if (this_dir == 0) { + ex_boot_enoent(_("catalog directory"), p3); + /* NOTREACHED */ + } + } else { + /* boot.cat is in the root directory */ + this_dir = root; + p2 = p1; + } + + /* + * make a directory entry in memory (using the same set up as for table + * entries + */ + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = this_dir->contents; + this_dir->contents = s_entry; + +#ifdef SORTING + /* inherit any sort weight from parent directory */ + s_entry->sort = this_dir->sort; + s_entry->sort += 2; + + /* see if this entry should have a new weighting */ + if (do_sort) { + s_entry->sort = sort_matches(bootcat_path, s_entry->sort); + } +#endif /* SORTING */ + + s_entry->isorec.flags[0] = ISO_FILE; + s_entry->priority = 32768; + iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); + s_entry->inode = TABLE_INODE; + s_entry->dev = (dev_t)UNCACHED_DEVICE; + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733((char *)s_entry->isorec.size, SECTOR_SIZE); + s_entry->size = SECTOR_SIZE; + s_entry->filedir = this_dir; + s_entry->name = e_strdup(p2); + iso9660_file_length(p2, s_entry, 0); + + /* flag file as necessary */ + s_entry->de_flags = bcat_de_flags; + + if ((use_XA || use_RockRidge) && + !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + fstatbuf.st_mode = 0444 | S_IFREG; + fstatbuf.st_nlink = 1; + generate_xa_rr_attributes("", + p2, s_entry, + &fstatbuf, &fstatbuf, 0); + } + /* + * memory files are stored at s_entry->table + * - but this is also used for each s_entry to generate + * TRANS.TBL entries. So if we are generating tables, + * store the TRANS.TBL data here for the moment + */ + if (generate_tables && !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + sprintf(buffer, "F\t%s\n", s_entry->name); + + /* copy the TRANS.TBL entry info and clear the buffer */ + s_entry->table = e_strdup(buffer); + memset(buffer, 0, SECTOR_SIZE); + + /* + * store the (empty) file data in the + * unused s_entry->whole_name element for the time being + * - this will be transferred to s_entry->table after any + * TRANS.TBL processing later + */ + s_entry->whole_name = buffer; + } else { + /* store the (empty) file data in the s_entry->table element */ + s_entry->table = buffer; + s_entry->whole_name = NULL; + } +} + +LOCAL void +get_torito_desc(boot_desc) + struct eltorito_boot_descriptor *boot_desc; +{ + int checksum; + unsigned char *checksum_ptr; + struct directory_entry *de2; /* Boot catalog */ + int i; + int offset; + int arch = 0; + int nentries = 0; + struct eltorito_defaultboot_entry boot_desc_record; + struct eltorito_sectionheader_entry boot_shdr_record; +#ifdef __needed__ + struct eltorito_section_entry boot_section_record; +#endif + struct eltorito_sectionheader_entry *last_section_header = 0; + + memset(boot_desc, 0, sizeof (*boot_desc)); + boot_desc->type[0] = 0; + strncpy(boot_desc->id, ISO_STANDARD_ID, sizeof (boot_desc->id)); + boot_desc->version[0] = 1; + + memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof (EL_TORITO_ID)); + + /* + * search from root of iso fs to find boot catalog + * - we already know where the boot catalog is + * - we created it above - but lets search for it anyway + * - good sanity check! + */ + de2 = search_tree_file(root, boot_catalog); + if (!de2 || !(de2->de_flags & MEMORY_FILE)) { + ex_boot_enoent(_("catalog"), boot_catalog); + /* NOTREACHED */ + } + set_731(boot_desc->bootcat_ptr, + (unsigned int) get_733(de2->isorec.extent)); + + /* + * If the platform id for the first (default) boot entry has not been + * explicitly set, we default to EL_TORITO_ARCH_x86 + */ + if ((first_boot_entry->type & ELTORITO_BOOT_ID) == 0) { + first_boot_entry->boot_platform = EL_TORITO_ARCH_x86; + } + arch = first_boot_entry->boot_platform; + + /* + * we have the boot image, so write boot catalog information + * Next we write out the primary descriptor for the disc + */ + memset(&valid_desc, 0, sizeof (valid_desc)); + valid_desc.headerid[0] = 1; + valid_desc.arch[0] = arch; /* Platform id for the default boot */ + + /* + * we'll shove start of publisher id into id field, + * may get truncated but who really reads this stuff! + */ + if (publisher) + memcpy_max(valid_desc.id, publisher, + MIN(23, strlen(publisher))); + + valid_desc.key1[0] = (char)0x55; + valid_desc.key2[0] = (char)0xAA; + + /* compute the checksum */ + checksum = 0; + checksum_ptr = (unsigned char *) &valid_desc; + /* Set checksum to 0 before computing checksum */ + set_721(valid_desc.cksum, 0); + for (i = 0; i < (int)sizeof (valid_desc); i += 2) { + checksum += (unsigned int) checksum_ptr[i]; + checksum += ((unsigned int) checksum_ptr[i + 1]) * 256; + } + + /* now find out the real checksum */ + checksum = -checksum; + set_721(valid_desc.cksum, (unsigned int) checksum); + + /* now write it to the virtual boot catalog */ + memcpy(de2->table, &valid_desc, 32); + + for (current_boot_entry = first_boot_entry, offset = sizeof (valid_desc); + current_boot_entry != NULL; + current_boot_entry = current_boot_entry->next, + offset += sizeof (boot_desc_record)) { + int newarch = arch; + + if (current_boot_entry->type & ELTORITO_BOOT_ID) + newarch = current_boot_entry->boot_platform; + else + current_boot_entry->boot_platform = arch; + + /* + * El Torito has no such limitation but we currently have... + */ + if (offset >= (SECTOR_SIZE - sizeof (boot_desc_record))) { + comerrno(EX_BAD, + _("Too many El Torito boot entries\n")); + } + if (current_boot_entry == first_boot_entry) { + ; + /* EMPTY */ + } else if ((current_boot_entry == first_boot_entry->next) || + (arch != newarch) || + (current_boot_entry->type & ELTORITO_SECTION_HEADER)) { + if (last_section_header) + set_721(&last_section_header->entry_count, nentries); + nentries = 1; + last_section_header = (struct eltorito_sectionheader_entry *) + (de2->table + offset); + fill_boot_shdr(&boot_shdr_record, newarch); + memcpy(de2->table + offset, &boot_shdr_record, + sizeof (boot_shdr_record)); + offset += sizeof (boot_desc_record); + } else { + nentries++; /* Add entry to this section header */ + } + /* + * This works because a section entry has the same essential + * layout as a default entry (and we do not populate the + * selection criteria fields). + */ + fill_boot_desc(&boot_desc_record, current_boot_entry); + memcpy(de2->table + offset, &boot_desc_record, + sizeof (boot_desc_record)); + } + + if (last_section_header) { + set_721(&last_section_header->entry_count, nentries); + last_section_header->header_id[0] = EL_TORITO_SHDR_ID_LAST_SHDR; + } + +} /* get_torito_desc(... */ + +LOCAL void +fill_boot_shdr(boot_shdr_entry, arch) + struct eltorito_sectionheader_entry *boot_shdr_entry; + int arch; +{ + memset(boot_shdr_entry, 0, sizeof (struct eltorito_sectionheader_entry)); + boot_shdr_entry->header_id[0] = EL_TORITO_SHDR_ID_SHDR; + boot_shdr_entry->platform_id[0] = arch; +} + +LOCAL void +fill_boot_desc(boot_desc_entry, boot_entry) + struct eltorito_defaultboot_entry *boot_desc_entry; + struct eltorito_boot_entry_info *boot_entry; +{ + struct directory_entry *de; /* Boot file */ + int bootmbr; + int i; + int nsectors; + int geosec; + + if (!boot_desc_entry || !boot_entry) + return; + + /* now adjust boot catalog lets find boot image first */ + de = search_tree_file(root, boot_entry->boot_image); + if (!de) { + ex_boot_enoent(_("image"), boot_entry->boot_image); + /* NOTREACHED */ + } + /* now make the initial/default entry for boot catalog */ + memset(boot_desc_entry, 0, sizeof (*boot_desc_entry)); + boot_desc_entry->boot_id[0] = (char)boot_entry->not_bootable ? + EL_TORITO_NOT_BOOTABLE : EL_TORITO_BOOTABLE; + + /* use default BIOS loadpnt */ + set_721(boot_desc_entry->loadseg, boot_entry->load_addr); + + /* + * figure out size of boot image in 512-byte sectors. + * However, round up to the nearest integral CD (2048-byte) sector. + * This is only used for no-emulation booting. + */ + nsectors = boot_entry->load_size ? boot_entry->load_size : + ISO_BLOCKS(de->size) * (SECTOR_SIZE/512); + + if (verbose > 0) { + fprintf(stderr, + _("Size of boot image is %d sectors -> "), nsectors); + } + + if (boot_entry->hard_disk_boot) { + /* sanity test hard disk boot image */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_HD; + if (verbose > 0) + fprintf(stderr, _("Emulating a hard disk\n")); + + /* read MBR */ + bootmbr = open(de->whole_name, O_RDONLY | O_BINARY); + if (bootmbr == -1) { + comerr(_("Error opening boot image '%s' for read.\n"), + de->whole_name); + } + if (read(bootmbr, &disk_mbr, sizeof (disk_mbr)) != + sizeof (disk_mbr)) { + comerr(_("Error reading MBR from boot image '%s'.\n"), + de->whole_name); + } + close(bootmbr); + if (la_to_u_2_byte(disk_mbr.magic) != MBR_MAGIC) { + errmsgno(EX_BAD, + _("Warning: boot image '%s' MBR is not a boot sector.\n"), + de->whole_name); + } + /* find partition type */ + boot_desc_entry->sys_type[0] = PARTITION_UNUSED; + for (i = 0; i < PARTITION_COUNT; ++i) { + int s_cyl_sec; + int e_cyl_sec; + + s_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].s_cyl_sec); + e_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].e_cyl_sec); + + if (disk_mbr.partition[i].type != PARTITION_UNUSED) { + if (boot_desc_entry->sys_type[0] != + PARTITION_UNUSED) { + comerrno(EX_BAD, + _("Boot image '%s' has multiple partitions.\n"), + de->whole_name); + } + boot_desc_entry->sys_type[0] = + disk_mbr.partition[i].type; + + /* a few simple sanity warnings */ + if (!boot_entry->not_bootable && + disk_mbr.partition[i].status != + PARTITION_ACTIVE) { + fprintf(stderr, + _("Warning: partition not marked active.\n")); + } + if (MBR_CYLINDER(s_cyl_sec) != 0 || + disk_mbr.partition[i].s_head != 1 || + MBR_SECTOR(s_cyl_sec != 1)) { + fprintf(stderr, + _("Warning: partition does not start at 0/1/1.\n")); + } + geosec = (MBR_CYLINDER(e_cyl_sec) + 1) * + (disk_mbr.partition[i].e_head + 1) * + MBR_SECTOR(e_cyl_sec); + if (geosec != nsectors) { + fprintf(stderr, + _("Warning: image size does not match geometry (%d)\n"), + geosec); + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition start %u/%u/%u\n", + MBR_CYLINDER(s_cyl_sec), + disk_mbr.partition[i].s_head, + MBR_SECTOR(s_cyl_sec)); + fprintf(stderr, "Partition end %u/%u/%u\n", + MBR_CYLINDER(e_cyl_sec), + disk_mbr.partition[i].e_head, + MBR_SECTOR(e_cyl_sec)); +#endif + } + } + if (boot_desc_entry->sys_type[0] == PARTITION_UNUSED) { + comerrno(EX_BAD, + _("Boot image '%s' has no partitions.\n"), + de->whole_name); + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition type %u\n", + boot_desc_entry->sys_type[0]); +#endif + /* load single boot sector, in this case the MBR */ + nsectors = 1; + + } else if (boot_entry->no_emul_boot) { + /* + * no emulation is a simple image boot of all the sectors + * in the boot image + */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_NOEMUL; + if (verbose > 0) + fprintf(stderr, _("No emulation\n")); + + } else { + /* choose size of emulated floppy based on boot image size */ + if (nsectors == 2880) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_144FLOP; + if (verbose > 0) + fprintf(stderr, _("Emulating a 1440 kB floppy\n")); + + } else if (nsectors == 5760) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_288FLOP; + if (verbose > 0) + fprintf(stderr, _("Emulating a 2880 kB floppy\n")); + + } else if (nsectors == 2400) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_12FLOP; + if (verbose > 0) + fprintf(stderr, _("Emulating a 1200 kB floppy\n")); + + } else { + comerrno(EX_BAD, + _("Error - boot image '%s' has not an allowable size.\n"), + de->whole_name); + } + + /* load single boot sector for floppies */ + nsectors = 1; + } + + /* fill in boot image details */ +#ifdef DEBUG_TORITO + fprintf(stderr, "Boot %u sectors\n", nsectors); + fprintf(stderr, "Extent of boot images is %d\n", + get_733(de->isorec.extent)); +#endif + set_721(boot_desc_entry->nsect, (unsigned int) nsectors); + set_731(boot_desc_entry->bootoff, + (unsigned int) get_733(de->isorec.extent)); + + + /* If the user has asked for it, patch the boot image */ + if (boot_entry->boot_info_table) { + int bootimage; + unsigned int bi_checksum; + unsigned int total_len; + static char csum_buffer[SECTOR_SIZE]; + int len; + struct mkisofs_boot_info bi_table; + + bootimage = open(de->whole_name, O_RDWR | O_BINARY); + if (bootimage == -1) { + comerr( + _("Error opening boot image file '%s' for update.\n"), + de->whole_name); + } + /* Compute checksum of boot image, sans 64 bytes */ + total_len = 0; + bi_checksum = 0; + while ((len = read(bootimage, csum_buffer, SECTOR_SIZE)) > 0) { + if (total_len & 3) { + comerrno(EX_BAD, + _("Odd alignment at non-end-of-file in boot image '%s'.\n"), + de->whole_name); + } + if (total_len < 64) + memset(csum_buffer, 0, 64 - total_len); + if (len < SECTOR_SIZE) + memset(csum_buffer + len, 0, SECTOR_SIZE-len); + for (i = 0; i < SECTOR_SIZE; i += 4) + bi_checksum += get_731(&csum_buffer[i]); + total_len += len; + } + + if (total_len != de->size) { + comerrno(EX_BAD, + _("Boot image file '%s' changed underneath us!\n"), + de->whole_name); + } + /* End of file, set position to byte 8 */ + lseek(bootimage, (off_t)8, SEEK_SET); + memset(&bi_table, 0, sizeof (bi_table)); + /* Is it always safe to assume PVD is at session_start+16? */ + set_731(bi_table.bi_pvd, session_start + 16); + set_731(bi_table.bi_file, de->starting_block); + set_731(bi_table.bi_length, de->size); + set_731(bi_table.bi_csum, bi_checksum); + + write(bootimage, &bi_table, sizeof (bi_table)); + close(bootimage); + } +} /* fill_boot_desc(... */ + +EXPORT void +get_boot_entry() +{ + if (current_boot_entry) + return; + + current_boot_entry = (struct eltorito_boot_entry_info *) + e_malloc(sizeof (struct eltorito_boot_entry_info)); + memset(current_boot_entry, 0, sizeof (*current_boot_entry)); + + if (!first_boot_entry) { + first_boot_entry = current_boot_entry; + last_boot_entry = current_boot_entry; + current_boot_entry->boot_platform = EL_TORITO_ARCH_x86; + } else { + current_boot_entry->boot_platform = last_boot_entry->boot_platform; + last_boot_entry->next = current_boot_entry; + last_boot_entry = current_boot_entry; + } +} + +EXPORT int +new_boot_entry() +{ + current_boot_entry = NULL; + return (1); +} + +/* + * Exit with a boot no entry message. + */ +EXPORT void +ex_boot_enoent(msg, pname) + char *msg; + char *pname; +{ + comerrno(EX_BAD, _("Uh oh, I cant find the boot %s '%s' inside the target tree.\n"), msg, pname); + /* NOTREACHED */ +} + +/* + * Function to write the EVD for the disc. + */ +LOCAL int +tvd_write(outfile) + FILE *outfile; +{ + /* check the boot image is not NULL */ + if (!boot_image) { + comerrno(EX_BAD, _("No boot image specified.\n")); + } + /* Next we write out the boot volume descriptor for the disc */ + get_torito_desc(&gboot_desc); + xfwrite(&gboot_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write, "Eltorito Volume Descriptor"}; diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/hash.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/hash.c new file mode 100644 index 00000000000..dc8641ac50d --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/hash.c @@ -0,0 +1,461 @@ +/* @(#)hash.c 1.28 10/12/19 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)hash.c 1.28 10/12/19 joerg"; + +#endif +/* + * File hash.c - generate hash tables for iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2010 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +/* + * From jb@danware.dk: + * + * Cygwin fakes inodes by hashing file info, actual collisions observed! + * This is documented in the cygwin source, look at winsup/cygwin/path.cc + * and search for the word 'Hash'. On NT, cygwin ORs together the + * high and low 32 bits of the 64 bit genuine inode, look at fhandler.cc. + * + * Note: Other operating systems which support the FAT filesystem may + * have the same problem because FAT does not use the inode + * concept. For NTFS, genuine inode numbers exist, but they are + * 64 bits and available only through an open file handle. + * + * The solution is the new options -no-cache-inodes/-cache-inodes that + * allow to disable the mkisofs inode cache. + */ + +#include "mkisofs.h" +#include + +#define NR_HASH (16*1024) + +#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 8) + (INO << 16)) % NR_HASH) + +static struct file_hash *hash_table[NR_HASH]; + +#ifdef HASH_DEBUG +EXPORT void debug_hash __PR((void)); +#endif +EXPORT void add_hash __PR((struct directory_entry *spnt)); +EXPORT struct file_hash *find_hash __PR((dev_t dev, ino_t inode)); +EXPORT void flush_hash __PR((void)); +EXPORT void add_directory_hash __PR((dev_t dev, ino_t inode)); +EXPORT struct file_hash *find_directory_hash __PR((dev_t dev, ino_t inode)); +LOCAL unsigned int name_hash __PR((const char *name)); +EXPORT void add_file_hash __PR((struct directory_entry *de)); +EXPORT struct directory_entry *find_file_hash __PR((char *name)); +LOCAL BOOL isoname_endsok __PR((char *name)); +EXPORT int delete_file_hash __PR((struct directory_entry *de)); +EXPORT void flush_file_hash __PR((void)); + +#ifdef HASH_DEBUG +EXPORT void +debug_hash() +{ + struct file_hash **p = hash_table; + int i; + int j = 0; + struct file_hash *p2; + int k; + int maxlen = 0; + int minlen = 100000000; + int tot = 0; + + for (i = 0; i < NR_HASH; i++, p++) { + if (*p == 0) + j++; + else { + p2 = *p; + k = 0; + while (p2) { + tot++; + k++; + p2 = p2->next; + } + if (k > maxlen) + maxlen = k; + if (k < minlen) + minlen = k; + } + } + error("Unbenutzt: %d von %d Einträgen maxlen %d minlen %d total %d optmittel %d\n", + j, NR_HASH, maxlen, minlen, tot, tot/NR_HASH); +} +#endif + +EXPORT void +add_hash(spnt) + struct directory_entry *spnt; +{ + struct file_hash *s_hash; + unsigned int hash_number; + + if (spnt->size == 0 || spnt->starting_block == 0) + if (spnt->size != 0 && spnt->starting_block == 0) { + comerrno(EX_BAD, + _("Non zero-length file '%s' assigned zero extent.\n"), + spnt->name); + }; + + if (!cache_inodes) + return; + if (spnt->dev == UNCACHED_DEVICE && + (spnt->inode == TABLE_INODE || spnt->inode == UNCACHED_INODE)) { + return; + } + hash_number = HASH_FN((unsigned int) spnt->dev, + (unsigned int) spnt->inode); + +#if 0 + if (verbose > 1) + fprintf(stderr, "%s ", spnt->name); +#endif + s_hash = (struct file_hash *)e_malloc(sizeof (struct file_hash)); + s_hash->next = hash_table[hash_number]; + s_hash->inode = spnt->inode; + s_hash->dev = spnt->dev; + s_hash->nlink = 0; + s_hash->starting_block = spnt->starting_block; + s_hash->size = spnt->size; +#ifdef SORTING + s_hash->de = spnt; +#endif /* SORTING */ + hash_table[hash_number] = s_hash; +} + +#ifdef PROTOTYPES +EXPORT struct file_hash * +find_hash(dev_t dev, ino_t inode) +#else +EXPORT struct file_hash * +find_hash(dev, inode) + dev_t dev; + ino_t inode; +#endif +{ + unsigned int hash_number; + struct file_hash *spnt; + + if (!cache_inodes) + return (NULL); + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return (NULL); + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + spnt = hash_table[hash_number]; + while (spnt) { + if (spnt->inode == inode && spnt->dev == dev) + return (spnt); + spnt = spnt->next; + }; + return (NULL); +} + +/* + * based on flush_file_hash() below - needed as we want to re-use the + * file hash table. + */ +EXPORT void +flush_hash() +{ + struct file_hash *fh; + struct file_hash *fh1; + int i; + + for (i = 0; i < NR_HASH; i++) { + fh = hash_table[i]; + while (fh) { + fh1 = fh->next; + free(fh); + fh = fh1; + } + hash_table[i] = NULL; + } +} + +static struct file_hash *directory_hash_table[NR_HASH]; + +#ifdef PROTOTYPES +EXPORT void +add_directory_hash(dev_t dev, ino_t inode) +#else +EXPORT void +add_directory_hash(dev, inode) + dev_t dev; + ino_t inode; +#endif +{ + struct file_hash *s_hash; + unsigned int hash_number; + + if (!cache_inodes) + return; + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return; + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + + s_hash = (struct file_hash *)e_malloc(sizeof (struct file_hash)); + s_hash->next = directory_hash_table[hash_number]; + s_hash->inode = inode; + s_hash->dev = dev; + s_hash->nlink = 0; + directory_hash_table[hash_number] = s_hash; +} + +#ifdef PROTOTYPES +EXPORT struct file_hash * +find_directory_hash(dev_t dev, ino_t inode) +#else +EXPORT struct file_hash * +find_directory_hash(dev, inode) + dev_t dev; + ino_t inode; +#endif +{ + unsigned int hash_number; + struct file_hash *spnt; + + if (!cache_inodes) + return (NULL); + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return (NULL); + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + spnt = directory_hash_table[hash_number]; + while (spnt) { + if (spnt->inode == inode && spnt->dev == dev) + return (spnt); + spnt = spnt->next; + }; + return (NULL); +} + +struct name_hash { + struct name_hash *next; + struct directory_entry *de; + int sum; +}; + +#define NR_NAME_HASH 128 + +static struct name_hash *name_hash_table[NR_NAME_HASH] = {0, }; + +/* + * Find the hash bucket for this name. + */ +LOCAL unsigned int +name_hash(name) + const char *name; +{ + unsigned int hash = 0; + const char *p; + + p = name; + + while (*p) { + /* + * Don't hash the iso9660 version number. + * This way we can detect duplicates in cases where we have + * directories (i.e. foo) and non-directories (i.e. foo;1). + */ + if (*p == ';') { + break; + } + hash = (hash << 15) + (hash << 3) + (hash >> 3) + (*p++ & 0xFF); + } + return (hash % NR_NAME_HASH); +} + +EXPORT void +add_file_hash(de) + struct directory_entry *de; +{ + struct name_hash *new; + int hash; + Uchar *p; + int sum = 0; + + new = (struct name_hash *)e_malloc(sizeof (struct name_hash)); + new->de = de; + new->next = NULL; + for (p = (Uchar *)de->isorec.name; *p; p++) { + if (*p == ';') + break; + sum += *p & 0xFF; + } + new->sum = sum; + hash = name_hash(de->isorec.name); + + /* Now insert into the hash table */ + new->next = name_hash_table[hash]; + name_hash_table[hash] = new; +} + +EXPORT struct directory_entry * +find_file_hash(name) + register char *name; +{ + register char *p1; + register char *p2; + register struct name_hash *nh; + register int sum = 0; + + if (debug > 1) + error("find_hash('%s')\n", name); + + for (p1 = name; *p1; p1++) { + if (*p1 == ';') + break; + sum += *p1 & 0xFF; + } + + for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) { + if (nh->sum != sum) + continue; + + p1 = name; + p2 = nh->de->isorec.name; + if (debug > 1) + error(_("Checking name '%s' isorec.name '%s'\n"), p1, p2); + + /* Look for end of string, or a mismatch. */ + while (1 == 1) { + if ((*p1 == '\0' || *p1 == ';') || + (*p2 == '\0' || *p2 == ';') || + (*p1 != *p2)) { + break; + } + p1++; + p2++; + } + if (!isoname_endsok(p1) || !isoname_endsok(p2)) { + if (debug > 1) { + if (!isoname_endsok(p1)) + error(_("'%s' does NOT END OK\n"), p1); + if (!isoname_endsok(p2)) + error(_("'%s' does NOT END OK\n"), p2); + } + /* + * If one file does not end with a valid version number + * and the other name ends here, we found a miss match. + */ + if (*p1 == '\0' || *p2 == '\0') + continue; + + if (*p1 == ';' && *p2 == ';') { + p1++; + p2++; + continue; + } + } + + /* + * If we are at the end of both strings, then we have a match. + */ + if ((*p1 == '\0' || *p1 == ';') && + (*p2 == '\0' || *p2 == ';')) { + return (nh->de); + } + } + return (NULL); +} + +/* + * The macro 'eo' is just an idea on how one might speed up isoname_endsok() + */ +#define eo(p) (((p)[0] == '\0') || \ + ((p)[0] == ';' && (p)[1] == '1' && (p)[2] == '\0') || \ + isoname_endsok(p)) + +LOCAL BOOL +isoname_endsok(name) + char *name; +{ + int i; + char *p; + + if (*name == '\0') + return (TRUE); + if (*name != ';') + return (FALSE); + + for (p = ++name, i = 0; *p && i < 5; p++, i++) { + if (*p < '0' || *p > '9') + return (FALSE); + } + i = atoi(name); + if (i < 1 || i > 32767) + return (FALSE); + return (TRUE); +} + +EXPORT int +delete_file_hash(de) + struct directory_entry *de; +{ + struct name_hash *nh; + struct name_hash *prev; + int hash; + + prev = NULL; + hash = name_hash(de->isorec.name); + for (nh = name_hash_table[hash]; nh; nh = nh->next) { + if (nh->de == de) + break; + prev = nh; + } + if (!nh) + return (1); + if (!prev) + name_hash_table[hash] = nh->next; + else + prev->next = nh->next; + free(nh); + return (0); +} + +EXPORT void +flush_file_hash() +{ + struct name_hash *nh; + struct name_hash *nh1; + int i; + + for (i = 0; i < NR_NAME_HASH; i++) { + nh = name_hash_table[i]; + while (nh) { + nh1 = nh->next; + free(nh); + nh = nh1; + } + name_hash_table[i] = NULL; + + } +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/inode.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/inode.c new file mode 100644 index 00000000000..59d906e4558 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/inode.c @@ -0,0 +1,460 @@ +/* @(#)inode.c 1.18 15/12/08 Copyright 2006-2015 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)inode.c 1.18 15/12/08 Copyright 2006-2015 J. Schilling"; +#endif +/* + * Inode and link count handling for ISO-9660/RR + * + * This module computes and sets up a RR link count that reflects + * the name-count for files/directories in the ISO-9660/RR image. + * This module also assigns inode numbers tp all files/directories + * using either the RRip-112 protocol or a mkisofs specific method + * of asigning the related number to the "extent" field in the ISO + * directory record. + * + * Copyright (c) 2006-2015 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mkisofs.h" +#include + +/* + * Highest inode value we assign in this session. + */ +LOCAL UInt32_t null_ino_high; + +EXPORT void do_inode __PR((struct directory *dpnt)); +EXPORT void do_dir_nlink __PR((struct directory *dpnt)); +LOCAL void assign_inodes __PR((struct directory *dpnt)); +LOCAL void compute_linkcount __PR((struct directory *dpnt)); +LOCAL void assign_linkcount __PR((struct directory *dpnt)); +LOCAL void update_inode __PR((struct directory_entry *s_entry, int value)); +LOCAL void update_nlink __PR((struct directory_entry *s_entry, int value)); +LOCAL int update_dir_nlink __PR((struct directory *dpnt)); + +/* + * Inode/hard link related stuff for non-directory type files. + */ +EXPORT void +do_inode(dpnt) + struct directory *dpnt; +{ + null_ino_high = null_inodes; + + if (correct_inodes) + assign_inodes(root); + +#ifdef UDF + if (!use_RockRidge && !use_udf) + return; +#else + if (!use_RockRidge) + return; +#endif + if (!cache_inodes) /* Never FALSE if correct_inodes TRUE */ + return; + + compute_linkcount(dpnt); + if (use_RockRidge) /* If we have Rock Ridge extensions, */ + assign_linkcount(dpnt); /* reassign computed linkcount in RR */ + + if (null_inodes < last_extent) + comerrno(EX_BAD, _("Inode number overflow, too many files in file system.\n")); +} + +/* + * Set the link count for directories to 2 + number of sub-directories. + */ +EXPORT void +do_dir_nlink(dpnt) + struct directory *dpnt; +{ + int rootlinks; + + if (!use_RockRidge) + return; + + /* + * Update everything except "/..". + */ + rootlinks = update_dir_nlink(dpnt); + if (reloc_dir) + rootlinks--; /* rr_moved is hidden */ + /* + * Update "/." now. + */ + update_nlink(dpnt->contents, rootlinks); + /* + * Update "/.." now. + */ + update_nlink(dpnt->contents->next, rootlinks); +} + +/* + * Assign inode numbers to files of zero size and to symlinks. + */ +LOCAL void +assign_inodes(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) { + if (s_entry->starting_block == 0) { + s_hash = find_hash(s_entry->dev, s_entry->inode); + /* find_directory_hash() ? */ + if (s_hash) + s_entry->starting_block = s_hash->starting_block; + } + if (s_entry->starting_block == 0 && s_entry->size != 0) { + unsigned int e = get_733((char *)s_entry->isorec.extent); + + if (e != 0) { + errmsgno(EX_BAD, + _("Implementation botch, fetching extend %d for %s from dir entry.\n"), + e, s_entry->whole_name); + } + } + if (use_RockRidge && s_entry->starting_block > 0) + update_inode(s_entry, s_entry->starting_block); + + /* + * Be careful: UDF Symlinks have size != 0, then + * s_hash->starting_block is a valid inode number. + */ + if (s_entry->size != 0) + continue; +#ifdef UDF + if ((s_entry->de_flags & IS_SYMLINK) != 0 && + create_udfsymlinks) + continue; +#else + if ((s_entry->de_flags & IS_SYMLINK) != 0) + continue; +#endif + + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) + continue; + + /* + * Assign inodes to symbolic links. + */ + if (s_entry->dev == UNCACHED_DEVICE && s_entry->inode == UNCACHED_INODE) { + s_entry->dev = PREV_SESS_DEV; + s_entry->inode = null_inodes; + } + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + /* + * Paranoia: Check for hashed files without proper inode #. + */ + if (s_hash->starting_block <= last_extent) + comerrno(EX_BAD, + _("Implementation botch: Hashed file '%s' has illegal inode %u.\n"), + s_entry->whole_name ? + s_entry->whole_name : s_entry->name, + s_hash->starting_block); + set_733((char *)s_entry->isorec.extent, s_hash->starting_block); + s_entry->starting_block = s_hash->starting_block; + } else { + s_entry->starting_block = null_inodes--; + set_733((char *)s_entry->isorec.extent, s_entry->starting_block); + add_hash(s_entry); + } + if (use_RockRidge) + update_inode(s_entry, s_entry->starting_block); + } + if (dpnt->subdir) { + assign_inodes(dpnt->subdir); + } + + dpnt = dpnt->next; + } +} + +/* + * Compute the link count for non-directory type files. + */ +LOCAL void +compute_linkcount(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) { + /* + * Skip directories. + */ + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) + continue; + if (s_entry->de_flags & RELOCATED_DIRECTORY) + continue; + + /* + * skip resource files or file stream files + * XXX should we assign a standard link count == 1 instead? + */ + if (s_entry->de_flags & RESOURCE_FORK) + continue; + + /* + * Assign inodes to symbolic links. + * We never come here in case that we create correct inodes, + * except with UDF symlinks. + */ + if (s_entry->dev == UNCACHED_DEVICE && s_entry->inode == UNCACHED_INODE) { + s_entry->dev = PREV_SESS_DEV; + + /* + * With UDF symlinks, the starting_block is a + * valid inode number. + */ +#ifdef UDF + if ((s_entry->de_flags & IS_SYMLINK) != 0 && + create_udfsymlinks) { +#else + if ((s_entry->de_flags & IS_SYMLINK) != 0) { +#endif + s_entry->inode = s_entry->starting_block; + } else { + s_entry->inode = null_inodes--; /* Only used for caching */ + if (correct_inodes) + comerrno(EX_BAD, + _("Implementation botch: Unhashed file '%s'.\n"), + s_entry->whole_name ? + s_entry->whole_name : s_entry->name); + } + } + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + s_hash->nlink++; + } else { + add_hash(s_entry); + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash == NULL) { + if (s_entry->dev == UNCACHED_DEVICE && + s_entry->inode == TABLE_INODE) { + continue; + } + comerrno(EX_BAD, + _("Implementation botch: File '%s' not hashed (dev/ino %llX/%llX).\n"), + s_entry->whole_name ? + s_entry->whole_name : s_entry->name, + (Llong)s_entry->dev, + (Llong)s_entry->inode); + } + s_hash->nlink++; + } + } + if (dpnt->subdir) { + compute_linkcount(dpnt->subdir); + } + + dpnt = dpnt->next; + } +} + +/* + * Assig the link count for non-directory type files to the value + * computed with compute_linkcount(). + */ +LOCAL void +assign_linkcount(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) { + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) + continue; + if (s_entry->de_flags & RELOCATED_DIRECTORY) + continue; + /* + * skip resource files or file stream files + */ + if (s_entry->de_flags & RESOURCE_FORK) + continue; + + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + update_nlink(s_entry, s_hash->nlink); + } else { + if (s_entry->dev == UNCACHED_DEVICE && + s_entry->inode == TABLE_INODE) { + continue; + } + comerrno(EX_BAD, + _("Implementation botch: File '%s' not hashed.\n"), + s_entry->whole_name ? + s_entry->whole_name : s_entry->name); + } + } + if (dpnt->subdir) { + assign_linkcount(dpnt->subdir); + } + + dpnt = dpnt->next; + } +} + +/* + * Rewrite the content of the RR inode field in the PX record. + */ +LOCAL void +update_inode(s_entry, value) + struct directory_entry *s_entry; + int value; +{ + unsigned char *pnt; + int len; + + if (!rrip112) + return; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + break; + } + if (pnt[0] == 'P' && pnt[1] == 'X') { + if ((pnt[2] & 0xFF) < 44) /* Paranoia */ + return; + set_733((char *)pnt + 36, value); + break; + } + len -= pnt[2]; + pnt += pnt[2]; + } +} + +/* + * Rewrite the content of the RR nlink field in the PX record. + */ +LOCAL void +update_nlink(s_entry, value) + struct directory_entry *s_entry; + int value; +{ + unsigned char *pnt; + int len; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + break; + } + if (pnt[0] == 'P' && pnt[1] == 'X') { + set_733((char *)pnt + 12, value); + break; + } + len -= pnt[2]; + pnt += pnt[2]; + } +} + +/* + * Set the link count for directories to 2 + number of sub-directories. + * This is done here for all diresctories except for "/..". + */ +LOCAL int +update_dir_nlink(dpnt) + struct directory *dpnt; +{ + struct directory *xpnt; + struct directory_entry *s_entry; + int i = 0; + + while (dpnt) { + if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { + dpnt = dpnt->next; + continue; + } + /* + * First, count up the number of subdirectories this dir has. + */ + for (i = 0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) + if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) + i++; + /* + * Next check to see if we have any relocated directories in + * this directory. The nlink field will include these as + * real directories when they are properly relocated. + * In the non-rockridge disk, the relocated entries appear as + * zero length files. + */ + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0 && + (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == + 0) { + i++; + } + } + /* + * Now update the field in the Rock Ridge entry. + */ + update_nlink(dpnt->self, i + 2); + + /* + * Update the '.' entry for this directory. + */ + update_nlink(dpnt->contents, i + 2); + + /* + * Update all of the '..' entries that point to this guy. + */ + for (xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) { + update_nlink(xpnt->contents->next, i + 2); + } + + if (dpnt->subdir) + update_dir_nlink(dpnt->subdir); + dpnt = dpnt->next; + } + return (i+2); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/iso9660.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/iso9660.h new file mode 100644 index 00000000000..3a8e59b4522 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/iso9660.h @@ -0,0 +1,376 @@ +/* @(#)iso9660.h 1.22 11/06/04 joerg */ +/* + * Header file iso9660.h - assorted structure definitions and typecasts. + * specific to iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2007 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _ISOFS_FS_H +#define _ISOFS_FS_H + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; + char data [ISODCL(8, 2048)]; +}; + +/* volume descriptor types */ +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +#define EL_TORITO_ID "EL TORITO SPECIFICATION" +#define EL_TORITO_ARCH_x86 0 +#define EL_TORITO_ARCH_PPC 1 +#define EL_TORITO_ARCH_MAC 2 +#define EL_TORITO_ARCH_EFI 0xEF + +#define EL_TORITO_BOOTABLE 0x88 +#define EL_TORITO_NOT_BOOTABLE 0 + +#define EL_TORITO_MEDIA_NOEMUL 0 +#define EL_TORITO_MEDIA_12FLOP 1 +#define EL_TORITO_MEDIA_144FLOP 2 +#define EL_TORITO_MEDIA_288FLOP 3 +#define EL_TORITO_MEDIA_HD 4 + +struct iso_primary_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char unused1 [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* + * Supplementary or enhanced volume descriptor + */ +struct iso_enhanced_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char flags [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* El Torito Boot Record Volume Descriptor */ +struct eltorito_boot_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char system_id [ISODCL(8, 39)]; + char unused2 [ISODCL(40, 71)]; + char bootcat_ptr [ISODCL(72, 75)]; + char unused5 [ISODCL(76, 2048)]; +}; + +/* Validation entry for El Torito */ +/* + * headerid must be 1 + * id is the manufacturer ID + * cksum to make the sum of all shorts in this record 0 + */ +struct eltorito_validation_entry { + char headerid [ISODCL(1, 1)]; /* 711 */ + char arch [ISODCL(2, 2)]; + char pad1 [ISODCL(3, 4)]; /* 721 */ + char id [ISODCL(5, 28)]; /* CD devel/man*/ + char cksum [ISODCL(29, 30)]; + char key1 [ISODCL(31, 31)]; + char key2 [ISODCL(32, 32)]; +}; + +/* El Torito initial/default entry in boot catalog */ +struct eltorito_defaultboot_entry { + char boot_id [ISODCL(1, 1)]; /* 711 */ + char boot_media [ISODCL(2, 2)]; + char loadseg [ISODCL(3, 4)]; /* 721 */ + char sys_type [ISODCL(5, 5)]; + char pad1 [ISODCL(6, 6)]; + char nsect [ISODCL(7, 8)]; + char bootoff [ISODCL(9, 12)]; + char pad2 [ISODCL(13, 32)]; +}; + +/* El Torito section header entry in boot catalog */ +struct eltorito_sectionheader_entry { +#define EL_TORITO_SHDR_ID_SHDR 0x90 +#define EL_TORITO_SHDR_ID_LAST_SHDR 0x91 + char header_id [ISODCL(1, 1)]; /* 711 */ + char platform_id [ISODCL(2, 2)]; + char entry_count [ISODCL(3, 4)]; /* 721 */ + char id [ISODCL(5, 32)]; +}; + +/* El Torito section entry in boot catalog */ +struct eltorito_section_entry { + char boot_id [ISODCL(1, 1)]; /* 711 */ + char boot_media [ISODCL(2, 2)]; + char loadseg [ISODCL(3, 4)]; /* 721 */ + char sys_type [ISODCL(5, 5)]; + char pad1 [ISODCL(6, 6)]; + char nsect [ISODCL(7, 8)]; + char bootoff [ISODCL(9, 12)]; + char sel_criteria [ISODCL(13, 13)]; + char vendor_sel_criteria [ISODCL(14, 32)]; +}; + +/* + * XXX JS: The next two structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See mkisofs.h + */ + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table { + unsigned char name_len[2]; /* 721 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[1]; +}; + +/* + * A ISO filename is: "abcde.eee;1" -> '.' ';' + * + * The maximum needed string length is: + * 30 chars (filename + ext) + * + 2 chars ('.' + ';') + * + strlen("32767") + * + null byte + * ================================ + * = 38 chars + * + * We currently do not support CD-ROM-XA entension records, but we must honor + * the needed space for ISO-9660:1999 (Version 2). + * + * XXX If we ever will start to support XA records, we will need to take care + * XXX that the the maximum ISO-9660 name length will be reduced by another + * XXX 14 bytes resulting in a new total of 179 Bytes. + */ +#define LEN_ISONAME 31 +#define MAX_ISONAME_V1 37 +#define MAX_ISONAME_V2 207 /* 254 - 33 - 14 (XA Record) */ +#define MAX_ISONAME_V2_RR 193 /* 254 - 33 - 28 (CE Record) */ +#define MAX_ISONAME_V2_RR_XA 179 /* 254 - 33 - 14 - 28 */ +#define MAX_ISONAME MAX_ISONAME_V2 /* Used for array space defs */ +#define MAX_ISODIR 254 /* Must be even and <= 255 */ + +struct iso_directory_record { + unsigned char length [ISODCL(1, 1)]; /* 711 */ + char ext_attr_length [ISODCL(2, 2)]; /* 711 */ + char extent [ISODCL(3, 10)]; /* 733 */ + char size [ISODCL(11, 18)]; /* 733 */ + char date [ISODCL(19, 25)]; /* 7 by 711 */ + unsigned char flags [ISODCL(26, 26)]; + char file_unit_size [ISODCL(27, 27)]; /* 711 */ + char interleave [ISODCL(28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ + unsigned char name_len [ISODCL(33, 33)]; /* 711 */ + char name [MAX_ISONAME+1]; /* Not really, but we need something here */ +}; + + +/* + * Iso directory flags. + */ +#define ISO_FILE 0 /* Not really a flag... */ +#define ISO_EXISTENCE 1 /* Do not make existence known (hidden) */ +#define ISO_DIRECTORY 2 /* This file is a directory */ +#define ISO_ASSOCIATED 4 /* This file is an assiciated file */ +#define ISO_RECORD 8 /* Record format in extended attr. != 0 */ +#define ISO_PROTECTION 16 /* No read/execute perm. in ext. attr. */ +#define ISO_DRESERVED1 32 /* Reserved bit 5 */ +#define ISO_DRESERVED2 64 /* Reserved bit 6 */ +#define ISO_MULTIEXTENT 128 /* Not final entry of a mult. ext. file */ + + +struct iso_ext_attr_record { + char owner [ISODCL(1, 4)]; /* 723 */ + char group [ISODCL(5, 8)]; /* 723 */ + char permissions [ISODCL(9, 10)]; /* 16 bits */ + char creation_date [ISODCL(11, 27)]; /* 8.4.26.1 */ + char modification_date [ISODCL(28, 44)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(45, 61)]; /* 8.4.26.1 */ + char effective_date [ISODCL(62, 78)]; /* 8.4.26.1 */ + char record_format [ISODCL(79, 79)]; /* 711 */ + char record_attributes [ISODCL(80, 80)]; /* 711 */ + char record_length [ISODCL(81, 84)]; /* 723 */ + char system_id [ISODCL(85, 116)]; /* achars */ + char system_use [ISODCL(117, 180)]; + char ext_attr_version [ISODCL(181, 181)]; /* 711 */ + char esc_seq_len [ISODCL(182, 182)]; /* 711 */ + char reserved [ISODCL(183, 246)]; /* for future use */ + char appl_use_len [ISODCL(247, 250)]; /* 723 */ + char appl_use[1]; /* really more */ +/* char esc_seq[]; escape sequences recorded after appl_use */ +}; + +/* + * Iso extended attribute permissions. + */ +#define ISO_GS_READ 0x0001 /* System Group Read */ +#define ISO_BIT_1 0x0002 +#define ISO_GS_EXEC 0x0004 /* System Group Execute */ +#define ISO_BIT_3 0x0008 + +#define ISO_O_READ 0x0010 /* Owner Read */ +#define ISO_BIT_5 0x0020 +#define ISO_O_EXEC 0x0040 /* Owner Exexute */ +#define ISO_BIT_7 0x0080 + +#define ISO_G_READ 0x0100 /* Group Read */ +#define ISO_BIT_9 0x0200 +#define ISO_G_EXEC 0x0400 /* Group Execute */ +#define ISO_BIT_11 0x0800 + +#define ISO_W_READ 0x1000 /* World (other) Read */ +#define ISO_BIT_13 0x2000 +#define ISO_W_EXEC 0x4000 /* World (other) Execute */ +#define ISO_BIT_15 0x8000 + +#define ISO_MB_ONE (ISO_BIT_1|ISO_BIT_3|ISO_BIT_5|ISO_BIT_7| \ + ISO_BIT_9|ISO_BIT_11|ISO_BIT_13|ISO_BIT_15) + +/* + * Extended Attributes record according to Yellow Book. + */ +struct iso_xa_dir_record { + char group_id [ISODCL(1, 2)]; + char user_id [ISODCL(3, 4)]; + char attributes [ISODCL(5, 6)]; + char signature [ISODCL(7, 8)]; + char file_number [ISODCL(9, 9)]; + char reserved [ISODCL(10, 14)]; +}; + +/* + * Definitions for XA attributes + */ +#define XA_O_READ 0x0001 /* Owner Read */ +#define XA_O_RES 0x0002 /* Owner Reserved (write ?) */ +#define XA_O_EXEC 0x0004 /* Owner Execute */ +#define XA_O_RES2 0x0008 /* Owner Reserved */ +#define XA_G_READ 0x0010 /* Group Read */ +#define XA_G_RES 0x0020 /* Group Reserved (write ?) */ +#define XA_G_EXEC 0x0040 /* Group Execute */ +#define XA_G_RES2 0x0080 /* Group Reserved */ +#define XA_W_READ 0x0100 /* World Read */ +#define XA_W_RES 0x0200 /* World Reserved (write ?) */ +#define XA_W_EXEC 0x0400 /* World Execute */ + +#define XA_FORM1 0x0800 /* File contains Form 1 sector */ +#define XA_FORM2 0x1000 /* File contains Form 2 sector */ +#define XA_INTERLEAVED 0x2000 /* File contains interleaved sectors */ +#define XA_CDDA 0x4000 /* File contains audio data */ +#define XA_DIR 0x8000 /* This is a directory */ + +/* + * Definitions for CD-ROM XA-Mode-2-form-1/2 sector sub-headers + */ +struct xa_subhdr { + Uchar file_number; /* Identifies file for block */ + Uchar channel_number; /* Playback channel selection */ + Uchar sub_mode; /* See bit definitions below */ + Uchar coding; /* Coding information */ +}; + +/* + * Sub mode bit definitions + */ +#define XA_SUBH_EOR 0x01 /* End-Of-Record */ +#define XA_SUBH_VIDEO 0x02 /* Video Block */ +#define XA_SUBH_AUDIO 0x04 /* Audio Block (not CD-DA) */ +#define XA_SUBH_DATA 0x08 /* Data Block */ +#define XA_SUBH_TRIGGER 0x10 /* Trigger Block */ +#define XA_SUBH_FORM2 0x20 /* 0 == Form1, 1 == Form2 */ +#define XA_SUBH_REALTIME 0x40 /* Real Time Block */ +#define XA_SUBH_EOF 0x80 /* End-Of-File */ + +#endif /* _ISOFS_FS_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/isonum.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/isonum.c new file mode 100644 index 00000000000..64dd0d7585f --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/isonum.c @@ -0,0 +1,228 @@ +/* @(#)isonum.c 1.9 10/12/19 Copyright 2006-2010 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)isonum.c 1.9 10/12/19 Copyright 2006-2010 J. Schilling"; +#endif +/* + * Copyright (c) 2006-2010 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "mkisofs.h" + + +EXPORT void set_721 __PR((void *vp, UInt32_t i)); +EXPORT void set_722 __PR((void *vp, UInt32_t i)); +EXPORT void set_723 __PR((void *vp, UInt32_t i)); +EXPORT void set_731 __PR((void *vp, UInt32_t i)); +EXPORT void set_732 __PR((void *vp, UInt32_t i)); +EXPORT void set_733 __PR((void *vp, UInt32_t i)); +EXPORT UInt32_t get_711 __PR((void *vp)); +EXPORT UInt32_t get_721 __PR((void *vp)); +EXPORT UInt32_t get_723 __PR((void *vp)); +EXPORT UInt32_t get_731 __PR((void *vp)); +EXPORT UInt32_t get_732 __PR((void *vp)); +EXPORT UInt32_t get_733 __PR((void *vp)); + +/* + * ISO-9660 7.2.1 + * Set 16 bit unsigned int, store Least significant byte first + */ +EXPORT void +set_721(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[0] = i & 0xff; + p[1] = (i >> 8) & 0xff; +} + +/* + * ISO-9660 7.2.2 + * Set 16 bit unsigned int, store Most significant byte first + */ +EXPORT void +set_722(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[0] = (i >> 8) & 0xff; + p[1] = i & 0xff; +} + +/* + * ISO-9660 7.2.3 + * Set 16 bit unsigned int, store Both Byte orders + */ +EXPORT void +set_723(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[3] = p[0] = i & 0xff; + p[2] = p[1] = (i >> 8) & 0xff; +} + +/* + * ISO-9660 7.3.1 + * Set 32 bit unsigned int, store Least significant byte first + */ +EXPORT void +set_731(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[0] = i & 0xff; + p[1] = (i >> 8) & 0xff; + p[2] = (i >> 16) & 0xff; + p[3] = (i >> 24) & 0xff; +} + +/* + * ISO-9660 7.3.2 + * Set 32 bit unsigned int, store Most significant byte first + */ +EXPORT void +set_732(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[3] = i & 0xff; + p[2] = (i >> 8) & 0xff; + p[1] = (i >> 16) & 0xff; + p[0] = (i >> 24) & 0xff; +} + +/* + * ISO-9660 7.3.3 + * Set 32 bit unsigned int, store Both Byte orders + */ +EXPORT void +set_733(vp, i) + void *vp; + UInt32_t i; +{ + Uchar *p = vp; + + p[7] = p[0] = i & 0xff; + p[6] = p[1] = (i >> 8) & 0xff; + p[5] = p[2] = (i >> 16) & 0xff; + p[4] = p[3] = (i >> 24) & 0xff; +} + +/* + * ISO-9660 7.1.1 + * Get 8 bit unsigned int + */ +EXPORT UInt32_t +get_711(vp) + void *vp; +{ + Uchar *p = vp; + + return (*p & 0xff); +} + +/* + * ISO-9660 7.2.1 + * Get 16 bit unsigned int, stored with Least significant byte first + */ +EXPORT UInt32_t +get_721(vp) + void *vp; +{ + Uchar *p = vp; + + return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); +} + + +/* + * ISO-9660 7.2.3 + * Get 16 bit unsigned int, stored with Both Byte orders + */ +EXPORT UInt32_t +get_723(vp) + void *vp; +{ + Uchar *p = vp; +#if 0 + if (p[0] != p[3] || p[1] != p[2]) { + comerrno(EX_BAD, _("Invalid format 7.2.3 number\n")); + } +#endif + return (get_721(p)); +} + + +/* + * ISO-9660 7.3.1 + * Get 32 bit unsigned int, stored with Least significant byte first + */ +EXPORT UInt32_t +get_731(vp) + void *vp; +{ + Uchar *p = vp; + + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +/* + * ISO-9660 7.3.2 + * Get 32 bit unsigned int, stored with Most significant byte first + */ +EXPORT UInt32_t +get_732(vp) + void *vp; +{ + Uchar *p = vp; + + return ((p[3] & 0xff) + | ((p[2] & 0xff) << 8) + | ((p[1] & 0xff) << 16) + | ((p[0] & 0xff) << 24)); +} + +/* + * ISO-9660 7.3.3 + * Get 32 bit unsigned int, stored with Both Byte orders + */ +EXPORT UInt32_t +get_733(vp) + void *vp; +{ + Uchar *p = vp; + + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/joliet.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/joliet.c new file mode 100644 index 00000000000..690be006b04 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/joliet.c @@ -0,0 +1,1456 @@ +/* @(#)joliet.c 1.68 15/12/30 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)joliet.c 1.68 15/12/30 joerg"; +#endif +/* + * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660. + * + * Copyright 1997 Eric Youngdale. + * APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 22/2/2000 + * Copyright (c) 1999-2015 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Joliet extensions for ISO9660. These are spottily documented by + * Microsoft. In their infinite stupidity, they completely ignored + * the possibility of using an SUSP record with the long filename + * in it, and instead wrote out a duplicate directory tree with the + * long filenames in it. + * + * I am not sure why they did this. One reason is that they get the path + * tables with the long filenames in them. + * + * There are two basic principles to Joliet, and the non-Unicode variant + * known as Romeo. Long filenames seem to be the main one, and the second + * is that the character set and a few other things is substantially relaxed. + * + * The SVD is identical to the PVD, except: + * + * Id is 2, not 1 (indicates SVD). + * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3). + * The root directory record points to a different extent (with different + * size). + * There are different path tables for the two sets of directory trees. + * + * The Unicode level is coded in the SVD as follows: + * + * Standard Level ASCII escape code + * UCS-2 Level-1 %/@ + * UCS-2 Level-2 %/C + * UCS-2 Level-3 %/E + * + * The following fields are recorded in Unicode: + * system_id + * volume_id + * volume_set_id + * publisher_id + * preparer_id + * application_id + * copyright_file_id + * abstract_file_id + * bibliographic_file_id + * + * Unicode strings are always encoded in big-endian format. + * + * In a directory record, everything is the same as with iso9660, except + * that the name is recorded in unicode. The name length is specified in + * total bytes, not in number of unicode characters. + * + * The character set used for the names is different with UCS - the + * restrictions are that the following are not allowed: + * + * Characters (00)(00) through (00)(1f) (control chars) + * (00)(2a) '*' + * (00)(2f) '/' + * (00)(3a) ':' + * (00)(3b) ';' + * (00)(3f) '?' + * (00)(5c) '\' + */ +#include "mkisofs.h" +#include +#include +#include +#include +#include + +LOCAL Uint jpath_table_index; +LOCAL struct directory **jpathlist; +LOCAL int next_jpath_index = 1; +LOCAL int jsort_goof; +LOCAL int jsort_glen; + +LOCAL char ucs_codes[] = { + '\0', /* UCS-level 0 is illegal */ + '@', /* UCS-level 1 */ + 'C', /* UCS-level 2 */ + 'E', /* UCS-level 3 */ +}; + +#ifdef UDF +EXPORT void convert_to_unicode __PR((unsigned char *buffer, + int size, char *source, + siconvt_t *inls)); +EXPORT int joliet_strlen __PR((const char *string, size_t maxlen, + siconvt_t *inls)); +#else +LOCAL void convert_to_unicode __PR((unsigned char *buffer, + int size, char *source, + siconvt_t *inls)); +LOCAL int joliet_strlen __PR((const char *string, size_t maxlen, + siconvt_t *inls)); +#endif +LOCAL void get_joliet_vol_desc __PR((struct iso_primary_descriptor *jvol_desc)); +LOCAL void assign_joliet_directory_addresses __PR((struct directory *node)); +LOCAL void build_jpathlist __PR((struct directory *node)); +LOCAL int joliet_compare_paths __PR((void const *r, void const *l)); +LOCAL int generate_joliet_path_tables __PR((void)); +LOCAL void generate_one_joliet_directory __PR((struct directory *dpnt, + FILE *outfile)); +LOCAL int joliet_sort_n_finish __PR((struct directory *this_dir)); + +LOCAL int joliet_compare_dirs __PR((const void *rr, const void *ll)); + +LOCAL int joliet_sort_directory __PR((struct directory_entry **sort_dir)); +EXPORT int joliet_sort_tree __PR((struct directory *node)); +LOCAL void generate_joliet_directories __PR((struct directory *node, + FILE *outfile)); +LOCAL int jpathtab_write __PR((FILE *outfile)); +LOCAL int jdirtree_size __PR((UInt32_t starting_extent)); +LOCAL int jroot_gen __PR((void)); +LOCAL int jdirtree_write __PR((FILE *outfile)); +LOCAL int jvd_write __PR((FILE *outfile)); +LOCAL int jpathtab_size __PR((UInt32_t starting_extent)); + +/* + * conv_charset: convert to/from charsets via Unicode. + * + * Any unknown character is set to '_' + * + */ +EXPORT void +conv_charset(to, tosizep, from, fromsizep, inls, onls) + unsigned char *to; + size_t *tosizep; + unsigned char *from; + size_t *fromsizep; + siconvt_t *inls; + siconvt_t *onls; +{ + UInt16_t unichar; + size_t fromsize = *fromsizep; + size_t tosize = *tosizep; + Uchar ob[2]; /* 2 octets (16 Bit) UCS-2 */ + + if (fromsize == 0 || tosize == 0) + return; + + /* + * If we have a null mapping, just return the input character + */ + if (inls->sic_name == onls->sic_name) { + *to = *from; + (*fromsizep)--; + (*tosizep)--; + return; + } +#ifdef USE_ICONV +#ifdef HAVE_ICONV_CONST +#define __IC_CONST const +#else +#define __IC_CONST +#endif + if (use_iconv(inls)) { + char *obuf = (char *)ob; + size_t osize = 2; /* UCS-2 character size */ + + if (iconv(inls->sic_cd2uni, (__IC_CONST char **)&from, + fromsizep, + &obuf, &osize) == -1) { + int err = geterrno(); + + if ((err == EINVAL || err == EILSEQ) && + *fromsizep == fromsize) { + ob[0] = 0; ob[1] = '_'; + (*fromsizep)--; + } + } + unichar = ob[0] * 256 + ob[1]; /* Compute 16 Bit UCS-2 char */ + } else +#endif + { + unsigned char c = *from; + + unichar = sic_c2uni(inls, c); /* Get the UNICODE char */ + (*fromsizep)--; + + if (unichar == 0) + unichar = '_'; + + ob[0] = unichar >> 8 & 0xFF; /* Compute 2 octet variant */ + ob[1] = unichar & 0xFF; + } + +#ifdef USE_ICONV + if (use_iconv(onls)) { + char *ibuf = (char *)ob; + size_t isize = 2; /* UCS-2 character size */ + + if (iconv(onls->sic_uni2cd, (__IC_CONST char **)&ibuf, &isize, + (char **)&to, tosizep) == -1) { + int err = geterrno(); + + if ((err == EINVAL || err == EILSEQ) && + *tosizep == tosize) { + *to = '_'; + (*tosizep)--; + } + } + } else +#endif + { + *to = sic_uni2c(onls, unichar); /* Get the backconverted char */ + (*tosizep)--; + } +} + + +/* + * Function: convert_to_unicode + * + * Purpose: Perform a unicode conversion on a text string + * using the supplied input character set. + * + * Notes: + */ +#ifdef UDF +EXPORT void +#else +LOCAL void +#endif +convert_to_unicode(buffer, size, source, inls) + unsigned char *buffer; + int size; + char *source; + siconvt_t *inls; +{ + unsigned char *tmpbuf; + int i; + int j; + UInt16_t unichar; + unsigned char uc; + int jsize = size; + + /* + * If we get a NULL pointer for the source, it means we have an + * inplace copy, and we need to make a temporary working copy first. + */ + if (source == NULL) { + tmpbuf = (Uchar *) e_malloc(size); + memcpy(tmpbuf, buffer, size); + } else { + tmpbuf = (Uchar *) source; + } + + /* + * Now start copying characters. If the size was specified to be 0, + * then assume the input was 0 terminated. + */ + j = 0; + for (i = 0; (i + 1) < size; i += 2, j++) { /* Size may be odd! */ + /* + * Let all valid unicode characters pass + * through (according to charset). Others are set to '_' . + */ + if (j < jsize) + uc = tmpbuf[j]; /* temporary copy */ + else + uc = '\0'; + if (uc == '\0') { + jsize = j; + unichar = 0; + } else { /* must be converted */ +#ifdef USE_ICONV + if (use_iconv(inls)) { + Uchar ob[2]; + __IC_CONST char *inbuf = (char *)&tmpbuf[j]; + size_t isize = 3; + char *obuf = (char *)ob; + size_t osize = 2; + + /* + * iconv() from glibc ignores osize and thus + * may try to access more than a single multi + * byte character from the input and read from + * non-existent memory. + */ + if (iconv(inls->sic_cd2uni, &inbuf, &isize, + &obuf, &osize) == -1) { + int err = geterrno(); + + if ((err == EINVAL || err == EILSEQ) && + isize == 3) { + ob[0] = ob[1] = 0; + isize--; + } + } + unichar = ob[0] * 256 + ob[1]; + j += 2 - isize; + } else +#endif + unichar = sic_c2uni(inls, uc); /* Get the UNICODE */ + + /* + * This code is currently also used for UDF formatting. + * Do not enforce silly Microsoft limitations in case + * that we only create UDF extensions. + */ + if (!use_Joliet) + goto all_chars; + + if (unichar <= 0x1f || unichar == 0x7f) + unichar = '\0'; /* control char */ + + switch (unichar) { /* test special characters */ + + case '*': + case '/': + case ':': + case ';': + case '?': + case '\\': + case '\0': /* illegal char mark */ + /* + * Even Joliet has some standards as to what is + * allowed in a pathname. Pretty tame in + * comparison to what DOS restricts you to. + */ + unichar = '_'; + } + all_chars: + ; + } + buffer[i] = unichar >> 8 & 0xFF; /* final UNICODE */ + buffer[i + 1] = unichar & 0xFF; /* conversion */ + } + + if (size & 1) { /* beautification */ + buffer[size - 1] = 0; + } + if (source == NULL) { + free(tmpbuf); + } +} + +/* + * Function: joliet_strlen + * + * Purpose: Return length in bytes of string after conversion to unicode. + * + * Notes: This is provided mainly as a convenience so that when more + * intelligent Unicode conversion for either Multibyte or 8-bit + * codes is available that we can easily adapt. + */ +#ifdef UDF +EXPORT int +#else +LOCAL int +#endif +joliet_strlen(string, maxlen, inls) + const char *string; + size_t maxlen; + siconvt_t *inls; +{ + int rtn = 0; + +#ifdef USE_ICONV + if (use_iconv(inls)) { + int j = 0; + + while (string[j] != '\0') { + Uchar ob[2]; + __IC_CONST char *inbuf = (char *)&string[j]; + size_t isize = 3; + char *obuf = (char *)ob; + size_t osize = 2; + + /* + * iconv() from glibc ignores osize and thus + * may try to access more than a single multi + * byte character from the input and read from + * non-existent memory. + */ + if (iconv(inls->sic_cd2uni, &inbuf, &isize, + &obuf, &osize) == -1) { + int err = geterrno(); + + if ((err == EINVAL || err == EILSEQ) && + isize == 3) { + ob[0] = ob[1] = 0; + isize--; + } + } + j += 3 - isize; + rtn += 2; + } + } else +#endif + rtn = strlen(string) << 1; + + /* + * We do clamp the maximum length of a Joliet or UDF string to be the + * maximum path size. + */ + if (rtn > 2*maxlen) { + rtn = 2*maxlen; + } + return (rtn); +} + +/* + * Function: get_joliet_vol_desc + * + * Purpose: generate a Joliet compatible volume desc. + * + * Notes: Assume that we have the non-joliet vol desc + * already present in the buffer. Just modifiy the + * appropriate fields. + */ +LOCAL void +get_joliet_vol_desc(jvol_desc) + struct iso_primary_descriptor *jvol_desc; +{ + jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY; + jvol_desc->version[0] = 1; + jvol_desc->file_structure_version[0] = 1; + /* + * For now, always do Unicode level 3. + * I don't really know what 1 and 2 are - perhaps a more limited + * Unicode set. + * FIXME(eric) - how does Romeo fit in here? + */ + sprintf(jvol_desc->escape_sequences, "%%/%c", ucs_codes[ucs_level]); + + /* Until we have Unicode path tables, leave these unset. */ + set_733((char *)jvol_desc->path_table_size, jpath_table_size); + set_731(jvol_desc->type_l_path_table, jpath_table[0]); + set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]); + set_732(jvol_desc->type_m_path_table, jpath_table[2]); + set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]); + + /* Set this one up. */ + memcpy(jvol_desc->root_directory_record, &jroot_record, + offsetof(struct iso_directory_record, name[0]) + 1); + + /* + * Finally, we have a bunch of strings to convert to Unicode. + * FIXME(eric) - I don't know how to do this in general, + * so we will just be really lazy and do a char -> short conversion. + * We probably will want to filter any characters >= 0x80. + */ + convert_to_unicode((Uchar *)jvol_desc->system_id, + sizeof (jvol_desc->system_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->volume_id, + sizeof (jvol_desc->volume_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->volume_set_id, + sizeof (jvol_desc->volume_set_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->publisher_id, + sizeof (jvol_desc->publisher_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->preparer_id, + sizeof (jvol_desc->preparer_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->application_id, + sizeof (jvol_desc->application_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->copyright_file_id, + sizeof (jvol_desc->copyright_file_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->abstract_file_id, + sizeof (jvol_desc->abstract_file_id), NULL, in_nls); + convert_to_unicode((Uchar *)jvol_desc->bibliographic_file_id, + sizeof (jvol_desc->bibliographic_file_id), NULL, in_nls); +} + +/* + * Asssign Joliet & UDF addresses + * We ignore all files that are neither in the Joliet nor in the UDF tree + */ +LOCAL void +assign_joliet_directory_addresses(node) + struct directory *node; +{ + int dir_size; + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + /* + * If we already have an extent for this + * (i.e. it came from a multisession disc), then + * don't reassign a new extent. + */ + dpnt->jpath_index = next_jpath_index++; + if (dpnt->jextent == 0) { + dpnt->jextent = last_extent; + dir_size = ISO_BLOCKS(dpnt->jsize); + last_extent += dir_size; + } + } + /* skip if hidden - but not for the rr_moved dir */ + if (dpnt->subdir && + ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 || + dpnt == reloc_dir)) { + assign_joliet_directory_addresses(dpnt->subdir); + } + dpnt = dpnt->next; + } +} + +LOCAL void +build_jpathlist(node) + struct directory *node; +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + jpathlist[dpnt->jpath_index] = dpnt; + } + if (dpnt->subdir) + build_jpathlist(dpnt->subdir); + dpnt = dpnt->next; + } +} /* build_jpathlist(... */ + +LOCAL int +joliet_compare_paths(r, l) + void const *r; + void const *l; +{ + struct directory const *ll = *(struct directory * const *) l; + struct directory const *rr = *(struct directory * const *) r; + int rparent, + lparent; + char *rpnt, + *lpnt; + unsigned char rtmp[2], + ltmp[2]; + siconvt_t *rinls, *linls; + + /* make sure root directory is first */ + if (rr == root) + return (-1); + + if (ll == root) + return (1); + + rparent = rr->parent->jpath_index; + lparent = ll->parent->jpath_index; + if (rr->parent == reloc_dir) { + rparent = rr->self->parent_rec->filedir->jpath_index; + } + if (ll->parent == reloc_dir) { + lparent = ll->self->parent_rec->filedir->jpath_index; + } + if (rparent < lparent) { + return (-1); + } + if (rparent > lparent) { + return (1); + } +#ifdef APPLE_HYB + /* + * we may be using the HFS name - so select the correct input + * charset + */ + if (USE_MAC_NAME(rr->self)) { + rpnt = rr->self->hfs_ent->name; + rinls = hfs_inls; + } else { + rpnt = rr->self->name; + rinls = in_nls; + } + + if (USE_MAC_NAME(ll->self)) { + lpnt = ll->self->hfs_ent->name; + linls = hfs_inls; + } else { + lpnt = ll->self->name; + linls = in_nls; + } +#else + rpnt = rr->self->name; + lpnt = ll->self->name; + linls = rinls = in_nls; +#endif /* APPLE_HYB */ + + /* compare the Unicode names */ + + while (*rpnt && *lpnt) { + convert_to_unicode(rtmp, 2, rpnt, rinls); + convert_to_unicode(ltmp, 2, lpnt, linls); + + if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp)) + return (-1); + if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp)) + return (1); + + rpnt++; + lpnt++; + } + + if (*rpnt) + return (1); + if (*lpnt) + return (-1); + + return (0); + +} /* compare_paths(... */ + +LOCAL int +generate_joliet_path_tables() +{ + struct directory_entry *de; + struct directory *dpnt; + int fix; + int j; + int namelen; + char *npnt; + char *npnt1; + int tablesize; + unsigned int jpindex; + + /* First allocate memory for the tables and initialize the memory */ + tablesize = jpath_blocks << 11; + jpath_table_m = (char *)e_malloc(tablesize); + jpath_table_l = (char *)e_malloc(tablesize); + memset(jpath_table_l, 0, tablesize); + memset(jpath_table_m, 0, tablesize); + + /* Now start filling in the path tables. Start with root directory */ + jpath_table_index = 0; + jpathlist = (struct directory **)e_malloc(sizeof (struct directory *) + * next_jpath_index); + memset(jpathlist, 0, sizeof (struct directory *) * next_jpath_index); + build_jpathlist(root); + + do { + fix = 0; +#ifdef PROTOTYPES + qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *), + (int (*) (const void *, const void *)) joliet_compare_paths); +#else + qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *), + joliet_compare_paths); +#endif + + for (j = 1; j < next_jpath_index; j++) { + if (jpathlist[j]->jpath_index != j) { + jpathlist[j]->jpath_index = j; + fix++; + } + } + } while (fix); + + for (j = 1; j < next_jpath_index; j++) { + dpnt = jpathlist[j]; + if (!dpnt) { + comerrno(EX_BAD, _("Entry %d not in path tables\n"), j); + } + npnt = dpnt->de_name; + + npnt1 = strrchr(npnt, PATH_SEPARATOR); + if (npnt1) { + npnt = npnt1 + 1; + } + de = dpnt->self; + if (!de) { + comerrno(EX_BAD, + _("Fatal Joliet goof - directory has amnesia\n")); + } +#ifdef APPLE_HYB + if (USE_MAC_NAME(de)) + namelen = joliet_strlen(de->hfs_ent->name, jlen, hfs_inls); + else +#endif /* APPLE_HYB */ + namelen = joliet_strlen(de->name, jlen, in_nls); + + if (dpnt == root) { + jpath_table_l[jpath_table_index] = 1; + jpath_table_m[jpath_table_index] = 1; + } else { + jpath_table_l[jpath_table_index] = namelen; + jpath_table_m[jpath_table_index] = namelen; + } + jpath_table_index += 2; + + set_731(jpath_table_l + jpath_table_index, dpnt->jextent); + set_732(jpath_table_m + jpath_table_index, dpnt->jextent); + jpath_table_index += 4; + + + if (dpnt->parent != reloc_dir) { + set_721(jpath_table_l + jpath_table_index, + dpnt->parent->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->parent->jpath_index); + jpindex = dpnt->parent->jpath_index; + } else { + set_721(jpath_table_l + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); + jpindex = dpnt->self->parent_rec->filedir->jpath_index; + } + + if (jpindex > 0xffff) { + static int warned = 0; + + if (!warned) { + warned++; + errmsgno(EX_BAD, + _("Unable to generate sane Joliet path tables - too many directories (%u)\n"), + jpindex); + if (!nolimitpathtables) + errmsgno(EX_BAD, + _("Try to use the option -no-limit-pathtables\n")); + } + if (!nolimitpathtables) + exit(EX_BAD); + /* + * Let it point to the root directory instead. + */ + set_721(jpath_table_l + jpath_table_index, 1); + set_722(jpath_table_m + jpath_table_index, 1); + } + + jpath_table_index += 2; + + /* + * The root directory is still represented in non-unicode + * fashion. + */ + if (dpnt == root) { + jpath_table_l[jpath_table_index] = 0; + jpath_table_m[jpath_table_index] = 0; + jpath_table_index++; + } else { +#ifdef APPLE_HYB + if (USE_MAC_NAME(de)) { + convert_to_unicode((Uchar *) jpath_table_l + + jpath_table_index, + namelen, de->hfs_ent->name, hfs_inls); + convert_to_unicode((Uchar *) jpath_table_m + + jpath_table_index, + namelen, de->hfs_ent->name, hfs_inls); + } else { +#endif /* APPLE_HYB */ + convert_to_unicode((Uchar *) jpath_table_l + + jpath_table_index, + namelen, de->name, in_nls); + convert_to_unicode((Uchar *) jpath_table_m + + jpath_table_index, + namelen, de->name, in_nls); +#ifdef APPLE_HYB + } +#endif /* APPLE_HYB */ + + jpath_table_index += namelen; + } + + if (jpath_table_index & 1) { + jpath_table_index++; /* For odd lengths we pad */ + } + } + + free(jpathlist); + if (jpath_table_index != jpath_table_size) { + errmsgno(EX_BAD, + _("Joliet path table lengths do not match %d expected: %d\n"), + jpath_table_index, + jpath_table_size); + } + return (0); +} /* generate_path_tables(... */ + +LOCAL void +generate_one_joliet_directory(dpnt, outfile) + struct directory *dpnt; + FILE *outfile; +{ + unsigned int dir_index; + char *directory_buffer; + int new_reclen; + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct iso_directory_record jrec; + unsigned int total_size; + int cvt_len; + struct directory *finddir; + + total_size = ISO_ROUND_UP(dpnt->jsize); + directory_buffer = (char *)e_malloc(total_size); + memset(directory_buffer, 0, total_size); + dir_index = 0; + + s_entry = dpnt->jcontents; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { + s_entry = s_entry->jnext; + continue; + } + /* + * If this entry was a directory that was relocated, + * we have a bit of trouble here. We need to dig out the real + * thing and put it back here. In the Joliet tree, there is + * no relocated rock ridge, as there are no depth limits to a + * directory tree. + */ + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + for (s_entry1 = reloc_dir->contents; s_entry1; + s_entry1 = s_entry1->next) { + if (s_entry1->parent_rec == s_entry) { + break; + } + } + if (s_entry1 == NULL) { + /* We got trouble. */ + comerrno(EX_BAD, + _("Unable to locate relocated directory\n")); + } + } else { + s_entry1 = s_entry; + } + + /* + * We do not allow directory entries to cross sector + * boundaries. Simply pad, and then start the next entry at + * the next sector + */ + new_reclen = s_entry1->jreclen; + if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) { + dir_index = ISO_ROUND_UP(dir_index); + } + memcpy(&jrec, &s_entry1->isorec, offsetof(struct iso_directory_record, name[0])); + +#ifdef APPLE_HYB + /* Use the HFS name if it exists */ + if (USE_MAC_NAME(s_entry1)) + cvt_len = joliet_strlen(s_entry1->hfs_ent->name, jlen, hfs_inls); + else +#endif /* APPLE_HYB */ + cvt_len = joliet_strlen(s_entry1->name, jlen, in_nls); + + /* + * Fix the record length + * - this was the non-Joliet version we were seeing. + */ + jrec.name_len[0] = cvt_len; + jrec.length[0] = s_entry1->jreclen; + + /* + * If this is a directory, + * fix the correct size and extent number. + */ + if ((jrec.flags[0] & ISO_DIRECTORY) != 0) { + if (strcmp(s_entry1->name, ".") == 0) { + jrec.name_len[0] = 1; + set_733((char *)jrec.extent, dpnt->jextent); + set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->jsize)); + } else if (strcmp(s_entry1->name, "..") == 0) { + jrec.name_len[0] = 1; + if (dpnt->parent == reloc_dir) { + set_733((char *)jrec.extent, dpnt->self->parent_rec->filedir->jextent); + set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); + } else { + set_733((char *)jrec.extent, dpnt->parent->jextent); + set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->parent->jsize)); + } + } else { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + finddir = reloc_dir->subdir; + } else { + finddir = dpnt->subdir; + } + while (finddir && finddir->self != s_entry1) { + finddir = finddir->next; + } + if (!finddir) { + comerrno(EX_BAD, + _("Fatal goof - unable to find directory location\n")); + } + set_733((char *)jrec.extent, finddir->jextent); + set_733((char *)jrec.size, + ISO_ROUND_UP(finddir->jsize)); + } + } + memcpy(directory_buffer + dir_index, &jrec, + offsetof(struct iso_directory_record, name[0])); + + dir_index += offsetof(struct iso_directory_record, name[0]); + + /* + * Finally dump the Unicode version of the filename. + * Note - . and .. are the same as with non-Joliet discs. + */ + if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && + strcmp(s_entry1->name, ".") == 0) { + directory_buffer[dir_index++] = 0; + } else if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && + strcmp(s_entry1->name, "..") == 0) { + directory_buffer[dir_index++] = 1; + } else { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry1)) { + /* Use the HFS name if it exists */ + convert_to_unicode( + (Uchar *) directory_buffer+dir_index, + cvt_len, + s_entry1->hfs_ent->name, hfs_inls); + } else +#endif /* APPLE_HYB */ + { + convert_to_unicode( + (Uchar *) directory_buffer+dir_index, + cvt_len, + s_entry1->name, in_nls); + } + dir_index += cvt_len; + } + + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + s_entry = s_entry->jnext; + } + + if (dpnt->jsize != dir_index) { + errmsgno(EX_BAD, + _("Unexpected joliet directory length %d expected: %d '%s'\n"), + dpnt->jsize, + dir_index, dpnt->de_name); + } + xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE); + last_extent_written += total_size >> 11; + free(directory_buffer); +} /* generate_one_joliet_directory(... */ + +LOCAL int +joliet_sort_n_finish(this_dir) + struct directory *this_dir; +{ + struct directory_entry *s_entry; + int status = 0; + + /* + * don't want to skip this directory if it's the reloc_dir + * at the moment + */ + if (this_dir != reloc_dir && + this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { + return (0); + } + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* skip hidden entries */ + if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { + continue; + } + /* + * First update the path table sizes for directories. + * + * Finally, set the length of the directory entry if Joliet is + * used. The name is longer, but no Rock Ridge is ever used + * here, so depending upon the options the entry size might + * turn out to be about the same. The Unicode name is always + * a multiple of 2 bytes, so we always add 1 to make it an + * even number. + */ + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + /* Use the HFS name if it exists */ + jpath_table_size += + joliet_strlen(s_entry->hfs_ent->name, jlen, hfs_inls) + + offsetof(struct iso_path_table, name[0]); + else +#endif /* APPLE_HYB */ + jpath_table_size += + joliet_strlen(s_entry->name, jlen, in_nls) + + offsetof(struct iso_path_table, name[0]); + if (jpath_table_size & 1) { + jpath_table_size++; + } + } else { + if (this_dir == root && + strlen(s_entry->name) == 1) { + + jpath_table_size += 1 + offsetof(struct iso_path_table, name[0]); + if (jpath_table_size & 1) + jpath_table_size++; + } + } + } + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + /* Use the HFS name if it exists */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + joliet_strlen(s_entry->hfs_ent->name, jlen, hfs_inls) + + 1; + else +#endif /* APPLE_HYB */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + joliet_strlen(s_entry->name, jlen, in_nls) + + 1; + } else { + /* + * Special - for '.' and '..' we generate the same + * records we did for non-Joliet discs. + */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + 1; + } + + + } + + if ((this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0) { + return (0); + } + this_dir->jcontents = this_dir->contents; + status = joliet_sort_directory(&this_dir->jcontents); + + /* + * Now go through the directory and figure out how large this one will + * be. Do not split a directory entry across a sector boundary + */ + s_entry = this_dir->jcontents; + /* + * XXX Is it ok to comment this out? + */ +/*XXX JS this_dir->ce_bytes = 0;*/ + for (s_entry = this_dir->jcontents; s_entry; + s_entry = s_entry->jnext) { + int jreclen; + + if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { + continue; + } + jreclen = s_entry->jreclen; + + if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= + SECTOR_SIZE) { + this_dir->jsize = ISO_ROUND_UP(this_dir->jsize); + } + this_dir->jsize += jreclen; + } + return (status); +} + +/* + * Similar to the iso9660 case, + * except here we perform a full sort based upon the + * regular name of the file, not the 8.3 version. + */ +LOCAL int +joliet_compare_dirs(rr, ll) + const void *rr; + const void *ll; +{ + char *rpnt, + *lpnt; + struct directory_entry **r, + **l; + unsigned char rtmp[2], + ltmp[2]; + siconvt_t *linls, *rinls; + + r = (struct directory_entry **)rr; + l = (struct directory_entry **)ll; + +#ifdef APPLE_HYB + /* + * we may be using the HFS name - so select the correct input + * charset + */ + if (USE_MAC_NAME(*r)) { + rpnt = (*r)->hfs_ent->name; + rinls = hfs_inls; + } else { + rpnt = (*r)->name; + rinls = in_nls; + } + + if (USE_MAC_NAME(*l)) { + lpnt = (*l)->hfs_ent->name; + linls = hfs_inls; + } else { + lpnt = (*l)->name; + linls = in_nls; + } +#else + rpnt = (*r)->name; + lpnt = (*l)->name; + rinls = linls = in_nls; +#endif /* APPLE_HYB */ + + /* + * If the entries are the same, this is an error. + * Joliet specs allow for a maximum of 64 characters. + * If we see different multi extent parts, it is OK to + * have the same name more than once. + */ + if (strncmp(rpnt, lpnt, jlen) == 0) { +#ifdef USE_LARGEFILES + if ((*r)->mxpart == (*l)->mxpart) +#endif + { + errmsgno(EX_BAD, + _("Error: %s and %s have the same Joliet name\n"), + (*r)->whole_name, (*l)->whole_name); + jsort_goof++; + { + char *p1 = rpnt; + char *p2 = lpnt; + int len = 0; + + for (; *p1 == *p2; p1++, p2++, len++) { + if (*p1 == '\0') + break; + } + if (len > jsort_glen) + jsort_glen = len; + } + } + } + /* + * Put the '.' and '..' entries on the head of the sorted list. + * For normal ASCII, this always happens to be the case, but out of + * band characters cause this not to be the case sometimes. + */ + if (strcmp(rpnt, ".") == 0) + return (-1); + if (strcmp(lpnt, ".") == 0) + return (1); + + if (strcmp(rpnt, "..") == 0) + return (-1); + if (strcmp(lpnt, "..") == 0) + return (1); + +#ifdef DVD_AUD_VID + /* + * There're rumors claiming that some players assume VIDEO_TS.IFO + * to be the first file in VIDEO_TS/ catalog. Well, it's basically + * the only file a player has to actually look for, as the whole + * video content can be "rolled down" from this file alone. + * + */ + /* + * XXX This code has to be moved from the Joliet implementation + * XXX to the UDF implementation if we implement decent UDF support + * XXX with a separate name space for the UDF file tree. + */ + if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) { + if (strcmp(rpnt, "VIDEO_TS.IFO") == 0) + return (-1); + if (strcmp(lpnt, "VIDEO_TS.IFO") == 0) + return (1); + } +#endif + + while (*rpnt && *lpnt) { + if (*rpnt == ';' && *lpnt != ';') + return (-1); + if (*rpnt != ';' && *lpnt == ';') + return (1); + + if (*rpnt == ';' && *lpnt == ';') + return (0); + + /* + * Extensions are not special here. + * Don't treat the dot as something that must be bumped to + * the start of the list. + */ +#if 0 + if (*rpnt == '.' && *lpnt != '.') + return (-1); + if (*rpnt != '.' && *lpnt == '.') + return (1); +#endif + + convert_to_unicode(rtmp, 2, rpnt, rinls); + convert_to_unicode(ltmp, 2, lpnt, linls); + + if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp)) + return (-1); + if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp)) + return (1); + + rpnt++; + lpnt++; + } + if (*rpnt) + return (1); + if (*lpnt) + return (-1); +#ifdef USE_LARGEFILES + /* + * (*r)->mxpart == (*l)->mxpart cannot happen here + */ + if ((*r)->mxpart < (*l)->mxpart) + return (-1); + else if ((*r)->mxpart > (*l)->mxpart) + return (1); +#endif + return (0); +} + + +/* + * Function: sort_directory + * + * Purpose: Sort the directory in the appropriate ISO9660 + * order. + * + * Notes: Returns 0 if OK, returns > 0 if an error occurred. + */ +LOCAL int +joliet_sort_directory(sort_dir) + struct directory_entry **sort_dir; +{ + int dcount = 0; + int i; + struct directory_entry *s_entry; + struct directory_entry **sortlist; + + s_entry = *sort_dir; + while (s_entry) { + /* + * only colletc non-hidden entries + */ + if ((s_entry->de_flags & (INHIBIT_JOLIET_ENTRY|INHIBIT_UDF_ENTRY)) != + (INHIBIT_JOLIET_ENTRY|INHIBIT_UDF_ENTRY)) + dcount++; + s_entry = s_entry->next; + } + + /* OK, now we know how many there are. Build a vector for sorting. */ + sortlist = (struct directory_entry **) + e_malloc(sizeof (struct directory_entry *) * dcount); + + dcount = 0; + s_entry = *sort_dir; + while (s_entry) { + /* + * only collect non-hidden entries + */ + if ((s_entry->de_flags & (INHIBIT_JOLIET_ENTRY|INHIBIT_UDF_ENTRY)) != + (INHIBIT_JOLIET_ENTRY|INHIBIT_UDF_ENTRY)) { + sortlist[dcount] = s_entry; + dcount++; + } + s_entry = s_entry->next; + } + + jsort_goof = 0; + jsort_glen = 0; +#ifdef PROTOTYPES + qsort(sortlist, dcount, sizeof (struct directory_entry *), + (int (*) (const void *, const void *)) joliet_compare_dirs); +#else + qsort(sortlist, dcount, sizeof (struct directory_entry *), + joliet_compare_dirs); +#endif + + if (jsort_goof) { + errmsgno(EX_BAD, + _("Joliet file names differ after %d chars\n"), + jsort_glen); + if (jsort_glen > JLONGMAX) { + errmsgno(EX_BAD, + _("Cannot use Joliet, please remove -J from the option list.\n")); + } else if (jsort_glen > JMAX) { + errmsgno(EX_BAD, + _("Try to use the option -joliet-long\n")); + } + } + + /* Now reassemble the linked list in the proper sorted order */ + for (i = 0; i < dcount - 1; i++) { + sortlist[i]->jnext = sortlist[i + 1]; + } + + sortlist[dcount - 1]->jnext = NULL; + *sort_dir = sortlist[0]; + + free(sortlist); + return (jsort_goof); +} + +EXPORT int +joliet_sort_tree(node) + struct directory *node; +{ + struct directory *dpnt; + int ret = 0; + + dpnt = node; + + while (dpnt) { + ret = joliet_sort_n_finish(dpnt); + if (ret) { + break; + } + if (dpnt->subdir) + ret = joliet_sort_tree(dpnt->subdir); + if (ret) { + break; + } + dpnt = dpnt->next; + } + return (ret); +} + +LOCAL void +generate_joliet_directories(node, outfile) + struct directory *node; + FILE *outfile; +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + /* + * In theory we should never reuse a directory, so this + * doesn't make much sense. + */ + if (dpnt->jextent > session_start) { + generate_one_joliet_directory(dpnt, outfile); + } + } + /* skip if hidden - but not for the rr_moved dir */ + if (dpnt->subdir && + (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || + dpnt == reloc_dir)) { + generate_joliet_directories(dpnt->subdir, outfile); + } + dpnt = dpnt->next; + } +} + + +/* + * Function to write the EVD for the disc. + */ +LOCAL int +jpathtab_write(outfile) + FILE *outfile; +{ + /* Next we write the path tables */ + xfwrite(jpath_table_l, jpath_blocks << 11, 1, outfile, 0, FALSE); + xfwrite(jpath_table_m, jpath_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += 2 * jpath_blocks; + free(jpath_table_l); + free(jpath_table_m); + jpath_table_l = NULL; + jpath_table_m = NULL; + return (0); +} + +LOCAL int +jdirtree_size(starting_extent) + UInt32_t starting_extent; +{ + assign_joliet_directory_addresses(root); + return (0); +} + +LOCAL int +jroot_gen() +{ + jroot_record.length[0] = + 1 + offsetof(struct iso_directory_record, name[0]); + jroot_record.ext_attr_length[0] = 0; + set_733((char *)jroot_record.extent, root->jextent); + set_733((char *)jroot_record.size, ISO_ROUND_UP(root->jsize)); + iso9660_date(jroot_record.date, root_statbuf.st_mtime); + jroot_record.flags[0] = ISO_DIRECTORY; + jroot_record.file_unit_size[0] = 0; + jroot_record.interleave[0] = 0; + set_723(jroot_record.volume_sequence_number, volume_sequence_number); + jroot_record.name_len[0] = 1; + return (0); +} + +LOCAL int +jdirtree_write(outfile) + FILE *outfile; +{ + generate_joliet_directories(root, outfile); + return (0); +} + +/* + * Function to write the EVD for the disc. + */ +LOCAL int +jvd_write(outfile) + FILE *outfile; +{ + struct iso_primary_descriptor jvol_desc; + + /* Next we write out the boot volume descriptor for the disc */ + jvol_desc = vol_desc; + get_joliet_vol_desc(&jvol_desc); + xfwrite(&jvol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Functions to describe padding block at the start of the disc. + */ +LOCAL int +jpathtab_size(starting_extent) + UInt32_t starting_extent; +{ + jpath_table[0] = starting_extent; + jpath_table[1] = 0; + jpath_table[2] = jpath_table[0] + jpath_blocks; + jpath_table[3] = 0; + + last_extent += 2 * jpath_blocks; + return (0); +} + +struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen, jvd_write, "Joliet Volume Descriptor" }; +struct output_fragment jpathtable_desc = {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write, "Joliet path table" }; +struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write, "Joliet directory tree" }; diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.c new file mode 100644 index 00000000000..443f2e93521 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.c @@ -0,0 +1,397 @@ +/* @(#)match.c 1.31 16/10/10 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)match.c 1.31 16/10/10 joerg"; +#endif +/* + * 27-Mar-96: Jan-Piet Mens + * added 'match' option (-m) to specify regular expressions NOT to be included + * in the CD image. + * + * Re-written 13-Apr-2000 James Pearson + * now uses a generic set of routines + * Conversions to make the code more portable May 2000 .. March 2004 + * Copyright (c) 2000-2016 J. Schilling + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "match.h" + +struct match { + struct match *next; + char *name; +}; + +typedef struct match match; + +static match *mats[MAX_MAT]; + +static char *mesg[MAX_MAT] = { + "excluded", + "excluded ISO-9660", + "excluded Joliet", + "excluded UDF", + "hidden attribute ISO-9660", +#ifdef APPLE_HYB + "excluded HFS", +#endif /* APPLE_HYB */ +}; + +#ifdef SORTING +struct sort_match { + struct sort_match *next; + char *name; + int val; +}; + +typedef struct sort_match sort_match; + +static sort_match *s_mats; + +EXPORT int +add_sort_match(fn, val) + char *fn; + int val; +{ + sort_match *s_mat; + + s_mat = (sort_match *)malloc(sizeof (sort_match)); + if (s_mat == NULL) { + errmsg(_("Can't allocate memory for sort filename\n")); + return (0); + } + + if ((s_mat->name = strdup(fn)) == NULL) { + errmsg(_("Can't allocate memory for sort filename\n")); + free(s_mat); + return (0); + } + + /* need to reserve the minimum value for other uses */ + if (val == NOT_SORTED) + val++; + + s_mat->val = val; + s_mat->next = s_mats; + s_mats = s_mat; + + return (1); +} + +EXPORT int +add_sort_list(file) + char *file; +{ + FILE *fp; + char name[4096]; + char *p; + int val; +extern int do_sort; + + do_sort++; + if ((fp = fopen(file, "r")) == NULL) { + comerr(_("Can't open sort file list %s\n"), file); + } + + while (fgets(name, sizeof (name), fp) != NULL) { + /* + * look for the last space or tab character + */ + if ((p = strrchr(name, ' ')) == NULL) + p = strrchr(name, '\t'); + else if (strrchr(p, '\t') != NULL) /* Tab after space? */ + p = strrchr(p, '\t'); + + if (p == NULL) { + /* + * XXX old code did not abort here. + */ + comerrno(EX_BAD, _("Incorrect sort file format\n\t%s\n"), name); + continue; + } else { + *p = '\0'; + val = atoi(++p); + } + if (!add_sort_match(name, val)) { + fclose(fp); + return (-1); + } + } + + fclose(fp); + return (1); +} + +EXPORT int +sort_matches(fn, val) + char *fn; + int val; +{ + register sort_match *s_mat; + + for (s_mat = s_mats; s_mat; s_mat = s_mat->next) { + if (fnmatch(s_mat->name, fn, FNM_PATHNAME) != FNM_NOMATCH) { + return (s_mat->val); /* found sort value */ + } + } + return (val); /* not found - default sort value */ +} + +EXPORT void +del_sort() +{ + register sort_match * s_mat, *s_mat1; + + s_mat = s_mats; + while (s_mat) { + s_mat1 = s_mat->next; + + free(s_mat->name); + free(s_mat); + + s_mat = s_mat1; + } + + s_mats = 0; +} + +#endif /* SORTING */ + + +EXPORT int +gen_add_match(fn, n) + char *fn; + int n; +{ + match *mat; + + if (n >= MAX_MAT) { + errmsgno(EX_BAD, _("Too many patterns.\n")); + return (0); + } + + mat = (match *)malloc(sizeof (match)); + if (mat == NULL) { + errmsg(_("Can't allocate memory for %s filename\n"), mesg[n]); + return (0); + } + + if ((mat->name = strdup(fn)) == NULL) { + errmsg(_("Can't allocate memory for %s filename\n"), mesg[n]); + free(mat); + return (0); + } + + mat->next = mats[n]; + mats[n] = mat; + + return (1); +} + +EXPORT int +add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, EXCLUDE); + + if (ret == 0) + return (-1); + return (1); +} + +EXPORT int +i_add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, I_HIDE); + + if (ret == 0) + return (-1); + return (1); +} + +EXPORT int +h_add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, H_HIDE); + + if (ret == 0) + return (-1); + return (1); +} + +#ifdef APPLE_HYB +EXPORT int +hfs_add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, HFS_HIDE); + + if (ret == 0) + return (-1); + return (1); +} +#endif /* APPLE_HYB */ + +EXPORT int +j_add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, J_HIDE); + + if (ret == 0) + return (-1); + return (1); +} + +EXPORT int +u_add_match(fn) + char *fn; +{ + int ret = gen_add_match(fn, U_HIDE); + + if (ret == 0) + return (-1); + return (1); +} + +EXPORT void +gen_add_list(file, n) + char *file; + int n; +{ + FILE *fp; + char name[4096]; + int len; + + if ((fp = fopen(file, "r")) == NULL) { + comerr(_("Can't open %s file list %s\n"), mesg[n], file); + } + + while (fgets(name, sizeof (name), fp) != NULL) { + /* + * strip of '\n' + */ + len = strlen(name); + if (name[len - 1] == '\n') { + name[len - 1] = '\0'; + } + if (!gen_add_match(name, n)) { + fclose(fp); + return; + } + } + + fclose(fp); +} + +EXPORT int +add_list(fn) + char *fn; +{ + gen_add_list(fn, EXCLUDE); + return (1); +} + +EXPORT int +i_add_list(fn) + char *fn; +{ + gen_add_list(fn, I_HIDE); + return (1); +} + +EXPORT int +h_add_list(fn) + char *fn; +{ + gen_add_list(fn, H_HIDE); + return (1); +} + +EXPORT int +j_add_list(fn) + char *fn; +{ + gen_add_list(fn, J_HIDE); + return (1); +} + +EXPORT int +u_add_list(fn) + char *fn; +{ + gen_add_list(fn, U_HIDE); + return (1); +} + +#ifdef APPLE_HYB +EXPORT int +hfs_add_list(fn) + char *fn; +{ + gen_add_list(fn, HFS_HIDE); + return (1); +} +#endif /* APPLE_HYB */ + +EXPORT int +gen_matches(fn, n) + char *fn; + int n; +{ + register match * mat; + + if (n >= MAX_MAT) + return (0); + + for (mat = mats[n]; mat; mat = mat->next) { + if (fnmatch(mat->name, fn, FNM_PATHNAME) != FNM_NOMATCH) { + return (1); /* found -> excluded filename */ + } + } + return (0); /* not found -> not excluded */ +} + +EXPORT int +gen_ishidden(n) + int n; +{ + if (n >= MAX_MAT) + return (0); + + return ((int)(mats[n] != 0)); +} + +EXPORT void +gen_del_match(n) + int n; +{ + register match *mat; + register match *mat1; + + if (n >= MAX_MAT) + return; + + mat = mats[n]; + + while (mat) { + mat1 = mat->next; + + free(mat->name); + free(mat); + + mat = mat1; + } + + mats[n] = 0; +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.h new file mode 100644 index 00000000000..bc82e6533ea --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/match.h @@ -0,0 +1,88 @@ +/* @(#)match.h 1.15 09/07/10 joerg */ +/* + * 27th March 1996. Added by Jan-Piet Mens for matching regular expressions + * in paths. + * + * Conversions to make the code more portable May 2000 .. March 2004 + * Copyright (c) 2000-2009 J. Schilling + */ + +#include + +#ifdef SORTING +#include +#define NOT_SORTED INT_MIN + +#ifdef MAX /* May be defined in param.h */ +#undef MAX +#endif +#define MAX(A, B) (A) > (B) ? (A) : (B) +#endif + +#define EXCLUDE 0 /* Exclude file completely */ +#define I_HIDE 1 /* ISO9660/Rock Ridge hide */ +#define J_HIDE 2 /* Joliet hide */ +#define U_HIDE 3 /* UDF hide */ +#define H_HIDE 4 /* ISO9660 hidden bit set */ + +#ifdef APPLE_HYB +#define HFS_HIDE 5 /* HFS hide */ +#define MAX_MAT 6 +#else +#define MAX_MAT 5 +#endif /* APPLE_HYB */ + +extern int gen_add_match __PR((char *fn, int n)); +extern int add_match __PR((char *fn)); +extern int i_add_match __PR((char *fn)); +extern int h_add_match __PR((char *fn)); +extern int j_add_match __PR((char *fn)); +extern int u_add_match __PR((char *fn)); +extern int hfs_add_match __PR((char *fn)); +extern int gen_matches __PR((char *fn, int n)); +extern void gen_add_list __PR((char *fn, int n)); +extern int add_list __PR((char *fn)); +extern int i_add_list __PR((char *fn)); +extern int h_add_list __PR((char *fn)); +extern int j_add_list __PR((char *fn)); +extern int u_add_list __PR((char *fn)); +extern int hfs_add_list __PR((char *fn)); +extern int gen_ishidden __PR((int n)); +extern void gen_del_match __PR((int n)); + +#ifdef SORTING +extern int add_sort_match __PR((char *fn, int val)); +extern int add_sort_list __PR((char *fn)); +extern int sort_matches __PR((char *fn, int val)); +extern void del_sort __PR((void)); +#endif /* SORTING */ + +/* + * The following are for compatiblity with the separate routines - the + * main code should be changed to call the generic routines directly + */ + +/* filenames to be excluded */ +#define matches(FN) gen_matches((FN), EXCLUDE) + +/* ISO9660/Rock Ridge filenames to be hidden */ +#define i_matches(FN) gen_matches((FN), I_HIDE) +#define i_ishidden() gen_ishidden(I_HIDE) + +/* Joliet filenames to be hidden */ +#define j_matches(FN) gen_matches((FN), J_HIDE) +#define j_ishidden() gen_ishidden(J_HIDE) + +/* UDF filenames to be hidden */ +#define u_matches(FN) gen_matches((FN), U_HIDE) +#define u_ishidden() gen_ishidden(U_HIDE) + +/* ISO9660 "hidden" files */ +#define h_matches(FN) gen_matches((FN), H_HIDE) +#define h_ishidden() gen_ishidden(H_HIDE) + +#ifdef APPLE_HYB +/* HFS filenames to be hidden */ +#define hfs_matches(FN) gen_matches((FN), HFS_HIDE) +#define hfs_ishidden() gen_ishidden(HFS_HIDE) +#endif /* APPLE_HYB */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.c new file mode 100644 index 00000000000..aec899a2b39 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.c @@ -0,0 +1,3941 @@ +/* @(#)mkisofs.c 1.284 16/10/23 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)mkisofs.c 1.284 16/10/23 joerg"; +#endif +/* + * Program mkisofs.c - generate iso9660 filesystem based upon directory + * tree on hard disk. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1997-2016 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 22/2/2000 */ +/* MAC UDF images by HELIOS Software GmbH support@helios.de */ +/* HFS+ by HELIOS Software GmbH support@helios.de */ + +#ifdef USE_FIND +#include +#include +#endif +#include "mkisofs.h" +#include "rock.h" +#include +#include +#include +#include +#include "match.h" +#include +#include +#include +#ifdef UDF +#include "udf.h" +#endif + +#include /* for setmode() prototype */ +#include + +#ifdef VMS +#include "vms.h" +#endif + +#ifdef no_more_needed +#include +#endif /* no_more_needed */ + +#include "../cdrecord/version.h" + +struct directory *root = NULL; +int path_ind; + +char version_string[] = VERSION; + +char *outfile; +FILE *discimage; +UInt32_t next_extent = 0; +UInt32_t last_extent = 0; +UInt32_t session_start = 0; +unsigned int path_table_size = 0; +unsigned int path_table[4] = {0, }; +unsigned int path_blocks = 0; + + +unsigned int jpath_table_size = 0; +unsigned int jpath_table[4] = {0, }; +unsigned int jpath_blocks = 0; + +struct iso_directory_record root_record; +struct iso_directory_record jroot_record; + +char *extension_record = NULL; +UInt32_t extension_record_extent = 0; +int extension_record_size = 0; +BOOL archive_isreg; +dev_t archive_dev; +ino_t archive_ino; + +/* These variables are associated with command line options */ +int check_oldnames = 0; +int check_session = 0; +int use_eltorito = 0; +int hard_disk_boot = 0; +int not_bootable = 0; +int no_emul_boot = 0; +int load_addr = 0; +int load_size = 0; +int boot_info_table = 0; +int use_sparcboot = 0; +int use_sunx86boot = 0; +int use_genboot = 0; +int use_RockRidge = 0; +int use_XA = 0; +int osecsize = 0; /* Output-sector size, 0 means default secsize 2048 */ +int use_Joliet = 0; +int jlen = JMAX; /* maximum Joliet file name length */ +/* + * Verbose levels currently used: + * + * 1+ Boot information + * 1+ Rcfile information + * 1+ Name mapping information + * 1+ Progress information + * 2+ Version informaton + * 2+ Output Extent (of_write) information + * 2+ PReP boot information + * 3+ HFS warnings + * 3+ Dump dirtree + */ +int verbose = 1; +int debug = 0; +int gui = 0; +BOOL legacy = FALSE; /* Implement legacy support for historic CLI */ +int all_files = 1; /* New default is to include all files */ +BOOL Hflag = FALSE; /* Follow links on cmdline (-H) */ +BOOL follow_links = FALSE; /* Follow all links (-L) */ +#if defined(IS_CYGWIN) || defined(__MINGW32__) || defined(_MSC_VER) +/* + * Do not cache inodes on Cygwin by default + * See below in main(), cache for 64bit ino_t + */ +int cache_inodes = 0; +#else +int cache_inodes = 1; /* Cache inodes if OS has unique inodes */ +#endif +int rationalize = 0; /* Need to call stat_fix() */ +int rationalize_uid = 0; +int rationalize_gid = 0; +int rationalize_filemode = 0; +int rationalize_dirmode = 0; +uid_t uid_to_use = 0; /* when rationalizing uid */ +gid_t gid_to_use = 0; /* when rationalizing gid */ +int filemode_to_use = 0; /* if non-zero, when rationalizing file mode */ +int dirmode_to_use = 0; /* if non-zero, when rationalizing dir mode */ +int new_dir_mode = 0555; /* neither -new-dir-mode nor -dir-mode used */ +int generate_tables = 0; +int dopad = 1; /* Now default to do padding */ +int print_size = 0; +int split_output = 0; +char *icharset = NULL; /* input charset to convert to UNICODE */ +char *ocharset = NULL; /* output charset to convert from UNICODE */ +char *preparer = PREPARER_DEFAULT; +char *publisher = PUBLISHER_DEFAULT; +char *appid = APPID_DEFAULT; +char *copyright = COPYRIGHT_DEFAULT; +char *biblio = BIBLIO_DEFAULT; +char *abstract = ABSTRACT_DEFAULT; +char *volset_id = VOLSET_ID_DEFAULT; +char *volume_id = VOLUME_ID_DEFAULT; +char *system_id = SYSTEM_ID_DEFAULT; +char *boot_catalog; +char *boot_image = BOOT_IMAGE_DEFAULT; +char *genboot_image = BOOT_IMAGE_DEFAULT; +int ucs_level = 3; /* We now have Unicode tables so use level 3 */ +int volume_set_size = 1; +int volume_sequence_number = 1; +/* -------------------------------------------------------------------------- */ +char *merge_image; /* CLI Parameter for -M option */ +char *check_image; /* CLI Parameter for -check-session option */ +char *reloc_root = NULL; /* CLI Parameter for -root option */ +char *reloc_old_root = NULL; /* CLI Parameter for -oldroot option */ +extern char *cdrecord_data; /* CLI Parameter for -C option */ +int disable_deep_reloc; /* CLI Parameter for -D option */ +char *dirmode_str; /* CLI Parameter for -dir-mode option */ +char *filemode_str; /* CLI Parameter for -file-mode option */ +char *gid_str; /* CLI Parameter for -gid option */ +int help; /* CLI Parameter for -help option */ +int joliet_long; /* CLI Parameter for -joliet-long option */ +char *jcharset; /* CLI Parameter for -jcharset option */ +int max_filenames; /* CLI Parameter for -max-iso9660-filenames option */ +char *log_file; /* CLI Parameter for -log-file option */ +char *new_dirmode_str; /* CLI Parameter for -new-dir-mode option */ +char *pathnames; /* CLI Parameter for -help option */ +int rationalize_rr; /* CLI Parameter for -path-list option */ +char *sectype; /* CLI Parameter for -s option */ +char *uid_str; /* CLI Parameter for -uid option */ +int untranslated_filenames; /* CLI Parameter for -U option */ +int pversion; /* CLI Parameter for -version option */ +int rationalize_xa; /* CLI Parameter for -xa option */ +ldate modification_date; /* CLI Parameter for -modification-date */ +#ifdef APPLE_HYB +char *afpfile = ""; /* CLI Parameter for -map option */ +char *root_info; /* CLI Parameter for -root-info option */ +#endif +BOOL nodesc = FALSE; /* Whether not to descend directories */ +#ifdef USE_FIND +BOOL dofind = FALSE; /* -find option found */ +int find_ac = 0; /* ac past -find option */ +char *const *find_av = NULL; /* av past -find option */ +int find_pac = 0; /* ac for first find primary */ +char *const *find_pav = NULL; /* av for first find primary */ +findn_t *find_node; /* syntaxtree from find_parse() */ +void *plusp; /* residual for -exec ...{} + */ +int find_patlen; /* len for -find pattern state */ + +LOCAL int walkflags = WALK_CHDIR | WALK_PHYS | WALK_NOEXIT; +LOCAL int maxdepth = -1; +LOCAL int mindepth = -1; +EXPORT struct WALK walkstate; +#else +LOCAL int walkflags = 0; +#endif + +extern time_t begun; +extern struct timeval tv_begun; + +LOCAL BOOL data_change_warn; + +struct eltorito_boot_entry_info *first_boot_entry = NULL; +struct eltorito_boot_entry_info *last_boot_entry = NULL; +struct eltorito_boot_entry_info *current_boot_entry = NULL; + +int use_graft_ptrs; /* Use graft points */ +int jhide_trans_tbl; /* Hide TRANS.TBL from Joliet tree */ +int hide_rr_moved; /* Name RR_MOVED .rr_moved in Rock Ridge tree */ +int omit_period = 0; /* Violates iso9660, but these are a pain */ +int transparent_compression = 0; /* So far only works with linux */ +int omit_version_number = 0; /* May violate iso9660, but noone uses vers */ +int no_rr = 0; /* Do not use RR attributes from old session */ +int force_rr = 0; /* Force to use RR attributes from old session */ +Uint RR_relocation_depth = 6; /* Violates iso9660, but most systems work */ +int do_largefiles = 0; /* Whether to allow multi-extent files */ +off_t maxnonlarge = (off_t)0xFFFFFFFF; +int iso9660_level = 1; +int iso9660_namelen = LEN_ISONAME; /* 31 characters, may be set to 37 */ +int full_iso9660_filenames = 0; /* Full 31 character iso9660 filenames */ +int nolimitpathtables = 0; /* Don't limit size of pathtable. Violates iso9660 */ +int relaxed_filenames = 0; /* For Amiga. Disc will not work with DOS */ +int allow_lowercase = 0; /* Allow lower case letters */ +int allow_multidot = 0; /* Allow more than on dot in filename */ +int iso_translate = 1; /* 1 == enables '#', '-' and '~' removal */ +int allow_leading_dots = 0; /* DOS cannot read names with leading dots */ +#ifdef VMS +int use_fileversion = 1; /* Use file version # from filesystem */ +#else +int use_fileversion = 0; /* Use file version # from filesystem */ +#endif +int split_SL_component = 1; /* circumvent a bug in the SunOS driver */ +int split_SL_field = 1; /* circumvent a bug in the SunOS */ +char *trans_tbl; /* default name for translation table */ +int stream_media_size = 0; /* # of blocks on the media */ +char *stream_filename; /* Default stream file name */ + +#ifdef APPLE_HYB +int donotwrite_macpart = 0; /* Do not write "hfs" hybrid with UDF */ +int apple_hyb = 0; /* -hfs HFS hybrid flag */ +int no_apple_hyb = 0; /* -no-hfs HFS hybrid flag */ +int apple_ext = 0; /* create HFS extensions flag */ +int apple_both = 0; /* common flag (for above) */ +int hfs_extra = 0; /* extra HFS blocks added to end of ISO vol */ +int use_mac_name = 0; /* use Mac name for ISO/Joliet/RR flag */ +hce_mem *hce; /* libhfs/mkisofs extras */ +char *hfs_boot_file = 0; /* name of HFS boot file */ +int gen_pt = 0; /* generate HFS partition table */ +char *autoname = 0; /* AutoStart filename */ +char *magic_file = 0; /* name of magic file */ +int probe = 0; /* search files for HFS/Unix type */ +int nomacfiles = 0; /* don't look for Mac/Unix files */ +int hfs_select = 0; /* Mac/Unix types to select */ +int create_dt = 1; /* create the Desktp files */ +int afe_size = 0; /* Apple File Exchange block size */ +int hfs_last = MAG_LAST; /* process magic file after map file */ +char *deftype; /* default Apple TYPE */ +char *defcreator; /* default Apple CREATOR */ +char *hfs_volume_id = NULL; /* HFS volume ID */ +int icon_pos = 0; /* Keep icon position */ +char *hfs_icharset = NULL; /* input HFS charset name */ +char *hfs_ocharset = NULL; /* output HFS charset name */ +int hfs_lock = 1; /* lock HFS volume (read-only) */ +char *hfs_bless = NULL; /* name of folder to 'bless' (System Folder) */ +char *hfs_parms = NULL; /* low level HFS parameters */ + +#ifdef PREP_BOOT +char *prep_boot_image[4]; +int use_prep_boot = 0; +int use_chrp_boot = 0; +#endif /* PREP_BOOT */ +#else /* APPLE_HYB */ +int donotwrite_macpart = 1; /* Do not write "hfs" hybrid with UDF */ +#endif /* APPLE_HYB */ + +#ifdef UDF +int rationalize_udf = 0; /* -udf (rationalized UDF) */ +int use_udf = 0; /* -udf or -UDF */ +int create_udfsymlinks = 1; /* include symlinks in UDF */ +#endif + +#ifdef DVD_AUD_VID +int dvd_audio = 0; +int dvd_hybrid = 0; +int dvd_video = 0; +int dvd_aud_vid_flag = DVD_SPEC_NONE; +#endif + +#ifdef SORTING +int do_sort = 0; /* sort file data */ +#endif /* SORTING */ + +/* + * inode numbers for zero sized files start from this number and count + * backwards. This is done to allow unique inode numbers even on multi-session + * disks. + */ +UInt32_t null_inodes = NULL_INO_MAX; +BOOL correct_inodes = TRUE; /* TRUE: add a "correct inodes" fingerprint */ +BOOL rrip112 = TRUE; /* TRUE: create Rock Ridge V 1.12 */ +BOOL long_rr_time = FALSE; /* TRUE: use long (17 Byte) time format */ + +siconvt_t *in_nls = NULL; /* input UNICODE conversion table */ +siconvt_t *out_nls = NULL; /* output UNICODE conversion table */ +#ifdef APPLE_HYB +siconvt_t *hfs_inls = NULL; /* input HFS UNICODE conversion table */ +siconvt_t *hfs_onls = NULL; /* output HFS UNICODE conversion table */ +#endif /* APPLE_HYB */ + +struct rcopts { + char *tag; + char **variable; +}; + +struct rcopts rcopt[] = { + {"PREP", &preparer}, + {"PUBL", &publisher}, + {"APPI", &appid}, + {"COPY", ©right}, + {"BIBL", &biblio}, + {"ABST", &abstract}, + {"VOLS", &volset_id}, + {"VOLI", &volume_id}, + {"SYSI", &system_id}, +#ifdef APPLE_HYB + {"HFS_TYPE", &deftype}, + {"HFS_CREATOR", &defcreator}, +#endif /* APPLE_HYB */ + {NULL, NULL} +}; + +#ifdef USE_FIND +LOCAL int getfind __PR((char *arg, long *valp, + int *pac, char *const **pav)); +#endif + +LOCAL int getH __PR((const char *arg, void *valp, int *pac, char *const **pav, const char *opt)); +LOCAL int getL __PR((const char *arg, void *valp, int *pac, char *const **pav, const char *opt)); +LOCAL int getP __PR((const char *arg, void *valp, int *pac, char *const **pav, const char *opt)); +LOCAL int dolegacy __PR((const char *arg, void *valp, int *pac, char *const **pav, const char *opt)); + +LOCAL int get_boot_image __PR((char *opt_arg)); +LOCAL int get_hd_boot __PR((char *opt_arg)); +LOCAL int get_ne_boot __PR((char *opt_arg)); +LOCAL int get_no_boot __PR((char *opt_arg)); +LOCAL int get_boot_addr __PR((char *opt_arg)); +LOCAL int get_boot_size __PR((char *opt_arg)); +LOCAL int get_boot_platid __PR((char *opt_arg)); +LOCAL int get_boot_table __PR((char *opt_arg)); +#ifdef APPLE_HYB +#ifdef PREP_BOOT +LOCAL int get_prep_boot __PR((char *opt_arg)); +LOCAL int get_chrp_boot __PR((char *opt_arg)); +#endif +LOCAL int get_bsize __PR((char *opt_arg)); + +LOCAL int hfs_cap __PR((void)); +LOCAL int hfs_neta __PR((void)); +LOCAL int hfs_dbl __PR((void)); +LOCAL int hfs_esh __PR((void)); +LOCAL int hfs_fe __PR((void)); +LOCAL int hfs_sgi __PR((void)); +LOCAL int hfs_mbin __PR((void)); +LOCAL int hfs_sgl __PR((void)); +LOCAL int hfs_dave __PR((void)); +LOCAL int hfs_sfm __PR((void)); +LOCAL int hfs_xdbl __PR((void)); +LOCAL int hfs_xhfs __PR((void)); +LOCAL int hfs_nohfs __PR((void)); +#endif /* APPLE_HYB */ + +LOCAL void ldate_error __PR((char *arg)); +LOCAL char *strntoi __PR((char *p, int n, int *ip)); +LOCAL int mosize __PR((int y, int m)); +LOCAL char *parse_date __PR((char *arg, struct tm *tp)); +LOCAL int get_ldate __PR((char *opt_arg, void *valp)); + +LOCAL int +get_boot_image(opt_arg) + char *opt_arg; +{ + do_sort++; /* We sort bootcat/botimage */ + use_eltorito++; + boot_image = opt_arg; /* pathname of the boot image */ + /* on disk */ + if (boot_image == NULL || *boot_image == '\0') { + comerrno(EX_BAD, + _("Required Eltorito boot image pathname missing\n")); + } + get_boot_entry(); + current_boot_entry->boot_image = boot_image; + return (1); +} + +LOCAL int +get_hd_boot(opt_arg) + char *opt_arg; +{ + use_eltorito++; + hard_disk_boot++; + get_boot_entry(); + current_boot_entry->hard_disk_boot = 1; + return (1); +} + +LOCAL int +get_ne_boot(opt_arg) + char *opt_arg; +{ + use_eltorito++; + no_emul_boot++; + get_boot_entry(); + current_boot_entry->no_emul_boot = 1; + return (1); +} + +LOCAL int +get_no_boot(opt_arg) + char *opt_arg; +{ + use_eltorito++; + not_bootable++; + get_boot_entry(); + current_boot_entry->not_bootable = 1; + return (1); +} + +LOCAL int +get_boot_addr(opt_arg) + char *opt_arg; +{ + long val; + char *ptr; + + use_eltorito++; + val = strtol(opt_arg, &ptr, 0); + if (*ptr || val < 0 || val >= 0x10000) { + comerrno(EX_BAD, _("Boot image load address invalid.\n")); + } + load_addr = val; + get_boot_entry(); + current_boot_entry->load_addr = load_addr; + return (1); +} + +LOCAL int +get_boot_size(opt_arg) + char *opt_arg; +{ + long val; + char *ptr; + + use_eltorito++; + val = strtol(opt_arg, &ptr, 0); + if (*ptr || val < 0 || val >= 0x10000) { + comerrno(EX_BAD, + _("Boot image load size invalid.\n")); + } + load_size = val; + get_boot_entry(); + current_boot_entry->load_size = load_size; + return (1); +} + +LOCAL int +get_boot_platid(opt_arg) + char *opt_arg; +{ + long val; + char *ptr; + + use_eltorito++; + if (streql(opt_arg, "x86")) { + val = EL_TORITO_ARCH_x86; + } else if (streql(opt_arg, "PPC")) { + val = EL_TORITO_ARCH_PPC; + } else if (streql(opt_arg, "Mac")) { + val = EL_TORITO_ARCH_MAC; + } else if (streql(opt_arg, "efi")) { + val = EL_TORITO_ARCH_EFI; + } else { + val = strtol(opt_arg, &ptr, 0); + if (*ptr || val < 0 || val >= 0x100) { + comerrno(EX_BAD, _("Bad boot system ID.\n")); + } + } + + /* + * If there is already a boot entry and the boot file name has been set + * for this boot entry and the new platform id differs from the + * previous value, we start a new boot section. + */ + if (current_boot_entry && + current_boot_entry->boot_image != NULL && + current_boot_entry->boot_platform != val) { + new_boot_entry(); + } + get_boot_entry(); + current_boot_entry->type |= ELTORITO_BOOT_ID; + current_boot_entry->boot_platform = val; + return (1); +} + +LOCAL int +get_boot_table(opt_arg) + char *opt_arg; +{ + use_eltorito++; + boot_info_table++; + get_boot_entry(); + current_boot_entry->boot_info_table = 1; + return (1); +} + +#ifdef APPLE_HYB +#ifdef PREP_BOOT +LOCAL int +get_prep_boot(opt_arg) + char *opt_arg; +{ + use_prep_boot++; + if (use_prep_boot > 4 - use_chrp_boot) { + comerrno(EX_BAD, + _("Maximum of 4 PRep+CHRP partition entries are allowed\n")); + } + /* pathname of the boot image on cd */ + prep_boot_image[use_prep_boot - 1] = opt_arg; + if (prep_boot_image[use_prep_boot - 1] == NULL) { + comerrno(EX_BAD, + _("Required PReP boot image pathname missing\n")); + } + return (1); +} + +LOCAL int +get_chrp_boot(opt_arg) + char *opt_arg; +{ + if (use_chrp_boot) + return (1); /* silently allow duplicates */ + use_chrp_boot = 1; + if (use_prep_boot > 3) { + comerrno(EX_BAD, + _("Maximum of 4 PRep+CHRP partition entries are allowed\n")); + } + return (1); +} +#endif /* PREP_BOOT */ + + +LOCAL int +get_bsize(opt_arg) + char *opt_arg; +{ + afe_size = atoi(opt_arg); + hfs_select |= DO_FEU; + hfs_select |= DO_FEL; + return (1); +} + +LOCAL int +hfs_cap() +{ + hfs_select |= DO_CAP; + return (1); +} + +LOCAL int +hfs_neta() +{ + hfs_select |= DO_NETA; + return (1); +} + +LOCAL int +hfs_dbl() +{ + hfs_select |= DO_DBL; + return (1); +} + +LOCAL int +hfs_esh() +{ + hfs_select |= DO_ESH; + return (1); +} + +LOCAL int +hfs_fe() +{ + hfs_select |= DO_FEU; + hfs_select |= DO_FEL; + return (1); +} + +LOCAL int +hfs_sgi() +{ + hfs_select |= DO_SGI; + return (1); +} + +LOCAL int +hfs_mbin() +{ + hfs_select |= DO_MBIN; + return (1); +} + +LOCAL int +hfs_sgl() +{ + hfs_select |= DO_SGL; + return (1); +} + +LOCAL int +hfs_dave() +{ + hfs_select |= DO_DAVE; + return (1); +} + + +LOCAL int +hfs_sfm() +{ + hfs_select |= DO_SFM; + return (1); +} + +LOCAL int +hfs_xdbl() +{ + hfs_select |= DO_XDBL; + return (1); +} + +LOCAL int +hfs_xhfs() +{ +#ifdef IS_MACOS_X + hfs_select |= DO_XHFS; +#else + errmsgno(EX_BAD, + _("Warning: --osx-hfs only works on MacOS X ... ignoring\n")); +#endif + return (1); +} + +LOCAL int +hfs_nohfs() +{ + no_apple_hyb = 1; + return (1); +} + +#endif /* APPLE_HYB */ + +LOCAL void +ldate_error(arg) + char *arg; +{ + comerrno(EX_BAD, _("Ilegal date specification '%s'.\n"), arg); +} + +LOCAL char * +strntoi(p, n, ip) + char *p; + int n; + int *ip; +{ + int i = 0; + int digits = 0; + int c; + + while (*p) { + if (digits >= n) + break; + c = *p; + if (c < '0' || c > '9') + break; + p++; + digits++; + i *= 10; + i += c - '0'; + } + *ip = i; + + return (p); +} + +#define dysize(A) (((A)%4)? 365 : (((A)%100) == 0 && ((A)%400)) ? 365 : 366) + +static int dmsize[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +LOCAL int +mosize(y, m) + int y; + int m; +{ + + if (m == 1 && dysize(y) == 366) + return (29); + return (dmsize[m]); +} + +LOCAL char * +parse_date(arg, tp) + char *arg; + struct tm *tp; +{ + char *oarg = arg; + char *p; + + tp->tm_mon = tp->tm_hour = tp->tm_min = tp->tm_sec = 0; + tp->tm_mday = 1; + tp->tm_isdst = -1; + + p = strchr(arg, '/'); + if (p == NULL) + p = strchr(arg, '-'); + if (p) { + if ((p - arg) != 2 && (p - arg) != 4) + ldate_error(oarg); + p = strntoi(arg, 4, &tp->tm_year); + if ((p - arg) != 2 && (p - arg) != 4) + ldate_error(oarg); + if ((p - arg) == 2) { + if (tp->tm_year < 69) + tp->tm_year += 100; + } else { + tp->tm_year -= 1900; + } + if (*p == '/' || *p == '-') + p++; + } else if (strlen(arg) < 4) { + ldate_error(oarg); + } else { + p = strntoi(arg, 4, &tp->tm_year); + if ((p - arg) != 4) + ldate_error(oarg); + tp->tm_year -= 1900; + } + if (*p == '\0' || strchr(".+-", *p)) + return (p); + arg = p; + p = strntoi(arg, 2, &tp->tm_mon); + if ((p - arg) != 2) + ldate_error(oarg); + tp->tm_mon -= 1; + if (tp->tm_mon < 0 || tp->tm_mon >= 12) + ldate_error(oarg); + if (*p == '/' || *p == '-') + p++; + if (*p == '\0' || strchr(".+-", *p)) + return (p); + arg = p; + p = strntoi(arg, 2, &tp->tm_mday); + if ((p - arg) != 2) + ldate_error(oarg); + if (tp->tm_mday < 1 || tp->tm_mday > mosize(tp->tm_year+1900, tp->tm_mon)) + ldate_error(oarg); + if (*p == ' ') + p++; + if (*p == '\0' || strchr(".+-", *p)) + return (p); + arg = p; + p = strntoi(arg, 2, &tp->tm_hour); + if ((p - arg) != 2) + ldate_error(oarg); + if (tp->tm_hour > 23) + ldate_error(oarg); + if (*p == ':') + p++; + if (*p == '\0' || strchr(".+-", *p)) + return (p); + arg = p; + p = strntoi(arg, 2, &tp->tm_min); + if ((p - arg) != 2) + ldate_error(oarg); + if (tp->tm_min > 59) + ldate_error(oarg); + if (*p == ':') + p++; + if (*p == '\0' || strchr(".+-", *p)) + return (p); + arg = p; + p = strntoi(arg, 2, &tp->tm_sec); + if ((p - arg) != 2) + ldate_error(oarg); + if (tp->tm_sec > 61) + ldate_error(oarg); + return (p); +} + +/* + * Parse a date spec similar to: + * YYYY[MM[DD[HH[MM[SS]]]]][.hh][+-GHGM] + */ +LOCAL int +get_ldate(opt_arg, valp) + char *opt_arg; + void *valp; +{ + time_t t; + int usec = 0; + int gmtoff = -100; + struct tm tm; + char *p; + char *arg; + + p = parse_date(opt_arg, &tm); + if (*p == '.') { + p++; + arg = p; + p = strntoi(arg, 2, &usec); + if ((p - arg) != 2) + ldate_error(opt_arg); + if (usec > 99) + ldate_error(opt_arg); + usec *= 10000; + } + if (*p == ' ') + p++; + if (*p == '+' || *p == '-') { + int i; + char *s = p++; + + arg = p; + p = strntoi(arg, 2, &gmtoff); + if ((p - arg) != 2) + ldate_error(opt_arg); + arg = p; + p = strntoi(arg, 2, &i); + if ((p - arg) != 2) + ldate_error(opt_arg); + if (i > 59) + ldate_error(opt_arg); + gmtoff *= 60; + gmtoff += i; + if (gmtoff % 15) + ldate_error(opt_arg); + if (*s == '-') + gmtoff *= -1; + gmtoff /= 15; + if (gmtoff < -48 || gmtoff > 52) + ldate_error(opt_arg); + } + if (*p != '\0') + ldate_error(opt_arg); + + seterrno(0); + t = mktime(&tm); + if (t == -1 && geterrno() != 0) + comerr(_("Date '%s' is out of range.\n"), opt_arg); + + ((ldate *)valp)->l_sec = t; + ((ldate *)valp)->l_usec = usec; + ((ldate *)valp)->l_gmtoff = gmtoff; + + return (1); +} + +#ifdef USE_FIND +/* ARGSUSED */ +LOCAL int +getfind(arg, valp, pac, pav) + char *arg; + long *valp; /* Not used until we introduce a ptr to opt struct */ + int *pac; + char *const **pav; +{ + dofind = TRUE; + find_ac = *pac; + find_av = *pav; + find_ac--, find_av++; + return (NOARGS); +} +#endif + +/* ARGSUSED */ +LOCAL int +getH(arg, valp, pac, pav, opt) /* Follow symlinks encountered on cmdline */ + const char *arg; + void *valp; + int *pac; + char *const **pav; + const char *opt; +{ +/*error("getH\n");*/ + if (opt[0] == '-' && opt[1] == 'H' && opt[2] == '\0') { +#ifdef APPLE_HYB + if (legacy) { + errmsgno(EX_BAD, _("The option '-H' is deprecated since 2002.\n")); + errmsgno(EX_BAD, _("The option '-H' was disabled in 2006.\n")); + errmsgno(EX_BAD, _("Use '-map' instead of '-H' as documented instead of using the legacy mode.\n")); + afpfile = (char *)arg; + return (1); + } +#endif + return (BADFLAG); /* POSIX -H is not yet active */ + } + follow_links = FALSE; + Hflag = TRUE; +#ifdef USE_FIND + *(int *)valp |= WALK_ARGFOLLOW; +#endif + return (1); +} + +/* ARGSUSED */ +LOCAL int +getL(arg, valp, pac, pav, opt) /* Follow all symlinks */ + const char *arg; + void *valp; + int *pac; + char *const **pav; + const char *opt; +{ +/*error("getL\n");*/ + if (opt[0] == '-' && opt[1] == 'L' && opt[2] == '\0') { + if (legacy) { + errmsgno(EX_BAD, _("The option '-L' is deprecated since 2002.\n")); + errmsgno(EX_BAD, _("The option '-L' was disabled in 2006.\n")); + errmsgno(EX_BAD, + _("Use '-allow-leading-dots' instead of '-L' as documented instead of using the legacy mode.\n")); + allow_leading_dots = TRUE; + return (1); + } + return (BADFLAG); /* POSIX -L is not yet active */ + } + follow_links = TRUE; + Hflag = FALSE; +#ifdef USE_FIND + *(int *)valp |= WALK_ALLFOLLOW; +#endif + return (1); +} + +/* ARGSUSED */ +LOCAL int +getP(arg, valp, pac, pav, opt) /* Do not follow symlinks */ + const char *arg; + void *valp; + int *pac; + char *const **pav; + const char *opt; +{ +/*error("getP\n");*/ + if (opt[0] == '-' && opt[1] == 'P' && opt[2] == '\0') { + if (legacy) { + errmsgno(EX_BAD, _("The option '-P' is deprecated since 2002.\n")); + errmsgno(EX_BAD, _("The option '-P' was disabled in 2006.\n")); + errmsgno(EX_BAD, _("Use '-publisher' instead of '-P' as documented instead of using the legacy mode.\n")); + publisher = (char *)arg; + return (1); + } + return (BADFLAG); /* POSIX -P is not yet active */ + } + follow_links = FALSE; + Hflag = FALSE; +#ifdef USE_FIND + *(int *)valp &= ~(WALK_ARGFOLLOW | WALK_ALLFOLLOW); +#endif + return (1); +} + +LOCAL struct ga_flags *gl_flags; +/* ARGSUSED */ +LOCAL int +dolegacy(arg, valp, pac, pav, opt) /* Follow symlinks encountered on cmdline */ + const char *arg; + void *valp; + int *pac; + char *const **pav; + const char *opt; +{ + legacy = TRUE; +#ifdef APPLE_HYB + gl_flags[2].ga_format = "H&"; /* Apple Hybrid "-map" */ +#endif +#ifdef OPT_L_HAS_ARG /* never ;-) */ + gl_flags[4].ga_format = "L&"; /* -allow-leading-dots */ +#endif + gl_flags[6].ga_format = "P&"; /* -publisher */ + return (1); +} + +struct mki_option { + /* + * The long option information. + */ + struct ga_flags opt; + /* + * The documentation string. If this is NULL or empty, this is a + * synonym for the previous option. + * + * If the string starts with a '-', the (long) option is a + * double dash option. + * + * If the next character in the string is a ^A (\1), then the following + * characters are the argument name for the option. The arg string ends + * before a \1 or a \2 is seen. A \1 is skipped. + * + * The rest of the string is the real documentation string. If it + * starts with \2, then the option is hidden from the online help. + */ + const char *doc; +}; + + +LOCAL int save_pname = 0; + +LOCAL const struct mki_option mki_options[] = +{ +#ifdef USE_FIND + {{"find~", NULL, (getpargfun)getfind }, + __("\1file... [find expr.]\1Option separator: Use find command line to the right")}, +#endif + /* + * The options -H/-L/-P did have different meaning in old releases of + * mkisofs. In October 2002, mkisofs introduced a warning that the + * short options -H/-L/-P should not be used with the old meaning + * anymore. The long options should be used instead. The options + * -H/-L/-P previously have been associated with the following long + * options: + * + * -H -map 2000..2002 + * -L -allow-leading-dots 1995..2002 + * -P -publisher 1993..2002 + * + * Since December 2006, the short options -H/-L/-P have been disabled + * for their old meaning. + * + * Warning: for the -legacy mode, the entries for -H/-L/-P need to stay + * at their current index in mki_options[] or dolegacy() needs to be + * changed to fit the modification. + */ + {{"posix-H~", &walkflags, getH }, + __("Follow symbolic links encountered on command line")}, + {{"H~", &walkflags, getH }, +#ifdef LATER + NULL}, +#else + __("\2")}, +#endif + {{"posix-L~", &walkflags, getL }, + __("Follow all symbolic links")}, + {{"L~", &walkflags, getL }, +#ifdef LATER + NULL}, +#else + __("\2")}, +#endif + {{"posix-P~", &walkflags, getP }, + __("Do not follow symbolic links (default)")}, + {{"P~", &walkflags, getP }, +#ifdef LATER + NULL}, +#else + __("\2")}, +#endif + + {{"abstract*", &abstract }, + __("\1FILE\1Set Abstract filename")}, + {{"A*,appid*", &appid }, + __("\1ID\1Set Application ID")}, + {{"biblio*", &biblio }, + __("\1FILE\1Set Bibliographic filename")}, + /* + * If this includes UWIN, we need to modify the condition. + */ +#if !defined(__MINGW32__) && !defined(_MSC_VER) + {{"cache-inodes", &cache_inodes }, + __("Cache inodes (needed to detect hard links)")}, +#endif + {{"no-cache-inodes%0", &cache_inodes }, + __("Do not cache inodes (if filesystem has no unique inodes)")}, + {{"rrip110%0", &rrip112 }, + __("Create old Rock Ridge V 1.10")}, + {{"rrip112", &rrip112 }, + __("Create new Rock Ridge V 1.12 (default)")}, + {{"check-oldnames", &check_oldnames }, + __("Check all imported ISO9660 names from old session")}, + {{"check-session*", &check_image }, + __("\1FILE\1Check all ISO9660 names from previous session")}, + {{"copyright*", ©right }, + __("\1FILE\1Set Copyright filename")}, + {{"debug+", &debug }, + __("Set debug flag")}, + {{"ignore-error", &ignerr }, + __("Ignore errors")}, + {{"b& ,eltorito-boot&", NULL, (getpargfun)get_boot_image }, + __("\1FILE\1Set El Torito boot image name")}, + {{"eltorito-alt-boot~", NULL, (getpargfun)new_boot_entry }, + __("Start specifying alternative El Torito boot parameters")}, + {{"eltorito-platform&", NULL, (getpargfun)get_boot_platid }, + __("\1ID\1Set El Torito platform id for the next boot entry")}, + {{"B&,sparc-boot&", NULL, (getpargfun)scan_sparc_boot }, + __("\1FILES\1Set sparc boot image names")}, + {{"sunx86-boot&", NULL, (getpargfun)scan_sunx86_boot }, + __("\1FILES\1Set sunx86 boot image names")}, + {{"G*,generic-boot*", &genboot_image }, + __("\1FILE\1Set generic boot image name")}, + {{"sparc-label&", NULL, (getpargfun)sparc_boot_label }, + __("\1label text\1Set sparc boot disk label")}, + {{"sunx86-label&", NULL, (getpargfun)sunx86_boot_label }, + __("\1label text\1Set sunx86 boot disk label")}, + {{"c* ,eltorito-catalog*", &boot_catalog }, + __("\1FILE\1Set El Torito boot catalog name")}, + {{"C*,cdrecord-params*", &cdrecord_data }, + __("\1PARAMS\1Magic paramters from cdrecord")}, + {{"d,omit-period", &omit_period }, + __("Omit trailing periods from filenames (violates ISO9660)")}, + {{"data-change-warn", &data_change_warn }, + __("Treat data/size changes as warning only")}, + {{"dir-mode*", &dirmode_str }, + __("\1mode\1Make the mode of all directories this mode.")}, + {{"D,disable-deep-relocation", &disable_deep_reloc }, + __("Disable deep directory relocation (violates ISO9660)")}, + {{"file-mode*", &filemode_str }, + __("\1mode\1Make the mode of all plain files this mode.")}, + {{"errctl&", NULL, (getpargfun)errconfig }, + __("\1name\1Read error control defs from file or inline.")}, + {{"f,follow-links", &follow_links }, + __("Follow symbolic links")}, + {{"gid*", &gid_str }, + __("\1gid\1Make the group owner of all files this gid.")}, + {{"graft-points", &use_graft_ptrs }, + __("Allow to use graft points for filenames")}, + {{"root*", &reloc_root }, + __("\1DIR\1Set root directory for all new files and directories")}, + {{"old-root*", &reloc_old_root }, + __("\1DIR\1Set root directory in previous session that is searched for files")}, + {{"help", &help }, + __("Print option help")}, + {{"hide& ", NULL, (getpargfun)i_add_match }, + __("\1GLOBFILE\1Hide ISO9660/RR file")}, + {{"hide-list&", NULL, (getpargfun)i_add_list }, + __("\1FILE\1File with list of ISO9660/RR files to hide")}, + {{"hidden& ", NULL, (getpargfun)h_add_match }, + __("\1GLOBFILE\1Set hidden attribute on ISO9660 file")}, + {{"hidden-list&", NULL, (getpargfun)h_add_list }, + __("\1FILE\1File with list of ISO9660 files with hidden attribute")}, + {{"hide-joliet& ", NULL, (getpargfun)j_add_match }, + __("\1GLOBFILE\1Hide Joliet file")}, + {{"hide-joliet-list&", NULL, (getpargfun)j_add_list }, + __("\1FILE\1File with list of Joliet files to hide")}, +#ifdef UDF + {{"hide-udf& ", NULL, (getpargfun)u_add_match }, + __("\1GLOBFILE\1Hide UDF file")}, + {{"hide-udf-list&", NULL, (getpargfun)u_add_list }, + __("\1FILE\1File with list of UDF files to hide")}, +#endif + {{"hide-joliet-trans-tbl", &jhide_trans_tbl}, + __("Hide TRANS.TBL from Joliet tree")}, + {{"hide-rr-moved", &hide_rr_moved }, + __("Rename RR_MOVED to .rr_moved in Rock Ridge tree")}, + {{"gui", &gui}, + __("Switch behaviour for GUI")}, + {{"input-charset*", &icharset }, + __("\1CHARSET\1Local input charset for file name conversion")}, + {{"output-charset*", &ocharset }, + __("\1CHARSET\1Output charset for file name conversion")}, + {{"iso-level#", &iso9660_level }, + __("\1LEVEL\1Set ISO9660 conformance level (1..3) or 4 for ISO9660 version 2")}, + {{"J,joliet", &use_Joliet }, + __("Generate Joliet directory information")}, + {{"joliet-long", &joliet_long }, + __("Allow Joliet file names to be 103 Unicode characters")}, + {{"jcharset*", &jcharset }, + __("\1CHARSET\1Local charset for Joliet directory information")}, + {{"l,full-iso9660-filenames", &full_iso9660_filenames }, + __("Allow full 31 character filenames for ISO9660 names")}, + {{"max-iso9660-filenames", &max_filenames }, + __("Allow 37 character filenames for ISO9660 names (violates ISO9660)")}, + + {{"allow-leading-dots", &allow_leading_dots }, + __("Allow ISO9660 filenames to start with '.' (violates ISO9660)")}, + {{"ldots", &allow_leading_dots }, + __("Allow ISO9660 filenames to start with '.' (violates ISO9660)")}, + + {{"log-file*", &log_file }, + __("\1LOG_FILE\1Re-direct messages to LOG_FILE")}, + {{"long-rr-time%1", &long_rr_time }, + __("Use long Rock Ridge time format")}, + {{"m& ,exclude& ", NULL, (getpargfun)add_match }, + __("\1GLOBFILE\1Exclude file name")}, + {{"exclude-list&", NULL, (getpargfun)add_list}, + __("\1FILE\1File with list of file names to exclude")}, + {{"modification-date&", &modification_date, (getpargfun)get_ldate }, + __("\1DATE\1Set the modification date field of the PVD")}, + {{"nobak%0", &all_files }, + __("Do not include backup files")}, + {{"no-bak%0", &all_files}, + __("Do not include backup files")}, + {{"pad", &dopad }, + __("Pad output to a multiple of 32k (default)")}, + {{"no-pad%0", &dopad }, + __("Do not pad output to a multiple of 32k")}, + {{"no-limit-pathtables", &nolimitpathtables }, + __("Allow more than 65535 parent directories (violates ISO9660)")}, + {{"no-long-rr-time%0", &long_rr_time }, + __("Use short Rock Ridge time format")}, + {{"M*,prev-session*", &merge_image }, + __("\1FILE\1Set path to previous session to merge")}, + {{"dev*", &merge_image }, + __("\1SCSIdev\1Set path to previous session to merge")}, + {{"N,omit-version-number", &omit_version_number }, + __("Omit version number from ISO9660 filename (violates ISO9660)")}, + {{"new-dir-mode*", &new_dirmode_str }, + __("\1mode\1Mode used when creating new directories.")}, + {{"force-rr", &force_rr }, + __("Inhibit automatic Rock Ridge detection for previous session")}, + {{"no-rr", &no_rr }, + __("Inhibit reading of Rock Ridge attributes from previous session")}, + {{"no-split-symlink-components%0", &split_SL_component }, + __("Inhibit splitting symlink components")}, + {{"no-split-symlink-fields%0", &split_SL_field }, + __("Inhibit splitting symlink fields")}, + {{"o* ,output* ", &outfile }, + __("\1FILE\1Set output file name")}, + {{"path-list*", &pathnames }, + __("\1FILE\1File with list of pathnames to process")}, + {{"p* ,preparer*", &preparer }, + __("\1PREP\1Set Volume preparer")}, + {{"print-size", &print_size }, + __("Print estimated filesystem size and exit")}, + {{"publisher*", &publisher }, + __("\1PUB\1Set Volume publisher")}, + {{"quiet%0", &verbose }, + __("Run quietly")}, + {{"r,rational-rock", &rationalize_rr }, + __("Generate rationalized Rock Ridge directory information")}, + {{"R,rock", &use_RockRidge }, + __("Generate Rock Ridge directory information")}, + {{"s* ,sectype*", §ype }, + __("\1TYPE\1Set output sector type to e.g. data/xa1/raw")}, + {{"short-rr-time%0", &long_rr_time }, + __("Use short Rock Ridge time format")}, + +#ifdef SORTING + { {"sort&", NULL, (getpargfun)add_sort_list }, + __("\1FILE\1Sort file content locations according to rules in FILE")}, +#endif /* SORTING */ + + {{"split-output", &split_output }, + __("Split output into files of approx. 1GB size")}, + {{"stream-file-name*", &stream_filename }, + __("\1FILE_NAME\1Set the stream file ISO9660 name (incl. version)")}, + {{"stream-media-size#", &stream_media_size }, + __("\1#\1Set the size of your CD media in sectors")}, + {{"sysid*", &system_id }, + __("\1ID\1Set System ID")}, + {{"T,translation-table", &generate_tables }, + __("Generate translation tables for systems that don't understand long filenames")}, + {{"table-name*", &trans_tbl }, + __("\1TABLE_NAME\1Translation table file name")}, + {{"ucs-level#", &ucs_level }, + __("\1LEVEL\1Set Joliet UCS level (1..3)")}, + +#ifdef UDF + {{"udf", &rationalize_udf }, + __("Generate rationalized UDF file system")}, + {{"UDF", &use_udf }, + __("Generate UDF file system")}, + {{"udf-symlinks", &create_udfsymlinks }, + __("Create symbolic links on UDF image (default)")}, + {{"no-udf-symlinks%0", &create_udfsymlinks }, + __("Do not reate symbolic links on UDF image")}, +#endif + +#ifdef DVD_AUD_VID + {{"dvd-audio", &dvd_audio }, + "Generate DVD-Audio compliant UDF file system"}, + {{"dvd-hybrid", &dvd_hybrid }, + "Generate a hybrid (DVD-Audio and DVD-Video) compliant UDF file system"}, + {{"dvd-video", &dvd_video }, + __("Generate DVD-Video compliant UDF file system")}, +#endif + + {{"uid*", &uid_str }, + __("\1uid\1Make the owner of all files this uid.")}, + {{"U,untranslated-filenames", &untranslated_filenames }, + /* CSTYLED */ + __("Allow Untranslated filenames (for HPUX & AIX - violates ISO9660). Forces -l, -d, -N, -allow-leading-dots, -relaxed-filenames, -allow-lowercase, -allow-multidot")}, + {{"relaxed-filenames", &relaxed_filenames }, + __("Allow 7 bit ASCII except lower case characters (violates ISO9660)")}, + {{"no-iso-translate%0", &iso_translate }, + __("Do not translate illegal ISO characters '~', '-' and '#' (violates ISO9660)")}, + {{"allow-lowercase", &allow_lowercase }, + __("Allow lower case characters in addition to the current character set (violates ISO9660)")}, + {{"allow-multidot", &allow_multidot }, + __("Allow more than one dot in filenames (e.g. .tar.gz) (violates ISO9660)")}, + {{"use-fileversion", &use_fileversion }, + __("\1LEVEL\1Use file version # from filesystem")}, + {{"v+,verbose+", &verbose }, + __("Verbose")}, + {{"version", &pversion }, + __("Print the current version")}, + {{"V*,volid*", &volume_id }, + __("\1ID\1Set Volume ID")}, + {{"volset* ", &volset_id }, + __("\1ID\1Set Volume set ID")}, + {{"volset-size#", &volume_set_size }, + __("\1#\1Set Volume set size")}, + {{"volset-seqno#", &volume_sequence_number }, + __("\1#\1Set Volume set sequence number")}, + {{"x& ,old-exclude&", NULL, (getpargfun)add_match }, + __("\1FILE\1Exclude file name(depreciated)")}, + {{"hard-disk-boot~", NULL, (getpargfun)get_hd_boot }, + __("Boot image is a hard disk image")}, + {{"no-emul-boot~", NULL, (getpargfun)get_ne_boot }, + __("Boot image is 'no emulation' image")}, + {{"no-boot~", NULL, (getpargfun)get_no_boot }, + __("Boot image is not bootable")}, + {{"boot-load-seg&", NULL, (getpargfun)get_boot_addr }, + __("\1#\1Set load segment for boot image")}, + {{"boot-load-size&", NULL, (getpargfun)get_boot_size }, + __("\1#\1Set numbers of load sectors")}, + {{"boot-info-table~", NULL, (getpargfun)get_boot_table }, + __("Patch boot image with info table")}, + {{"XA", &use_XA }, + __("Generate XA directory attributes")}, + {{"xa", &rationalize_xa }, + __("Generate rationalized XA directory attributes")}, + {{"z,transparent-compression", &transparent_compression }, + __("Enable transparent compression of files")}, + +#ifdef APPLE_HYB + {{"hfs-type*", &deftype }, + __("\1TYPE\1Set HFS default TYPE")}, + {{"hfs-creator", &defcreator }, + __("\1CREATOR\1Set HFS default CREATOR")}, + {{"g,apple", &apple_ext }, + __("Add Apple ISO9660 extensions")}, + {{"h,hfs", &apple_hyb }, + __("Create ISO9660/HFS hybrid")}, + {{"map*", &afpfile }, + __("\1MAPPING_FILE\1Map file extensions to HFS TYPE/CREATOR")}, + {{"magic*", &magic_file }, + __("\1FILE\1Magic file for HFS TYPE/CREATOR")}, + {{"probe", &probe }, + __("Probe all files for Apple/Unix file types")}, + {{"mac-name", &use_mac_name }, + __("Use Macintosh name for ISO9660/Joliet/RockRidge file name")}, + {{"no-mac-files", &nomacfiles }, + __("Do not look for Unix/Mac files (depreciated)")}, + {{"boot-hfs-file*", &hfs_boot_file }, + __("\1FILE\1Set HFS boot image name")}, + {{"part", &gen_pt }, + __("Generate HFS partition table")}, + {{"cluster-size&", NULL, (getpargfun)get_bsize }, + __("\1SIZE\1Cluster size for PC Exchange Macintosh files")}, + {{"auto*", &autoname }, + __("\1FILE\1Set HFS AutoStart file name")}, + {{"no-desktop%0", &create_dt }, + __("Do not create the HFS (empty) Desktop files")}, + {{"hide-hfs& ", NULL, (getpargfun)hfs_add_match }, + __("\1GLOBFILE\1Hide HFS file")}, + {{"hide-hfs-list&", NULL, (getpargfun)hfs_add_list }, + __("\1FILE\1List of HFS files to hide")}, + {{"hfs-volid*", &hfs_volume_id }, + __("\1HFS_VOLID\1Volume name for the HFS partition")}, + {{"icon-position", &icon_pos }, + __("Keep HFS icon position")}, + {{"root-info*", &root_info }, + __("\1FILE\1finderinfo for root folder")}, + {{"input-hfs-charset*", &hfs_icharset }, + __("\1CHARSET\1Local input charset for HFS file name conversion")}, + {{"output-hfs-charset*", &hfs_ocharset }, + __("\1CHARSET\1Output charset for HFS file name conversion")}, + {{"hfs-unlock%0", &hfs_lock }, + __("Leave HFS Volume unlocked")}, + {{"hfs-bless*", &hfs_bless }, + __("\1FOLDER_NAME\1Name of Folder to be blessed")}, + {{"hfs-parms*", &hfs_parms }, + __("\1PARAMETERS\1Comma separated list of HFS parameters")}, +#ifdef PREP_BOOT + {{"prep-boot&", NULL, (getpargfun)get_prep_boot }, + __("\1FILE\1PReP boot image file -- up to 4 are allowed")}, + {{"chrp-boot&", NULL, (getpargfun)get_chrp_boot }, + __("Add CHRP boot header")}, +#endif /* PREP_BOOT */ + {{"cap~", NULL, (getpargfun)hfs_cap }, + __("-Look for AUFS CAP Macintosh files")}, + {{"netatalk~", NULL, (getpargfun)hfs_neta}, + __("-Look for NETATALK Macintosh files")}, + {{"double~", NULL, (getpargfun)hfs_dbl }, + __("-Look for AppleDouble Macintosh files")}, + {{"ethershare~", NULL, (getpargfun)hfs_esh }, + __("-Look for Helios EtherShare Macintosh files")}, + {{"exchange~", NULL, (getpargfun)hfs_fe }, + __("-Look for PC Exchange Macintosh files")}, + {{"sgi~", NULL, (getpargfun)hfs_sgi }, + __("-Look for SGI Macintosh files")}, + {{"macbin~", NULL, (getpargfun)hfs_mbin }, + __("-Look for MacBinary Macintosh files")}, + {{"single~", NULL, (getpargfun)hfs_sgl }, + __("-Look for AppleSingle Macintosh files")}, + {{"ushare~", NULL, (getpargfun)hfs_esh }, + __("-Look for IPT UShare Macintosh files")}, + {{"xinet~", NULL, (getpargfun)hfs_sgi }, + __("-Look for XINET Macintosh files")}, + {{"dave~", NULL, (getpargfun)hfs_dave }, + __("-Look for DAVE Macintosh files")}, + {{"sfm~", NULL, (getpargfun)hfs_sfm }, + __("-Look for SFM Macintosh files")}, + {{"osx-double~", NULL, (getpargfun)hfs_xdbl }, + __("-Look for MacOS X AppleDouble Macintosh files")}, + {{"osx-hfs~", NULL, (getpargfun)hfs_xhfs }, + __("-Look for MacOS X HFS Macintosh files")}, + {{"no-hfs~", NULL, (getpargfun)hfs_nohfs }, + __("Do not create ISO9660/HFS hybrid")}, +#endif /* APPLE_HYB */ + {{"legacy~", NULL, dolegacy }, + __("\2")}, +}; + +#define OPTION_COUNT (sizeof mki_options / sizeof (mki_options[0])) + +LOCAL void read_rcfile __PR((char *appname)); +LOCAL void susage __PR((int excode)); +LOCAL void usage __PR((int excode)); +EXPORT int iso9660_date __PR((char *result, time_t crtime)); +LOCAL void hide_reloc_dir __PR((void)); +LOCAL char *get_pnames __PR((int argc, char *const *argv, int opt, + char *pname, int pnsize, FILE *fp)); +EXPORT int main __PR((int argc, char *argv[])); +LOCAL void list_locales __PR((void)); +EXPORT char *findgequal __PR((char *s)); +LOCAL char *escstrcpy __PR((char *to, size_t tolen, char *from)); +struct directory *get_graft __PR((char *arg, char *graft_point, size_t glen, + char *nodename, size_t nlen, + char **short_namep, BOOL do_insert)); +EXPORT void *e_malloc __PR((size_t size)); +EXPORT char *e_strdup __PR((const char *s)); +LOCAL void ovstrcpy __PR((char *p2, char *p1)); +LOCAL void checkarch __PR((char *name)); + +LOCAL void +read_rcfile(appname) + char *appname; +{ + FILE *rcfile = (FILE *)NULL; + struct rcopts *rco; + char *pnt, + *pnt1; + char linebuffer[256]; + static char rcfn[] = ".mkisofsrc"; + char filename[1000]; + int linum; + + strlcpy(filename, rcfn, sizeof (filename)); + if (access(filename, R_OK) == 0) + rcfile = fopen(filename, "r"); + if (!rcfile && errno != ENOENT) + errmsg(_("Cannot open '%s'.\n"), filename); + + if (!rcfile) { + pnt = getenv("MKISOFSRC"); + if (pnt && strlen(pnt) <= sizeof (filename)) { + strlcpy(filename, pnt, sizeof (filename)); + if (access(filename, R_OK) == 0) + rcfile = fopen(filename, "r"); + if (!rcfile && errno != ENOENT) + errmsg(_("Cannot open '%s'.\n"), filename); + } + } + if (!rcfile) { + pnt = getenv("HOME"); + if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= + sizeof (filename)) { + strlcpy(filename, pnt, sizeof (filename)); + if (strlen(rcfn) + 2 <= + (sizeof (filename) - strlen(filename))) { + strcat(filename, "/"); + strcat(filename, rcfn); + } + if (access(filename, R_OK) == 0) + rcfile = fopen(filename, "r"); + if (!rcfile && errno != ENOENT) + errmsg(_("Cannot open '%s'.\n"), filename); + } + } + if (!rcfile && strlen(appname) + sizeof (rcfn) + 2 <= + sizeof (filename)) { + strlcpy(filename, appname, sizeof (filename)); + pnt = strrchr(filename, '/'); + if (pnt) { + strlcpy(pnt + 1, rcfn, + sizeof (filename) - (pnt + 1 - filename)); + if (access(filename, R_OK) == 0) + rcfile = fopen(filename, "r"); + if (!rcfile && errno != ENOENT) + errmsg(_("Cannot open '%s'.\n"), filename); + } + } + if (!rcfile) + return; + if (verbose > 0) { + fprintf(stderr, _("Using \"%s\"\n"), filename); + } + /* OK, we got it. Now read in the lines and parse them */ + linum = 0; + while (fgets(linebuffer, sizeof (linebuffer), rcfile)) { + char *name; + char *name_end; + + ++linum; + /* skip any leading white space */ + pnt = linebuffer; + while (*pnt == ' ' || *pnt == '\t') + ++pnt; + /* + * If we are looking at a # character, this line is a comment. + */ + if (*pnt == '#') + continue; + /* + * The name should begin in the left margin. Make sure it is + * in upper case. Stop when we see white space or a comment. + */ + name = pnt; + while (*pnt && (isalpha((unsigned char) *pnt) || *pnt == '_')) { + if (islower((unsigned char) *pnt)) + *pnt = toupper((unsigned char) *pnt); + pnt++; + } + if (name == pnt) { + fprintf(stderr, _("%s:%d: name required\n"), filename, + linum); + continue; + } + name_end = pnt; + /* Skip past white space after the name */ + while (*pnt == ' ' || *pnt == '\t') + pnt++; + /* silently ignore errors in the rc file. */ + if (*pnt != '=') { + fprintf(stderr, _("%s:%d: equals sign required after '%.*s'\n"), + filename, linum, + /* XXX Should not be > int */ + (int)(name_end-name), name); + continue; + } + /* Skip pas the = sign, and any white space following it */ + pnt++; /* Skip past '=' sign */ + while (*pnt == ' ' || *pnt == '\t') + pnt++; + + /* now it is safe to NUL terminate the name */ + + *name_end = 0; + + /* Now get rid of trailing newline */ + + pnt1 = pnt; + while (*pnt1) { + if (*pnt1 == '\n') { + *pnt1 = 0; + break; + } + pnt1++; + } + /* OK, now figure out which option we have */ + for (rco = rcopt; rco->tag; rco++) { + if (strcmp(rco->tag, name) == 0) { + *rco->variable = e_strdup(pnt); + break; + } + } + if (rco->tag == NULL) { + fprintf(stderr, _("%s:%d: field name \"%s\" unknown\n"), + filename, linum, + name); + } + } + if (ferror(rcfile)) + errmsg(_("Read error on '%s'.\n"), filename); + fclose(rcfile); +} + +char *path_table_l = NULL; +char *path_table_m = NULL; + +char *jpath_table_l = NULL; +char *jpath_table_m = NULL; + +int goof = 0; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +LOCAL void +susage(excode) + int excode; +{ + const char *program_name = "mkisofs"; + +#ifdef USE_FIND + fprintf(stderr, _("Usage: %s [options] [-find] file... [find expression]\n"), program_name); +#else + fprintf(stderr, _("Usage: %s [options] file...\n"), program_name); +#endif + fprintf(stderr, _("\nUse %s -help\n"), program_name); + fprintf(stderr, _("to get a list all of valid options.\n")); +#ifdef USE_FIND + fprintf(stderr, _("\nUse %s -find -help\n"), program_name); + fprintf(stderr, _("to get a list of all valid -find options.\n")); +#endif + error(_("\nMost important Options:\n")); + error(_(" -posix-H Follow sylinks encountered on command line\n")); + error(_(" -posix-L Follow all symlinks\n")); + error(_(" -posix-P Do not follow symlinks (default)\n")); + error(_(" -o FILE, -output FILE Set output file name\n")); + error(_(" -R, -rock Generate Rock Ridge directory information\n")); + error(_(" -r, -rational-rock Generate rationalized Rock Ridge directory info\n")); + error(_(" -J, -joliet Generate Joliet directory information\n")); + error(_(" -print-size Print estimated filesystem size and exit\n")); +#ifdef UDF + error(_(" -UDF Generate UDF file system\n")); +#endif +#ifdef DVD_AUD_VID + error(_(" -dvd-audio Generate DVD-Audio compliant UDF file system\n")); + error(_(" -dvd-video Generate DVD-Video compliant UDF file system\n")); + error(_(" -dvd-hybrid Generate a hybrid (DVD-Audio/DVD-Video) compliant UDF file system\n")); +#endif + error(_(" -iso-level LEVEL Set ISO9660 level (1..3) or 4 for ISO9660 v 2\n")); + error(_(" -V ID, -volid ID Set Volume ID\n")); + error(_(" -graft-points Allow to use graft points for filenames\n")); + error(_(" -M FILE, -prev-session FILE Set path to previous session to merge\n")); + + exit(excode); +} + +const char *optend __PR((const char *fmt)); +const char * +optend(fmt) + const char *fmt; +{ + int c; + + for (; *fmt != '\0'; fmt++) { + c = *fmt; + if (c == '\\') { + if (*++fmt == '\0') + break; + continue; + } + if (c == ',' || c == '%' || c == '*' || c == '?' || + c == '#' || c == '&' || c == '~' || c == '+') + break; + + } + return (fmt); +} + +int printopts __PR((FILE *f, const char *fmt, const char *arg, int twod)); +int +printopts(f, fmt, arg, twod) + FILE *f; + const char *fmt; + const char *arg; + int twod; +{ + const char *p; + int len = 0; + int optlen; + int arglen = 0; + + if (arg) { + if (*arg == '-' || *arg == '\\') + arg++; + + if (*arg == '\1') { + p = ++arg; + while (*p != '\0' && *p != '\1' && *p != '\2') + p++; + arglen = p - arg; + if (arglen == 0) + arg = NULL; + } else { + arg = NULL; + } + } + for (p = optend(fmt); p > fmt; p = optend(fmt)) { + optlen = p - fmt; + len += fprintf(f, "%s%.*s%s%.*s", + *fmt == '+' ? "" : + (optlen > 1 && twod) ? "--" : "-", + (int)(p - fmt), fmt, + arg != NULL ? " " : "", + arglen, arg != NULL ? arg : ""); + fmt = p; + while (*fmt != '\0' && *fmt != ',') + fmt++; + if (*fmt == ',') { + fmt++; + len += fprintf(f, ", "); + } + } + return (len); +} + +const char *docstr __PR((const char *str, int *no_help)); +const char * +docstr(str, no_help) + const char *str; + int *no_help; +{ + if (no_help) + *no_help = 0; + if (str == NULL) + return (str); + + if (*str == '-' || *str == '\\') + str++; + + if (*str == '\1') { + str++; + while (*str != '\0' && *str != '\1' && *str != '\2') + str++; + } + if (*str == '\1') { + str++; + } else if (*str == '\2') { + str++; + if (no_help) + *no_help = 1; + } + + if (*str == '\0') + return (NULL); + return (str); +} + +LOCAL void +usage(excode) + int excode; +{ + const char *program_name = "mkisofs"; + + int i; + +#ifdef USE_FIND + fprintf(stderr, _("Usage: %s [options] [-find] file... [find expression]\n"), program_name); +#else + fprintf(stderr, _("Usage: %s [options] file...\n"), program_name); +#endif + + fprintf(stderr, _("Options:\n")); + for (i = 0; i < (int)OPTION_COUNT; i++) { + if (docstr(mki_options[i].doc, NULL) != NULL) { + int len; + int j; + + fprintf(stderr, " "); + len = 2; + j = i; + do { + int twodash; + int no_help; + const char *doc; + + doc = mki_options[j].doc; + twodash = (doc != NULL && *doc == '-'); + doc = docstr(doc, &no_help); + + if (!no_help) { + /* + * If more options for one doc, then + * print a comma as separator. + */ + if (j > i) + len += fprintf(stderr, ", "); + len += printopts(stderr, + mki_options[j].opt.ga_format, + mki_options[j].doc, + twodash); + } + ++j; + } + while (j < (int)OPTION_COUNT && + docstr(mki_options[j].doc, NULL) == NULL); + + if (len >= 30) { + fprintf(stderr, "\n"); + len = 0; + } + for (; len < 30; len++) + fputc(' ', stderr); + + fprintf(stderr, "%s\n", + docstr(mki_options[i].doc, NULL)); + } + } + exit(excode); +} + + +/* + * Fill in date in the iso9660 format + * This takes 7 bytes and supports year 1900 .. 2155 with 1 second granularity + * + * The standards state that the timezone offset is in multiples of 15 + * minutes, and is what you add to GMT to get the localtime. The U.S. + * is always at a negative offset, from -5h to -8h (can vary a little + * with DST, I guess). The Linux iso9660 filesystem has had the sign + * of this wrong for ages (mkisofs had it wrong too until February 1997). + */ +EXPORT int +iso9660_date(result, crtime) + char *result; + time_t crtime; +{ + struct tm local; + struct tm gmt; + + local = *localtime(&crtime); + gmt = *gmtime(&crtime); + + result[0] = local.tm_year; + result[1] = local.tm_mon + 1; + result[2] = local.tm_mday; + result[3] = local.tm_hour; + result[4] = local.tm_min; + result[5] = local.tm_sec; + + local.tm_min -= gmt.tm_min; + local.tm_hour -= gmt.tm_hour; + local.tm_yday -= gmt.tm_yday; + local.tm_year -= gmt.tm_year; + if (local.tm_year) /* Hit new-year limit */ + local.tm_yday = local.tm_year; /* yday = +-1 */ + + result[6] = (local.tm_min + 60 * + (local.tm_hour + 24 * local.tm_yday)) / 15; + + return (0); +} + +/* + * Fill in date in the iso9660 long format + * This takes 17 bytes and supports year 0 .. 9999 with 10ms granularity + * If iso9660_ldate() is called with gmtoff set to -100, the gmtoffset for + * the related time is computed via localtime(). For the modification + * date in the PVD, the date and the GMT offset may be defined via the + * -modification-date command line option. + */ +EXPORT int +iso9660_ldate(result, crtime, nsec, gmtoff) + char *result; + time_t crtime; + int nsec; + int gmtoff; +{ + struct tm local; + struct tm gmt; + + local = *localtime(&crtime); + gmt = *gmtime(&crtime); + + /* + * There was a comment here about breaking in the year 2000. + * That's not true, in 2000 tm_year == 100, so 1900+tm_year == 2000. + */ + sprintf(result, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%2.2d", + 1900 + local.tm_year, + local.tm_mon + 1, local.tm_mday, + local.tm_hour, local.tm_min, local.tm_sec, + nsec / 10000000); + + if (gmtoff == -100) { + local.tm_min -= gmt.tm_min; + local.tm_hour -= gmt.tm_hour; + local.tm_yday -= gmt.tm_yday; + local.tm_year -= gmt.tm_year; + if (local.tm_year) /* Hit new-year limit */ + local.tm_yday = local.tm_year; /* yday = +-1 */ + + result[16] = (local.tm_min + 60 * + (local.tm_hour + 24 * local.tm_yday)) / 15; + } else { + result[16] = gmtoff; + } + return (0); +} + +/* hide "./rr_moved" if all its contents are hidden */ +LOCAL void +hide_reloc_dir() +{ + struct directory_entry *s_entry; + + for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; + + if ((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) + return; + } + + /* all entries are hidden, so hide this directory */ + reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; + reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY; +} + +/* + * get pathnames from the command line, and then from given file + */ +LOCAL char * +get_pnames(argc, argv, opt, pname, pnsize, fp) + int argc; + char * const *argv; + int opt; + char *pname; + int pnsize; + FILE *fp; +{ + int len; + + /* we may of already read the first line from the pathnames file */ + if (save_pname) { + save_pname = 0; + return (pname); + } + +#ifdef USE_FIND + if (dofind && opt < (find_pav - argv)) + return (argv[opt]); + else if (!dofind && opt < argc) + return (argv[opt]); +#else + if (opt < argc) + return (argv[opt]); +#endif + + if (fp == NULL) + return ((char *)0); + + if (fgets(pname, pnsize, fp)) { + /* Discard newline */ + len = strlen(pname); + if (pname[len - 1] == '\n') { + pname[len - 1] = '\0'; + } + return (pname); + } + return ((char *)0); +} + +EXPORT int +main(argc, argv) + int argc; + char *argv[]; +{ + int cac = argc; + char * const *cav = argv; + + struct directory_entry de; + +#ifdef HAVE_SBRK + unsigned long mem_start; +#endif + struct stat statbuf; + struct iso_directory_record *mrootp = NULL; + struct output_fragment *opnt; + struct ga_flags flags[OPTION_COUNT + 1]; + int c; + int n; + char *node = NULL; + FILE *pfp = NULL; + char pname[2*PATH_MAX + 1 + 1]; /* may be too short */ + char *arg; /* if '\\' present */ + char nodename[PATH_MAX + 1]; + int no_path_names = 1; + int warn_violate = 0; + int have_cmd_line_pathspec = 0; + int rationalize_all = 0; + int argind = 0; +#ifdef APPLE_HYB + int hfs_ct = 0; +#endif /* APPLE_HYB */ + + +#ifdef __EMX__ + /* This gives wildcard expansion with Non-Posix shells with EMX */ + _wildcard(&argc, &argv); +#endif + save_args(argc, argv); + +#if defined(USE_NLS) + setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "mkisofs" /* Use this only if it weren't */ +#endif + arg = searchfileinpath("share/locale", F_OK, + SIP_ANY_FILE|SIP_NO_PATH, NULL); + if (arg) + (void) bindtextdomain(TEXT_DOMAIN, arg); + else +#ifdef PROTOTYPES + (void) bindtextdomain(TEXT_DOMAIN, INS_BASE "/share/locale"); +#else + (void) bindtextdomain(TEXT_DOMAIN, "/usr/share/locale"); +#endif + (void) textdomain(TEXT_DOMAIN); +#endif + + + if (argc < 2) { + errmsgno(EX_BAD, _("Missing pathspec.\n")); + susage(1); + } + /* Get the defaults from the .mkisofsrc file */ + read_rcfile(argv[0]); + + { + int i; + + for (i = 0; i < (int)OPTION_COUNT; i++) { + flags[i] = mki_options[i].opt; + } + flags[i].ga_format = NULL; + gl_flags = flags; + } + time(&begun); + gettimeofday(&tv_begun, NULL); + modification_date.l_sec = tv_begun.tv_sec; + modification_date.l_usec = tv_begun.tv_usec; + modification_date.l_gmtoff = -100; + +#if defined(IS_CYGWIN) + /* + * If we have 64 bit inode numbers, Cygwin should be able to work + * correctly on NTFS. + */ + if (sizeof (ino_t) >= 8) + cache_inodes = 1; +#endif + cac--; + cav++; + c = getvargs(&cac, &cav, GA_NO_PROPS, flags); + if (c < 0) { + if (c == BADFLAG && strchr(cav[0], '=')) { + argind = argc - cac; + goto args_ok; + } + error(_("Bad Option '%s' (error %d %s).\n"), + cav[0], c, getargerror(c)); + susage(EX_BAD); + } +args_ok: + if (argind == 0) + argind = argc - cac; + path_ind = argind; + if (cac > 0) + have_cmd_line_pathspec = 1; + if (help) + usage(0); + if (pversion) { + printf(_("mkisofs %s (%s-%s-%s)\n\n\ +Copyright (C) 1993-1997 %s\n\ +Copyright (C) 1997-2016 %s\n"), + version_string, + HOST_CPU, HOST_VENDOR, HOST_OS, + _("Eric Youngdale"), + _("Joerg Schilling")); +#ifdef APPLE_HYB + printf(_("Copyright (C) 1997-2001 James Pearson\n")); +#endif +#ifdef UDF + printf(_("Copyright (C) 2006 HELIOS Software GmbH\n")); +#endif +#ifdef OPTION_SILO_BOOT + printf(_("Warning: this is unofficial (modified) version of mkisofs that incorporates\n")); + printf(_(" support for a non Sparc compliant boot method called SILO.\n")); + printf(_(" The official method to create Sparc boot CDs is to use -sparc-boot\n")); + printf(_(" In case of problems first test with an official version of mkisofs.\n")); +#endif + exit(0); + } +#ifdef USE_FIND + if (dofind) { + finda_t fa; + + cac = find_ac; + cav = find_av; + find_firstprim(&cac, &cav); + find_pac = cac; + find_pav = cav; + argind = argc - find_ac; + + if (cac > 0) { + find_argsinit(&fa); + fa.walkflags = walkflags; + fa.Argc = cac; + fa.Argv = (char **)cav; + find_node = find_parse(&fa); + if (fa.primtype == FIND_ERRARG) + comexit(fa.error); + if (fa.primtype != FIND_ENDARGS) + comerrno(EX_BAD, _("Incomplete expression.\n")); + plusp = fa.plusp; + find_patlen = fa.patlen; + walkflags = fa.walkflags; + maxdepth = fa.maxdepth; + mindepth = fa.mindepth; + + if (find_node && + !(check_image || print_size) && + (outfile == NULL || + (outfile[0] == '-' && outfile[1] == '\0'))) { + if (find_pname(find_node, "-exec") || + find_pname(find_node, "-exec+") || + find_pname(find_node, "-ok")) + comerrno(EX_BAD, + _("Cannot -exec with '-o -'.\n")); + } + } + + if (find_ac <= 0 || find_ac == find_pac) { + errmsgno(EX_BAD, _("Missing pathspec for -find.\n")); + susage(EX_BAD); + } + } +#endif +#ifdef DVD_AUD_VID + + dvd_aud_vid_flag = (dvd_audio ? DVD_SPEC_AUDIO : 0) + | (dvd_hybrid ? DVD_SPEC_HYBRD : 0) + | (dvd_video ? DVD_SPEC_VIDEO : 0); + +#endif + + if (abstract) { + if (strlen(abstract) > 37) { + comerrno(EX_BAD, + _("Abstract filename string too long (cur. %lld max. 37 chars).\n"), + (Llong)strlen(abstract)); + } + } + if (appid) { + if (strlen(appid) > 128) { + comerrno(EX_BAD, + _("Application-id string too long (cur. %lld max. 128 chars).\n"), + (Llong)strlen(appid)); + } + } + if (biblio) { + if (strlen(biblio) > 37) { + comerrno(EX_BAD, + _("Bibliographic filename string too long (cur. %lld max. 37 chars).\n"), + (Llong)strlen(biblio)); + } + } + if (!cache_inodes) { + correct_inodes = FALSE; + if (use_RockRidge) { + errmsgno(EX_BAD, + _("Warning: Cannot write inode/link information with -no-cache-inodes.\n")); + } else { + errmsgno(EX_BAD, + _("Warning: Cannot add inode hints with -no-cache-inodes.\n")); + } + } + if (!correct_inodes) + rrip112 = FALSE; + if (check_image) { + check_session++; + check_oldnames++; + merge_image = check_image; + outfile = DEV_NULL; + /* + * cdrecord_data is handled specially in multi.c + * as we cannot write to all strings. + * If mkisofs is called with -C xx,yy + * our default is overwritten. + */ +/* cdrecord_data = "0,0";*/ + } + if (copyright) { + if (strlen(copyright) > 37) { + comerrno(EX_BAD, + _("Copyright filename string too long (cur. %lld max. 37 chars).\n"), + (Llong)strlen(copyright)); + } + } + if (genboot_image) + use_genboot++; + if (boot_catalog) + use_eltorito++; + else + boot_catalog = BOOT_CATALOG_DEFAULT; + if (omit_period && iso9660_level < 4) + warn_violate++; + if (data_change_warn) + errconfig("WARN|GROW|SHRINK *"); + if (dirmode_str) { + char *end = 0; + + rationalize++; + use_RockRidge++; + rationalize_dirmode++; + + /* + * If -new-dir-mode was specified, new_dir_mode is set + * up later with a value that matches the -new-dir-mode arg. + */ + new_dir_mode = dirmode_to_use = strtol(dirmode_str, &end, 8); + if (!end || *end != 0 || + dirmode_to_use < 0 || dirmode_to_use > 07777) { + comerrno(EX_BAD, _("Bad mode for -dir-mode\n")); + } + } + if (disable_deep_reloc) + RR_relocation_depth = 0xFFFFFFFF; + if (filemode_str) { + char *end = 0; + + rationalize++; + use_RockRidge++; + rationalize_filemode++; + + filemode_to_use = strtol(filemode_str, &end, 8); + if (!end || *end != 0 || + filemode_to_use < 0 || filemode_to_use > 07777) { + comerrno(EX_BAD, _("Bad mode for -file-mode\n")); + } + } +#ifdef __warn_follow__ + if (follow_links) { + errmsgno(EX_BAD, + _("Warning: -follow-links does not always work correctly; be careful.\n")); + } +#endif + if (gid_str) { + char *end = 0; + + rationalize++; + use_RockRidge++; + rationalize_gid++; + + gid_to_use = strtol(gid_str, &end, 0); + if (!end || *end != 0) { + comerrno(EX_BAD, _("Bad value for -gid\n")); + } + } + switch (iso9660_level) { + + case 1: + /* + * Only on file section + * 8.3 d or d1 characters for files + * 8 d or d1 characters for directories + */ + break; + case 2: + /* + * Only on file section + */ + break; + case 3: + /* + * No restrictions + */ + do_largefiles++; + break; + case 4: + /* + * This is ISO-9660:1988 (ISO-9660 version 2) + */ + do_largefiles++; + iso9660_namelen = MAX_ISONAME_V2; /* allow 207 chars */ + full_iso9660_filenames++; /* 31+ chars */ + omit_version_number++; + RR_relocation_depth = 0xFFFFFFFF; + + /* + * From -U ... + */ + omit_period++; /* trailing dot */ + allow_leading_dots++; + relaxed_filenames++; /* all chars */ + allow_lowercase++; /* even lowcase */ + allow_multidot++; /* > 1 dots */ + break; + + default: + comerrno(EX_BAD, _("Illegal iso9660 Level %d, use 1..3 or 4.\n"), + iso9660_level); + } + + if (joliet_long) { + use_Joliet++; + jlen = JLONGMAX; + } + if (jcharset) { + use_Joliet++; + icharset = jcharset; + } + if (max_filenames && iso9660_level < 4) { + iso9660_namelen = MAX_ISONAME_V1; /* allow 37 chars */ + full_iso9660_filenames++; + omit_version_number++; + warn_violate++; + } + if (allow_leading_dots && iso9660_level < 4) + warn_violate++; + if (omit_version_number && iso9660_level < 4) + warn_violate++; + if (new_dirmode_str) { + char *end = 0; + + rationalize++; + + new_dir_mode = strtol(new_dirmode_str, &end, 8); + if (!end || *end != 0 || + new_dir_mode < 0 || new_dir_mode > 07777) { + comerrno(EX_BAD, _("Bad mode for -new-dir-mode\n")); + } + } + if (sectype) { + if (strcmp(sectype, "data") == 0) + osecsize = 2048; + else if (strcmp(sectype, "xa1") == 0) + osecsize = 2056; + else if (strcmp(sectype, "raw") == 0) { + osecsize = 2352; + comerrno(EX_BAD, + _("Unsupported sector type '%s'.\n"), + sectype); + } + } + if (preparer) { + if (strlen(preparer) > 128) { + comerrno(EX_BAD, _("Preparer string too long (cur. %lld max. 128 chars).\n"), + (Llong)strlen(preparer)); + } + } + if (publisher) { + if (strlen(publisher) > 128) { + comerrno(EX_BAD, + _("Publisher string too long (cur. %lld max. 128 chars).\n"), + (Llong)strlen(publisher)); + } + } + if (rationalize_rr) { + rationalize_all++; + use_RockRidge++; + } + if (stream_filename) { + if (strlen(stream_filename) > MAX_ISONAME) + comerrno(EX_BAD, + _("stream-file-name too long (%llu), max is %d.\n"), + (Ullong)strlen(stream_filename), MAX_ISONAME); + if (strchr(stream_filename, '/')) + comerrno(EX_BAD, _("Illegal character '/' in stream-file-name.\n")); + iso9660_level = 4; + } else { + stream_filename = omit_version_number ? "STREAM.IMG" : "STREAM.IMG;1"; + } + if (system_id) { + if (strlen(system_id) > 32) { + comerrno(EX_BAD, + _("System ID string too long\n")); + } + } + if (trans_tbl) + generate_tables++; + else + trans_tbl = "TRANS.TBL"; + if (ucs_level < 1 || ucs_level > 3) + comerrno(EX_BAD, _("Illegal UCS Level %d, use 1..3.\n"), + ucs_level); +#ifdef DVD_AUD_VID + if (dvd_aud_vid_flag) { + if (!use_udf) + rationalize_udf++; + } +#endif +#ifdef UDF + if (rationalize_udf) { + rationalize_all++; + use_udf++; + } +#endif + if (uid_str) { + char *end = 0; + + rationalize++; + use_RockRidge++; + rationalize_uid++; + + uid_to_use = strtol(uid_str, &end, 0); + if (!end || *end != 0) { + comerrno(EX_BAD, _("Bad value for -uid\n")); + } + } + if (untranslated_filenames && iso9660_level < 4) { + /* + * Minimal (only truncation of 31+ characters) + * translation of filenames. + * + * Forces -l, -d, -N, -allow-leading-dots, + * -relaxed-filenames, + * -allow-lowercase, -allow-multidot + * + * This is for HP-UX, which does not recognize ANY + * extentions (Rock Ridge, Joliet), causing pain when + * loading software. pfs_mount can be used to read the + * extensions, but the untranslated filenames can be + * read by the "native" cdfs mounter. Completely + * violates iso9660. + */ + full_iso9660_filenames++; /* 31 chars */ + omit_period++; /* trailing dot */ + allow_leading_dots++; + omit_version_number++; + relaxed_filenames++; /* all chars */ + allow_lowercase++; /* even lowcase */ + allow_multidot++; /* > 1 dots */ + warn_violate++; + } + if (relaxed_filenames && iso9660_level < 4) + warn_violate++; + if (iso_translate == 0 && iso9660_level < 4) + warn_violate++; + if (allow_lowercase && iso9660_level < 4) + warn_violate++; + if (allow_multidot && iso9660_level < 4) + warn_violate++; + if (volume_id) { + if (strlen(volume_id) > 32) { + comerrno(EX_BAD, + _("Volume ID string too long (cur. %lld max. 32 chars).\n"), + (Llong)strlen(volume_id)); + } + } + if (volset_id) { + if (strlen(volset_id) > 128) { + comerrno(EX_BAD, + _("Volume set ID string too long (cur. %lld max. 128 chars).\n"), + (Llong)strlen(volset_id)); + } + } + if (volume_set_size) { + if (volume_set_size <= 0) { + comerrno(EX_BAD, + _("Illegal Volume Set Size %d\n"), volume_set_size); + } + if (volume_set_size > 1) { + comerrno(EX_BAD, + _("Volume Set Size > 1 not yet supported\n")); + } + } + if (volume_sequence_number) { + if (volume_sequence_number > volume_set_size) { + comerrno(EX_BAD, + _("Volume set sequence number too big\n")); + } + } + if (rationalize_xa) { + rationalize_all++; + use_XA++; + } + if (transparent_compression) { +#ifdef VMS + comerrno(EX_BAD, + _("Transparent compression not supported with VMS\n")); +#endif + } +#ifdef APPLE_HYB + if (deftype) { + hfs_ct++; + if (strlen(deftype) != 4) { + comerrno(EX_BAD, + _("HFS default TYPE string has illegal length.\n")); + } + } else { + deftype = APPLE_TYPE_DEFAULT; + } + if (defcreator) { + hfs_ct++; + if (strlen(defcreator) != 4) { + comerrno(EX_BAD, + _("HFS default CREATOR string has illegal length.\n")); + } + } else { + defcreator = APPLE_CREATOR_DEFAULT; + } + if (afpfile && *afpfile != '\0') + hfs_last = MAP_LAST; + if (magic_file) + hfs_last = MAG_LAST; + if (nomacfiles) { + errmsgno(EX_BAD, + _("Warning: -no-mac-files no longer used ... ignoring\n")); + } + if (hfs_boot_file) + gen_pt = 1; + if (root_info) + icon_pos = 1; + if (hfs_icharset) + use_mac_name = 1; + if (hfs_parms) + hfs_parms = e_strdup(hfs_parms); + + if (apple_hyb && apple_ext) { + comerrno(EX_BAD, _("Can't have both -apple and -hfs options\n")); + } + /* + * if -probe, -macname, any hfs selection and/or mapping file is given, + * but no HFS option, then select apple_hyb + */ + if (!apple_hyb && !apple_ext) { + if (*afpfile || probe || use_mac_name || hfs_select || + hfs_boot_file || magic_file || + hfs_ishidden() || gen_pt || autoname || + afe_size || icon_pos || hfs_ct || + hfs_icharset || hfs_ocharset) { + apple_hyb = 1; +#ifdef UDF + if ((DO_XHFS & hfs_select) && use_udf) { + donotwrite_macpart = 1; + if (!no_apple_hyb) { + error( + _("Warning: no HFS hybrid will be created with -udf and --osx-hfs\n")); + } + } +#endif + } + } +#ifdef UDF + if (!use_udf && create_udfsymlinks) + create_udfsymlinks = 0; +#if 0 + if (use_RockRidge && use_udf && create_udfsymlinks) { + error(_("Warning: cannot create UDF symlinks with activated Rock Ridge\n")); + create_udfsymlinks = 0; + } +#endif +#endif + if (no_apple_hyb) { + donotwrite_macpart = 1; + } + if (apple_hyb && !donotwrite_macpart && do_largefiles > 0) { + do_largefiles = 0; + maxnonlarge = (off_t)0x7FFFFFFF; + error(_("Warning: cannot support large files with -hfs\n")); + } +#ifdef UDF + if (apple_hyb && use_udf && !donotwrite_macpart) { + comerrno(EX_BAD, _("Can't have -hfs with -udf\n")); + } +#endif + if (apple_ext && hfs_boot_file) { + comerrno(EX_BAD, _("Can't have -hfs-boot-file with -apple\n")); + } + if (apple_ext && autoname) { + comerrno(EX_BAD, _("Can't have -auto with -apple\n")); + } + if (apple_hyb && (use_sparcboot || use_sunx86boot)) { + comerrno(EX_BAD, _("Can't have -hfs with -sparc-boot/-sunx86-boot\n")); + } + if (apple_hyb && use_genboot) { + comerrno(EX_BAD, _("Can't have -hfs with -generic-boot\n")); + } +#ifdef PREP_BOOT + if (apple_ext && use_prep_boot) { + comerrno(EX_BAD, _("Can't have -prep-boot with -apple\n")); + } +#endif /* PREP_BOOT */ + + if (apple_hyb || apple_ext) + apple_both = 1; + + if (probe) + /* we need to search for all types of Apple/Unix files */ + hfs_select = ~0; + + if (apple_both && verbose && !(hfs_select || *afpfile || magic_file)) { + errmsgno(EX_BAD, + _("Warning: no Apple/Unix files will be decoded/mapped\n")); + } + if (apple_both && verbose && !afe_size && + (hfs_select & (DO_FEU | DO_FEL))) { + errmsgno(EX_BAD, + _("Warning: assuming PC Exchange cluster size of 512 bytes\n")); + afe_size = 512; + } + if (apple_both) { + /* set up the TYPE/CREATOR mappings */ + hfs_init(afpfile, 0, hfs_select); + } + if (apple_ext && !use_RockRidge) { +#ifdef nonono + /* use RockRidge to set the SystemUse field ... */ + use_RockRidge++; + rationalize_all++; +#else + /* EMPTY */ +#endif + } + if (apple_ext && !(use_XA || use_RockRidge)) { + comerrno(EX_BAD, _("Need either -XA/-xa or -R/-r for -apple to become active.\n")); + } +#endif /* APPLE_HYB */ + + /* + * if the -hide-joliet option has been given, set the Joliet option + */ + if (!use_Joliet && j_ishidden()) + use_Joliet++; +#ifdef UDF + /* + * if the -hide-udf option has been given, set the UDF option + */ + if (!use_udf && u_ishidden()) + use_udf++; +#endif + + if (rationalize_all) { + rationalize++; + rationalize_uid++; + rationalize_gid++; + rationalize_filemode++; + rationalize_dirmode++; + } + + /* + * XXX This is a hack until we have a decent separate name handling + * XXX for UDF filenames. + */ +#ifdef DVD_AUD_VID + if (dvd_aud_vid_flag && use_Joliet) { + use_Joliet = 0; + error(_("Warning: Disabling Joliet support for DVD-Video/DVD-Audio.\n")); + } +#endif +#ifdef UDF + if (use_udf && !use_Joliet) + jlen = 255; +#endif + + if (use_RockRidge && (iso9660_namelen > MAX_ISONAME_V2_RR)) + iso9660_namelen = MAX_ISONAME_V2_RR; + + if (warn_violate) + error(_("Warning: creating filesystem that does not conform to ISO-9660.\n")); + if (iso9660_level > 3) + error(_("Warning: Creating ISO-9660:1999 (version 2) filesystem.\n")); + if (iso9660_namelen > LEN_ISONAME) + error(_("Warning: ISO-9660 filenames longer than %d may cause buffer overflows in the OS.\n"), + LEN_ISONAME); + if (use_Joliet && !use_RockRidge) { + error(_("Warning: creating filesystem with (nonstandard) Joliet extensions\n")); + error(_(" but without (standard) Rock Ridge extensions.\n")); + error(_(" It is highly recommended to add Rock Ridge\n")); + } + if (transparent_compression) { + error(_("Warning: using transparent compression. This is a nonstandard Rock Ridge\n")); + error(_(" extension. The resulting filesystem can only be transparently\n")); + error(_(" read on Linux. On other operating systems you need to call\n")); + error(_(" mkzftree by hand to decompress the files.\n")); + } + if (transparent_compression && !use_RockRidge) { + error(_("Warning: transparent decompression is a Linux Rock Ridge extension, but\n")); + error(_(" creating filesystem without Rock Ridge attributes; files\n")); + error(_(" will not be transparently decompressed.\n")); + } + +#if defined(USE_NLS) && defined(HAVE_NL_LANGINFO) && defined(CODESET) + /* + * If the locale has not been set up, nl_langinfo() returns the + * name of the default codeset. This should be either "646", + * "ISO-646", "ASCII", or something similar. Unfortunately, the + * POSIX standard does not include a list of valid locale names, + * so ne need to find all values in use. + * + * Observed: + * Solaris "646" + * Linux "ANSI_X3.4-1968" strange value from Linux... + */ + if (icharset == NULL) { + char *codeset = nl_langinfo(CODESET); + Uchar *p; + + if (codeset != NULL) + codeset = e_strdup(codeset); + if (codeset == NULL) /* Should not happen */ + goto setcharset; + if (*codeset == '\0') /* Invalid locale */ + goto setcharset; + + for (p = (Uchar *)codeset; *p != '\0'; p++) { + if (islower(*p)) + *p = toupper(*p); + } + p = (Uchar *)strstr(codeset, "ISO"); + if (p != NULL) { + if (*p == '_' || *p == '-') + p++; + codeset = (char *)p; + } + if (strcmp("646", codeset) != 0 && + strcmp("ASCII", codeset) != 0 && + strcmp("US-ASCII", codeset) != 0 && + strcmp("US_ASCII", codeset) != 0 && + strcmp("USASCII", codeset) != 0 && + strcmp("ANSI_X3.4-1968", codeset) != 0) + icharset = nl_langinfo(CODESET); + + if (codeset != NULL) + free(codeset); + + if (verbose > 0 && icharset != NULL) { + error(_("Setting input-charset to '%s' from locale.\n"), + icharset); + } + } +setcharset: + /* + * Allow to switch off locale with -input-charset "". + */ + if (icharset != NULL && *icharset == '\0') + icharset = NULL; +#endif + if (icharset == NULL) { +#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__)) && !defined(IS_CYGWIN_1) + icharset = "cp437"; +#else + icharset = "default"; +#endif + } + in_nls = sic_open(icharset); + + /* + * set the output charset to the same as the input or the given output + * charset + */ + if (ocharset == NULL) { + ocharset = in_nls ? in_nls->sic_name : NULL; + } + out_nls = sic_open(ocharset); + + if (in_nls == NULL || out_nls == NULL) { /* Unknown charset specified */ + fprintf(stderr, _("Unknown charset '%s'.\nKnown charsets are:\n"), + in_nls == NULL ? icharset : (ocharset ? ocharset : "NULL")); + list_locales(); + exit(EX_BAD); + } +#ifdef USE_ICONV + /* + * XXX If we ever allow this, we neeed to fix the call to conv_charset() + * XXX in name.c::iso9660_file_length(). + */ + if ((in_nls->sic_cd2uni != NULL || out_nls->sic_cd2uni != NULL) && + (in_nls->sic_name != out_nls->sic_name)) { + errmsgno(EX_BAD, + _("Iconv based locales may change file name length.\n")); + comerrno(EX_BAD, + _("Cannot yet have different -input-charset/-output-charset.\n")); + } +#endif + +#ifdef APPLE_HYB + if (hfs_icharset == NULL || strcmp(hfs_icharset, "mac-roman") == 0) { + hfs_icharset = "cp10000"; + } + hfs_inls = sic_open(hfs_icharset); + + if (hfs_ocharset == NULL) { + hfs_ocharset = hfs_inls ? hfs_inls->sic_name : NULL; + } + if (hfs_ocharset == NULL || strcmp(hfs_ocharset, "mac-roman") == 0) { + hfs_ocharset = "cp10000"; + } + hfs_onls = sic_open(hfs_ocharset); + + if (use_mac_name) + apple_hyb = 1; + if (apple_hyb && (hfs_inls == NULL || hfs_onls == NULL)) { + fprintf(stderr, _("Unknown HFS charset '%s'.\nKnown charsets are:\n"), + hfs_inls == NULL ? hfs_icharset : (hfs_ocharset ? hfs_ocharset : "NULL")); + list_locales(); + exit(EX_BAD); + } +#ifdef USE_ICONV + if (apple_hyb && + ((hfs_inls->sic_cd2uni != NULL || hfs_onls->sic_cd2uni != NULL) && + (hfs_inls->sic_name != hfs_onls->sic_name))) { + errmsgno(EX_BAD, + _("Iconv based locales may change file name length.\n")); + comerrno(EX_BAD, + _("Cannot yet have different -input-hfs-charset/-output-hfs-charset.\n")); + } +#endif +#endif /* APPLE_HYB */ + + if (merge_image != NULL) { + if (open_merge_image(merge_image) < 0) { + /* Complain and die. */ + comerr(_("Unable to open previous session image '%s'.\n"), + merge_image); + } + } + /* We don't need root privilleges anymore. */ +#ifdef HAVE_SETREUID + if (setreuid(-1, getuid()) < 0) +#else +#ifdef HAVE_SETEUID + if (seteuid(getuid()) < 0) +#else + if (setuid(getuid()) < 0) +#endif +#endif + comerr(_("Panic cannot set back effective uid.\n")); + + +#ifdef no_more_needed +#ifdef __NetBSD__ + { + int resource; + struct rlimit rlp; + + if (getrlimit(RLIMIT_DATA, &rlp) == -1) + errmsg(_("Warning: Cannot get rlimit.\n")); + else { + rlp.rlim_cur = 33554432; + if (setrlimit(RLIMIT_DATA, &rlp) == -1) + errmsg(_("Warning: Cannot set rlimit.\n")); + } + } +#endif +#endif /* no_more_needed */ +#ifdef HAVE_SBRK + mem_start = (unsigned long) sbrk(0); +#endif + + if (verbose > 1) { + fprintf(stderr, "%s (%s-%s-%s)\n", + version_string, + HOST_CPU, HOST_VENDOR, HOST_OS); + } + if (cdrecord_data == NULL && !check_session && merge_image != NULL) { + comerrno(EX_BAD, + _("Multisession usage bug: Must specify -C if -M is used.\n")); + } + if (cdrecord_data != NULL && merge_image == NULL) { + errmsgno(EX_BAD, + _("Warning: -C specified without -M: old session data will not be merged.\n")); + } +#ifdef APPLE_HYB + if (merge_image != NULL && apple_hyb) { + errmsgno(EX_BAD, + _("Warning: files from previous sessions will not be included in the HFS volume.\n")); + } +#endif /* APPLE_HYB */ + + /* + * see if we have a list of pathnames to process + */ + if (pathnames) { + /* "-" means take list from the standard input */ + if (strcmp(pathnames, "-") != 0) { + if ((pfp = fopen(pathnames, "r")) == NULL) { + comerr(_("Unable to open pathname list %s.\n"), + pathnames); + } + } else + pfp = stdin; + } + + /* The first step is to scan the directory tree, and take some notes */ + + if ((arg = get_pnames(argc, argv, argind, pname, + sizeof (pname), pfp)) == NULL) { + if (check_session == 0 && !stream_media_size) { + errmsgno(EX_BAD, _("Missing pathspec.\n")); + susage(1); + } + } + + /* + * if we don't have a pathspec, then save the pathspec found + * in the pathnames file (stored in pname) - we don't want + * to skip this pathspec when we read the pathnames file again + */ + if (!have_cmd_line_pathspec && !stream_media_size) { + save_pname = 1; + } + if (stream_media_size) { +#ifdef UDF + if (use_XA || use_RockRidge || use_udf || use_Joliet) +#else + if (use_XA || use_RockRidge || use_Joliet) +#endif + comerrno(EX_BAD, + _("Cannot use XA, Rock Ridge, UDF or Joliet with -stream-media-size\n")); + if (merge_image) + comerrno(EX_BAD, + _("Cannot use multi session with -stream-media-size\n")); + if (use_eltorito || use_sparcboot || use_sunx86boot || +#ifdef APPLE_HYB + use_genboot || use_prep_boot || hfs_boot_file) +#else + use_genboot) +#endif + comerrno(EX_BAD, + _("Cannot use boot options with -stream-media-size\n")); +#ifdef APPLE_HYB + if (apple_hyb) + comerrno(EX_BAD, + _("Cannot use Apple hybrid options with -stream-media-size\n")); +#endif + } + + if (use_RockRidge) { + /* BEGIN CSTYLED */ +#if 1 + extension_record = generate_rr_extension_record("RRIP_1991A", + "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", + "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", + &extension_record_size); +#else + extension_record = generate_rr_extension_record("IEEE_P1282", + "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", + "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", + &extension_record_size); +#endif + /* END CSTYLED */ + } + checkarch(outfile); + if (log_file) { + FILE *lfp; + int i; + + /* open log file - test that we can open OK */ + if ((lfp = fopen(log_file, "w")) == NULL) { + comerr(_("Can't open logfile: '%s'.\n"), log_file); + } + fclose(lfp); + + /* redirect all stderr message to log_file */ + fprintf(stderr, _("re-directing all messages to %s\n"), log_file); + fflush(stderr); + + /* associate stderr with the log file */ + if (freopen(log_file, "w", stderr) == NULL) { + comerr(_("Can't open logfile: '%s'.\n"), log_file); + } + if (verbose > 1) { + for (i = 0; i < argc; i++) + fprintf(stderr, "%s ", argv[i]); + + fprintf(stderr, "\n%s (%s-%s-%s)\n", + version_string, + HOST_CPU, HOST_VENDOR, HOST_OS); + } + } + /* Find name of root directory. */ + if (arg != NULL) + node = findgequal(arg); + if (!use_graft_ptrs) + node = NULL; + if (node == NULL) { + if (use_graft_ptrs && arg != NULL) + node = escstrcpy(nodename, sizeof (nodename), arg); + else + node = arg; + } else { + /* + * Remove '\\' escape chars which are located + * before '\\' and '=' chars + */ + node = escstrcpy(nodename, sizeof (nodename), ++node); + } + + /* + * See if boot catalog file exists in root directory, if not we will + * create it. + */ + if (use_eltorito) + init_boot_catalog(node); + + /* + * Find the device and inode number of the root directory. Record this + * in the hash table so we don't scan it more than once. + */ + stat_filter(node, &statbuf); + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + + memset(&de, 0, sizeof (de)); + + /* + * PO: + * Isn't root NULL at this time anyway? + * I think it is created by the first call to + * find_or_create_directory() below. + */ + de.filedir = root; /* We need this to bootstrap */ + + if (cdrecord_data != NULL && merge_image == NULL) { + /* + * in case we want to add a new session, but don't want to + * merge old one + */ + get_session_start(NULL); + } + if (merge_image != NULL) { + char sector[SECTOR_SIZE]; + UInt32_t extent; + + errno = 0; + mrootp = merge_isofs(merge_image); + if (mrootp == NULL) { + /* Complain and die. */ + if (errno == 0) + errno = -1; + comerr(_("Unable to find previous session PVD '%s'.\n"), + merge_image); + } + memcpy(de.isorec.extent, mrootp->extent, 8); + + /* + * Look for RR Attributes in '.' entry of root dir. + * This is the first ISO directory entry in the root dir. + */ + extent = get_733(mrootp->extent); + readsecs(extent, sector, 1); + c = rr_flags((struct iso_directory_record *)sector); + if (c & RR_FLAG_XA) + fprintf(stderr, _("XA signatures found\n")); + if (c & RR_FLAG_AA) + fprintf(stderr, _("AA signatures found\n")); + if (c & ~(RR_FLAG_XA|RR_FLAG_AA)) { + extern int su_version; + extern int rr_version; + extern char er_id[]; + + if (c & RR_FLAG_SP) { + fprintf(stderr, _("SUSP signatures version %d found\n"), su_version); + if (c & RR_FLAG_ER) { + if (rr_version < 1) { + fprintf(stderr, + _("No valid Rock Ridge signature found\n")); + if (!force_rr) + no_rr++; + } else { + fprintf(stderr, + _("Rock Ridge signatures version %d found\n"), + rr_version); + fprintf(stderr, + _("Rock Ridge id '%s'\n"), er_id); + } + } + } else { + fprintf(stderr, _("Bad Rock Ridge signatures found (SU record missing)\n")); + if (!force_rr) + no_rr++; + } + } else { + fprintf(stderr, _("No SUSP/Rock Ridge present\n")); + if ((c & (RR_FLAG_XA|RR_FLAG_AA)) == 0) { + if (!force_rr) + no_rr++; + } + } + if (no_rr) + fprintf(stderr, _("Disabling Rock Ridge / XA / AA\n")); + } + /* + * Create an empty root directory. If we ever scan it for real, + * we will fill in the contents. + */ + find_or_create_directory(NULL, "", &de, TRUE); + +#ifdef APPLE_HYB + /* may need to set window layout of the volume */ + if (root_info) + set_root_info(root_info); +#endif /* APPLE_HYB */ + + /* + * Scan the actual directory (and any we find below it) for files to + * write out to the output image. Note - we take multiple source + * directories and keep merging them onto the image. + */ + if (check_session) + goto path_done; + +#ifdef USE_FIND + if (dofind) { +extern int walkfunc __PR((char *nm, struct stat *fs, int type, struct WALK *state)); + + walkinitstate(&walkstate); + if (find_patlen > 0) { + walkstate.patstate = ___malloc(sizeof (int) * find_patlen, + _("space for pattern state")); + } + + find_timeinit(time(0)); + walkstate.walkflags = walkflags; + walkstate.maxdepth = maxdepth; + walkstate.mindepth = mindepth; + walkstate.lname = NULL; + walkstate.tree = find_node; + walkstate.err = 0; + walkstate.pflags = 0; + + nodesc = TRUE; + for (; + (arg = get_pnames(argc, argv, argind, pname, sizeof (pname), + pfp)) != NULL; + argind++) { + /* + * Make silly GCC happy and double initialize graft_dir. + */ + struct directory *graft_dir = NULL; + char graft_point[PATH_MAX + 1]; + struct wargs wa; + char *snp; + + graft_point[0] = '\0'; + snp = NULL; + if (use_graft_ptrs) + graft_dir = get_graft(arg, + graft_point, sizeof (graft_point), + nodename, sizeof (nodename), + &snp, FALSE); + if (graft_point[0] != '\0') { + arg = nodename; + wa.dir = graft_dir; + } else { + wa.dir = root; + } + wa.name = snp; + walkstate.auxp = &wa; + walkstate.auxi = strlen(arg); + treewalk(arg, walkfunc, &walkstate); + no_path_names = 0; + } + find_plusflush(plusp, &walkstate); + } else +#endif + + while ((arg = get_pnames(argc, argv, argind, pname, + sizeof (pname), pfp)) != NULL) { + char graft_point[PATH_MAX + 1]; + + get_graft(arg, graft_point, sizeof (graft_point), + nodename, sizeof (nodename), NULL, TRUE); + argind++; + no_path_names = 0; + } + +path_done: + if (pfp && pfp != stdin) + fclose(pfp); + + /* + * exit if we don't have any pathnames to process + * - not going to happen at the moment as we have to have at least one + * path on the command line + */ + if (no_path_names && !check_session && !stream_media_size) { + errmsgno(EX_BAD, _("No pathnames found.\n")); + susage(1); + } + /* + * Now merge in any previous sessions. This is driven on the source + * side, since we may need to create some additional directories. + */ + if (merge_image != NULL) { + if (merge_previous_session(root, mrootp, + reloc_root, reloc_old_root) < 0) { + comerrno(EX_BAD, _("Cannot merge previous session.\n")); + } + close_merge_image(); + + /* + * set up parent_dir and filedir in relocated entries which + * were read from previous session so that + * finish_cl_pl_entries can do its job + */ + match_cl_re_entries(); + free(mrootp); + } +#ifdef APPLE_HYB + /* free up any HFS filename mapping memory */ + if (apple_both) + clean_hfs(); +#endif /* APPLE_HYB */ + + /* hide "./rr_moved" if all its contents have been hidden */ + if (reloc_dir && i_ishidden()) + hide_reloc_dir(); + + /* insert the boot catalog if required */ + if (use_eltorito) + insert_boot_cat(); + + /* + * Free up any matching memory + */ + for (n = 0; n < MAX_MAT; n++) + gen_del_match(n); + +#ifdef SORTING + del_sort(); +#endif /* SORTING */ + + /* + * Sort the directories in the required order (by ISO9660). Also, + * choose the names for the 8.3 filesystem if required, and do any + * other post-scan work. + */ + goof += sort_tree(root); + + if (goof) { + comerrno(EX_BAD, _("ISO9660/Rock Ridge tree sort failed.\n")); + } +#ifdef UDF + if (use_Joliet || use_udf) { +#else + if (use_Joliet) { +#endif + goof += joliet_sort_tree(root); + } + if (goof) { + comerrno(EX_BAD, _("Joliet tree sort failed.\n")); + } + /* + * Fix a couple of things in the root directory so that everything is + * self consistent. Fix this up so that the path tables get done right. + */ + root->self = root->contents; + + /* OK, ready to write the file. Open it up, and generate the thing. */ + if (print_size) { + discimage = fopen(DEV_NULL, "wb"); + if (!discimage) { + comerr(_("Unable to open /dev/null\n")); + } + } else if (outfile != NULL && + !(outfile[0] == '-' && outfile[1] == '\0')) { + discimage = fopen(outfile, "wb"); + if (!discimage) { + comerr(_("Unable to open disc image file '%s'.\n"), outfile); + } + } else { + discimage = stdout; + setmode(fileno(stdout), O_BINARY); + } +#ifdef HAVE_SETVBUF + setvbuf(discimage, NULL, _IOFBF, 64*1024); +#endif + + /* Now assign addresses on the disc for the path table. */ + + path_blocks = ISO_BLOCKS(path_table_size); + if (path_blocks & 1) + path_blocks++; + + jpath_blocks = ISO_BLOCKS(jpath_table_size); + if (jpath_blocks & 1) + jpath_blocks++; + + /* + * Start to set up the linked list that we use to track the contents + * of the disc. + */ +#ifdef APPLE_HYB +#ifdef PREP_BOOT + if ((apple_hyb && !donotwrite_macpart) || use_prep_boot || use_chrp_boot) +#else /* PREP_BOOT */ + if (apple_hyb && !donotwrite_macpart) +#endif /* PREP_BOOT */ + outputlist_insert(&hfs_desc); +#endif /* APPLE_HYB */ + if (use_sparcboot || use_sunx86boot) + outputlist_insert(&sunlabel_desc); + if (use_genboot) + outputlist_insert(&genboot_desc); + outputlist_insert(&startpad_desc); + + /* PVD for disc. */ + outputlist_insert(&voldesc_desc); + + /* SVD for El Torito. MUST be immediately after the PVD! */ + if (use_eltorito) { + outputlist_insert(&torito_desc); + } + /* Enhanced PVD for disc. neded if we write ISO-9660:1999 */ + if (iso9660_level > 3) + outputlist_insert(&xvoldesc_desc); + + /* SVD for Joliet. */ + if (use_Joliet) { + outputlist_insert(&joliet_desc); + } + /* Finally the last volume descriptor. */ + outputlist_insert(&end_vol); + +#ifdef UDF + if (use_udf) { + outputlist_insert(&udf_vol_recognition_area_frag); + } +#endif + + /* Insert the version descriptor. */ + outputlist_insert(&version_desc); + +#ifdef UDF + if (use_udf) { + /* + * Most of the space before sector 256 is wasted when + * UDF is turned on. The waste could be reduced by + * putting the ISO9660/Joliet structures before the + * pad_to_sector_256; the problem is that they might + * overshoot sector 256, so there would have to be some + * ugly logic to detect this case and rearrange things + * appropriately. I don't know if it's worth it. + */ + outputlist_insert(&udf_pad_to_sector_32_frag); + outputlist_insert(&udf_main_seq_frag); + outputlist_insert(&udf_main_seq_copy_frag); + outputlist_insert(&udf_integ_seq_frag); + outputlist_insert(&udf_pad_to_sector_256_frag); + outputlist_insert(&udf_anchor_vol_desc_frag); + outputlist_insert(&udf_file_set_desc_frag); + outputlist_insert(&udf_dirtree_frag); + outputlist_insert(&udf_file_entries_frag); + } +#endif + + /* Now start with path tables and directory tree info. */ + if (!stream_media_size) + outputlist_insert(&pathtable_desc); + else + outputlist_insert(&strpath_desc); + + if (use_Joliet) { + outputlist_insert(&jpathtable_desc); + } + + if (!stream_media_size) + outputlist_insert(&dirtree_desc); + + if (use_Joliet) { + outputlist_insert(&jdirtree_desc); + } + outputlist_insert(&dirtree_clean); + + if (extension_record) { + outputlist_insert(&extension_desc); + } + + if (!stream_media_size) { + outputlist_insert(&files_desc); + } else { + outputlist_insert(&strfile_desc); + outputlist_insert(&strdir_desc); + } + + /* + * Allow room for the various headers we will be writing. + * There will always be a primary and an end volume descriptor. + */ + last_extent = session_start; + + /* + * Calculate the size of all of the components of the disc, and assign + * extent numbers. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + opnt->of_start_extent = last_extent; + if (opnt->of_size != NULL) { + if (verbose > 2) + fprintf(stderr, _("Computing size: %-40sStart Block %u\n"), + opnt->of_name, last_extent); + (*opnt->of_size) (last_extent); + } + } + + /* + * Generate the contents of any of the sections that we want to + * generate. Not all of the fragments will do anything here + * - most will generate the data on the fly when we get to the write + * pass. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + if (opnt->of_generate != NULL) { + if (verbose > 2) + fprintf(stderr, _("Generating content: %-40s\n"), + opnt->of_name); + (*opnt->of_generate) (); + } + } + + /* + * Padding just after the ISO-9660 filesystem. + * + * files_desc does not have an of_size function. For this + * reason, we must insert us after the files content has been + * generated. + */ +#ifdef UDF + if (use_udf) { + /* Single anchor volume descriptor pointer at end */ + outputlist_insert(&udf_end_anchor_vol_desc_frag); + if (udf_end_anchor_vol_desc_frag.of_size != NULL) { + (*udf_end_anchor_vol_desc_frag.of_size) (last_extent); + } + if (dopad) { + /* + * Pad with anchor volume descriptor pointer + * blocks instead of zeroes. + */ + outputlist_insert(&udf_padend_avdp_frag); + if (udf_padend_avdp_frag.of_size != NULL) { + (*udf_padend_avdp_frag.of_size) (last_extent); + } + } + } else +#endif + if (dopad && !(use_sparcboot || use_sunx86boot)) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + c = 0; + if (use_sparcboot) { + if (dopad) { + /* Padding before the boot partitions. */ + outputlist_insert(&interpad_desc); + if (interpad_desc.of_size != NULL) { + (*interpad_desc.of_size) (last_extent); + } + } + c = make_sun_label(); + last_extent += c; + outputlist_insert(&sunboot_desc); + if (dopad) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + } else if (use_sunx86boot) { + if (dopad) { + /* Padding before the boot partitions. */ + outputlist_insert(&interpad_desc); + if (interpad_desc.of_size != NULL) { + (*interpad_desc.of_size) (last_extent); + } + } + c = make_sunx86_label(); + last_extent += c; + outputlist_insert(&sunboot_desc); + if (dopad) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + } + if (print_size > 0) { + if (verbose > 0) + fprintf(stderr, + _("Total extents scheduled to be written = %u\n"), + (last_extent - session_start)); + printf("%u\n", (last_extent - session_start)); + exit(0); + } + /* + * Now go through the list of fragments and write the data that + * corresponds to each one. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + Uint oext; + + oext = last_extent_written; + if (opnt->of_start_extent != 0 && + opnt->of_start_extent != last_extent_written) { + /* + * Consistency check. + * XXX Should make sure that all entries have + * XXXX of_start_extent set up correctly. + */ + comerrno(EX_BAD, + _("Implementation botch: %s should start at %u but starts at %u.\n"), + opnt->of_name, opnt->of_start_extent, last_extent_written); + } + if (opnt->of_write != NULL) { + if (verbose > 1) + fprintf(stderr, _("Writing: %-40sStart Block %u\n"), + opnt->of_name, last_extent_written); + (*opnt->of_write) (discimage); + if (verbose > 1) + fprintf(stderr, _("Done with: %-40sBlock(s) %u\n"), + opnt->of_name, last_extent_written-oext); + } + } + if (last_extent != last_extent_written) { + comerrno(EX_BAD, + _("Implementation botch: FS should end at %u but ends at %u.\n"), + last_extent, last_extent_written); + } + + if (verbose > 0) { +#ifdef HAVE_SBRK + fprintf(stderr, _("Max brk space used %x\n"), + (unsigned int)(((unsigned long) sbrk(0)) - mem_start)); +#endif + fprintf(stderr, _("%u extents written (%u MB)\n"), + (last_extent-session_start), + (last_extent-session_start) >> 9); + } +#ifdef VMS + return (1); +#else + return (0); +#endif +} + +LOCAL void +list_locales() +{ + int n; + + n = sic_list(stdout); + if (n <= 0) { + const char *ins_base = sic_base(); + + if (ins_base == NULL) + ins_base = "$INS_BASE/lib/siconv/"; + errmsgno(EX_BAD, _("Installation problem: '%s' %s.\n"), + ins_base, n < 0 ? _("missing"):_("incomplete")); + if (n == 0) { + errmsgno(EX_BAD, + _("Check '%s' for missing translation tables.\n"), + ins_base); + } + } +#ifdef USE_ICONV + if (n > 0) { + errmsgno(EX_BAD, + _("'iconv -l' lists more available names.\n")); + } +#endif +} + +/* + * Find unescaped equal sign in graft pointer string. + */ +EXPORT char * +findgequal(s) + char *s; +{ + char *p = s; + + while ((p = strchr(p, '=')) != NULL) { + if (p > s && p[-1] != '\\') + return (p); + p++; + } + return (NULL); +} + +/* + * Find unescaped equal sign in string. + */ +LOCAL char * +escstrcpy(to, tolen, from) + char *to; + size_t tolen; + char *from; +{ + char *p = to; + + if (debug) + error("FROM: '%s'\n", from); + + to[0] = '\0'; + if (tolen > 0) { + to[--tolen] = '\0'; /* Fill in last nul char */ + } + while ((*p = *from++) != '\0' && tolen-- > 0) { + if (*p == '\\') { + if ((*p = *from++) == '\0') + break; + if (*p != '\\' && *p != '=') { + p[1] = p[0]; + *p++ = '\\'; + } + } + p++; + } + if (debug) + error("ESC: '%s'\n", to); + return (to); +} + +struct directory * +get_graft(arg, graft_point, glen, nodename, nlen, short_namep, do_insert) + char *arg; + char *graft_point; + size_t glen; + char *nodename; + size_t nlen; + char **short_namep; + BOOL do_insert; +{ + char *node = NULL; + struct directory_entry de; + struct directory *graft_dir = root; + struct stat st; + char *short_name; + int status; + + fillbytes(&de, sizeof (de), '\0'); + /* + * We would like a syntax like: + * + * /tmp=/usr/tmp/xxx + * + * where the user can specify a place to graft each component + * of the tree. To do this, we may have to create directories + * along the way, of course. Secondly, I would like to allow + * the user to do something like: + * + * /home/baz/RMAIL=/u3/users/baz/RMAIL + * + * so that normal files could also be injected into the tree + * at an arbitrary point. + * + * The idea is that the last component of whatever is being + * entered would take the name from the last component of + * whatever the user specifies. + * + * The default will be that the file is injected at the root of + * the image tree. + */ + node = findgequal(arg); + if (!use_graft_ptrs) + node = NULL; + /* + * Remove '\\' escape chars which are located + * before '\\' and '=' chars ---> below in escstrcpy() + */ + + short_name = NULL; + + if (node != NULL || reloc_root) { + char *pnt; + char *xpnt; + size_t len; + + /* insert -root prefix */ + if (reloc_root != NULL) { + strlcpy(graft_point, reloc_root, glen); + len = strlen(graft_point); + + if ((len < (glen -1)) && + (len == 0 || graft_point[len-1] != '/')) { + graft_point[len++] = '/'; + graft_point[len] = '\0'; + } + } else { + len = 0; + } + + if (node) { + *node = '\0'; + escstrcpy(&graft_point[len], glen - len, arg); + *node = '='; + } + + /* + * Remove unwanted "./" & "/" sequences from start... + */ + do { + xpnt = graft_point; + while (xpnt[0] == '.' && xpnt[1] == '/') + xpnt += 2; + while (*xpnt == PATH_SEPARATOR) { + xpnt++; + } + /* + * The string becomes shorter, there is no need to check + * the length. Make sure to support overlapping strings. + */ + ovstrcpy(graft_point, xpnt); + } while (xpnt > graft_point); + + if (node) { + node = escstrcpy(nodename, nlen, ++node); + } else { + node = arg; + } + + graft_dir = root; + xpnt = graft_point; + + /* + * If "node" points to a directory, then graft_point + * needs to point to a directory too. + */ + if (follow_links) + status = stat_filter(node, &st); + else + status = lstat_filter(node, &st); + if (status == 0 && S_ISDIR(st.st_mode)) { + len = strlen(graft_point); + + if ((len < (glen -1)) && + (len == 0 || graft_point[len-1] != '/')) { + graft_point[len++] = '/'; + graft_point[len] = '\0'; + } + } + if (debug) + error("GRAFT:'%s'\n", xpnt); + /* + * Loop down deeper and deeper until we find the + * correct insertion spot. + * Canonicalize the filename while parsing it. + */ + for (;;) { + do { + while (xpnt[0] == '.' && xpnt[1] == '/') + xpnt += 2; + while (xpnt[0] == '/') + xpnt += 1; + if (xpnt[0] == '.' && xpnt[1] == '.' && xpnt[2] == '/') { + if (graft_dir && graft_dir != root) { + graft_dir = graft_dir->parent; + xpnt += 2; + } + } + } while ((xpnt[0] == '/') || (xpnt[0] == '.' && xpnt[1] == '/')); + pnt = strchr(xpnt, PATH_SEPARATOR); + if (pnt == NULL) { + if (*xpnt != '\0') { + short_name = xpnt; + if (short_namep) + *short_namep = xpnt; + } + break; + } + *pnt = '\0'; + if (debug) { + error("GRAFT Point:'%s' in '%s : %s' (%s)\n", + xpnt, + graft_dir->whole_name, + graft_dir->de_name, + graft_point); + } + graft_dir = find_or_create_directory(graft_dir, + graft_point, + NULL, TRUE); + *pnt = PATH_SEPARATOR; + xpnt = pnt + 1; + } + } else { + graft_dir = root; + if (use_graft_ptrs) + node = escstrcpy(nodename, nlen, arg); + else + node = arg; + } + + /* + * Now see whether the user wants to add a regular file, or a + * directory at this point. + */ + if (follow_links || Hflag) + status = stat_filter(node, &st); + else + status = lstat_filter(node, &st); + if (status != 0) { + /* + * This is a fatal error - the user won't be getting + * what they want if we were to proceed. + */ + comerr(_("Invalid node - '%s'.\n"), node); + } else { + if (S_ISDIR(st.st_mode)) { + if (debug) { + error(_("graft_dir: '%s : %s', node: '%s', (scan)\n"), + graft_dir->whole_name, + graft_dir->de_name, node); + } + if (!do_insert) + return (graft_dir); + if (!scan_directory_tree(graft_dir, + node, &de)) { + exit(1); + } + if (debug) { + error(_("scan done\n")); + } + } else { + if (short_name == NULL) { + short_name = strrchr(node, + PATH_SEPARATOR); + if (short_name == NULL || + short_name < node) { + short_name = node; + } else { + short_name++; + } + } + if (debug) { + error(_("graft_dir: '%s : %s', node: '%s', short_name: '%s'\n"), + graft_dir->whole_name, + graft_dir->de_name, node, + short_name); + } + if (!do_insert) + return (graft_dir); + if (!insert_file_entry(graft_dir, node, + short_name, NULL, 0)) { + /* + * Should we ignore this? + */ +/* exit(1);*/ + /* EMPTY */ + } + } + } + return (graft_dir); +} + +EXPORT void * +e_malloc(size) + size_t size; +{ + void *pt = 0; + + if (size == 0) + size = 1; + if ((pt = malloc(size)) == NULL) { + comerr(_("Not enough memory\n")); + } + /* + * Not all code is clean yet. + * Filling all allocated data with zeroes will help + * to avoid core dumps. + */ + memset(pt, 0, size); + return (pt); +} + +EXPORT char * +e_strdup(s) + const char *s; +{ + char *ret = strdup(s); + + if (s == NULL) + comerr(_("Not enough memory for strdup(%s)\n"), s); + return (ret); +} + +/* + * A strcpy() that works with overlapping buffers + */ +LOCAL void +ovstrcpy(p2, p1) + register char *p2; + register char *p1; +{ + while ((*p2++ = *p1++) != '\0') + ; +} + +LOCAL void +checkarch(name) + char *name; +{ + struct stat stbuf; + + archive_isreg = FALSE; + archive_dev = (dev_t)0; + archive_ino = (ino_t)0; + + if (name == NULL) + return; + if (stat(name, &stbuf) < 0) + return; + + if (S_ISREG(stbuf.st_mode)) { + archive_dev = stbuf.st_dev; + archive_ino = stbuf.st_ino; + archive_isreg = TRUE; + } else if (((stbuf.st_mode & S_IFMT) == 0) || + S_ISFIFO(stbuf.st_mode) || + S_ISSOCK(stbuf.st_mode)) { + /* + * This is a pipe or similar on different UNIX implementations. + * (stbuf.st_mode & S_IFMT) == 0 may happen in stange cases. + */ + archive_dev = NODEV; + archive_ino = (ino_t)-1; + } +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.h new file mode 100644 index 00000000000..050f0e22d8b --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/mkisofs.h @@ -0,0 +1,873 @@ +/* @(#)mkisofs.h 1.150 16/10/10 joerg */ +/* + * Header file mkisofs.h - assorted structure definitions and typecasts. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2016 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#include /* Must be before stdio.h for LARGEFILE support */ +#include +#include +#include +#include +#include +#include /* Needed for for LARGEFILE support */ +#include +#include +#include +#include +#include +#include +#include /* Define missing prototypes */ +#include "scsi.h" + +#ifdef DVD_AUD_VID +#ifndef UDF +#define UDF +#endif +#endif + +#ifdef USE_LARGEFILES +/* + * XXX Hack until fseeko()/ftello() are available everywhere or until + * XXX we know a secure way to let autoconf ckeck for fseeko()/ftello() + * XXX without defining FILE_OFFSETBITS to 64 in confdefs.h + */ +# define fseek fseeko +# define ftell ftello +#endif + +#ifndef HAVE_LSTAT +#ifndef VMS +#define lstat stat +#endif +#endif + +#include "iso9660.h" +#include "defaults.h" +#include + +extern siconvt_t *in_nls; /* input UNICODE conversion table */ +extern siconvt_t *out_nls; /* output UNICODE conversion table */ +extern siconvt_t *hfs_inls; /* input HFS UNICODE conversion table */ +extern siconvt_t *hfs_onls; /* output HFS UNICODE conversion table */ + +/* + * Structure used to pass arguments via trewalk() to walkfun(). + */ +struct wargs { + void *dir; /* Pointer to struct directory *root */ + char *name; /* NULL or alternative short name */ +}; + +#ifdef APPLE_HYB +#include "mactypes.h" +#include "hfs.h" + +struct hfs_info { + unsigned char finderinfo[32]; + char name[HFS_MAX_FLEN + 1]; + /* should have fields for dates here as well */ + char *keyname; + struct hfs_info *next; +}; + +#endif /* APPLE_HYB */ + +/* + * Our version of "struct timespec". + * Currently only used with UDF. + */ +typedef struct timesp { + time_t tv_sec; + Int32_t tv_nsec; +} timesp; + +struct directory_entry { + struct directory_entry *next; + struct directory_entry *jnext; + struct iso_directory_record isorec; + unsigned int starting_block; + off_t size; + int mxpart; /* Extent number */ + unsigned short priority; + unsigned char jreclen; /* Joliet record len */ + char *name; + char *table; + char *whole_name; + struct directory *filedir; + struct directory_entry *parent_rec; + struct directory_entry *mxroot; /* Pointer to orig entry */ + unsigned int de_flags; +#ifdef UDF + mode_t mode; /* used for udf */ + dev_t rdev; /* used for udf devices */ + uid_t uid; /* used for udf */ + gid_t gid; /* used for udf */ + timesp atime; /* timespec for atime */ + timesp mtime; /* timespec for mtime */ + timesp ctime; /* timespec for ctime */ +#endif + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + unsigned char *rr_attributes; + unsigned int rr_attr_size; + unsigned int total_rr_attr_size; + unsigned int got_rr_name; +#ifdef APPLE_HYB + struct directory_entry *assoc; /* entry has a resource fork */ + hfsdirent *hfs_ent; /* HFS parameters */ + off_t hfs_off; /* offset to real start of fork */ + int hfs_type; /* type of HFS Unix file */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for entry */ +#endif /* SORTING */ +#ifdef UDF + int udf_file_entry_sector; /* also used as UDF unique ID */ +#endif +}; + +struct file_hash { + struct file_hash *next; + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + nlink_t nlink; /* Used to compute new link count */ + unsigned int starting_block; + off_t size; +#ifdef SORTING + struct directory_entry *de; +#endif /* SORTING */ +}; + + +/* + * This structure is used to control the output of fragments to the cdrom + * image. Everything that will be written to the output image will eventually + * go through this structure. There are two pieces - first is the sizing where + * we establish extent numbers for everything, and the second is when we actually + * generate the contents and write it to the output image. + * + * This makes it trivial to extend mkisofs to write special things in the image. + * All you need to do is hook an additional structure in the list, and the rest + * works like magic. + * + * The three passes each do the following: + * + * The 'size' pass determines the size of each component and assigns the extent number + * for that component. + * + * The 'generate' pass will adjust the contents and pointers as required now that extent + * numbers are assigned. In some cases, the contents of the record are also generated. + * + * The 'write' pass actually writes the data to the disc. + */ +struct output_fragment { + struct output_fragment *of_next; + int (*of_size) __PR((UInt32_t)); + int (*of_generate) __PR((void)); + int (*of_write) __PR((FILE *)); + char *of_name; /* Textual description */ + unsigned int of_start_extent; /* For consist check */ +}; + +extern struct output_fragment *out_list; +extern struct output_fragment *out_tail; + +extern struct output_fragment startpad_desc; +extern struct output_fragment voldesc_desc; +extern struct output_fragment xvoldesc_desc; +extern struct output_fragment joliet_desc; +extern struct output_fragment torito_desc; +extern struct output_fragment end_vol; +extern struct output_fragment version_desc; +extern struct output_fragment pathtable_desc; +extern struct output_fragment jpathtable_desc; +extern struct output_fragment dirtree_desc; +extern struct output_fragment dirtree_clean; +extern struct output_fragment jdirtree_desc; +extern struct output_fragment extension_desc; +extern struct output_fragment files_desc; +extern struct output_fragment interpad_desc; +extern struct output_fragment endpad_desc; +extern struct output_fragment sunboot_desc; +extern struct output_fragment sunlabel_desc; +extern struct output_fragment genboot_desc; +extern struct output_fragment strfile_desc; +extern struct output_fragment strdir_desc; +extern struct output_fragment strpath_desc; + +#ifdef APPLE_HYB +extern struct output_fragment hfs_desc; + +#endif /* APPLE_HYB */ +#ifdef DVD_AUD_VID +/* + * This structure holds the information necessary to create a valid + * DVD-Video image. Basically it's how much to pad the files so the + * file offsets described in the video_ts.ifo and vts_xx_0.ifo are + * the correct one in the image that we create. + */ +typedef struct { + int realsize_ifo; + int realsize_menu; + int realsize_bup; + int size_ifo; + int size_menu; + int size_title; + int size_bup; + int pad_ifo; + int pad_menu; + int pad_title; + int pad_bup; + int number_of_vob_files; + int realsize_vob[10]; +} title_set_t; + +typedef struct { + int num_titles; + title_set_t *title_set; +} title_set_info_t; +#endif /* DVD_AUD_VID */ + +/* + * This structure describes one complete directory. It has pointers + * to other directories in the overall tree so that it is clear where + * this directory lives in the tree, and it also must contain pointers + * to the contents of the directory. Note that subdirectories of this + * directory exist twice in this stucture. Once in the subdir chain, + * and again in the contents chain. + */ +struct directory { + struct directory *next; /* Next directory at same level as this one */ + struct directory *subdir; /* First subdirectory in this directory */ + struct directory *parent; + struct directory_entry *contents; + struct directory_entry *jcontents; + struct directory_entry *self; + char *whole_name; /* Entire source path */ + char *de_path; /* Entire path iside ISO-9660 */ + char *de_name; /* Last path name component */ + unsigned int ce_bytes; /* Number of bytes of CE entries read */ + /* for this dir */ + unsigned int depth; + unsigned int size; + unsigned int extent; + unsigned int jsize; + unsigned int jextent; + unsigned int path_index; + unsigned int jpath_index; + unsigned short dir_flags; + unsigned short dir_nlink; +#ifdef APPLE_HYB + hfsdirent *hfs_ent; /* HFS parameters */ + struct hfs_info *hfs_info; /* list of info for all entries in dir */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for child files */ +#endif /* SORTING */ +}; + +struct deferred_write { + struct deferred_write *next; + char *table; + unsigned int extent; + off_t size; + char *name; + struct directory_entry *s_entry; + unsigned int pad; + off_t off; + unsigned int dw_flags; +#ifdef APPLE_HYB + int hfstype; +#endif +}; + +struct eltorito_boot_entry_info { + struct eltorito_boot_entry_info *next; + char *boot_image; + int not_bootable; + int no_emul_boot; + int hard_disk_boot; + int boot_info_table; + int load_size; + int load_addr; + +#define ELTORITO_BOOT_ID 1 +#define ELTORITO_SECTION_HEADER 2 + int type; + /* + * Valid if (type & ELTORITO_BOOT_ID) != 0 + */ + int boot_platform; + +}; + +typedef struct ldate { + time_t l_sec; + int l_usec; + int l_gmtoff; +} ldate; + +extern int goof; +extern struct directory *root; +extern struct directory *reloc_dir; +extern UInt32_t next_extent; +extern UInt32_t last_extent; +extern UInt32_t last_extent_written; +extern UInt32_t session_start; + +extern unsigned int path_table_size; +extern unsigned int path_table[4]; +extern unsigned int path_blocks; +extern char *path_table_l; +extern char *path_table_m; + +extern unsigned int jpath_table_size; +extern unsigned int jpath_table[4]; +extern unsigned int jpath_blocks; +extern char *jpath_table_l; +extern char *jpath_table_m; + +extern struct iso_directory_record root_record; +extern struct iso_directory_record jroot_record; + +extern int check_oldnames; +extern int check_session; +extern int use_eltorito; +extern int hard_disk_boot; +extern int not_bootable; +extern int no_emul_boot; +extern int load_addr; +extern int load_size; +extern int boot_info_table; +extern int use_RockRidge; +extern int osecsize; +extern int use_XA; +extern int use_Joliet; +extern int rationalize; +extern int rationalize_uid; +extern int rationalize_gid; +extern int rationalize_filemode; +extern int rationalize_dirmode; +extern uid_t uid_to_use; +extern gid_t gid_to_use; +extern int filemode_to_use; +extern int dirmode_to_use; +extern int new_dir_mode; +extern int follow_links; +extern int cache_inodes; +extern int verbose; +extern int debug; +extern int gui; +extern int all_files; +extern int generate_tables; +extern int print_size; +extern int split_output; +extern int use_graft_ptrs; +extern int jhide_trans_tbl; +extern int hide_rr_moved; +extern int omit_period; +extern int omit_version_number; +extern int no_rr; +extern int transparent_compression; +extern Uint RR_relocation_depth; +extern int do_largefiles; +extern off_t maxnonlarge; +extern int iso9660_level; +extern int iso9660_namelen; +extern int full_iso9660_filenames; +extern int nolimitpathtables; +extern int relaxed_filenames; +extern int allow_lowercase; +extern int allow_multidot; +extern int iso_translate; +extern int allow_leading_dots; +extern int use_fileversion; +extern int split_SL_component; +extern int split_SL_field; +extern char *trans_tbl; + +#define JMAX 64 /* maximum Joliet file name length (spec) */ +#define JLONGMAX 103 /* out of spec Joliet file name length */ +extern int jlen; /* selected maximum Joliet file name length */ + +#ifdef DVD_AUD_VID + +#define DVD_SPEC_NONE 0x0 +#define DVD_SPEC_VIDEO 0x1 +#define DVD_SPEC_AUDIO 0x2 +#define DVD_SPEC_HYBRD (DVD_SPEC_VIDEO | DVD_SPEC_AUDIO) +extern int dvd_audio; +extern int dvd_hybrid; +extern int dvd_video; +extern int dvd_aud_vid_flag; +#endif /* DVD_AUD_VID */ + + +extern int donotwrite_macpart; + +#ifdef APPLE_HYB +extern int apple_hyb; /* create HFS hybrid */ +extern int apple_ext; /* use Apple extensions */ +extern int apple_both; /* common flag (for above) */ +extern int hfs_extra; /* extra ISO extents (hfs_ce_size) */ +extern hce_mem *hce; /* libhfs/mkisofs extras */ +extern int use_mac_name; /* use Mac name for ISO9660/Joliet/RR */ +extern int create_dt; /* create the Desktp files */ +extern char *hfs_boot_file; /* name of HFS boot file */ +extern char *magic_file; /* magic file for CREATOR/TYPE matching */ +extern int hfs_last; /* order in which to process map/magic files */ +extern char *deftype; /* default Apple TYPE */ +extern char *defcreator; /* default Apple CREATOR */ +extern int gen_pt; /* generate HFS partition table */ +extern char *autoname; /* Autostart filename */ +extern int afe_size; /* Apple File Exchange block size */ +extern char *hfs_volume_id; /* HFS volume ID */ +extern int icon_pos; /* Keep Icon position */ +extern int hfs_lock; /* lock HFS volume (read-only) */ +extern char *hfs_bless; /* name of folder to 'bless' (System Folder) */ +extern char *hfs_parms; /* low level HFS parameters */ + +#define MAP_LAST 1 /* process magic then map file */ +#define MAG_LAST 2 /* process map then magic file */ + +#ifndef PREP_BOOT +#define PREP_BOOT +#endif /* PREP_BOOT */ + +#ifdef PREP_BOOT +extern char *prep_boot_image[4]; +extern int use_prep_boot; +extern int use_chrp_boot; + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +#ifdef SORTING +extern int do_sort; +#endif /* SORTING */ + +/* tree.c */ +extern int stat_filter __PR((char *, struct stat *)); +extern int lstat_filter __PR((char *, struct stat *)); +extern int sort_tree __PR((struct directory *)); +extern void attach_dot_entries __PR((struct directory * dirnode, + struct stat * this_stat, + struct stat * parent_stat)); +extern struct directory * + find_or_create_directory __PR((struct directory *, + char *, + struct directory_entry * self, int)); +extern void finish_cl_pl_entries __PR((void)); +extern int scan_directory_tree __PR((struct directory * this_dir, + char *path, + struct directory_entry * self)); + +extern int insert_file_entry __PR((struct directory *, char *, + char *, struct stat *, int)); + +extern struct directory_entry * + dup_directory_entry __PR((struct directory_entry *s_entry)); +extern void generate_iso9660_directories __PR((struct directory *, FILE *)); +extern void dump_tree __PR((struct directory * node)); +extern struct directory_entry *search_tree_file __PR((struct + directory * node, char *filename)); +extern void init_fstatbuf __PR((void)); +extern struct stat root_statbuf; +extern struct stat fstatbuf; + +/* eltorito.c */ +extern void init_boot_catalog __PR((const char *path)); +extern void insert_boot_cat __PR((void)); +extern void get_boot_entry __PR((void)); +extern int new_boot_entry __PR((void)); +extern void ex_boot_enoent __PR((char *msg, char *pname)); + +/* boot.c */ +extern int sparc_boot_label __PR((char *label)); +extern int sunx86_boot_label __PR((char *label)); +extern int scan_sparc_boot __PR((char *files)); +extern int scan_sunx86_boot __PR((char *files)); +extern int make_sun_label __PR((void)); +extern int make_sunx86_label __PR((void)); + +/* isonum.c */ +extern void set_721 __PR((void *, UInt32_t)); +extern void set_722 __PR((void *, UInt32_t)); +extern void set_723 __PR((void *, UInt32_t)); +extern void set_731 __PR((void *, UInt32_t)); +extern void set_732 __PR((void *, UInt32_t)); +extern void set_733 __PR((void *, UInt32_t)); + +extern UInt32_t get_711 __PR((void *)); +extern UInt32_t get_721 __PR((void *)); +extern UInt32_t get_723 __PR((void *)); +extern UInt32_t get_731 __PR((void *)); +extern UInt32_t get_732 __PR((void *)); +extern UInt32_t get_733 __PR((void *)); + +/* write.c */ +extern int sort_directory __PR((struct directory_entry **, int)); +extern void generate_one_directory __PR((struct directory *, FILE *)); +extern void memcpy_max __PR((char *, char *, int)); +extern int oneblock_size __PR((UInt32_t starting_extent)); +extern struct iso_primary_descriptor vol_desc; +extern void xfwrite __PR((void *buffer, int size, int count, FILE * file, int submode, BOOL islast)); +extern void outputlist_insert __PR((struct output_fragment * frag)); + +#ifdef APPLE_HYB +extern Ulong get_adj_size __PR((int Csize)); +extern int adj_size __PR((int Csize, UInt32_t start_extent, int extra)); +extern void adj_size_other __PR((struct directory * dpnt)); +extern int insert_padding_file __PR((int size)); +extern int gen_mac_label __PR((struct deferred_write *)); + +#ifdef PREP_BOOT +extern void gen_prepboot_label __PR((unsigned char *)); + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +/* multi.c */ + +extern FILE *in_image; +extern BOOL ignerr; +extern int open_merge_image __PR((char *path)); +extern int close_merge_image __PR((void)); +extern struct iso_directory_record * + merge_isofs __PR((char *path)); +extern unsigned char *parse_xa __PR((unsigned char *pnt, int *lenp, + struct directory_entry * dpnt)); +extern int rr_flags __PR((struct iso_directory_record *idr)); +extern int merge_previous_session __PR((struct directory *, + struct iso_directory_record *, char *, char *)); +extern int get_session_start __PR((int *)); + +/* joliet.c */ +#ifdef UDF +extern void convert_to_unicode __PR((unsigned char *buffer, + int size, char *source, siconvt_t *inls)); +extern int joliet_strlen __PR((const char *string, size_t maxlen, + siconvt_t *inls)); +#endif +extern void conv_charset __PR((unsigned char *to, size_t *tosizep, + unsigned char *from, size_t *fromsizep, + siconvt_t *, + siconvt_t *)); +extern int joliet_sort_tree __PR((struct directory * node)); + +/* match.c */ +extern int matches __PR((char *)); +extern int add_match __PR((char *)); + +/* files.c */ +struct dirent *readdir_add_files __PR((char **, char *, DIR *)); + +/* name.c */ + +extern void iso9660_check __PR((struct iso_directory_record *idr, struct directory_entry *ndr)); +extern int iso9660_file_length __PR((const char *name, + struct directory_entry * sresult, int flag)); + +/* various */ +extern int iso9660_date __PR((char *, time_t)); +extern int iso9660_ldate __PR((char *, time_t, int, int)); +extern void add_hash __PR((struct directory_entry *)); +extern struct file_hash *find_hash __PR((dev_t, ino_t)); + +extern void flush_hash __PR((void)); +extern void add_directory_hash __PR((dev_t, ino_t)); +extern struct file_hash *find_directory_hash __PR((dev_t, ino_t)); +extern void flush_file_hash __PR((void)); +extern int delete_file_hash __PR((struct directory_entry *)); +extern struct directory_entry *find_file_hash __PR((char *)); +extern void add_file_hash __PR((struct directory_entry *)); + +extern int generate_xa_rr_attributes __PR((char *, char *, + struct directory_entry *, + struct stat *, struct stat *, + int deep_flag)); +extern char *generate_rr_extension_record __PR((char *id, + char *descriptor, + char *source, int *size)); + +extern int check_prev_session __PR((struct directory_entry **, int len, + struct directory_entry *, + struct stat *, + struct stat *, + struct directory_entry **)); + +extern void match_cl_re_entries __PR((void)); +extern void finish_cl_pl_for_prev_session __PR((void)); +extern char *find_rr_attribute __PR((unsigned char *pnt, int len, char *attr_type)); + +extern void udf_set_extattr_macresfork __PR((unsigned char *buf, off_t size, unsigned rba)); +extern void udf_set_extattr_freespace __PR((unsigned char *buf, off_t size, unsigned rba)); +extern int udf_get_symlinkcontents __PR((char *, char *, off_t *)); + +/* inode.c */ +extern void do_inode __PR((struct directory *dpnt)); +extern void do_dir_nlink __PR((struct directory *dpnt)); + +#ifdef APPLE_HYB +/* volume.c */ +extern int make_mac_volume __PR((struct directory * dpnt, UInt32_t start_extent)); +extern int write_fork __PR((hfsfile * hfp, long tot)); + +/* apple.c */ + +extern void del_hfs_info __PR((struct hfs_info *)); +extern int get_hfs_dir __PR((char *, char *, struct directory_entry *)); +extern int get_hfs_info __PR((char *, char *, struct directory_entry *)); +extern int get_hfs_rname __PR((char *, char *, char *)); +extern int hfs_exclude __PR((char *)); +extern void print_hfs_info __PR((struct directory_entry *)); +extern void hfs_init __PR((char *, unsigned short, unsigned int)); +extern void delete_rsrc_ent __PR((struct directory_entry *)); +extern void clean_hfs __PR((void)); +extern void perr __PR((char *)); +extern void set_root_info __PR((char *)); +extern int file_is_resource __PR((char *fname, int hfstype)); +extern int hfs_excludepath __PR((char *)); + +/* desktop.c */ + +extern int make_desktop __PR((hfsvol *, int)); + +/* mac_label.c */ + +#ifdef _MAC_LABEL_H +#ifdef PREP_BOOT +extern void gen_prepboot_label __PR((MacLabel * mac_label)); +#endif +extern int gen_mac_label __PR((defer *)); +#endif +extern int autostart __PR((void)); + +/* libfile */ + +extern char *get_magic_match __PR((const char *)); +extern void clean_magic __PR((void)); + +#endif /* APPLE_HYB */ + +#ifdef USE_FIND +/* + * The callback function for treewalk() from walk.c + */ +#ifdef _SCHILY_WALK_H +EXPORT int walkfunc __PR((char *nm, struct stat *fs, int type, + struct WALK *state)); +#endif +#endif + +extern char *extension_record; +extern UInt32_t extension_record_extent; +/*extern int n_data_extents;*/ +extern BOOL archive_isreg; +extern dev_t archive_dev; +extern ino_t archive_ino; + +/* + * These are a few goodies that can be specified on the command line, and are + * filled into the root record + */ +extern char *preparer; +extern char *publisher; +extern char *copyright; +extern char *biblio; +extern char *abstract; +extern char *appid; +extern char *volset_id; +extern char *system_id; +extern char *volume_id; +extern char *boot_catalog; +extern char *boot_image; +extern char *genboot_image; +extern int ucs_level; +extern int volume_set_size; +extern int volume_sequence_number; + +extern struct eltorito_boot_entry_info *first_boot_entry; +extern struct eltorito_boot_entry_info *last_boot_entry; +extern struct eltorito_boot_entry_info *current_boot_entry; + +extern UInt32_t null_inodes; +extern BOOL correct_inodes; +extern BOOL rrip112; +extern BOOL long_rr_time; /* TRUE: use long (17 Byte) time format */ + +extern char *findgequal __PR((char *)); +extern void *e_malloc __PR((size_t)); +extern char *e_strdup __PR((const char *)); + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define ROUND_UP(X, Y) (((X + (Y - 1)) / Y) * Y) + +#ifdef APPLE_HYB +/* + * ISO blocks == 2048, HFS blocks == 512 + */ +#define HFS_BLK_CONV (SECTOR_SIZE/HFS_BLOCKSZ) + +#define HFS_ROUND_UP(X) ISO_ROUND_UP(((X)*HFS_BLOCKSZ)) /* XXX ??? */ +#define HFS_BLOCKS(X) (ISO_BLOCKS(X) * HFS_BLK_CONV) + +#define USE_MAC_NAME(E) (use_mac_name && ((E)->hfs_ent != NULL) && (E)->hfs_type) +#endif /* APPLE_HYB */ + +/* + * Inode and device values for special purposes. + */ +#define PREV_SESS_DEV ((dev_t)-2) +#define TABLE_INODE ((ino_t)-2) +#define UNCACHED_INODE ((ino_t)-1) +#define UNCACHED_DEVICE ((dev_t)-1) + +/* + * The highest value used for the inodes we assign to files that do not have + * a starting block address (zero length files, symlinks, dev nodes, pipes, + * socket). + * We need to make sure that these numbers are valid ISO-9660 block addresses, + * this is why we use unsigned 32-bit integer values. + * We need to make sure that the inode numbers assigned for zero sized files + * is in a proper range, this is why we use numbers above the range of block + * addresses we use in the image. We start counting backwards from 0xFFFFFFF0 + * to leave enough space for special numbers from the range listed above. + */ +#define NULL_INO_MAX ((UInt32_t)0xFFFFFFF0) + +#ifdef VMS +#define STAT_INODE(X) (X.st_ino[0]) +#define PATH_SEPARATOR ']' +#define SPATH_SEPARATOR "" +#else +#define STAT_INODE(X) (X.st_ino) +#define PATH_SEPARATOR '/' +#define SPATH_SEPARATOR "/" +#endif + +/* + * When using multi-session, indicates that we can reuse the + * TRANS.TBL information for this directory entry. If this flag + * is set for all entries in a directory, it means we can just + * reuse the TRANS.TBL and not generate a new one. + */ +#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 /* de_flags only */ +#define DIR_HAS_DOT 0x02 /* dir_flags only */ +#define DIR_HAS_DOTDOT 0x04 /* dir_flags only */ +#define INHIBIT_JOLIET_ENTRY 0x08 +#define INHIBIT_RR_ENTRY 0x10 /* not used */ +#define RELOCATED_DIRECTORY 0x20 /* de_flags only */ +#define INHIBIT_ISO9660_ENTRY 0x40 +#define MEMORY_FILE 0x80 /* de_flags only */ +#define HIDDEN_FILE 0x100 /* de_flags only */ +#define DIR_WAS_SCANNED 0x200 /* dir_flags only */ +#define RESOURCE_FORK 0x400 /* de_flags only */ +#define IS_SYMLINK 0x800 /* de_flags only */ +#define MULTI_EXTENT 0x1000 /* de_flags only */ +#define INHIBIT_UDF_ENTRY 0x2000 + +/* + * Volume sequence number to use in all of the iso directory records. + */ +#define DEF_VSN 1 + +/* + * Make sure we have a definition for this. If not, take a very conservative + * guess. + * POSIX requires the max pathname component lenght to be defined in limits.h + * If variable, it may be undefined. If undefined, there should be + * a definition for _POSIX_NAME_MAX in limits.h or in unistd.h + * As _POSIX_NAME_MAX is defined to 14, we cannot use it. + * XXX Eric's wrong comment: + * XXX From what I can tell SunOS is the only one with this trouble. + */ +#include + +#ifndef NAME_MAX +#ifdef FILENAME_MAX +#define NAME_MAX FILENAME_MAX +#else +#define NAME_MAX 256 +#endif +#endif + +#ifndef PATH_MAX +#ifdef FILENAME_MAX +#define PATH_MAX FILENAME_MAX +#else +#define PATH_MAX 1024 +#endif +#endif + +/* + * Cygwin seems to have PATH_MAX == 260 which is less than the usable + * path length. We raise PATH_MAX to at least 1024 for now for all platforms + * unless someone reports problems with mkisofs memory size. + */ +#if PATH_MAX < 1024 +#undef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#ifdef UDF +extern int use_udf; +#endif +extern int create_udfsymlinks; + +#if !defined(HAVE_MEMSET) && !defined(memset) +#define memset(s, c, n) fillbytes(s, n, c) +#endif +#if !defined(HAVE_MEMCHR) && !defined(memchr) +#define memchr(s, c, n) findbytes(s, n, c) +#endif +#if !defined(HAVE_MEMCPY) && !defined(memcpy) +#define memcpy(s1, s2, n) movebytes(s2, s1, n) +#endif +#if !defined(HAVE_MEMMOVE) && !defined(memmove) +#define memmove(s1, s2, n) movebytes(s2, s1, n) +#endif diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/multi.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/multi.c new file mode 100644 index 00000000000..ddd04548876 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/multi.c @@ -0,0 +1,2234 @@ +/* @(#)multi.c 1.104 16/01/06 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)multi.c 1.104 16/01/06 joerg"; +#endif +/* + * File multi.c - scan existing iso9660 image and merge into + * iso9660 filesystem. Used for multisession support. + * + * Written by Eric Youngdale (1996). + * Copyright (c) 1999-2016 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "mkisofs.h" +#include "rock.h" +#include +#include +#include +#include +#include /* Needed for printasc() */ + +#ifdef VMS + +#include +#include +#include "vms.h" +#endif + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +/* + * Cannot debug memset() with gdb on Linux, so use fillbytes() + */ +/*#define memset(s, c, n) fillbytes(s, n, c)*/ + +#define TF_CREATE 1 +#define TF_MODIFY 2 +#define TF_ACCESS 4 +#define TF_ATTRIBUTES 8 + +LOCAL void printasc __PR((char *txt, unsigned char *p, int len)); +LOCAL void prbytes __PR((char *txt, unsigned char *p, int len)); +unsigned char *parse_xa __PR((unsigned char *pnt, int *lenp, + struct directory_entry *dpnt)); +EXPORT int rr_flags __PR((struct iso_directory_record *idr)); +LOCAL int parse_rrflags __PR((Uchar *pnt, int len, int cont_flag)); +LOCAL BOOL find_rr __PR((struct iso_directory_record *idr, Uchar **pntp, int *lenp)); +LOCAL int parse_rr __PR((unsigned char *pnt, int len, + struct directory_entry *dpnt)); +LOCAL int check_rr_dates __PR((struct directory_entry *dpnt, + struct directory_entry *current, + struct stat *statbuf, + struct stat *lstatbuf)); +LOCAL BOOL valid_iso_directory __PR((struct iso_directory_record *idr, + int idr_off, + size_t space_left)); +LOCAL struct directory_entry ** + read_merging_directory __PR((struct iso_directory_record *, int *)); +LOCAL int free_mdinfo __PR((struct directory_entry **, int len)); +LOCAL void free_directory_entry __PR((struct directory_entry *dirp)); +LOCAL int iso_dir_ents __PR((struct directory_entry *de)); +LOCAL void copy_mult_extent __PR((struct directory_entry *se1, + struct directory_entry *se2)); +LOCAL void merge_remaining_entries __PR((struct directory *, + struct directory_entry **, int)); + +LOCAL int merge_old_directory_into_tree __PR((struct directory_entry *, + struct directory *)); +LOCAL void check_rr_relocation __PR((struct directory_entry *de)); + +FILE *in_image = NULL; +BOOL ignerr = FALSE; +int su_version = -1; +int rr_version = -1; +int aa_version = -1; +char er_id[256]; + +#ifndef USE_SCG +/* + * Don't define readsecs if mkisofs is linked with + * the SCSI library. + * readsecs() will be implemented as SCSI command in this case. + * + * Use global var in_image directly in readsecs() + * the SCSI equivalent will not use a FILE* for I/O. + * + * The main point of this pointless abstraction is that Solaris won't let + * you read 2K sectors from the cdrom driver. The fact that 99.9% of the + * discs out there have a 2K sectorsize doesn't seem to matter that much. + * Anyways, this allows the use of a scsi-generics type of interface on + * Solaris. + */ +#ifdef PROTOTYPES +EXPORT int +readsecs(UInt32_t startsecno, void *buffer, int sectorcount) +#else +EXPORT int +readsecs(startsecno, buffer, sectorcount) + UInt32_t startsecno; + void *buffer; + int sectorcount; +#endif +{ + int f = fileno(in_image); + + if (lseek(f, (off_t)startsecno * SECTOR_SIZE, SEEK_SET) == (off_t)-1) { + comerr(_("Seek error on old image\n")); + } + if (read(f, buffer, (sectorcount * SECTOR_SIZE)) + != (sectorcount * SECTOR_SIZE)) { + comerr(_("Read error on old image\n")); + } + return (sectorcount * SECTOR_SIZE); +} + +#endif + +LOCAL void +printasc(txt, p, len) + char *txt; + unsigned char *p; + int len; +{ + int i; + + error("%s ", txt); + for (i = 0; i < len; i++) { + if (isprint(p[i])) + error("%c", p[i]); + else + error("."); + } + error("\n"); +} + +LOCAL void +prbytes(txt, p, len) + char *txt; + register Uchar *p; + register int len; +{ + error("%s", txt); + while (--len >= 0) + error(" %02X", *p++); + error("\n"); +} + +unsigned char * +parse_xa(pnt, lenp, dpnt) + unsigned char *pnt; + int *lenp; + struct directory_entry *dpnt; +{ + struct iso_xa_dir_record *xadp; + int len = *lenp; +static int did_xa = 0; + +/*error("len: %d\n", len);*/ + + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + +/* if (dpnt) prbytes("XA ", pnt, len);*/ + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + *lenp = len; + if (!did_xa) { + did_xa = 1; + errmsgno(EX_BAD, _("Found XA directory extension record.\n")); + } + } else if (pnt[2] == 0) { + char *cp = NULL; + + if (dpnt) + cp = (char *)&dpnt->isorec; + if (cp) { + prbytes("ISOREC:", (Uchar *)cp, 33+cp[32]); + printasc("ISOREC:", (Uchar *)cp, 33+cp[32]); + prbytes("XA REC:", pnt, len); + printasc("XA REC:", pnt, len); + } + if (no_rr == 0) { + errmsgno(EX_BAD, _("Disabling RR / XA / AA.\n")); + no_rr = 1; + } + *lenp = 0; + if (cp) { + errmsgno(EX_BAD, _("Problems with old ISO directory entry for file: '%s'.\n"), &cp[33]); + } + errmsgno(EX_BAD, _("Illegal extended directory attributes found (bad XA disk?).\n")); +/* errmsgno(EX_BAD, _("Disabling Rock Ridge for old session.\n"));*/ + comerrno(EX_BAD, _("Try again using the -no-rr option.\n")); + } + } + if (len >= 4 && pnt[3] != 1 && pnt[3] != 2) { + prbytes("BAD RR ATTRIBUTES:", pnt, len); + printasc("BAD RR ATTRIBUTES:", pnt, len); + } + return (pnt); +} + +LOCAL BOOL +find_rr(idr, pntp, lenp) + struct iso_directory_record *idr; + Uchar **pntp; + int *lenp; +{ + struct iso_xa_dir_record *xadp; + int len; + unsigned char *pnt; + BOOL ret = FALSE; + + len = idr->length[0] & 0xff; + len -= sizeof (struct iso_directory_record); + len += sizeof (idr->name); + len -= idr->name_len[0]; + + pnt = (unsigned char *) idr; + pnt += sizeof (struct iso_directory_record); + pnt -= sizeof (idr->name); + pnt += idr->name_len[0]; + if ((idr->name_len[0] & 1) == 0) { + pnt++; + len--; + } + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + ret = TRUE; + } + } + *pntp = pnt; + *lenp = len; + return (ret); +} + +LOCAL int +parse_rrflags(pnt, len, cont_flag) + Uchar *pnt; + int len; + int cont_flag; +{ + int ncount; + UInt32_t cont_extent; + UInt32_t cont_offset; + UInt32_t cont_size; + int flag1; + int flag2; + + cont_extent = cont_offset = cont_size = 0; + + ncount = 0; + flag1 = -1; + flag2 = 0; + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + return (0); /* JS ??? Is this right ??? */ + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + return (0); /* JS ??? Is this right ??? */ + } + ncount++; + if (pnt[0] == 'R' && pnt[1] == 'R') + flag1 = pnt[4] & 0xff; + + if (strncmp((char *)pnt, "PX", 2) == 0) /* POSIX attributes */ + flag2 |= RR_FLAG_PX; + if (strncmp((char *)pnt, "PN", 2) == 0) /* POSIX device number */ + flag2 |= RR_FLAG_PN; + if (strncmp((char *)pnt, "SL", 2) == 0) /* Symlink */ + flag2 |= RR_FLAG_SL; + if (strncmp((char *)pnt, "NM", 2) == 0) /* Alternate Name */ + flag2 |= RR_FLAG_NM; + if (strncmp((char *)pnt, "CL", 2) == 0) /* Child link */ + flag2 |= RR_FLAG_CL; + if (strncmp((char *)pnt, "PL", 2) == 0) /* Parent link */ + flag2 |= RR_FLAG_PL; + if (strncmp((char *)pnt, "RE", 2) == 0) /* Relocated Direcotry */ + flag2 |= RR_FLAG_RE; + if (strncmp((char *)pnt, "TF", 2) == 0) /* Time stamp */ + flag2 |= RR_FLAG_TF; + if (strncmp((char *)pnt, "SP", 2) == 0) { /* SUSP record */ + flag2 |= RR_FLAG_SP; + if (su_version < 0) + su_version = pnt[3] & 0xff; + } + if (strncmp((char *)pnt, "AA", 2) == 0) { /* Apple Signature record */ + flag2 |= RR_FLAG_AA; + if (aa_version < 0) + aa_version = pnt[3] & 0xff; + } + if (strncmp((char *)pnt, "ER", 2) == 0) { + flag2 |= RR_FLAG_ER; /* ER record */ + if (rr_version < 0) + rr_version = pnt[7] & 0xff; /* Ext Version */ + strlcpy(er_id, (char *)&pnt[8], (pnt[4] & 0xFF) + 1); + } + + if (strncmp((char *)pnt, "CE", 2) == 0) { /* Continuation Area */ + cont_extent = get_733(pnt+4); + cont_offset = get_733(pnt+12); + cont_size = get_733(pnt+20); + } + if (strncmp((char *)pnt, "ST", 2) == 0) { /* Terminate SUSP */ + break; + } + + len -= pnt[2]; + pnt += pnt[2]; + } + if (cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + flag2 |= parse_rrflags(§or[cont_offset], cont_size, 1); + } + return (flag2); +} + +int +rr_flags(idr) + struct iso_directory_record *idr; +{ + int len; + unsigned char *pnt; + int ret = 0; + + if (find_rr(idr, &pnt, &len)) + ret |= RR_FLAG_XA; + ret |= parse_rrflags(pnt, len, 0); + return (ret); +} + +/* + * Parse the RR attributes so we can find the file name. + */ +LOCAL int +parse_rr(pnt, len, dpnt) + unsigned char *pnt; + int len; + struct directory_entry *dpnt; +{ + UInt32_t cont_extent; + UInt32_t cont_offset; + UInt32_t cont_size; + char name_buf[256]; + + cont_extent = cont_offset = cont_size = 0; + + pnt = parse_xa(pnt, &len, dpnt /* 0 */); + + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + return (-1); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + return (-1); + } + if (strncmp((char *)pnt, "NM", 2) == 0) { + strncpy(name_buf, (char *)pnt + 5, pnt[2] - 5); + name_buf[pnt[2] - 5] = 0; + if (dpnt->name) { + size_t nlen = strlen(dpnt->name); + + /* + * append to name from previous NM records + */ + dpnt->name = realloc(dpnt->name, nlen + + strlen(name_buf) + 1); + strcpy(dpnt->name + nlen, name_buf); + } else { + dpnt->name = e_strdup(name_buf); + dpnt->got_rr_name = 1; + } + /* continue searching for more NM records */ + } else if (strncmp((char *)pnt, "CE", 2) == 0) { + cont_extent = get_733(pnt + 4); + cont_offset = get_733(pnt + 12); + cont_size = get_733(pnt + 20); + } else if (strncmp((char *)pnt, "ST", 2) == 0) { + break; + } + + len -= pnt[2]; + pnt += pnt[2]; + } + if (cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + if (parse_rr(§or[cont_offset], cont_size, dpnt) == -1) + return (-1); + } + + /* Fall back to the iso name if no RR name found */ + if (dpnt->name == NULL) { + char *cp; + + strlcpy(name_buf, dpnt->isorec.name, sizeof (name_buf)); + cp = strchr(name_buf, ';'); + if (cp != NULL) { + *cp = '\0'; + } + dpnt->name = e_strdup(name_buf); + } + return (0); +} /* parse_rr */ + + +/* + * Returns 1 if the two files are identical + * Returns 0 if the two files differ + */ +LOCAL int +check_rr_dates(dpnt, current, statbuf, lstatbuf) + struct directory_entry *dpnt; + struct directory_entry *current; + struct stat *statbuf; + struct stat *lstatbuf; +{ + UInt32_t cont_extent; + UInt32_t cont_offset; + UInt32_t cont_size; + UInt32_t offset; + unsigned char *pnt; + int len; + int same_file; + int same_file_type; + mode_t mode; + char time_buf[7]; + + + cont_extent = cont_offset = cont_size = 0; + same_file = 1; + same_file_type = 1; + + pnt = dpnt->rr_attributes; + len = dpnt->rr_attr_size; + /* + * We basically need to parse the rr attributes again, and dig out the + * dates and file types. + */ + pnt = parse_xa(pnt, &len, /* dpnt */ 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + return (-1); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + return (-1); + } + + /* + * If we have POSIX file modes, make sure that the file type is + * the same. If it isn't, then we must always write the new + * file. + */ + if (strncmp((char *)pnt, "PX", 2) == 0) { + mode = get_733(pnt + 4); + if ((lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT)) { + same_file_type = 0; + same_file = 0; + } + } + if (strncmp((char *)pnt, "TF", 2) == 0) { + offset = 5; + if (pnt[4] & TF_CREATE) { + iso9660_date((char *)time_buf, + lstatbuf->st_ctime); + if (memcmp(time_buf, pnt + offset, 7) != 0) + same_file = 0; + offset += 7; + } + if (pnt[4] & TF_MODIFY) { + iso9660_date((char *)time_buf, + lstatbuf->st_mtime); + if (memcmp(time_buf, pnt + offset, 7) != 0) + same_file = 0; + offset += 7; + } + } + if (strncmp((char *)pnt, "CE", 2) == 0) { + cont_extent = get_733(pnt + 4); + cont_offset = get_733(pnt + 12); + cont_size = get_733(pnt + 20); + } + if (strncmp((char *)pnt, "ST", 2) == 0) { /* Terminate SUSP */ + break; + } + + len -= pnt[2]; + pnt += pnt[2]; + } + if (cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + /* + * Continue to scan the extension record. + * Note that this has not been tested yet, but it is + * definitely more correct that calling parse_rr() + * as done in Eric's old code. + */ + pnt = §or[cont_offset]; + len = cont_size; + /* + * Clear the "pending extension record" state as + * we did already read it now. + */ + cont_extent = cont_offset = cont_size = 0; + } + + /* + * If we have the same fundamental file type, then it is clearly safe + * to reuse the TRANS.TBL entry. + */ + if (same_file_type) { + current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + } + return (same_file); +} + +LOCAL BOOL +valid_iso_directory(idr, idr_off, space_left) + struct iso_directory_record *idr; + int idr_off; + size_t space_left; +{ + size_t idr_length = idr->length[0] & 0xFF; + size_t idr_ext_length = idr->ext_attr_length[0] & 0xFF; + size_t idr_namelength = idr->name_len[0] & 0xFF; + int namelimit = space_left - + offsetof(struct iso_directory_record, name[0]); + int nlimit = (idr_namelength < namelimit) ? + idr_namelength : namelimit; + + /* + * Check for sane length entries. + */ + if (idr_length > space_left) { + comerrno(EX_BAD, + _("Bad directory length %zu (> %d available) for '%.*s'.\n"), + idr_length, namelimit, nlimit, idr->name); + } + + if (idr_length == 0) { + if ((idr_off % SECTOR_SIZE) != 0) { + /* + * It marks a valid continuation entry. + */ + return (TRUE); + } else { + comerrno(EX_BAD, + _("Zero directory length for '%.*s'.\n"), + nlimit, idr->name); + } + } + if (idr_length <= offsetof(struct iso_directory_record, name[0])) { + comerrno(EX_BAD, _("Bad directory length %zu (< %zu minimum).\n"), + idr_length, 1 + offsetof(struct iso_directory_record, name[0])); + } + if ((idr_length & 1) != 0) { + comerrno(EX_BAD, _("Odd directory length %zu for '%.*s'.\n"), + idr_length, nlimit, idr->name); + } + + if (idr_namelength == 0) { + comerrno(EX_BAD, _("Zero filename length.\n")); + } + + if (!(idr_namelength & 1)) { + /* + * if nam_len[0] is even, there has to be a pad byte at the end + * to make the directory length even + */ + idr_namelength++; + } + if ((offsetof(struct iso_directory_record, name[0]) + + idr_namelength) > idr_length) { + int xlimit = idr_length - + offsetof(struct iso_directory_record, name[0]) - + idr_ext_length; + + if (xlimit < 0) + xlimit = 0; + if (nlimit < xlimit) + xlimit = nlimit; + comerrno(EX_BAD, _("Bad filename length %zu (> %d) for '%.*s'.\n"), + idr_namelength, xlimit, xlimit, idr->name); + } + if ((offsetof(struct iso_directory_record, name[0]) + + idr_namelength + idr_ext_length) > idr_length) { + int xlimit = idr_length - + offsetof(struct iso_directory_record, name[0]) - + idr_namelength; + + comerrno(EX_BAD, _("Bad extended attribute length %zu (> %d) for '%.*s'.\n"), + idr_ext_length, xlimit, nlimit, idr->name); + } + +#ifdef __do_rr_ + /* check for rock ridge extensions */ + + if (no_rr) { + /* + * Rock Ridge extensions are not present or manually disabled. + */ + return (TRUE); + } else { + int rlen = idr_length - + offsetof(struct iso_directory_record, name[0]) - + idr_namelength; + + /* Check for the minimum of Rock Ridge extensions. */ + } +#endif + return (TRUE); +} + +LOCAL struct directory_entry ** +read_merging_directory(mrootp, nentp) + struct iso_directory_record *mrootp; + int *nentp; +{ + unsigned char *cpnt; + unsigned char *cpnt1; + char *p; + char *dirbuff; + int i; + struct iso_directory_record *idr; + UInt32_t len; + UInt32_t nbytes; + int nent; + int nmult; /* # of multi extent root entries */ + int mx; + struct directory_entry **pnt; + UInt32_t rlen; + struct directory_entry **rtn; + int seen_rockridge; + unsigned char *tt_buf; + UInt32_t tt_extent; + UInt32_t tt_size; + + static int warning_given = 0; + + /* + * This is the number of sectors we will need to read. We need to + * round up to get the last fractional sector - we are asking for the + * data in terms of a number of sectors. + */ + nbytes = roundup(get_733(mrootp->size), SECTOR_SIZE); + + /* + * First, allocate a buffer large enough to read in the entire + * directory. + */ + dirbuff = (char *)e_malloc(nbytes); + + readsecs(get_733(mrootp->extent), dirbuff, nbytes / SECTOR_SIZE); + + /* + * Next look over the directory, and count up how many entries we have. + */ + len = get_733(mrootp->size); + i = 0; + *nentp = 0; + nent = 0; + nmult = 0; + mx = 0; + while ((i + offsetof(struct iso_directory_record, name[0])) < len) { + idr = (struct iso_directory_record *)&dirbuff[i]; + + if (!valid_iso_directory(idr, i, len - i)) + break; + + if (idr->length[0] == 0) { + i = ISO_ROUND_UP(i); + continue; + } + nent++; + if ((mx & ISO_MULTIEXTENT) == 0 && + (idr->flags[0] & ISO_MULTIEXTENT) != 0) { + nmult++; /* Need a multi extent root entry */ + } + mx = idr->flags[0]; + i += idr->length[0]; + } + + /* + * Now allocate the buffer which will hold the array we are about to + * return. We need one entry per real directory entry and in addition + * one multi-extent root entry per multi-extent file. + */ + rtn = (struct directory_entry **)e_malloc((nent+nmult) * sizeof (*rtn)); + + /* + * Finally, scan the directory one last time, and pick out the relevant + * bits of information, and store it in the relevant bits of the + * structure. + */ + i = 0; + pnt = rtn; + tt_extent = 0; + seen_rockridge = 0; + tt_size = 0; + mx = 0; + while ((i + offsetof(struct iso_directory_record, name[0])) < len) { + idr = (struct iso_directory_record *)&dirbuff[i]; + + if (!valid_iso_directory(idr, i, len - i)) + break; + + if (idr->length[0] == 0) { + i = ISO_ROUND_UP(i); + continue; + } + *pnt = (struct directory_entry *)e_malloc(sizeof (**rtn)); + (*pnt)->next = NULL; +#ifdef DEBUG + error("IDR name: '%s' ist: %d soll: %d\n", + idr->name, strlen(idr->name), idr->name_len[0]); +#endif + movebytes(idr, &(*pnt)->isorec, idr->length[0] & 0xFF); + (*pnt)->starting_block = + get_733(idr->extent); + (*pnt)->size = get_733(idr->size); + if ((*pnt)->size == 0) { + /* + * Find lowest used inode number for zero sized files + */ + if (((UInt32_t)(*pnt)->starting_block) <= null_inodes) { + null_inodes = (UInt32_t)(*pnt)->starting_block; + null_inodes--; + } + } + (*pnt)->priority = 0; + (*pnt)->name = NULL; + (*pnt)->got_rr_name = 0; + (*pnt)->table = NULL; + (*pnt)->whole_name = NULL; + (*pnt)->filedir = NULL; + (*pnt)->parent_rec = NULL; + /* + * Set this information so that we correctly cache previous + * session bits of information. + */ + (*pnt)->inode = (*pnt)->starting_block; + (*pnt)->dev = PREV_SESS_DEV; + (*pnt)->rr_attributes = NULL; + (*pnt)->rr_attr_size = 0; + (*pnt)->total_rr_attr_size = 0; + (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; +#ifdef APPLE_HYB + (*pnt)->assoc = NULL; + (*pnt)->hfs_ent = NULL; +#endif /* APPLE_HYB */ + + /* + * Check for and parse any RR attributes for the file. All we + * are really looking for here is the original name of the + * file. + */ + rlen = idr->length[0] & 0xff; + cpnt = (unsigned char *) idr; + + rlen -= offsetof(struct iso_directory_record, name[0]); + cpnt += offsetof(struct iso_directory_record, name[0]); + + rlen -= idr->name_len[0]; + cpnt += idr->name_len[0]; + + if ((idr->name_len[0] & 1) == 0) { + cpnt++; + rlen--; + } + + if (no_rr) + rlen = 0; + if (rlen > 0) { + (*pnt)->total_rr_attr_size = + (*pnt)->rr_attr_size = rlen; + (*pnt)->rr_attributes = e_malloc(rlen); + memcpy((*pnt)->rr_attributes, cpnt, rlen); + seen_rockridge = 1; + } +#ifdef DEBUG + error("INT name: '%s' ist: %d soll: %d\n", + (*pnt)->isorec.name, strlen((*pnt)->isorec.name), + idr->name_len[0]); +#endif + + if (idr->name_len[0] < sizeof ((*pnt)->isorec.name)) { + /* + * Now zero out the remainder of the name field. + */ + cpnt = (unsigned char *) (*pnt)->isorec.name; + cpnt += idr->name_len[0]; + memset(cpnt, 0, + sizeof ((*pnt)->isorec.name) - idr->name_len[0]); + } else { + /* + * Simple sanity work to make sure that we have no + * illegal data structures in our tree. + */ + (*pnt)->isorec.name[MAX_ISONAME] = '\0'; + (*pnt)->isorec.name_len[0] = MAX_ISONAME; + } + /* + * If the filename len from the old session is more + * then 31 chars, there is a high risk of hard violations + * of the ISO9660 standard. + * Run it through our name canonication machine.... + */ + if (idr->name_len[0] > LEN_ISONAME || check_oldnames) { + iso9660_check(idr, *pnt); + } + + if (parse_rr((*pnt)->rr_attributes, rlen, *pnt) == -1) { + comerrno(EX_BAD, + _("Cannot parse Rock Ridge attributes for '%s'.\n"), + idr->name); + } + if (((*pnt)->isorec.name_len[0] == 1) && + (((*pnt)->isorec.name[0] == 0) || /* "." entry */ + ((*pnt)->isorec.name[0] == 1))) { /* ".." entry */ + + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + if ((*pnt)->whole_name != NULL) { + free((*pnt)->whole_name); + } + if ((*pnt)->isorec.name[0] == 0) { + (*pnt)->name = e_strdup("."); + } else { + (*pnt)->name = e_strdup(".."); + } + } +#ifdef DEBUG + fprintf(stderr, "got DE name: %s\n", (*pnt)->name); +#endif + + if (strncmp(idr->name, trans_tbl, strlen(trans_tbl)) == 0) { + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + if ((*pnt)->whole_name != NULL) { + free((*pnt)->whole_name); + } +/* (*pnt)->name = e_strdup("");*/ + (*pnt)->name = e_strdup(trans_tbl); + tt_extent = get_733(idr->extent); + tt_size = get_733(idr->size); + if (tt_extent == 0) + tt_size = 0; + } + /* + * The beginning of a new multi extent directory chain is when + * the last directory had no ISO_MULTIEXTENT flag set and the + * current entry did set ISO_MULTIEXTENT. + */ + if ((mx & ISO_MULTIEXTENT) == 0 && + (idr->flags[0] & ISO_MULTIEXTENT) != 0) { + struct directory_entry *s_entry; + struct iso_directory_record *idr2 = idr; + int i2 = i; + off_t tsize = 0; + + /* + * Sum up the total file size for the multi extent file + */ + while ((i2 + offsetof(struct iso_directory_record, name[0])) < len) { + idr2 = (struct iso_directory_record *)&dirbuff[i2]; + if (idr2->length[0] == 0) { + i2 = ISO_ROUND_UP(i2); + continue; + } + + tsize += get_733(idr2->size); + if ((idr2->flags[0] & ISO_MULTIEXTENT) == 0) + break; + i2 += idr2->length[0]; + } + + s_entry = dup_directory_entry(*pnt); /* dup first for mxroot */ + s_entry->de_flags |= MULTI_EXTENT; + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY|INHIBIT_JOLIET_ENTRY; + s_entry->size = tsize; + s_entry->starting_block = (*pnt)->starting_block; + s_entry->mxroot = s_entry; + s_entry->mxpart = 0; + s_entry->next = *pnt; /* Next in list */ + pnt[1] = pnt[0]; /* Move to next slot */ + *pnt = s_entry; /* First slot is mxroot */ + pnt++; /* Point again to cur. */ + } + if ((mx & ISO_MULTIEXTENT) != 0 || + (idr->flags[0] & ISO_MULTIEXTENT) != 0) { + (*pnt)->de_flags |= MULTI_EXTENT; + (*pnt)->de_flags |= INHIBIT_UDF_ENTRY; + (pnt[-1])->next = *pnt; + (*pnt)->mxroot = (pnt[-1])->mxroot; + (*pnt)->mxpart = (pnt[-1])->mxpart + 1; + } + pnt++; + mx = idr->flags[0]; + i += idr->length[0]; + } +#ifdef APPLE_HYB + /* + * If we find an associated file, check if there is a file + * with same ISO name and link it to this entry + */ + for (pnt = rtn, i = 0; i < nent; i++, pnt++) { + int j; + + rlen = get_711((*pnt)->isorec.name_len); + if ((*pnt)->isorec.flags[0] & ISO_ASSOCIATED) { + for (j = 0; j < nent; j++) { + if (strncmp(rtn[j]->isorec.name, + (*pnt)->isorec.name, rlen) == 0 && + (rtn[j]->isorec.flags[0] & ISO_ASSOCIATED) == 0) { + rtn[j]->assoc = *pnt; + + /* + * don't want this entry to be + * in the Joliet tree + */ + (*pnt)->de_flags |= INHIBIT_JOLIET_ENTRY; + /* + * XXX Is it correct to exclude UDF too? + */ + (*pnt)->de_flags |= INHIBIT_UDF_ENTRY; + + /* + * as we have associated files, then + * assume we are are dealing with + * Apple's extensions - if not already + * set + */ + if (apple_both == 0) { + apple_both = apple_ext = 1; + } + break; + } + } + } + } +#endif /* APPLE_HYB */ + + /* + * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it + * to get the filenames of the files. Also, save the table info, just + * in case we need to use it. + * + * The entries look something like: F ISODUMP.;1 isodump + */ + if (tt_extent != 0 && tt_size != 0) { + nbytes = roundup(tt_size, SECTOR_SIZE); + tt_buf = (unsigned char *) e_malloc(nbytes); + readsecs(tt_extent, tt_buf, nbytes / SECTOR_SIZE); + + /* + * Loop through the file, examine each entry, and attempt to + * attach it to the correct entry. + */ + cpnt = tt_buf; + cpnt1 = tt_buf; + while (cpnt - tt_buf < tt_size) { + /* Skip to a line terminator, or end of the file. */ + while ((cpnt1 - tt_buf < tt_size) && + (*cpnt1 != '\n') && + (*cpnt1 != '\0')) { + cpnt1++; + } + /* Zero terminate this particular line. */ + if (cpnt1 - tt_buf < tt_size) { + *cpnt1 = '\0'; + } + /* + * Now dig through the actual directories, and try and + * find the attachment for this particular filename. + */ + for (pnt = rtn, i = 0; i < nent; i++, pnt++) { + rlen = get_711((*pnt)->isorec.name_len); + + /* + * If this filename is so long that it would + * extend past the end of the file, it cannot + * be the one we want. + */ + if (cpnt + 2 + rlen - tt_buf >= tt_size) { + continue; + } + /* + * Now actually compare the name, and make sure + * that the character at the end is a ' '. + */ + if (strncmp((char *)cpnt + 2, + (*pnt)->isorec.name, rlen) == 0 && + cpnt[2 + rlen] == ' ' && + (p = strchr((char *)&cpnt[2 + rlen], '\t'))) { + p++; + /* + * This is a keeper. Now determine the + * correct table entry that we will + * use on the new image. + */ + if (strlen(p) > 0) { + (*pnt)->table = + e_malloc(strlen(p) + 4); + sprintf((*pnt)->table, + "%c\t%s\n", + *cpnt, p); + } + if (!(*pnt)->got_rr_name) { + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + (*pnt)->name = e_strdup(p); + } + break; + } + } + cpnt = cpnt1 + 1; + cpnt1 = cpnt; + } + + free(tt_buf); + } else if (!seen_rockridge && !warning_given) { + /* + * Warn the user that iso-9660 names were used because neither + * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were + * found. + */ + fprintf(stderr, + _("Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) \n")); + fprintf(stderr, + _("name translations were found on previous session.\n")); + fprintf(stderr, + _("ISO-9660 file names have been used instead.\n")); + warning_given = 1; + } + if (dirbuff != NULL) { + free(dirbuff); + } + *nentp = nent + nmult; + return (rtn); +} /* read_merging_directory */ + +/* + * Free any associated data related to the structures. + */ +LOCAL int +free_mdinfo(ptr, len) + struct directory_entry **ptr; + int len; +{ + int i; + struct directory_entry **p; + + p = ptr; + for (i = 0; i < len; i++, p++) { + /* + * If the tree-handling code decided that it needed an entry, it + * will have removed it from the list. Thus we must allow for + * null pointers here. + */ + if (*p == NULL) { + continue; + } + free_directory_entry(*p); + } + + free(ptr); + return (0); +} + +LOCAL void +free_directory_entry(dirp) + struct directory_entry *dirp; +{ + if (dirp->name != NULL) + free(dirp->name); + + if (dirp->whole_name != NULL) + free(dirp->whole_name); + + if (dirp->rr_attributes != NULL) + free(dirp->rr_attributes); + + if (dirp->table != NULL) + free(dirp->table); + + free(dirp); +} + +/* + * Search the list to see if we have any entries from the previous + * session that match this entry. If so, copy the extent number + * over so we don't bother to write it out to the new session. + */ +int +check_prev_session(ptr, len, curr_entry, statbuf, lstatbuf, odpnt) + struct directory_entry **ptr; + int len; + struct directory_entry *curr_entry; + struct stat *statbuf; + struct stat *lstatbuf; + struct directory_entry **odpnt; +{ + int i; + int rr; + int retcode = -2; /* Default not found */ + + for (i = 0; i < len; i++) { + if (ptr[i] == NULL) { /* Used or empty entry skip */ + continue; + } +#if 0 + if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && + ptr[i]->name[0] == '\0') { + continue; + } + if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && + ptr[i]->name[0] == 1) { + continue; + } +#else + if (ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0) { + continue; + } + if (ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0) { + continue; + } +#endif + + if (ptr[i]->name != NULL && + strcmp(ptr[i]->name, curr_entry->name) != 0) { + /* Not the same name continue */ + continue; + } + /* + * It's a directory so we must always merge it with the new + * session. Never ever reuse directory extents. See comments + * in tree.c for an explaination of why this must be the case. + */ + if ((curr_entry->isorec.flags[0] & ISO_DIRECTORY) != 0) { + retcode = i; + goto found_it; + } + /* + * We know that the files have the same name. If they also + * have the same file type (i.e. file, dir, block, etc), then + * we can safely reuse the TRANS.TBL entry for this file. The + * check_rr_dates() function will do this for us. + * + * Verify that the file type and dates are consistent. If not, + * we probably have a different file, and we need to write it + * out again. + */ + retcode = i; + + if (ptr[i]->rr_attributes != NULL) { + if ((rr = check_rr_dates(ptr[i], curr_entry, statbuf, + lstatbuf)) == -1) + return (-1); + + if (rr == 0) { /* Different files */ + goto found_it; + } + } + /* + * Verify size and timestamp. If rock ridge is in use, we + * need to compare dates from RR too. Directories are special, + * we calculate their size later. + */ + if (ptr[i]->size != curr_entry->size) { + /* Different files */ + goto found_it; + } + if (memcmp(ptr[i]->isorec.date, + curr_entry->isorec.date, 7) != 0) { + /* Different files */ + goto found_it; + } + /* We found it and we can reuse the extent */ + memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); + curr_entry->starting_block = get_733(ptr[i]->isorec.extent); + curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + + if ((curr_entry->isorec.flags[0] & ISO_MULTIEXTENT) || + (ptr[i]->isorec.flags[0] & ISO_MULTIEXTENT)) { + copy_mult_extent(curr_entry, ptr[i]); + } + goto found_it; + } + return (retcode); + +found_it: + if (ptr[i]->mxroot == ptr[i]) { /* Remove all multi ext. entries */ + int j = i + 1; /* First one will be removed below */ + + while (j < len && ptr[j] && ptr[j]->mxroot == ptr[i]) { + free(ptr[j]); + ptr[j++] = NULL; + } + } + if (odpnt != NULL) { + *odpnt = ptr[i]; + } else { + free(ptr[i]); + } + ptr[i] = NULL; + return (retcode); +} + +/* + * Return the number of directory entries for a file. This is usually 1 + * but may be 3 or more in case of multi extent files. + */ +LOCAL int +iso_dir_ents(de) + struct directory_entry *de; +{ + struct directory_entry *de2; + int ret = 0; + + if (de->mxroot == NULL) + return (1); + de2 = de; + while (de2 != NULL && de2->mxroot == de->mxroot) { + ret++; + de2 = de2->next; + } + return (ret); +} + +/* + * Copy old multi-extent directory information from the previous session. + * If both the old session and the current session are created by mkisofs + * then this code could be extremely simple as the information is only copied + * in case that the file did not change since the last session was made. + * As we don't know the other ISO formatter program, any combination of + * multi-extent files and even a single extent file could be possible. + * We need to handle all files the same way ad the old session was created as + * we reuse the data extents from the file in the old session. + */ +LOCAL void +copy_mult_extent(se1, se2) + struct directory_entry *se1; + struct directory_entry *se2; +{ + struct directory_entry *curr_entry = se1; + int len1; + int len2; + int mxpart = 0; + + len1 = iso_dir_ents(se1); + len2 = iso_dir_ents(se2); + + if (len1 == 1) { + /* + * Convert single-extent to multi-extent. + * If *se1 is not multi-extent, *se2 definitely is + * and we need to set up a MULTI_EXTENT directory header. + */ + se1->de_flags |= MULTI_EXTENT; + se1->isorec.flags[0] |= ISO_MULTIEXTENT; + se1->mxroot = curr_entry; + se1->mxpart = 0; + se1 = dup_directory_entry(se1); + curr_entry->de_flags |= INHIBIT_ISO9660_ENTRY|INHIBIT_JOLIET_ENTRY; + se1->de_flags |= INHIBIT_UDF_ENTRY; + se1->next = curr_entry->next; + curr_entry->next = se1; + se1 = curr_entry; + len1 = 2; + } + + while (se2->isorec.flags[0] & ISO_MULTIEXTENT) { + len1--; + len2--; + if (len1 <= 0) { + struct directory_entry *sex = dup_directory_entry(se1); + + sex->mxroot = curr_entry; + sex->next = se1->next; + se1->next = sex; + len1++; + } + memcpy(se1->isorec.extent, se2->isorec.extent, 8); + se1->starting_block = get_733(se2->isorec.extent); + se1->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + se1->de_flags |= MULTI_EXTENT; + se1->isorec.flags[0] |= ISO_MULTIEXTENT; + se1->mxroot = curr_entry; + se1->mxpart = mxpart++; + + se1 = se1->next; + se2 = se2->next; + } + memcpy(se1->isorec.extent, se2->isorec.extent, 8); + se1->starting_block = get_733(se2->isorec.extent); + se1->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + se1->isorec.flags[0] &= ~ISO_MULTIEXTENT; /* Last entry */ + se1->mxpart = mxpart; + while (len1 > 1) { /* Drop other entries */ + struct directory_entry *sex; + + sex = se1->next; + se1->next = sex->next; + free(sex); + len1--; + } +} + +/* + * open_merge_image: Open an existing image. + */ +int +open_merge_image(path) + char *path; +{ +#ifndef USE_SCG + in_image = fopen(path, "rb"); + if (in_image == NULL) { + return (-1); + } +#else + in_image = fopen(path, "rb"); + if (in_image == NULL) { + if (scsidev_open(path) < 0) + return (-1); + } +#endif + return (0); +} + +/* + * close_merge_image: Close an existing image. + */ +int +close_merge_image() +{ +#ifdef USE_SCG + return (scsidev_close()); +#else + return (fclose(in_image)); +#endif +} + +/* + * merge_isofs: Scan an existing image, and return a pointer + * to the root directory for this image. + */ +struct iso_directory_record * +merge_isofs(path) + char *path; +{ + char buffer[SECTOR_SIZE]; + int file_addr; + int i; + int sum = 0; + char *p = buffer; + struct iso_primary_descriptor *pri = NULL; + struct iso_directory_record *rootp; + struct iso_volume_descriptor *vdp; + + /* + * Start by searching for the volume header. Ultimately, we need to + * search for volume headers in multiple places because we might be + * starting with a multisession image. FIXME(eric). + */ + get_session_start(&file_addr); + + for (i = 0; i < 100; i++) { + if (readsecs(file_addr, buffer, + sizeof (buffer) / SECTOR_SIZE) != sizeof (buffer)) { + comerr(_("Read error on old image %s\n"), path); + } + vdp = (struct iso_volume_descriptor *)buffer; + + if ((strncmp(vdp->id, ISO_STANDARD_ID, sizeof (vdp->id)) == 0) && + (get_711(vdp->type) == ISO_VD_PRIMARY)) { + break; + } + file_addr += 1; + } + + if (i == 100) { + return (NULL); + } + for (i = 0; i < 2048-3; i++) { + sum += p[i] & 0xFF; + } + pri = (struct iso_primary_descriptor *)vdp; + + /* Check the blocksize of the image to make sure it is compatible. */ + if (get_723(pri->logical_block_size) != SECTOR_SIZE) { + errmsgno(EX_BAD, + _("Previous session has incompatible sector size %u.\n"), + get_723(pri->logical_block_size)); + return (NULL); + } + if (get_723(pri->volume_set_size) != 1) { + errmsgno(EX_BAD, + _("Previous session has volume set size %u (must be 1).\n"), + get_723(pri->volume_set_size)); + return (NULL); + } + /* Get the location and size of the root directory. */ + rootp = (struct iso_directory_record *) + e_malloc(sizeof (struct iso_directory_record)); + + memcpy(rootp, pri->root_directory_record, + sizeof (pri->root_directory_record)); + + for (i = 0; i < 100; i++) { + if (readsecs(file_addr, buffer, + sizeof (buffer) / SECTOR_SIZE) != sizeof (buffer)) { + comerr(_("Read error on old image %s\n"), path); + } + if (strncmp(buffer, "MKI ", 4) == 0) { + int sum2; + + sum2 = p[2045] & 0xFF; + sum2 *= 256; + sum2 += p[2046] & 0xFF; + sum2 *= 256; + sum2 += p[2047] & 0xFF; + if (sum == sum2) { + error(_("ISO-9660 image includes checksum signature for correct inode numbers.\n")); + } else { + correct_inodes = FALSE; + rrip112 = FALSE; + } + break; + } + file_addr += 1; + } + + return (rootp); +} + +LOCAL void +merge_remaining_entries(this_dir, pnt, n_orig) + struct directory *this_dir; + struct directory_entry **pnt; + int n_orig; +{ + int i; + struct directory_entry *s_entry; + UInt32_t ttbl_extent = 0; + unsigned int ttbl_index = 0; + char whole_path[PATH_MAX]; + + /* + * Whatever is leftover in the list needs to get merged back into the + * directory. + */ + for (i = 0; i < n_orig; i++) { + if (pnt[i] == NULL) { + continue; + } + if (pnt[i]->name != NULL && pnt[i]->whole_name == NULL) { + /* Set the name for this directory. */ + strlcpy(whole_path, this_dir->de_name, + sizeof (whole_path)); + strcat(whole_path, SPATH_SEPARATOR); + strcat(whole_path, pnt[i]->name); + + pnt[i]->whole_name = e_strdup(whole_path); + } + if (pnt[i]->name != NULL && +/* strcmp(pnt[i]->name, "") == 0 )*/ + strcmp(pnt[i]->name, trans_tbl) == 0) { + ttbl_extent = + get_733(pnt[i]->isorec.extent); + ttbl_index = i; + continue; + } + + /* + * Skip directories for now - these need to be treated + * differently. + */ + if ((pnt[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) { + /* + * FIXME - we need to insert this directory into the + * tree, so that the path tables we generate will be + * correct. + */ + if ((strcmp(pnt[i]->name, ".") == 0) || + (strcmp(pnt[i]->name, "..") == 0)) { + free_directory_entry(pnt[i]); + pnt[i] = NULL; + continue; + } else { + merge_old_directory_into_tree(pnt[i], this_dir); + } + } + pnt[i]->next = this_dir->contents; + pnt[i]->filedir = this_dir; + this_dir->contents = pnt[i]; + pnt[i] = NULL; + } + + + /* + * If we don't have an entry for the translation table, then don't + * bother trying to copy the starting extent over. Note that it is + * possible that if we are copying the entire directory, the entry for + * the translation table will have already been inserted into the + * linked list and removed from the old entries list, in which case we + * want to leave the extent number as it was before. + */ + if (ttbl_extent == 0) { + return; + } + /* + * Finally, check the directory we are creating to see whether there + * are any new entries in it. If there are not, we can reuse the same + * translation table. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* + * Don't care about '.' or '..'. They are never in the table + * anyways. + */ + if (s_entry->name != NULL && strcmp(s_entry->name, ".") == 0) { + continue; + } + if (s_entry->name != NULL && strcmp(s_entry->name, "..") == 0) { + continue; + } +/* if (s_entry->name != NULL &&*/ +/* strcmp(s_entry->name, "") == 0)*/ + if (s_entry->name != NULL && + strcmp(s_entry->name, trans_tbl) == 0) { + continue; + } + if ((s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0) { + return; + } + } + + /* + * Locate the translation table, and re-use the same extent. It isn't + * clear that there should ever be one in there already so for now we + * try and muddle through the best we can. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { +/* if (strcmp(s_entry->name, "") == 0)*/ + if (strcmp(s_entry->name, trans_tbl) == 0) { + fprintf(stderr, "Should never get here\n"); + set_733(s_entry->isorec.extent, ttbl_extent); + return; + } + } + + pnt[ttbl_index]->next = this_dir->contents; + pnt[ttbl_index]->filedir = this_dir; + this_dir->contents = pnt[ttbl_index]; + pnt[ttbl_index] = NULL; +} + + +/* + * Here we have a case of a directory that has completely disappeared from + * the face of the earth on the tree we are mastering from. Go through and + * merge it into the tree, as well as everything beneath it. + * + * Note that if a directory has been moved for some reason, this will + * incorrectly pick it up and attempt to merge it back into the old + * location. FIXME(eric). + */ +LOCAL int +merge_old_directory_into_tree(dpnt, parent) + struct directory_entry *dpnt; + struct directory *parent; +{ + struct directory_entry **contents = NULL; + int i; + int n_orig; + struct directory *this_dir, + *next_brother; + char whole_path[PATH_MAX]; + + this_dir = (struct directory *)e_malloc(sizeof (struct directory)); + memset(this_dir, 0, sizeof (struct directory)); + this_dir->next = NULL; + this_dir->subdir = NULL; + this_dir->self = dpnt; + this_dir->contents = NULL; + this_dir->size = 0; + this_dir->extent = 0; + this_dir->depth = parent->depth + 1; + this_dir->parent = parent; + if (!parent->subdir) + parent->subdir = this_dir; + else { + next_brother = parent->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = this_dir; + } + + /* Set the name for this directory. */ + if (strlcpy(whole_path, parent->de_name, sizeof (whole_path)) >= sizeof (whole_path) || + strlcat(whole_path, SPATH_SEPARATOR, sizeof (whole_path)) >= sizeof (whole_path) || + strlcat(whole_path, dpnt->name, sizeof (whole_path)) >= sizeof (whole_path)) + comerrno(EX_BAD, _("Path name '%s%s%s' exceeds max length %zd\n"), + parent->de_name, + SPATH_SEPARATOR, + dpnt->name, + sizeof (whole_path)); + this_dir->de_name = e_strdup(whole_path); + this_dir->whole_name = e_strdup(whole_path); + + /* + * Now fill this directory using information from the previous session. + */ + contents = read_merging_directory(&dpnt->isorec, &n_orig); + /* + * Start by simply copying the '.', '..' and non-directory entries to + * this directory. Technically we could let merge_remaining_entries + * handle this, but it gets rather confused by the '.' and '..' entries + */ + for (i = 0; i < n_orig; i++) { + /* + * We can always reuse the TRANS.TBL in this particular case. + */ + contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + + if (((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) && + (i >= 2)) { + continue; + } + /* If we have a directory, don't reuse the extent number. */ + if ((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) { + memset(contents[i]->isorec.extent, 0, 8); + + if (strcmp(contents[i]->name, ".") == 0) + this_dir->dir_flags |= DIR_HAS_DOT; + + if (strcmp(contents[i]->name, "..") == 0) + this_dir->dir_flags |= DIR_HAS_DOTDOT; + } + /* + * for regilar files, we do it here. + * If it has CL or RE attributes, remember its extent + */ + check_rr_relocation(contents[i]); + + /* + * Set the whole name for this file. + */ + if (strlcpy(whole_path, this_dir->whole_name, sizeof (whole_path)) >= sizeof (whole_path) || + strlcat(whole_path, SPATH_SEPARATOR, sizeof (whole_path)) >= sizeof (whole_path) || + strlcat(whole_path, contents[i]->name, sizeof (whole_path)) >= sizeof (whole_path)) + comerrno(EX_BAD, _("Path name '%s%s%s' exceeds max length %zd\n"), + this_dir->whole_name, + SPATH_SEPARATOR, + contents[i]->name, + sizeof (whole_path)); + + contents[i]->whole_name = e_strdup(whole_path); + + contents[i]->next = this_dir->contents; + contents[i]->filedir = this_dir; + this_dir->contents = contents[i]; + contents[i] = NULL; + } + + /* + * and for directories, we do it here. + * If it has CL or RE attributes, remember its extent + */ + check_rr_relocation(dpnt); + + /* + * Zero the extent number for ourselves. + */ + memset(dpnt->isorec.extent, 0, 8); + + /* + * Anything that is left are other subdirectories that need to be + * merged. + */ + merge_remaining_entries(this_dir, contents, n_orig); + free_mdinfo(contents, n_orig); +#if 0 + /* + * This is no longer required. The post-scan sort will handle all of + * this for us. + */ + sort_n_finish(this_dir); +#endif + + return (0); +} + + +char *cdrecord_data = NULL; + +int +get_session_start(file_addr) + int *file_addr; +{ + char *pnt; + +#ifdef CDRECORD_DETERMINES_FIRST_WRITABLE_ADDRESS + /* + * FIXME(eric). We need to coordinate with cdrecord to obtain the + * parameters. For now, we assume we are writing the 2nd session, so + * we start from the session that starts at 0. + */ + if (file_addr != NULL) + *file_addr = 16; + + /* + * We need to coordinate with cdrecord to get the next writable address + * from the device. Here is where we use it. + */ + session_start = last_extent = last_extent_written = cdrecord_result(); +#else + + if (file_addr != NULL) + *file_addr = 0L; + session_start = last_extent = last_extent_written = 0L; + if (check_session && cdrecord_data == NULL) + return (0); + + if (cdrecord_data == NULL) { + comerrno(EX_BAD, + _("Special parameters for cdrecord not specified with -C\n")); + } + /* + * Next try and find the ',' in there which delimits the two numbers. + */ + pnt = strchr(cdrecord_data, ','); + if (pnt == NULL) { + comerrno(EX_BAD, _("Malformed cdrecord parameters\n")); + } + + *pnt = '\0'; + if (file_addr != NULL) { + *file_addr = atol(cdrecord_data); + } + pnt++; + + session_start = last_extent = last_extent_written = atol(pnt); + + pnt--; + *pnt = ','; + +#endif + return (0); +} + +/* + * This function scans the directory tree, looking for files, and it makes + * note of everything that is found. We also begin to construct the ISO9660 + * directory entries, so that we can determine how large each directory is. + */ +int +merge_previous_session(this_dir, mrootp, reloc_root, reloc_old_root) + struct directory *this_dir; + struct iso_directory_record *mrootp; + char *reloc_root; + char *reloc_old_root; +{ + struct directory_entry **orig_contents = NULL; + struct directory_entry *odpnt = NULL; + int n_orig; + struct directory_entry *s_entry; + int status; + int lstatus; + struct stat statbuf, + lstatbuf; + int retcode; + + /* skip leading slash */ + while (reloc_old_root && reloc_old_root[0] == PATH_SEPARATOR) { + reloc_old_root++; + } + while (reloc_root && reloc_root[0] == PATH_SEPARATOR) { + reloc_root++; + } + + /* + * Parse the same directory in the image that we are merging for + * multisession stuff. + */ + orig_contents = read_merging_directory(mrootp, &n_orig); + if (orig_contents == NULL) { + if (reloc_old_root) { + comerrno(EX_BAD, + _("Reading old session failed, cannot execute -old-root.\n")); + } + return (0); + } + + if (reloc_old_root && reloc_old_root[0]) { + struct directory_entry **new_orig_contents = orig_contents; + int new_n_orig = n_orig; + + /* decend until we reach the original root */ + while (reloc_old_root[0]) { + int i; + char *next; + int last; + + for (next = reloc_old_root; *next && *next != PATH_SEPARATOR; next++); + if (*next) { + last = 0; + *next = 0; + next++; + } else { + last = 1; + } + while (*next == PATH_SEPARATOR) { + next++; + } + + for (i = 0; i < new_n_orig; i++) { + struct iso_directory_record subroot; + + if (new_orig_contents[i]->name != NULL && + strcmp(new_orig_contents[i]->name, reloc_old_root) != 0) { + /* Not the same name continue */ + continue; + } + /* + * enter directory, free old one only if not the top level, + * which is still needed + */ + subroot = new_orig_contents[i]->isorec; + if (new_orig_contents != orig_contents) { + free_mdinfo(new_orig_contents, new_n_orig); + } + new_orig_contents = read_merging_directory(&subroot, &new_n_orig); + + if (!new_orig_contents) { + comerrno(EX_BAD, + _("Reading directory %s in old session failed, cannot execute -old-root.\n"), + reloc_old_root); + } + i = -1; + break; + } + + if (i == new_n_orig) { + comerrno(EX_BAD, + _("-old-root (sub)directory %s not found in old session.\n"), + reloc_old_root); + } + + /* restore string, proceed to next sub directory */ + if (!last) { + reloc_old_root[strlen(reloc_old_root)] = PATH_SEPARATOR; + } + reloc_old_root = next; + } + + /* + * preserve the old session, skipping those dirs/files that are found again + * in the new root + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + status = stat_filter(s_entry->whole_name, &statbuf); + lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); + + /* + * check_prev_session() will search for s_entry and remove it from + * orig_contents if found + */ + retcode = check_prev_session(orig_contents, n_orig, s_entry, + &statbuf, &lstatbuf, NULL); + if (retcode == -1) + return (-1); + /* + * Skip other directory entries for multi-extent files + */ + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + + for (s_e = s_entry->mxroot; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + s_entry = s_e; + ; + } + } + } + merge_remaining_entries(this_dir, orig_contents, n_orig); + + /* use new directory */ + free_mdinfo(orig_contents, n_orig); + orig_contents = new_orig_contents; + n_orig = new_n_orig; + + if (reloc_root && reloc_root[0]) { + /* also decend into new root before searching for files */ + this_dir = find_or_create_directory(this_dir, reloc_root, NULL, TRUE); + if (!this_dir) { + return (-1); + } + } + } + + + /* + * Now we scan the directory itself, and look at what is inside of it. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + status = stat_filter(s_entry->whole_name, &statbuf); + lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); + + /* + * We always should create an entirely new directory tree + * whenever we generate a new session, unless there were + * *no* changes whatsoever to any of the directories, in which + * case it would be kind of pointless to generate a new + * session. + * I believe it is possible to rigorously prove that any change + * anywhere in the filesystem will force the entire tree to be + * regenerated because the modified directory will get a new + * extent number. Since each subdirectory of the changed + * directory has a '..' entry, all of them will need to be + * rewritten too, and since the parent directory of the + * modified directory will have an extent pointer to the + * directory it too will need to be rewritten. Thus we will + * never be able to reuse any directory information when + * writing new sessions. + * + * We still check the previous session so we can mark off the + * equivalent entry in the list we got from the original disc, + * however. + */ + + /* + * The check_prev_session function looks for an identical + * entry in the previous session. If we see it, then we copy + * the extent number to s_entry, and cross it off the list. + */ + retcode = check_prev_session(orig_contents, n_orig, s_entry, + &statbuf, &lstatbuf, &odpnt); + if (retcode == -1) + return (-1); + + if (odpnt != NULL && + (s_entry->isorec.flags[0] & ISO_DIRECTORY) != 0) { + int dflag; + + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + struct directory *child; + + /* + * XXX It seems that the tree that has been + * XXX read from the previous session does not + * XXX carry whole_name entries. We provide a + * XXX hack in + * XXX multi.c:find_or_create_directory() + * XXX that should be removed when a + * XXX reasonable method could be found. + */ + child = find_or_create_directory(this_dir, + s_entry->whole_name, + s_entry, 1); + dflag = merge_previous_session(child, + &odpnt->isorec, + NULL, reloc_old_root); + if (dflag == -1) { + return (-1); + } + free(odpnt); + odpnt = NULL; + } + } + if (odpnt) { + free(odpnt); + odpnt = NULL; + } + /* + * Skip other directory entries for multi-extent files + */ + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + + for (s_e = s_entry->mxroot; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + s_entry = s_e; + ; + } + } + } + + if (!reloc_old_root) { + /* + * Whatever is left over, are things which are no longer in the tree on + * disk. We need to also merge these into the tree. + */ + merge_remaining_entries(this_dir, orig_contents, n_orig); + } + free_mdinfo(orig_contents, n_orig); + return (1); +} + +/* + * This code deals with relocated directories which may exist + * in the previous session. + */ +struct dir_extent_link { + unsigned int extent; + struct directory_entry *de; + struct dir_extent_link *next; +}; + +static struct dir_extent_link *cl_dirs = NULL; +static struct dir_extent_link *re_dirs = NULL; + +LOCAL void +check_rr_relocation(de) + struct directory_entry *de; +{ + unsigned char sector[SECTOR_SIZE]; + unsigned char *pnt = de->rr_attributes; + int len = de->rr_attr_size; + UInt32_t cont_extent = 0, + cont_offset = 0, + cont_size = 0; + + pnt = parse_xa(pnt, &len, /* dpnt */ 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + break; + } + if (strncmp((char *)pnt, "CL", 2) == 0) { + struct dir_extent_link *dlink = e_malloc(sizeof (*dlink)); + + dlink->extent = get_733(pnt + 4); + dlink->de = de; + dlink->next = cl_dirs; + cl_dirs = dlink; + + } else if (strncmp((char *)pnt, "RE", 2) == 0) { + struct dir_extent_link *dlink = e_malloc(sizeof (*dlink)); + + dlink->extent = de->starting_block; + dlink->de = de; + dlink->next = re_dirs; + re_dirs = dlink; + + } else if (strncmp((char *)pnt, "CE", 2) == 0) { + cont_extent = get_733(pnt + 4); + cont_offset = get_733(pnt + 12); + cont_size = get_733(pnt + 20); + + } else if (strncmp((char *)pnt, "ST", 2) == 0) { + len = pnt[2]; + } + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + /* ??? What if cont_offset+cont_size > SECTOR_SIZE */ + readsecs(cont_extent, sector, 1); + pnt = sector + cont_offset; + len = cont_size; + cont_extent = cont_offset = cont_size = 0; + } + } + +} + +void +match_cl_re_entries() +{ + struct dir_extent_link *re = re_dirs; + + /* for each relocated directory */ + for (; re; re = re->next) { + struct dir_extent_link *cl = cl_dirs; + + for (; cl; cl = cl->next) { + /* find a place where it was relocated from */ + if (cl->extent == re->extent) { + /* set link to that place */ + re->de->parent_rec = cl->de; + re->de->filedir = cl->de->filedir; + + /* + * see if it is in rr_moved + */ + if (reloc_dir != NULL) { + struct directory_entry *rr_moved_e = reloc_dir->contents; + + for (; rr_moved_e; rr_moved_e = rr_moved_e->next) { + /* yes it is */ + if (re->de == rr_moved_e) { + /* forget it */ + re->de = NULL; + } + } + } + break; + } + } + } +} + +void +finish_cl_pl_for_prev_session() +{ + struct dir_extent_link *re = re_dirs; + + /* for those that were relocated, but NOT to rr_moved */ + re = re_dirs; + for (; re; re = re->next) { + if (re->de != NULL) { + /* + * here we have hypothetical case when previous session + * was not created by mkisofs and contains relocations + */ + struct directory_entry *s_entry = re->de; + struct directory_entry *s_entry1; + struct directory *d_entry = reloc_dir->subdir; + + /* do the same as finish_cl_pl_entries */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + while (d_entry) { + if (d_entry->self == s_entry) + break; + d_entry = d_entry->next; + } + if (!d_entry) { + comerrno(EX_BAD, _("Unable to locate directory parent\n")); + } + + if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) { + char *rr_attr; + + /* + * First fix the PL pointer in the directory in the + * rr_reloc dir + */ + s_entry1 = d_entry->contents->next; + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "PL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, s_entry->filedir->extent); + + /* Now fix the CL pointer */ + s_entry1 = s_entry->parent_rec; + + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "CL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, d_entry->extent); + } + } + } + /* free memory */ + re = re_dirs; + while (re) { + struct dir_extent_link *next = re->next; + + free(re); + re = next; + } + re = cl_dirs; + while (re) { + struct dir_extent_link *next = re->next; + + free(re); + re = next; + } +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/name.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/name.c new file mode 100644 index 00000000000..7b1003f6611 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/name.c @@ -0,0 +1,542 @@ +/* @(#)name.c 1.38 10/12/19 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)name.c 1.38 10/12/19 joerg"; + +#endif +/* + * File name.c - map full Unix file names to unique 8.3 names that + * would be valid on DOS. + * + * + * Written by Eric Youngdale (1993). + * Almost totally rewritten by J. Schilling (2000). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2010 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "mkisofs.h" +#include +#include +#include + +void iso9660_check __PR((struct iso_directory_record *idr, struct directory_entry *ndr)); +int iso9660_file_length __PR((const char *name, + struct directory_entry *sresult, + int dirflag)); + +void +iso9660_check(idr, ndr) + struct iso_directory_record *idr; + struct directory_entry *ndr; +{ + int nlen; + char schar; + char *p; + char *np; + + nlen = idr->name_len[0]; + schar = idr->name[nlen]; + + if (nlen == 1 && (idr->name[0] == '\0' || idr->name[0] == '\001')) + return; + + idr->name[nlen] = '\0'; /* Make it null terminated */ + if ((p = strrchr(idr->name, ';')) != NULL) { + *p = '\0'; /* Strip off old version # */ + } + iso9660_file_length(idr->name, ndr, + (idr->flags[0] & ISO_DIRECTORY) != 0); + + if ((np = strrchr(ndr->isorec.name, ';')) != NULL) { + *np = '\0'; /* Strip off new version # */ + } + if (strcmp(idr->name, ndr->isorec.name) != 0) { + if (p) + *p = ';'; /* Restore old version # */ + if (np) + *np = ';'; /* Restore new version # */ + errmsgno(EX_BAD, + _("Old session has illegal name '%.*s' length %d\n"), + idr->name_len[0], + idr->name, + idr->name_len[0]); + errmsgno(EX_BAD, + _("New session will use name '%s'\n"), + ndr->isorec.name); + } + if (p) + *p = ';'; /* Restore old version # */ + if (np) + *np = ';'; /* Restore new version # */ + idr->name[nlen] = schar; /* Restore old iso record*/ +} + +/* + * Function: iso9660_file_length + * + * Purpose: Map file name to 8.3 format, return length + * of result. + * + * Arguments: name file name we need to map. + * sresult directory entry structure to contain mapped name. + * dirflag flag indicating whether this is a directory or not. + * + * Note: name being const * is a bug introduced by Eric but hard to + * fix without going through the whole source. + */ +int +iso9660_file_length(name, sresult, dirflag) + const char *name; /* Not really const !!! */ + struct directory_entry *sresult; + int dirflag; +{ + char c; + char *cp; + int before_dot = 8; + int after_dot = 3; + int chars_after_dot = 0; + int chars_before_dot = 0; + int current_length = 0; + int extra = 0; + int ignore = 0; + char *last_dot; + const char *pnt; + int priority = 32767; + char *result; + int ochars_after_dot; + int ochars_before_dot; + int seen_dot = 0; + int seen_semic = 0; +#ifdef Eric_code_does_not_work + int tildes = 0; +#endif + + result = sresult->isorec.name; + + if (sresult->priority) + priority = sresult->priority; + + /* + * For the '.' entry, generate the correct record, and return 1 for + * the length. + */ + if (strcmp(name, ".") == 0) { + *result = 0; + return (1); + } + /* + * For the '..' entry, generate the correct record, and return 1 + * for the length. + */ + if (strcmp(name, "..") == 0) { + *result++ = 1; + *result++ = 0; + return (1); + } + /* + * Now scan the directory one character at a time, and figure out + * what to do. + */ + pnt = name; + + /* + * Find the '.' that we intend to use for the extension. + * Usually this is the last dot, but if we have . followed by nothing + * or a ~, we would consider this to be unsatisfactory, and we keep + * searching. + */ + last_dot = strrchr(pnt, '.'); + if ((last_dot != NULL) && + ((last_dot[1] == '~') || (last_dot[1] == '\0'))) { + cp = last_dot; + *cp = '\0'; + last_dot = strrchr(pnt, '.'); + *cp = '.'; + /* + * If we found no better '.' back up to the last match. + */ + if (last_dot == NULL) + last_dot = cp; + } + + if (last_dot != NULL) { + ochars_after_dot = strlen(last_dot); /* dot counts */ + ochars_before_dot = last_dot - pnt; + } else { + ochars_before_dot = 128; + ochars_after_dot = 0; + } + /* + * If we have full names, the names we generate will not work + * on a DOS machine, since they are not guaranteed to be 8.3. + * Nonetheless, in many cases this is a useful option. We + * still only allow one '.' character in the name, however. + */ + if (full_iso9660_filenames || iso9660_level > 1) { + before_dot = iso9660_namelen; + after_dot = before_dot - 1; + + if (!dirflag) { + if (ochars_after_dot > ((iso9660_namelen/2)+1)) { + /* + * The minimum number of characters before + * the dot is 3 to allow renaming. + * Let us allow to have 15 characters after + * dot to give more rational filenames. + */ + before_dot = iso9660_namelen/2; + after_dot = ochars_after_dot; + } else { + before_dot -= ochars_after_dot; /* dot counts */ + after_dot = ochars_after_dot; + } + } + } + + while (*pnt) { +#ifdef VMS + if (strcmp(pnt, ".DIR;1") == 0) { + break; + } +#endif + +#ifdef Eric_code_does_not_work + /* + * XXX If we make this code active we get corrupted direcrory + * XXX trees with infinite loops. + */ + /* + * This character indicates a Unix style of backup file + * generated by some editors. Lower the priority of the file. + */ + if (iso_translate && *pnt == '#') { + priority = 1; + pnt++; + continue; + } + /* + * This character indicates a Unix style of backup file + * generated by some editors. Lower the priority of the file. + */ + if (iso_translate && *pnt == '~') { + priority = 1; + tildes++; + pnt++; + continue; + } +#endif + /* + * This might come up if we had some joker already try and put + * iso9660 version numbers into the file names. This would be + * a silly thing to do on a Unix box, but we check for it + * anyways. If we see this, then we don't have to add our own + * version number at the end. UNLESS the ';' is part of the + * filename and no valid version number is following. + */ + if (use_fileversion && *pnt == ';' && seen_dot) { + /* + * Check if a valid version number follows. + * The maximum valid version number is 32767. + */ + for (c = 1, cp = (char *)&pnt[1]; c < 6 && *cp; c++, cp++) { + if (*cp < '0' || *cp > '9') + break; + } + if (c <= 6 && *cp == '\0' && atoi(&pnt[1]) <= 32767) + seen_semic++; + } + /* + * If we have a name with multiple '.' characters, we ignore + * everything after we have gotten the extension. + */ + if (ignore) { + pnt++; + continue; + } + if (current_length >= iso9660_namelen) { +#ifdef nono + /* + * Does not work as we may truncate before the dot. + */ + error(_("Truncating '%s' to '%.*s'.\n"), + name, + current_length, sresult->isorec.name); + ignore++; +#endif + pnt++; + continue; + } + /* Spin past any iso9660 version number we might have. */ + if (seen_semic) { + if (seen_semic == 1) { + seen_semic++; + *result++ = ';'; + } + if (*pnt >= '0' && *pnt <= '9') { + *result++ = *pnt; + } + extra++; + pnt++; + continue; + } + + if (*pnt == '.') { + if (!allow_multidot) { + if (strcmp(pnt, ".tar.gz") == 0) + pnt = last_dot = ".tgz"; + if (strcmp(pnt, ".ps.gz") == 0) + pnt = last_dot = ".psz"; + } + + if (!chars_before_dot && !allow_leading_dots) { + /* + * DOS can't read files with dot first + */ + chars_before_dot++; + *result++ = '_'; /* Substitute underscore */ + + } else if (pnt == last_dot) { + if (seen_dot) { + ignore++; + continue; + } + *result++ = '.'; + seen_dot++; + } else if (allow_multidot) { + if (chars_before_dot < before_dot) { + chars_before_dot++; + *result++ = '.'; + } + } else { + /* + * If this isn't the dot that we use + * for the extension, then change the + * character into a '_' instead. + */ + if (chars_before_dot < before_dot) { + chars_before_dot++; + *result++ = '_'; + } + } + } else { + if ((seen_dot && (chars_after_dot < after_dot) && + ++chars_after_dot) || + (!seen_dot && (chars_before_dot < before_dot) && + ++chars_before_dot)) { + + c = *pnt; + if (c & 0x80) { + /* + * We allow 8 bit chars if -iso-level + * is at least 4 + * + * XXX We should check if the output + * XXX character set is a 7 Bit ASCI + * extension. + */ + if (iso9660_level >= 4) { + size_t flen = 1; + size_t tlen = 1; + + /* + * XXX This currently only works for + * XXX non iconv() based locales. + */ + if (in_nls->sic_cd2uni == NULL) { + conv_charset( + (Uchar *)&c, &tlen, + (Uchar *)&c, &flen, + in_nls, out_nls); + } + } else { + c = '_'; + } + } else if (!allow_lowercase) { + c = islower((unsigned char)c) ? + toupper((unsigned char)c) : c; + } + if (relaxed_filenames) { + /* + * Here we allow a more relaxed syntax. + */ + if (c == '/') + c = '_'; + *result++ = c; + } else switch (c) { + /* + * Dos style filenames. + * We really restrict the names here. + */ + + default: + *result++ = c; + break; + + /* + * Descriptions of DOS's 'Parse Filename' + * (function 29H) describes V1 and V2.0+ + * separator and terminator characters. These + * characters in a DOS name make the file + * visible but un-manipulable (all useful + * operations error off. + */ + /* separators */ + case '+': + case '=': + case '%': /* not legal DOS */ + /* filename */ + case ':': + case ';': /* already handled */ + case '.': /* already handled */ + case ',': /* already handled */ + case '\t': + case ' ': + /* V1 only separators */ + case '/': + case '"': + case '[': + case ']': + /* terminators */ + case '>': + case '<': + case '|': + /* + * Other characters that are not valid ISO-9660 + * characters. + */ + case '!': +/* case '#':*/ + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': +/* case '-':*/ + case '?': + case '@': + case '\\': + case '^': + case '`': + case '{': + case '}': +/* case '~':*/ + /* + * All characters below 32 (space) are not + * allowed too. + */ + case 1: case 2: case 3: case 4: + case 5: case 6: case 7: case 8: + /* case 9: */ + case 10: case 11: case 12: + case 13: case 14: case 15: + case 16: case 17: case 18: + case 19: case 20: case 21: + case 22: case 23: case 24: + case 25: case 26: case 27: + case 28: case 29: case 30: + case 31: + + /* + * Hmm - what to do here? Skip? Win95 + * looks like it substitutes '_' + */ + *result++ = '_'; + break; + + case '#': + case '-': + case '~': + /* + * Check if we should allow these + * illegal characters used by + * Microsoft. + */ + if (iso_translate) + *result++ = '_'; + else + *result++ = c; + break; + } /* switch (*pnt) */ + } else { /* if (chars_{after,before}_dot) ... */ + pnt++; + continue; + } + } /* else *pnt == '.' */ + current_length++; + pnt++; + } /* while (*pnt) */ + + /* + * OK, that wraps up the scan of the name. Now tidy up a few other + * things. + * Look for emacs style of numbered backups, like foo.c.~3~. If we + * see this, convert the version number into the priority number. + * In case of name conflicts, this is what would end up being used as + * the 'extension'. + */ +#ifdef Eric_code_does_not_work + if (tildes == 2) { + int prio1 = 0; + + pnt = name; + while (*pnt && *pnt != '~') { + pnt++; + } + if (*pnt) { + pnt++; + } + while (*pnt && *pnt != '~') { + prio1 = 10 * prio1 + *pnt - '0'; + pnt++; + } + priority = prio1; + } +#endif + /* + * If this is not a directory, force a '.' in case we haven't seen one, + * and add a version number if we haven't seen one of those either. + */ + if (!dirflag) { + if (!seen_dot && !omit_period) { + if (chars_before_dot >= (iso9660_namelen-1)) { + chars_before_dot--; + result--; + } + *result++ = '.'; + extra++; + } + if (!omit_version_number && !seen_semic) { + *result++ = ';'; + *result++ = '1'; + extra += 2; + } + } + *result++ = 0; + sresult->priority = priority; + +/*#define DEBBUG*/ +#ifdef DEBBUG + error("NAME: '%s'\n", sresult->isorec.name); + error("chars_before_dot %d chars_after_dot %d seen_dot %d extra %d\n", + chars_before_dot, chars_after_dot, seen_dot, extra); +#endif + return (chars_before_dot + chars_after_dot + seen_dot + extra); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.c new file mode 100644 index 00000000000..dabbc5022e0 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.c @@ -0,0 +1,944 @@ +/* @(#)rock.c 1.66 12/12/02 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)rock.c 1.66 12/12/02 joerg"; +#endif +/* + * File rock.c - generate RRIP records for iso9660 filesystems. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2012 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "mkisofs.h" +#include "rock.h" +#include +#include + +#define SU_VERSION 1 + +#define SL_ROOT 8 +#define SL_PARENT 4 +#define SL_CURRENT 2 +#define SL_CONTINUE 1 + +#define CE_SIZE 28 /* SUSP Continuation aerea */ +#define CL_SIZE 12 /* RR Child Link for deep dir relocation */ +#define ER_SIZE 8 /* RR Extension record for RR signature */ +#define NM_SIZE 5 /* RR Real name */ +#define PL_SIZE 12 /* RR Paren Link for deep dir relocation */ +#define PN_SIZE 20 /* RR POSIX device modes (Major/Minor) */ +#define PX_OLD_SIZE 36 /* RR POSIX Extensions (mode/nlink/uid/gid) */ +#define PX_SIZE 44 /* RR POSIX Extensions (mode/nlink/uid/gid/ino) */ +#define RE_SIZE 4 /* RR Relocated directory */ +#define RR_SIZE 5 /* RR RR Signature in every file */ +#define SL_SIZE 20 /* RR Symlink */ +#define ZF_SIZE 16 /* RR* Linux compression extension */ +#ifdef APPLE_HYB +#define AA_SIZE 14 /* size of Apple extension */ +#endif /* APPLE_HYB */ +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ +#define TF_SIZE (5 + 4 * 7) /* RR Time field */ +#define TF_SIZE_LONG (5 + 4 * 17) /* RR Time field */ +#else +#define TF_SIZE (5 + 3 * 7) +#define TF_SIZE_LONG (5 + 3 * 17) +#endif + +LOCAL void rstrncpy __PR((char *t, char *f, size_t tlen, + siconvt_t *inls, + siconvt_t *onls)); +LOCAL void add_CE_entry __PR((char *field, int line)); +LOCAL int gen_xa_attr __PR((mode_t attr)); +LOCAL void gen_xa __PR((struct stat *lstatbuf)); +EXPORT int generate_xa_rr_attributes __PR((char *whole_name, + char *name, + struct directory_entry *s_entry, + struct stat *statbuf, + struct stat *lstatbuf, + int deep_opt)); + char *generate_rr_extension_record __PR((char *id, + char *descriptor, + char *source, + int *size)); +/* + * If we need to store this number of bytes, make sure we + * do not box ourselves in so that we do not have room for + * a CE entry for the continuation record + */ +#define RR_CUR_USE (CE_SIZE + currlen + (ipnt - recstart)) + +#define MAYBE_ADD_CE_ENTRY(BYTES) \ + (((int)(BYTES)) + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0) + +/* + * Buffer to build RR attributes + */ +LOCAL Uchar Rock[16384]; +LOCAL Uchar symlink_buff[PATH_MAX+1]; +LOCAL int ipnt = 0; /* Current "write" offset in Rock[] */ +LOCAL int recstart = 0; /* Start offset in Rock[] for this area */ +LOCAL int currlen = 0; /* # of non RR bytes used in this area */ +LOCAL int mainrec = 0; /* # of RR bytes use in main dir area */ +LOCAL int reclimit; /* Max. # of bytes usable in this area */ + +/* if we are using converted filenames, we don't want the '/' character */ +LOCAL void +rstrncpy(t, f, tlen, inls, onls) + char *t; + char *f; + size_t tlen; /* The to-length */ + siconvt_t *inls; + siconvt_t *onls; +{ + size_t flen = strlen(f); + + while (tlen > 0 && *f) { + size_t ofl = flen; + size_t otl = tlen; + + conv_charset((Uchar *)t, &tlen, (Uchar *)f, &flen, inls, onls); + if (*t == '/') { + *t = '_'; + } + t += otl - tlen; + f += ofl - flen; + } +} + +LOCAL void +add_CE_entry(field, line) + char *field; + int line; +{ + if (MAYBE_ADD_CE_ENTRY(0)) { + errmsgno(EX_BAD, + _("Panic: no space, cannot add RR CE entry (%d bytes mising) for %s line %d.\n"), + (CE_SIZE + currlen + (ipnt - recstart) - reclimit), + field, line); + errmsgno(EX_BAD, _("currlen: %d ipnt: %d, recstart: %d\n"), + currlen, ipnt, recstart); + errmsgno(EX_BAD, _("Send bug report to the maintainer.\n")); + comerrno(EX_BAD, _("Aborting.\n")); + } + + if (recstart) + set_733((char *)Rock + recstart - 8, ipnt + 28 - recstart); + Rock[ipnt++] = 'C'; + Rock[ipnt++] = 'E'; + Rock[ipnt++] = CE_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + recstart = ipnt; + currlen = 0; + if (!mainrec) + mainrec = ipnt; + reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ +} + +#ifdef PROTOTYPES +LOCAL int +gen_xa_attr(mode_t attr) +#else +LOCAL int +gen_xa_attr(attr) + mode_t attr; +#endif +{ + int ret = 0; + + if (attr & S_IRUSR) + ret |= XA_O_READ; + if (attr & S_IXUSR) + ret |= XA_O_EXEC; + + if (attr & S_IRGRP) + ret |= XA_G_READ; + if (attr & S_IXGRP) + ret |= XA_G_EXEC; + + if (attr & S_IROTH) + ret |= XA_W_READ; + if (attr & S_IXOTH) + ret |= XA_W_EXEC; + + ret |= XA_FORM1; + + if (S_ISDIR(attr)) + ret |= XA_DIR; + + return (ret); +} + +LOCAL void +gen_xa(lstatbuf) + struct stat *lstatbuf; +{ + /* + * Group ID + */ + set_722((char *)Rock + ipnt, lstatbuf->st_gid); + ipnt += 2; + /* + * User ID + */ + set_722((char *)Rock + ipnt, lstatbuf->st_uid); + ipnt += 2; + /* + * Attributes + */ + set_722((char *)Rock + ipnt, gen_xa_attr(lstatbuf->st_mode)); + ipnt += 2; + + Rock[ipnt++] = 'X'; /* XA Signature */ + Rock[ipnt++] = 'A'; + Rock[ipnt++] = 0; /* File number (we always use '0' */ + + Rock[ipnt++] = 0; /* Reserved (5 Byte) */ + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + +} + +#ifdef PROTOTYPES +EXPORT int +generate_xa_rr_attributes(char *whole_name, char *name, + struct directory_entry *s_entry, + struct stat *statbuf, + struct stat *lstatbuf, + int deep_opt) +#else +EXPORT int +generate_xa_rr_attributes(whole_name, name, + s_entry, + statbuf, + lstatbuf, + deep_opt) + char *whole_name; + char *name; + struct directory_entry *s_entry; + struct stat *statbuf, + *lstatbuf; + int deep_opt; +#endif +{ + int flagpos; + int flagval; + int need_ce; + + statbuf = statbuf; /* this shuts up unreferenced compiler */ + /* warnings */ + mainrec = recstart = ipnt = 0; + + if (use_XA) { + gen_xa(lstatbuf); + } + +/* reclimit = 0xf8; XXX we now use 254 == 0xfe */ + reclimit = MAX_ISODIR; + + /* no need to fill in the RR stuff if we won't see the file */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + return (0); + + /* + * Obtain the amount of space that is currently used for the directory + * record. We may safely use the current name length; because if name + * confilcts force us to change the ISO-9660 name later, the name will + * never become longer than now. + */ + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + s_entry->isorec.name_len[0] = 1; + } else { + s_entry->isorec.name_len[0] = strlen(s_entry->isorec.name); + } + currlen = s_entry->isorec.length[0] = s_entry->isorec.name_len[0] + + offsetof(struct iso_directory_record, name[0]); + if (currlen & 1) + s_entry->isorec.length[0] = ++currlen; + + if (currlen < 33+37) { + /* + * If the ISO-9660 name length is less than 37, we may use + * ISO-9660:1988 name rules and for this reason, the name len + * may later increase from adding e.g. ".;1"; in this case + * just use the upper limit. + */ + currlen = 33+37; + } + +#ifdef APPLE_HYB + /* if we have regular file, then add Apple extensions */ + if (S_ISREG(lstatbuf->st_mode) && apple_ext && s_entry->hfs_ent) { + if (MAYBE_ADD_CE_ENTRY(AA_SIZE)) + add_CE_entry("AA", __LINE__); + Rock[ipnt++] = 'A'; /* AppleSignature */ + Rock[ipnt++] = 'A'; + Rock[ipnt++] = AA_SIZE; /* includes AppleSignature bytes */ + Rock[ipnt++] = 0x02; /* SystemUseID */ + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[0]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[1]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[2]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[3]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[0]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[1]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[2]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[3]; + Rock[ipnt++] = (s_entry->hfs_ent->fdflags >> 8) & 0xff; + Rock[ipnt++] = s_entry->hfs_ent->fdflags & 0xff; + } +#endif /* APPLE_HYB */ + + if (!use_RockRidge) + goto xa_only; + + /* Identify that we are using the SUSP protocol */ + if (deep_opt & NEED_SP) { + /* + * We may not use a CE record here but we never will need to + * do so, as this SP record is only used for the "." entry + * of the root directory. + */ + Rock[ipnt++] = 'S'; + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 7; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 0xbe; + Rock[ipnt++] = 0xef; + if (use_XA) + Rock[ipnt++] = sizeof (struct iso_xa_dir_record); + else + Rock[ipnt++] = 0; + } + + /* First build the posix name field */ + if (MAYBE_ADD_CE_ENTRY(RR_SIZE)) + add_CE_entry("RR", __LINE__); + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 5; + Rock[ipnt++] = SU_VERSION; + flagpos = ipnt; + flagval = 0; + Rock[ipnt++] = 0; /* We go back and fix this later */ + + if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0) { + char *npnt; + int remain; /* Remaining name length */ + int use; /* Current name part used */ + +#ifdef APPLE_HYB + /* use the HFS name if it exists */ + if (USE_MAC_NAME(s_entry)) { + remain = strlen(s_entry->hfs_ent->name); + npnt = s_entry->hfs_ent->name; + } else { +#endif /* APPLE_HYB */ + + remain = strlen(name); + npnt = name; +#ifdef APPLE_HYB + } +#endif /* APPLE_HYB */ + + if (MAYBE_ADD_CE_ENTRY(NM_SIZE+1)) + add_CE_entry("NM", __LINE__); + while (remain) { + use = remain; + need_ce = 0; + /* Can we fit this SUSP and a CE entry? */ + if (MAYBE_ADD_CE_ENTRY(NM_SIZE+use)) { + use = reclimit - NM_SIZE - RR_CUR_USE; + need_ce++; + } + /* Only room for 256 per SUSP field */ + if (use > 0xf8) { + use = 0xf8; + need_ce++; + } + if (use < 0) { + comerrno(EX_BAD, + _("Negative RR name length residual: %d\n"), + use); + } + + /* First build the posix name field */ + Rock[ipnt++] = 'N'; + Rock[ipnt++] = 'M'; + Rock[ipnt++] = NM_SIZE + use; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = (remain != use ? 1 : 0); + flagval |= (1 << 3); + + /* + * Convert charsets as required + * XXX If we are using iconv() based locales and in/out + * XXX locale differ, then strlen(&Rock[ipnt]) may + * XXX increase. We would need to compute the length + * XXX early enough. + */ +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + rstrncpy((char *)&Rock[ipnt], npnt, use, + hfs_inls, out_nls); + else +#endif /* APPLE_HYB */ + rstrncpy((char *)&Rock[ipnt], npnt, use, + in_nls, out_nls); + npnt += use; + ipnt += use; + remain -= use; + if (remain && need_ce) + add_CE_entry("NM", __LINE__); + } + } + + /* Add the posix modes */ + if (MAYBE_ADD_CE_ENTRY(PX_SIZE)) + add_CE_entry("PX", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'X'; + if (rrip112) { + Rock[ipnt++] = PX_SIZE; + } else { + Rock[ipnt++] = PX_OLD_SIZE; + } + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 0); + set_733((char *)Rock + ipnt, lstatbuf->st_mode); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_nlink); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_uid); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_gid); + ipnt += 8; + if (rrip112) { + /* + * We will set up correct inode numbers later + * after we did assign them. + */ + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + } + + /* Check for special devices */ +#if defined(S_IFCHR) || defined(S_IFBLK) + /* + * The code in this if statement used to be #ifdef'd with NON_UNIXFS. + * But as schily/stat.h always provides the macros S_ISCHR() & S_ISBLK() + * and schily/device.h always provides major()/minor() it is not needed + * anymore. + */ + if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { + if (MAYBE_ADD_CE_ENTRY(PN_SIZE)) + add_CE_entry("PN", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'N'; + Rock[ipnt++] = PN_SIZE; + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 1); +#if 1 + /* This is the new and only code which uses */ + set_733((char *)Rock + ipnt, major(lstatbuf->st_rdev)); + ipnt += 8; + set_733((char *)Rock + ipnt, minor(lstatbuf->st_rdev)); + ipnt += 8; +#else + /* + * If we don't have sysmacros.h, then we have to guess as to + * how best to pick apart the device number for major/minor. + * Note: this may very well be wrong for many systems, so it + * is always best to use the major/minor macros if the system + * supports it. + */ + if (sizeof (dev_t) <= 2) { + set_733((char *)Rock + ipnt, (lstatbuf->st_rdev >> 8)); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_rdev & 0xff); + ipnt += 8; + } else if (sizeof (dev_t) <= 4) { + set_733((char *)Rock + ipnt, + (lstatbuf->st_rdev >> 8) >> 8); + ipnt += 8; + set_733((char *)Rock + ipnt, + lstatbuf->st_rdev & 0xffff); + ipnt += 8; + } else { + set_733((char *)Rock + ipnt, + (lstatbuf->st_rdev >> 16)>>16); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_rdev); + ipnt += 8; + } +#endif + } +#endif /* defined(S_IFCHR) || defined(S_IFBLK) */ + + /* Check for and symbolic links. VMS does not have these. */ +#ifdef S_IFLNK + if (S_ISLNK(lstatbuf->st_mode)) { + int lenpos; + int lenval; + int j0; + int j1; + int nchar; + Uchar *cpnt; + Uchar *cpnt1; + BOOL last_sl = FALSE; /* Don't suppress last '/' */ + +#ifdef HAVE_READLINK + nchar = readlink(deep_opt&DID_CHDIR?name:whole_name, + (char *)symlink_buff, + sizeof (symlink_buff)-1); + if (nchar < 0) + errmsg(_("Cannot read link '%s'.\n"), whole_name); +#else + nchar = -1; +#endif /* HAVE_READLINK */ + symlink_buff[nchar < 0 ? 0 : nchar] = 0; + nchar = strlen((char *)symlink_buff); + set_733(s_entry->isorec.size, 0); + cpnt = &symlink_buff[0]; + flagval |= (1 << 2); + + if (!split_SL_field) { + int sl_bytes = 0; + + for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) { + if (*cpnt1 == '/') { + sl_bytes += 4; + } else { + sl_bytes += 1; + } + } + if (sl_bytes > 250) { + /* + * the symbolic link won't fit into one + * SL System Use Field print an error message + * and continue with splited one + */ + fprintf(stderr, + _("symbolic link ``%s'' to long for one SL System Use Field, splitting"), + cpnt); + } + if (MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) + add_CE_entry("SL+", __LINE__); + } + while (nchar) { + if (MAYBE_ADD_CE_ENTRY(SL_SIZE)) + add_CE_entry("SL", __LINE__); + Rock[ipnt++] = 'S'; + Rock[ipnt++] = 'L'; + lenpos = ipnt; + Rock[ipnt++] = SL_SIZE; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 0; /* Flags */ + lenval = 5; + while (*cpnt || last_sl) { + cpnt1 = (Uchar *) + strchr((char *)cpnt, '/'); + if (cpnt1) { + nchar--; + *cpnt1 = 0; + } + + /* + * We treat certain components in a special + * way. + */ + if (cpnt[0] == '.' && cpnt[1] == '.' && + cpnt[2] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-parent", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + Rock[ipnt++] = SL_PARENT; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + nchar -= 2; + } else if (cpnt[0] == '.' && cpnt[1] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-current", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + Rock[ipnt++] = SL_CURRENT; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + nchar -= 1; + } else if (cpnt[0] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-root", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + if (cpnt == &symlink_buff[0]) + Rock[ipnt++] = SL_ROOT; + else + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + } else { + /* + * If we do not have enough room for a + * component, start a new continuations + * segment now + */ + if (split_SL_component ? + MAYBE_ADD_CE_ENTRY(6) : + MAYBE_ADD_CE_ENTRY(6 + strlen((char *)cpnt))) { + add_CE_entry("SL++", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + j0 = strlen((char *)cpnt); + while (j0) { + j1 = j0; + if (j1 > 0xf8) + j1 = 0xf8; + need_ce = 0; + if (j1 + currlen + 2 + CE_SIZE + + (ipnt - recstart) > + reclimit) { + + j1 = reclimit - + (currlen + 2) - + CE_SIZE - + (ipnt - recstart); + need_ce++; + } + Rock[ipnt++] = + (j1 != j0 ? + SL_CONTINUE : 0); + Rock[ipnt++] = j1; + strncpy((char *)Rock + ipnt, + (char *)cpnt, j1); + ipnt += j1; + lenval += j1 + 2; + cpnt += j1; + /* + * Number we processed + * this time + */ + nchar -= j1; + j0 -= j1; + if (need_ce) { + add_CE_entry( + "SL-path-split", + __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so + * that we can + * restart + * properly + */ + cpnt1 = NULL; + } + break; + } + } + } + if (cpnt1) { + *cpnt1 = '/'; + if (cpnt1 > symlink_buff && !last_sl && + cpnt1[1] == '\0') { + last_sl = TRUE; + } + cpnt = cpnt1 + 1; + } else + break; + } + Rock[lenpos] = lenval; + if (nchar) { + /* We need another SL entry */ + Rock[lenpos + 2] = SL_CONTINUE; + } + } /* while nchar */ + } /* Is a symbolic link */ +#endif /* S_IFLNK */ + + /* Add in the Rock Ridge TF time field */ + if (MAYBE_ADD_CE_ENTRY(long_rr_time ? TF_SIZE_LONG:TF_SIZE)) + add_CE_entry("TF", __LINE__); + Rock[ipnt++] = 'T'; + Rock[ipnt++] = 'F'; + Rock[ipnt++] = long_rr_time ? TF_SIZE_LONG:TF_SIZE; + Rock[ipnt++] = SU_VERSION; +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ + Rock[ipnt++] = long_rr_time ? 0x8f:0x0f; +#else + Rock[ipnt++] = long_rr_time ? 0x8e:0x0e; +#endif + flagval |= (1 << 7); + +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ + if (long_rr_time) { + iso9660_date((char *)&Rock[ipnt], lstatbuf->st_ftime); + ipnt += 7; + } else { + /* + * XXX Do we have nanoseconds on QNX? + */ + iso9660_ldate((char *)&Rock[ipnt], lstatbuf->st_ftime, 0, -100); + ipnt += 17; + } +#endif + if (long_rr_time) { + iso9660_ldate((char *)&Rock[ipnt], + lstatbuf->st_mtime, stat_mnsecs(lstatbuf), -100); + ipnt += 17; + iso9660_ldate((char *)&Rock[ipnt], + lstatbuf->st_atime, stat_ansecs(lstatbuf), -100); + ipnt += 17; + iso9660_ldate((char *)&Rock[ipnt], + lstatbuf->st_ctime, stat_cnsecs(lstatbuf), -100); + ipnt += 17; + } else { + iso9660_date((char *)&Rock[ipnt], lstatbuf->st_mtime); + ipnt += 7; + iso9660_date((char *)&Rock[ipnt], lstatbuf->st_atime); + ipnt += 7; + iso9660_date((char *)&Rock[ipnt], lstatbuf->st_ctime); + ipnt += 7; + } + + /* Add in the Rock Ridge RE (relocated dir) field */ + if (deep_opt & NEED_RE) { + if (MAYBE_ADD_CE_ENTRY(RE_SIZE)) + add_CE_entry("RE", __LINE__); + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 'E'; + Rock[ipnt++] = RE_SIZE; + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 6); + } + /* Add in the Rock Ridge PL record, if required. */ + if (deep_opt & NEED_PL) { + if (MAYBE_ADD_CE_ENTRY(PL_SIZE)) + add_CE_entry("PL", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'L'; + Rock[ipnt++] = PL_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + flagval |= (1 << 5); + } + + /* Add in the Rock Ridge CL field, if required. */ + if (deep_opt & NEED_CL) { + if (MAYBE_ADD_CE_ENTRY(CL_SIZE)) + add_CE_entry("CL", __LINE__); + Rock[ipnt++] = 'C'; + Rock[ipnt++] = 'L'; + Rock[ipnt++] = CL_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *)Rock + ipnt, 0); + ipnt += 8; + flagval |= (1 << 4); + } + +#ifndef VMS + /* + * If transparent compression was requested, fill in the correct field + * for this file, if (and only if) it is actually a compressed file! + * This relies only on magic number, but it should in general not + * be an issue since if you're using -z odds are most of your + * files are already compressed. + * + * In the future it would be nice if mkisofs actually did the + * compression. + */ + if (transparent_compression && S_ISREG(lstatbuf->st_mode)) { + static const Uchar zisofs_magic[8] = + { 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 }; + FILE *zffile; + unsigned int file_size; + Uchar header[16]; + int OK_flag; + int blocksize; + int headersize; + + /* + * First open file and verify that the correct algorithm was + * used + */ + file_size = 0; + OK_flag = 1; + + memset(header, 0, sizeof (header)); + + zffile = fopen(whole_name, "rb"); + if (zffile != NULL) { + if (fread(header, 1, sizeof (header), zffile) != sizeof (header)) + OK_flag = 0; + + /* Check magic number */ + if (memcmp(header, zisofs_magic, sizeof (zisofs_magic))) + OK_flag = 0; + + /* Get the real size of the file */ + file_size = get_731((char *)header+8); + + /* Get the header size (>> 2) */ + headersize = header[12]; + + /* Get the block size (log2) */ + blocksize = header[13]; + + fclose(zffile); + } else { + OK_flag = 0; + blocksize = headersize = 0; /* Make silly GCC quiet */ + } + + if (OK_flag) { + if (MAYBE_ADD_CE_ENTRY(ZF_SIZE)) + add_CE_entry("ZF", __LINE__); + Rock[ipnt++] = 'Z'; + Rock[ipnt++] = 'F'; + Rock[ipnt++] = ZF_SIZE; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 'p'; /* Algorithm: "paged zlib" */ + Rock[ipnt++] = 'z'; + /* 2 bytes for algorithm-specific information */ + Rock[ipnt++] = headersize; + Rock[ipnt++] = blocksize; + set_733((char *)Rock + ipnt, file_size); /* Real file size */ + ipnt += 8; + } + } +#endif + /* + * Add in the Rock Ridge CE field, if required. We use this for the + * extension record that is stored in the root directory. + */ + if (deep_opt & NEED_CE) + add_CE_entry("ER", __LINE__); + + /* + * Done filling in all of the fields. Now copy it back to a buffer + * for the file in question. + */ + /* Now copy this back to the buffer for the file */ + Rock[flagpos] = flagval; + + /* If there was a CE, fill in the size field */ + if (recstart) + set_733((char *)Rock + recstart - 8, ipnt - recstart); + +xa_only: + s_entry->rr_attributes = (Uchar *) e_malloc(ipnt); + s_entry->total_rr_attr_size = ipnt; + s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); + memcpy(s_entry->rr_attributes, Rock, ipnt); + return (ipnt); +} + +/* + * Guaranteed to return a single sector with the relevant info + */ +EXPORT char * +generate_rr_extension_record(id, descriptor, source, size) + char *id; + char *descriptor; + char *source; + int *size; +{ + int lipnt = 0; + char *pnt; + int len_id; + int len_des; + int len_src; + + len_id = strlen(id); + len_des = strlen(descriptor); + len_src = strlen(source); + Rock[lipnt++] = 'E'; + Rock[lipnt++] = 'R'; + Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; + Rock[lipnt++] = 1; + Rock[lipnt++] = len_id; + Rock[lipnt++] = len_des; + Rock[lipnt++] = len_src; + Rock[lipnt++] = 1; + + memcpy(Rock + lipnt, id, len_id); + lipnt += len_id; + + memcpy(Rock + lipnt, descriptor, len_des); + lipnt += len_des; + + memcpy(Rock + lipnt, source, len_src); + lipnt += len_src; + + if (lipnt > SECTOR_SIZE) { + comerrno(EX_BAD, _("Extension record too long\n")); + } + pnt = (char *)e_malloc(SECTOR_SIZE); + memset(pnt, 0, SECTOR_SIZE); + memcpy(pnt, Rock, lipnt); + *size = lipnt; + return (pnt); +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.h new file mode 100644 index 00000000000..ef51c97f771 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/rock.h @@ -0,0 +1,54 @@ +/* @(#)rock.h 1.3 14/04/29 Copyright 2003-2014 J. Schilling */ +/* + * Header file for the Rock Ridge encoder and parser + * + * Copyright (c) 2003-2014 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Defines for SUSP and Rock Ridge signature flags. + * The first block is defined by RRIP-1.09. + */ +#define RR_FLAG_PX 1 /* POSIX attributes */ +#define RR_FLAG_PN 2 /* POSIX device number */ +#define RR_FLAG_SL 4 /* Symlink */ +#define RR_FLAG_NM 8 /* Alternate Name */ +#define RR_FLAG_CL 16 /* Child link */ +#define RR_FLAG_PL 32 /* Parent link */ +#define RR_FLAG_RE 64 /* Relocated Direcotry */ +#define RR_FLAG_TF 128 /* Time stamp */ + +#define RR_FLAG_SF 256 /* Sparse File */ + +#define RR_FLAG_SP 1024 /* SUSP record */ +#define RR_FLAG_AA 2048 /* Apple Signature record */ +#define RR_FLAG_XA 4096 /* XA signature record */ + +#define RR_FLAG_CE 8192 /* SUSP Continuation aerea */ +#define RR_FLAG_ER 16384 /* Extensions Reference for RR */ +#define RR_FLAG_RR 32768 /* RR Signature in every file */ +#define RR_FLAG_ZF 65535 /* Linux compression extension */ + +/* + * Defines that control the behavior of the Rock Ridge encoder + */ +#define NEED_RE 1 /* Need Relocated Direcotry */ +#define NEED_PL 2 /* Need Parent link */ +#define NEED_CL 4 /* Need Child link */ +#define NEED_CE 8 /* Need Continuation Area */ +#define NEED_SP 16 /* Need SUSP record */ +#define DID_CHDIR 1024 /* Did chdir() to file dir */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/scsi.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/scsi.h new file mode 100644 index 00000000000..09d1a1fa22b --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/scsi.h @@ -0,0 +1,20 @@ +/* @(#)scsi.h 1.3 16/10/13 Copyright 1997-2004 J. Schilling */ +/* + * Copyright (c) 1997-2004 J. Schilling + */ +/*@@C@@*/ + +#ifndef _SCSI_H +#define _SCSI_H + +/* + * Implemented inside multi.c in case that USE_SCG has not been defined. + */ +extern int readsecs __PR((UInt32_t startsecno, void *buffer, int sectorcount)); + +#ifdef USE_SCG +extern int scsidev_open __PR((char *path)); +extern int scsidev_close __PR((void)); +#endif + +#endif /* _SCSI_H */ diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/stream.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/stream.c new file mode 100644 index 00000000000..55108cb84eb --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/stream.c @@ -0,0 +1,257 @@ +/* @(#)stream.c 1.17 15/12/08 Copyright 2002-2015 J. Schilling */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)stream.c 1.17 15/12/08 Copyright 2002-2015 J. Schilling"; +#endif +/* + * ISO-9660 stream (pipe) file module for mkisofs + * + * Copyright (c) 2002-2015 J. Schilling + * Implemented after an idea from M.H. Voase + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mkisofs.h" +#include "iso9660.h" +#include + +LOCAL int size_str_file __PR((UInt32_t starting_extent)); +LOCAL int size_str_dir __PR((UInt32_t starting_extent)); +LOCAL int size_str_path __PR((UInt32_t starting_extent)); + +LOCAL int gen_str_path __PR((void)); + +LOCAL int write_str_file __PR((FILE *outfile)); +LOCAL int write_str_dir __PR((FILE *outfile)); +LOCAL int write_str_path __PR((FILE *outfile)); + +extern int stream_media_size; +extern char *stream_filename; +extern time_t begun; + +LOCAL unsigned int avail_extent; +LOCAL unsigned int stream_extent; +LOCAL unsigned int stream_size; +LOCAL unsigned int stream_pad; +LOCAL char *l_path; +LOCAL char *m_path; +LOCAL struct iso_directory_record s_dir; +LOCAL int stream_finished = 0; + +/* + * Compute the size of the file + */ +LOCAL int +size_str_file(starting_extent) + UInt32_t starting_extent; +{ + int n; +extern int dopad; + + stream_extent = last_extent; /* Start of stream file content */ + + avail_extent = stream_media_size; + n = last_extent; /* Room for FS blocks before file */ + n += 1; /* Room for the directory block */ + stream_pad = 0; + if (n < 50) { + stream_pad = 50 - n; + n = 50; /* Make net. size easy to compute */ + } + if (dopad) + n += 150; /* Room for final padding */ + + if (n >= avail_extent) { + comerrno(EX_BAD, + _("-stream-media-size %d but must be at least %d\n"), + avail_extent, n+2); + } + avail_extent -= n; + + last_extent += avail_extent + stream_pad; + + return (0); +} + +/* + * The size of the directory record - one sector + */ +LOCAL int +size_str_dir(starting_extent) + UInt32_t starting_extent; +{ + root->extent = last_extent; + last_extent += 1; + return (0); +} + +/* + * The size of the path tables - two sectors + */ +LOCAL int +size_str_path(starting_extent) + UInt32_t starting_extent; +{ + path_table[0] = starting_extent; + path_table[1] = 0; + path_table[2] = path_table[0] + 1; + path_table[3] = 0; + last_extent += 2 * 1; + return (0); +} + +/* + * Generate the path table data + */ +LOCAL int +gen_str_path() +{ + /* + * Basically add the root directory entry + */ + l_path = (char *)e_malloc(SECTOR_SIZE); + m_path = (char *)e_malloc(SECTOR_SIZE); + memset(l_path, 0, SECTOR_SIZE); + memset(m_path, 0, SECTOR_SIZE); + l_path[0] = 1; + m_path[0] = 1; + set_731(l_path + 2, root->extent); + set_732(m_path + 2, root->extent); + set_721(l_path + 6, 1); + set_722(m_path + 6, 1); + l_path[8] = '\0'; l_path[9] = '\0'; + m_path[8] = '\0'; m_path[9] = '\0'; + return (0); +} + +/* + * Write the file content + */ +LOCAL int +write_str_file(outfile) + FILE *outfile; +{ + unsigned int idx = 0; + unsigned int iso_blocks; + int count; + char *buf; + + buf = e_malloc(SECTOR_SIZE); + stream_size = 0; + while ((idx + SECTOR_SIZE) < (avail_extent * SECTOR_SIZE)) { + memset(buf, 0, SECTOR_SIZE); + count = fread(buf, 1, SECTOR_SIZE, stdin); + if (count <= 0) { + stream_finished = 1; + break; + } + idx += count; + xfwrite(buf, count, 1, outfile, 0, FALSE); + } + + stream_size = idx; + iso_blocks = ISO_BLOCKS(idx); + memset(buf, 0, SECTOR_SIZE); + if (SECTOR_SIZE * iso_blocks - idx) + xfwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, outfile, 0, FALSE); + /* + * If we didn't fill the available area, pad to directory block + */ + for (count = 0; count < (avail_extent - iso_blocks); count++) + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + + for (count = 0; count < stream_pad; count++) + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + + last_extent_written += avail_extent + stream_pad; + free(buf); + return (0); +} + +/* + * Generate and write the directory record data + */ +LOCAL int +write_str_dir(outfile) + FILE *outfile; +{ + int reclen; + char *buf; + + buf = e_malloc(SECTOR_SIZE); memset(buf, 0, SECTOR_SIZE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + s_dir.length[0] = 34; /* BAD: Hardcoded - Will fix, MHV */ + s_dir.ext_attr_length[0] = 0; + set_733((char *)s_dir.extent, root->extent); + set_733((char *)s_dir.size, SECTOR_SIZE); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = ISO_DIRECTORY; + s_dir.file_unit_size[0] = 0; + s_dir.interleave[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = 1; + s_dir.name[0] = 0; /* "." */ + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + s_dir.name[0] = 1; /* ".." */ + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + reclen = offsetof(struct iso_directory_record, name[0]) + + strlen(stream_filename); + if (reclen & 1) + reclen++; + s_dir.length[0] = reclen; + s_dir.ext_attr_length[0] = 0; + set_733((char *)s_dir.extent, stream_extent); + set_733((char *)s_dir.size, stream_size); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = 0; + s_dir.file_unit_size[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = strlen(stream_filename); + memcpy(s_dir.name, stream_filename, s_dir.name_len[0]); + xfwrite(&s_dir, reclen, 1, outfile, 0, FALSE); + + /* + * This calc is: 2 single char directory entries (34) + an additional entry + * with filename length stream_filename + round up for even lenght count + */ + xfwrite(buf, SECTOR_SIZE - ((2 * 34) + reclen), 1, outfile, 0, FALSE); + free(buf); + last_extent_written++; + return (0); +} + +/* + * Generate the path table data + */ +LOCAL int +write_str_path(outfile) + FILE *outfile; +{ + xfwrite(l_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + xfwrite(m_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written += 2; + free(l_path); + free(m_path); + path_table_l = NULL; + path_table_m = NULL; + return (0); +} + +struct output_fragment strfile_desc = { NULL, size_str_file, NULL, write_str_file, "Stream File" }; +struct output_fragment strdir_desc = { NULL, size_str_dir, NULL, write_str_dir, "Stream File Directory" }; +struct output_fragment strpath_desc = { NULL, size_str_path, gen_str_path, write_str_path, "Stream File Path table" }; diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/sunlabel.h b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/sunlabel.h new file mode 100644 index 00000000000..b53243b360d --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/sunlabel.h @@ -0,0 +1,194 @@ +/* @(#)sunlabel.h 1.5 03/12/28 Copyright 1999-2003 J. Schilling */ +/* + * Support for Sun disk label + * + * Copyright (c) 1999-2003 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#define NDKMAP 8 /* # of sparc partitions */ +#define NX86MAP 16 /* # if x86 partitions */ +#define DKL_MAGIC 0xDABE /* magic number */ +#define DKL_MAGIC_0 0xDA /* magic number high byte */ +#define DKL_MAGIC_1 0xBE /* magic number low byte */ + +#define CD_DEFLABEL "CD-ROM Disc with Sun sparc boot created by mkisofs" +#define CD_X86LABEL "CD-ROM Disc with Sun x86 boot created by mkisofs" + +/* + * Define a virtual geometry for the CD disk label. + * The current values are stolen from Sun install disks and do not seem to be + * a good idea as they limit the size of the CD to 327680 sectors which is less + * than 74 minutes. + * There are 84 minute CD's with 378000 sectors and there will be DVD's with + * even more. + */ +#define CD_RPM 350 +#define CD_PCYL 2048 +#define CD_APC 0 +#define CD_INTRLV 1 +#define CD_NCYL 2048 +#define CD_ACYL 0 +#define CD_NHEAD 1 +#define CD_NSECT 640 + +/* + * NOTE: The virtual cylinder size on CD must be a mutiple of 2048. + * This is true if CD_NSECT is a multiple of 4. + */ +#define CD_CYLSIZE (CD_NSECT*CD_NHEAD*512) + +#define V_VERSION 1 /* The VTOC version */ +#define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */ + +#define V_ROOT 0x02 /* Root partiton */ +#define V_USR 0x04 /* Usr partiton */ + +#define V_RONLY 0x10 /* Read only */ + +/* + * The Sun sparc disk label (at offset 0 on a disk) + */ +struct sun_label { + char dkl_ascilabel[128]; + struct dk_vtoc { + Uchar v_version[4]; /* layout version */ + char v_volume[8]; /* volume name */ + Uchar v_nparts[2]; /* number of partitions */ + struct dk_map2 { + Uchar p_tag[2]; /* ID tag of partition */ + Uchar p_flag[2]; /* permission flag */ + + } v_part[NDKMAP]; + Uchar v_xxpad[2]; /* To come over Sun's alignement problem */ + Uchar v_bootinfo[3*4]; /* info for mboot */ + Uchar v_sanity[4]; /* to verify vtoc sanity */ + Uchar v_reserved[10*4]; + Uchar v_timestamp[NDKMAP*4]; + + } dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ + char dkl_pad[512-(128+sizeof (struct dk_vtoc)+NDKMAP*8+14*2)]; + Uchar dkl_rpm[2]; /* rotations per minute */ + Uchar dkl_pcyl[2]; /* # physical cylinders */ + Uchar dkl_apc[2]; /* alternates per cylinder */ + Uchar dkl_obs1[2]; /* obsolete */ + Uchar dkl_obs2[2]; /* obsolete */ + Uchar dkl_intrlv[2]; /* interleave factor */ + Uchar dkl_ncyl[2]; /* # of data cylinders */ + Uchar dkl_acyl[2]; /* # of alternate cylinders */ + Uchar dkl_nhead[2]; /* # of heads in this partition */ + Uchar dkl_nsect[2]; /* # of 512 byte sectors per track */ + Uchar dkl_obs3[2]; /* obsolete */ + Uchar dkl_obs4[2]; /* obsolete */ + + struct dk_map { /* logical partitions */ + Uchar dkl_cylno[4]; /* starting cylinder */ + Uchar dkl_nblk[4]; /* number of blocks */ + } dkl_map[NDKMAP]; /* logical partition headers */ + + Uchar dkl_magic[2]; /* identifies this label format */ + Uchar dkl_cksum[2]; /* xor checksum of sector */ +}; + +/* + * The Sun x86 / AT&T disk label (at offset 512 on a fdisk partition) + */ +struct x86_label { + struct x86_vtoc { + Uchar v_bootinfo[3*4]; /* unsupported */ + Uchar v_sanity[4]; /* to verify vtoc sanity */ + Uchar v_version[4]; /* layout version */ + char v_volume[8]; /* volume name */ + Uchar v_sectorsz[2]; /* # of bytes in a sector */ + Uchar v_nparts[2]; /* # of partitions */ + Uchar v_reserved[10*4]; + struct dkl_partition { + Uchar p_tag[2]; /* ID tag of partition */ + Uchar p_flag[2]; /* permission flag */ + Uchar p_start[4]; /* starting sector */ + Uchar p_size[4]; /* number of blocks */ + } v_part[NX86MAP]; + Uchar timestamp[NX86MAP][4]; + char v_asciilabel[128]; + } dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ + Uchar dkl_pcyl[4]; /* # physical cylinders */ + Uchar dkl_ncyl[4]; /* # of data cylinders */ + Uchar dkl_acyl[2]; /* # of alternate cylinders */ + Uchar dkl_bcyl[2]; + Uchar dkl_nhead[4]; /* # of heads in this partition */ + Uchar dkl_nsect[4]; /* # of 512 byte sectors per track */ + Uchar dkl_intrlv[2]; /* interleave factor */ + Uchar dkl_skew[2]; + Uchar dkl_apc[2]; /* alternates per cylinder */ + Uchar dkl_rpm[2]; /* rotations per minute */ + Uchar dkl_write_reinstruct[2]; + Uchar dkl_read_reinstruct[2]; + Uchar dkl_extra[4*2]; /* for later expansions */ + char dkl_pad[512-(sizeof (struct x86_vtoc)+4*4+14*2)]; + Uchar dkl_magic[2]; /* identifies this label format */ + Uchar dkl_cksum[2]; /* xor checksum of sector */ +}; + +/* + * One x86 PC fdisk partition record. + */ +struct pc_pr { + Uchar pr_status; /* Boot status */ + Uchar pr_head; /* Starting head # */ + char pr_sec_cyl[2]; /* Starting sec+cyl # */ + Uchar pr_type; /* Partition type */ + Uchar pr_e_head; /* Ending head # */ + char pr_e_sec_cyl[2]; /* Ending sec+cyl # */ + char pr_partoff[4]; /* Partition start sector # */ + char pr_nsect[4]; /* # of sectors in partition */ +}; + +/* + * Flags and macros for above partition record. + */ +#define SEC_MASK 0x3F +#define GET_SEC(a) ((a) & SEC_MASK) +#define GET_CYL(a) ((((a) & 0xFF) >> 8) | (((a) & 0xC0) << 2)) + +#define STATUS_INACT 0 /* Marked non bootable */ +#define STATUS_ACTIVE 0x80 /* Marked as bootable */ + +#define TYPE_FREE 0 /* Unused partition */ +#define TYPE_DOS12 0x01 /* FAT12 fileystem */ +#define TYPE_XENIX 0x02 /* XENIX root */ +#define TYPE_XENIX2 0x03 /* XENIX usr */ +#define TYPE_DOS16 0x04 /* FAT16 filesystem */ +#define TYPE_XDOS 0x05 /* Extended DOS part */ +#define TYPE_DOS4 0x06 /* FAT16 >= 32 MB */ +#define TYPE_SOLARIS 0x82 /* Solaris x86 */ +#define TYPE_SOLARIS_BOOT 0xBE /* Solaris boot */ +#define TYPE_CDOS4 0xDB /* CPM */ + +/* + * The first sector on a disk from a x86 PC (at offset 0 on a disk) + */ +struct pc_part { + char bootcode[0x1BE]; /* Master boot record */ + struct pc_pr part[4]; /* The 4 primary partitions */ + Uchar magic[2]; /* Fixed at 0x55 0xAA */ +}; diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/tree.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/tree.c new file mode 100644 index 00000000000..64db12119c3 --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/tree.c @@ -0,0 +1,2991 @@ +/* @(#)tree.c 1.136 16/10/23 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)tree.c 1.136 16/10/23 joerg"; +#endif +/* + * File tree.c - scan directory tree and build memory structures for iso9660 + * filesystem + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2016 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#include "mkisofs.h" +#include "rock.h" +#include "match.h" +#include +#include +#include +#include +#include + +#ifdef UDF +#include "udf.h" +#endif + +#ifdef VMS +#include +#include +#include "vms.h" +#endif + +LOCAL Uchar symlink_buff[PATH_MAX+1]; + +LOCAL char *filetype __PR((int t)); +LOCAL char *rstr __PR((char *s1, char *s2)); +LOCAL void stat_fix __PR((struct stat *st)); +EXPORT int stat_filter __PR((char *path, struct stat *st)); +EXPORT int lstat_filter __PR((char *path, struct stat *st)); +LOCAL int sort_n_finish __PR((struct directory *this_dir)); +LOCAL void generate_reloc_directory __PR((void)); +EXPORT void attach_dot_entries __PR((struct directory *dirnode, + struct stat *this_stat, + struct stat *parent_stat)); +EXPORT char *find_rr_attribute __PR((unsigned char *pnt, int len, + char *attr_type)); +EXPORT void finish_cl_pl_entries __PR((void)); +LOCAL void dir_nesting_warn __PR((struct directory *this_dir, + char *path, int contflag)); +EXPORT int scan_directory_tree __PR((struct directory *this_dir, + char *path, + struct directory_entry *de)); +LOCAL struct directory_entry * + dup_relocated_dir __PR((struct directory *this_dir, + struct directory_entry *s_entry, + char *whole_path, + char *short_name, + struct stat *statp)); +EXPORT int insert_file_entry __PR((struct directory *this_dir, + char *whole_path, + char *short_name, + struct stat *statp, int have_rsrc)); +EXPORT struct directory_entry * + dup_directory_entry __PR((struct directory_entry *s_entry)); +EXPORT void generate_iso9660_directories __PR((struct directory *node, + FILE *outfile)); + +LOCAL void set_de_path __PR((struct directory *parent, + struct directory *this)); + +EXPORT struct directory * + find_or_create_directory __PR((struct directory *parent, + char *path, + struct directory_entry *de, + int flag)); +LOCAL void delete_directory __PR((struct directory *parent, + struct directory *child)); +EXPORT int sort_tree __PR((struct directory *node)); +EXPORT void dump_tree __PR((struct directory *node)); +EXPORT struct directory_entry * + search_tree_file __PR((struct directory *node, + char *filename)); +EXPORT void init_fstatbuf __PR((void)); + +extern int verbose; +struct stat fstatbuf; /* We use this for the artificial */ + /* entries we create */ +struct stat root_statbuf; /* Stat buffer for root directory */ +struct directory *reloc_dir; + +LOCAL char * +filetype(t) + int t; +{ + static char unkn[32]; + + if (S_ISFIFO(t)) /* 1 */ + return ("fifo"); + if (S_ISCHR(t)) /* 2 */ + return ("chr"); + if (S_ISMPC(t)) /* 3 */ + return ("multiplexed chr"); + if (S_ISDIR(t)) /* 4 */ + return ("dir"); + if (S_ISNAM(t)) /* 5 */ + return ("named file"); + if (S_ISBLK(t)) /* 6 */ + return ("blk"); + if (S_ISMPB(t)) /* 7 */ + return ("multiplexed blk"); + if (S_ISREG(t)) /* 8 */ + return ("regular file"); + if (S_ISCTG(t)) /* 9 */ + return ("contiguous file"); + if (S_ISLNK(t)) /* 10 */ + return ("symlink"); + if (S_ISSHAD(t)) /* 11 */ + return ("Solaris shadow inode"); + if (S_ISSOCK(t)) /* 12 */ + return ("socket"); + if (S_ISDOOR(t)) /* 13 */ + return ("door"); + if (S_ISWHT(t)) /* 14 */ + return ("whiteout"); + if (S_ISEVC(t)) /* 15 */ + return ("event count"); + + /* + * Needs to be last in case somebody makes this + * a supported file type. + */ + if ((t & S_IFMT) == 0) /* 0 (unallocated) */ + return ("unallocated"); + + sprintf(unkn, "octal '%o'", t & S_IFMT); + return (unkn); +} + +/* + * Check if s1 ends in strings s2 + */ +LOCAL char * +rstr(s1, s2) + char *s1; + char *s2; +{ + int l1; + int l2; + + l1 = strlen(s1); + l2 = strlen(s2); + if (l2 > l1) + return ((char *)NULL); + + if (strcmp(&s1[l1 - l2], s2) == 0) + return (&s1[l1 - l2]); + return ((char *)NULL); +} + +LOCAL void +stat_fix(st) + struct stat *st; +{ + int adjust_modes = 0; + + if (S_ISREG(st->st_mode)) + adjust_modes = rationalize_filemode; + else if (S_ISDIR(st->st_mode)) + adjust_modes = rationalize_dirmode; + else + adjust_modes = (rationalize_filemode || rationalize_dirmode); + + /* + * If rationalizing, override the uid and gid, since the + * originals will only be useful on the author's system. + */ + if (rationalize_uid) + st->st_uid = uid_to_use; + if (rationalize_gid) + st->st_gid = gid_to_use; + + if (adjust_modes) { + + if (S_ISREG(st->st_mode) && (filemode_to_use != 0)) { + st->st_mode = filemode_to_use | S_IFREG; + } else if (S_ISDIR(st->st_mode) && (dirmode_to_use != 0)) { + st->st_mode = dirmode_to_use | S_IFDIR; + } else { + /* + * Make sure the file modes make sense. Turn + * on all read bits. Turn on all exec/search + * bits if any exec/search bit is set. Turn + * off all write bits, and all special mode + * bits (on a r/o fs lock bits are useless, + * and with uid+gid 0 don't want set-id bits, + * either). + */ + + st->st_mode |= 0444; +#if !defined(_WIN32) && !defined(__DJGPP__) /* make all file "executable" */ + if (st->st_mode & 0111) +#endif + st->st_mode |= 0111; + st->st_mode &= ~07222; + } + } +} + +EXPORT int +stat_filter(path, st) + char *path; + struct stat *st; +{ + int result = stat(path, st); + + if (result >= 0 && rationalize) + stat_fix(st); + return (result); +} + +EXPORT int +lstat_filter(path, st) + char *path; + struct stat *st; +{ + int result = lstat(path, st); + + if (result >= 0 && rationalize) + stat_fix(st); + return (result); +} + +LOCAL int +sort_n_finish(this_dir) + struct directory *this_dir; +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct directory_entry *table; + int count; + int d1; + int d2; + int d3; + register int new_reclen; + char *c; + int status = 0; + int tablesize = 0; + char newname[MAX_ISONAME+1]; + char rootname[MAX_ISONAME+1]; + char extname[MAX_ISONAME+1]; + + /* + * Here we can take the opportunity to toss duplicate entries from the + * directory. + */ + /* ignore if it's hidden */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { + return (0); + } + table = NULL; + + init_fstatbuf(); + + /* + * If we had artificially created this directory, then we might be + * missing the required '.' entries. Create these now if we need + * them. + */ + if ((this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != + (DIR_HAS_DOT | DIR_HAS_DOTDOT)) { + attach_dot_entries(this_dir, NULL, NULL); + } + flush_file_hash(); + s_entry = this_dir->contents; + while (s_entry) { +#ifdef USE_LARGEFILES + /* + * Skip all but the last extent from a multi extent file, + * we like them all have the same name. + */ + if ((s_entry->de_flags & MULTI_EXTENT) && + (s_entry->isorec.flags[0] & ISO_MULTIEXTENT)) { + s_entry = s_entry->next; + continue; + } +#endif + /* ignore if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + /* + * First assume no conflict, and handle this case + */ + if (!(s_entry1 = find_file_hash(s_entry->isorec.name))) { + add_file_hash(s_entry); + s_entry = s_entry->next; + continue; + } +#ifdef APPLE_HYB + /* + * if the pair are associated, then skip (as they have the + * same name!) + */ + if (apple_both && s_entry1->assoc && + s_entry1->assoc == s_entry) { + s_entry = s_entry->next; + continue; + } +#endif /* APPLE_HYB */ + + if (s_entry1 == s_entry) { + comerrno(EX_BAD, + _("Fatal goof, file '%s' already in hash table.\n"), + s_entry->isorec.name); + } + /* + * OK, handle the conflicts. Try substitute names until we + * come up with a winner + */ + strlcpy(rootname, s_entry->isorec.name, sizeof (rootname)); + /* + * Strip off the non-significant part of the name so that we + * are left with a sensible root filename. If we don't find + * a '.', then try a ';'. + */ + c = strchr(rootname, '.'); + /* + * In case we ever allow more than on dot, only modify the + * section past the last dot if the file name starts with a + * dot. + */ + if (c != NULL && c == rootname && c != strrchr(rootname, '.')) { + c = strrchr(rootname, '.'); + } + extname[0] = '\0'; /* In case we have no ext. */ + if (c) { + strlcpy(extname, c, sizeof (extname)); + *c = 0; /* Cut off complete ext. */ + } else { + /* + * Could not find any '.'. + */ + c = strchr(rootname, ';'); + if (c) { + *c = 0; /* Cut off version number */ + } + } + c = strchr(extname, ';'); + if (c) { + *c = 0; /* Cut off version number */ + } + d1 = strlen(rootname); + if (full_iso9660_filenames || iso9660_level > 1) { + d2 = strlen(extname); + /* + * 31/37 chars minus the 3 characters we are + * appending below to create unique filenames. + */ + if ((d1 + d2) > (iso9660_namelen - 3)) + rootname[iso9660_namelen - 3 - d2] = 0; + } else { + if (d1 > 5) + rootname[5] = 0; + } + new_reclen = strlen(rootname); + sprintf(newname, "%s000%s%s", + rootname, + extname, + ((s_entry->isorec.flags[0] & ISO_DIRECTORY) || + omit_version_number ? "" : ";1")); + + for (d1 = 0; d1 < 36; d1++) { + for (d2 = 0; d2 < 36; d2++) { + for (d3 = 0; d3 < 36; d3++) { + newname[new_reclen + 0] = + (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10); + newname[new_reclen + 1] = + (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10); + newname[new_reclen + 2] = + (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10); + if (debug) + error(_("NEW name '%s'\n"), newname); + +#ifdef VMS + /* Sigh. VAXCRTL seems to be broken here */ + { + int ijk = 0; + + while (newname[ijk]) { + if (newname[ijk] == ' ') + newname[ijk] = '0'; + ijk++; + } + } +#endif + + if (!find_file_hash(newname)) + goto got_valid_name; + } + } + } + + /* + * If we fell off the bottom here, we were in real trouble. + */ + comerrno(EX_BAD, + _("Unable to generate unique name for file %s\n"), + s_entry->name); + +got_valid_name: + /* + * OK, now we have a good replacement name. Now decide which + * one of these two beasts should get the name changed + */ + if (s_entry->priority < s_entry1->priority) { + if (verbose > 0) { + fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), + newname, + this_dir->whole_name, SPATH_SEPARATOR, + s_entry->name, s_entry1->name); + } + + s_entry->isorec.name_len[0] = strlen(newname); + new_reclen = offsetof(struct iso_directory_record, + name[0]) + + strlen(newname); + if (use_XA || use_RockRidge) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += s_entry->rr_attr_size; + } + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + s_entry->isorec.length[0] = new_reclen; + strcpy(s_entry->isorec.name, newname); +#ifdef USE_LARGEFILES + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + + /* + * Copy over the new name to all other entries + */ + for (s_e = s_entry->mxroot; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + s_e->isorec.length[0] = new_reclen; + s_e->isorec.name_len[0] = s_entry->isorec.name_len[0]; + strcpy(s_e->isorec.name, newname); + } + } +#endif +#ifdef APPLE_HYB + /* + * Has resource fork - needs new name + */ + if (apple_both && s_entry->assoc) { + struct directory_entry *s_entry2 = + s_entry->assoc; + + /* + * resource fork name *should* be the same as + * the data fork + */ + s_entry2->isorec.name_len[0] = + s_entry->isorec.name_len[0]; + strcpy(s_entry2->isorec.name, + s_entry->isorec.name); + s_entry2->isorec.length[0] = new_reclen; + } +#endif /* APPLE_HYB */ + } else { + delete_file_hash(s_entry1); + if (verbose > 0) { + fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), + newname, + this_dir->whole_name, SPATH_SEPARATOR, + s_entry1->name, s_entry->name); + } + s_entry1->isorec.name_len[0] = strlen(newname); + new_reclen = offsetof(struct iso_directory_record, + name[0]) + + strlen(newname); + if (use_XA || use_RockRidge) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += s_entry1->rr_attr_size; + } + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + s_entry1->isorec.length[0] = new_reclen; + strcpy(s_entry1->isorec.name, newname); +#ifdef USE_LARGEFILES + if (s_entry1->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + + /* + * Copy over the new name to all other entries + */ + for (s_e = s_entry1->mxroot; + s_e && s_e->mxroot == s_entry1->mxroot; + s_e = s_e->next) { + s_e->isorec.length[0] = new_reclen; + s_e->isorec.name_len[0] = s_entry1->isorec.name_len[0]; + strcpy(s_e->isorec.name, newname); + } + } +#endif + add_file_hash(s_entry1); +#ifdef APPLE_HYB + /* + * Has resource fork - needs new name + */ + if (apple_both && s_entry1->assoc) { + struct directory_entry *s_entry2 = + s_entry1->assoc; + + /* + * resource fork name *should* be the same as + * the data fork + */ + s_entry2->isorec.name_len[0] = + s_entry1->isorec.name_len[0]; + strcpy(s_entry2->isorec.name, + s_entry1->isorec.name); + s_entry2->isorec.length[0] = new_reclen; + } +#endif /* APPLE_HYB */ + } + add_file_hash(s_entry); + s_entry = s_entry->next; + } + + if (generate_tables && + !find_file_hash(trans_tbl) && + (reloc_dir != this_dir) && + (this_dir->extent == 0)) { + /* + * First we need to figure out how big this table is + */ + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; +#ifdef APPLE_HYB + /* + * Skip table entry for the resource fork + */ + if (apple_both && + (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) + continue; +#endif /* APPLE_HYB */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + continue; + if (s_entry->table) { + /* + * Max namelen, a space before and a space + * after the iso filename. + */ + tablesize += MAX_ISONAME + 2 + + strlen(s_entry->table); + } + } + } + if (tablesize > 0) { + table = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(table, 0, sizeof (struct directory_entry)); + table->table = NULL; + table->next = this_dir->contents; + this_dir->contents = table; + + table->filedir = root; + table->isorec.flags[0] = ISO_FILE; + table->priority = 32768; + iso9660_date(table->isorec.date, fstatbuf.st_mtime); + table->inode = TABLE_INODE; + table->dev = UNCACHED_DEVICE; + set_723(table->isorec.volume_sequence_number, + volume_sequence_number); + set_733((char *)table->isorec.size, tablesize); + table->size = tablesize; + table->filedir = this_dir; + if (jhide_trans_tbl) + table->de_flags |= INHIBIT_JOLIET_ENTRY; + /* + * Always hide transtable from UDF tree. + */ + table->de_flags |= INHIBIT_UDF_ENTRY; +/* table->name = e_strdup("");*/ + table->name = e_strdup(trans_tbl); + /* + * We use sprintf() to create the strings, for this reason + * we need to add one byte for the null character at the + * end of the string even though we don't use it. + */ + table->table = (char *)e_malloc(ISO_ROUND_UP(tablesize)+1); + memset(table->table, 0, ISO_ROUND_UP(tablesize)+1); + iso9660_file_length(trans_tbl, table, 0); + + if (use_XA || use_RockRidge) { + fstatbuf.st_mode = 0444 | S_IFREG; + fstatbuf.st_nlink = 1; + generate_xa_rr_attributes("", + trans_tbl, table, + &fstatbuf, &fstatbuf, 0); + } + } + /* + * We have now chosen the 8.3 names and we should now know the length + * of every entry in the directory. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + new_reclen = strlen(s_entry->isorec.name); + + /* + * First update the path table sizes for directories. + */ + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + path_table_size += new_reclen + + offsetof(struct iso_path_table, + name[0]); + if (new_reclen & 1) + path_table_size++; + } else { + new_reclen = 1; + if (this_dir == root && strlen(s_entry->name) + == 1) { + path_table_size += new_reclen + + offsetof(struct iso_path_table, + name[0]); + } + } + } + if (path_table_size & 1) + path_table_size++; /* For odd lengths we pad */ + s_entry->isorec.name_len[0] = new_reclen; + + new_reclen += offsetof(struct iso_directory_record, name[0]); + + if (new_reclen & 1) + new_reclen++; + + new_reclen += s_entry->rr_attr_size; + + if (new_reclen & 1) + new_reclen++; + + if (new_reclen > 0xff) { + comerrno(EX_BAD, + _("Fatal error - RR overflow (reclen %d) for file %s\n"), + new_reclen, + s_entry->name); + } + s_entry->isorec.length[0] = new_reclen; + } + + status = sort_directory(&this_dir->contents, (reloc_dir == this_dir)); + if (status > 0) { + errmsgno(EX_BAD, _("Unable to sort directory %s\n"), + this_dir->whole_name); + errmsgno(EX_BAD, + _("If there was more than one directory type argument to mkisofs\n")); + comerrno(EX_BAD, + _("use -graft-points to create different target directory names.\n")); + } + /* + * If we are filling out a TRANS.TBL, generate the entries that will + * go in the thing. + */ + if (table) { + count = 0; + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (s_entry == table) + continue; + if (!s_entry->table) + continue; + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; +#ifdef APPLE_HYB + /* + * Skip table entry for the resource fork + */ + if (apple_both && + (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) + continue; +#endif /* APPLE_HYB */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + continue; + /* + * Warning: we cannot use the return value of sprintf + * because old BSD based sprintf() implementations + * will return a pointer to the result instead of a + * count. + * Old mkiofs introduced a space after the iso + * filename to make parsing TRANS.TBL easier. + */ + sprintf(table->table + count, "%c %-*s%s", + s_entry->table[0], + MAX_ISONAME + 1, + s_entry->isorec.name, s_entry->table + 1); + count += strlen(table->table + count); + free(s_entry->table); + /* + * for a memory file, set s_entry->table to the + * correct data - which is stored in + * s_entry->whole_name + */ + if (s_entry->de_flags & MEMORY_FILE) { + s_entry->table = s_entry->whole_name; + s_entry->whole_name = NULL; + } else { + s_entry->table = NULL; + } + } + + if (count != tablesize) { + comerrno(EX_BAD, + _("Translation table size mismatch %d %d\n"), + count, tablesize); + } + } + /* + * Now go through the directory and figure out how large this one will + * be. Do not split a directory entry across a sector boundary + */ + s_entry = this_dir->contents; + this_dir->ce_bytes = 0; + while (s_entry) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + new_reclen = s_entry->isorec.length[0]; + if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen + >= SECTOR_SIZE) + + this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & + ~(SECTOR_SIZE - 1); + this_dir->size += new_reclen; + + /* + * See if continuation entries were used on disc + */ + if (use_RockRidge && + s_entry->rr_attr_size != s_entry->total_rr_attr_size) { + unsigned char *pnt; + int len; + int nbytes; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); +/* pnt = parse_xa(pnt, &len, s_entry);*/ + + /* + * We make sure that each continuation entry record is + * not split across sectors, but each file could in + * theory have more than one CE, so we scan through + * and figure out what we need. + */ + while (len > 3) { + if (pnt[0] == 'C' && pnt[1] == 'E') { + nbytes = get_733((char *)pnt + 20); + + if ((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= + SECTOR_SIZE) + this_dir->ce_bytes = + ISO_ROUND_UP(this_dir->ce_bytes); + /* + * Now store the block in the + * ce buffer + */ + this_dir->ce_bytes += nbytes; + if (this_dir->ce_bytes & 1) + this_dir->ce_bytes++; + } + len -= pnt[2]; + pnt += pnt[2]; + } + } + s_entry = s_entry->next; + } + return (status); +} + +LOCAL void +generate_reloc_directory() +{ + time_t current_time; + struct directory_entry *s_entry; + + /* + * Create an entry for our internal tree + */ + time(¤t_time); + reloc_dir = (struct directory *) + e_malloc(sizeof (struct directory)); + memset(reloc_dir, 0, sizeof (struct directory)); + reloc_dir->parent = root; + reloc_dir->next = root->subdir; + root->subdir = reloc_dir; + reloc_dir->depth = 1; + if (hide_rr_moved) { + reloc_dir->whole_name = e_strdup("./.rr_moved"); + reloc_dir->de_name = e_strdup(".rr_moved"); + } else { + reloc_dir->whole_name = e_strdup("./rr_moved"); + reloc_dir->de_name = e_strdup("rr_moved"); + } + reloc_dir->de_path = reloc_dir->de_name; + reloc_dir->extent = 0; + + + /* + * Now create an actual directory entry + */ + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = root->contents; + reloc_dir->self = s_entry; + + /* + * The rr_moved entry will not appear in the Joliet nor the UDF tree. + */ + reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + + reloc_dir->dir_flags |= INHIBIT_UDF_ENTRY; + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + + root->contents = s_entry; + root->contents->name = e_strdup(reloc_dir->de_name); + root->contents->filedir = root; + root->contents->isorec.flags[0] = ISO_DIRECTORY; + root->contents->priority = 32768; + iso9660_date(root->contents->isorec.date, current_time); + root->contents->inode = UNCACHED_INODE; + root->contents->dev = UNCACHED_DEVICE; + set_723(root->contents->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(reloc_dir->de_name, root->contents, 1); + + init_fstatbuf(); + + if (use_XA || use_RockRidge) { + fstatbuf.st_mode = 0555 | S_IFDIR; + fstatbuf.st_nlink = 2; + generate_xa_rr_attributes("", + hide_rr_moved ? ".rr_moved" : "rr_moved", + s_entry, &fstatbuf, &fstatbuf, NEED_RE); + }; + + /* + * Now create the . and .. entries in rr_moved + * Now create an actual directory entry + */ + if (root_statbuf.st_nlink == 0) + root_statbuf = fstatbuf; + attach_dot_entries(reloc_dir, NULL, &root_statbuf); +} + +/* + * Function: attach_dot_entries + * + * Purpose: Create . and .. entries for a new directory. + * + * Notes: Only used for artificial directories that + * we are creating. + */ +EXPORT void +attach_dot_entries(dirnode, this_stat, parent_stat) + struct directory *dirnode; + struct stat *this_stat; + struct stat *parent_stat; +{ + struct directory_entry *s_entry; + struct directory_entry *orig_contents; + int deep_flag = 0; + + init_fstatbuf(); + fstatbuf.st_mode = new_dir_mode | S_IFDIR; + fstatbuf.st_nlink = 2; + if (parent_stat == NULL) + parent_stat = &fstatbuf; + if (this_stat == NULL) + this_stat = &fstatbuf; + + orig_contents = dirnode->contents; + + if ((dirnode->dir_flags & DIR_HAS_DOTDOT) == 0) { + if (dirnode->parent && + dirnode->parent == reloc_dir) { + deep_flag = NEED_PL; + } + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry, dirnode->self, + sizeof (struct directory_entry)); +#ifdef APPLE_HYB + if (dirnode->self->hfs_ent) { + s_entry->hfs_ent = (hfsdirent *) + e_malloc(sizeof (hfsdirent)); + memcpy(s_entry->hfs_ent, dirnode->self->hfs_ent, + sizeof (hfsdirent)); + } +#endif + s_entry->name = e_strdup(".."); + s_entry->whole_name = NULL; + s_entry->isorec.name_len[0] = 1; + s_entry->isorec.flags[0] = ISO_DIRECTORY; + iso9660_file_length("..", s_entry, 1); + iso9660_date(s_entry->isorec.date, parent_stat->st_mtime); + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733(s_entry->isorec.size, SECTOR_SIZE); + memset(s_entry->isorec.extent, 0, 8); + s_entry->filedir = dirnode->parent; + + dirnode->contents = s_entry; + dirnode->contents->next = orig_contents; + orig_contents = s_entry; + + if (use_XA || use_RockRidge) { + generate_xa_rr_attributes("", + "..", s_entry, + parent_stat, + parent_stat, deep_flag); + } + dirnode->dir_flags |= DIR_HAS_DOTDOT; + } + deep_flag = 0; + if ((dirnode->dir_flags & DIR_HAS_DOT) == 0) { + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry, dirnode->self, + sizeof (struct directory_entry)); +#ifdef APPLE_HYB + if (dirnode->self->hfs_ent) { + s_entry->hfs_ent = (hfsdirent *) + e_malloc(sizeof (hfsdirent)); + memcpy(s_entry->hfs_ent, dirnode->self->hfs_ent, + sizeof (hfsdirent)); + } +#endif + s_entry->name = e_strdup("."); + s_entry->whole_name = NULL; + s_entry->isorec.name_len[0] = 1; + s_entry->isorec.flags[0] = ISO_DIRECTORY; + iso9660_file_length(".", s_entry, 1); + iso9660_date(s_entry->isorec.date, this_stat->st_mtime); + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733(s_entry->isorec.size, SECTOR_SIZE); + memset(s_entry->isorec.extent, 0, 8); + s_entry->filedir = dirnode; + + dirnode->contents = s_entry; + dirnode->contents->next = orig_contents; + + if (use_XA || use_RockRidge) { + if (dirnode == root) { + deep_flag |= NEED_CE | NEED_SP; /* For extension record */ + } + generate_xa_rr_attributes("", + ".", s_entry, + this_stat, this_stat, deep_flag); + } + dirnode->dir_flags |= DIR_HAS_DOT; + } +} + +EXPORT char * +find_rr_attribute(pnt, len, attr_type) + unsigned char *pnt; + int len; + char *attr_type; +{ + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + errmsgno(EX_BAD, + _("**BAD RRVERSION (%d) in '%c%c' field (%2.2X %2.2X).\n"), + pnt[3], pnt[0], pnt[1], pnt[0], pnt[1]); + } + if (pnt[2] < 4) { + errmsgno(EX_BAD, + _("**BAD RRLEN (%d) in '%2.2s' field %2.2X %2.2X.\n"), + pnt[2], pnt, pnt[0], pnt[1]); + return (NULL); + } + if (strncmp((char *)pnt, attr_type, 2) == 0) + return ((char *)pnt); + else if (strncmp((char *)pnt, "ST", 2) == 0) + return (NULL); + len -= pnt[2]; + pnt += pnt[2]; + } + return (NULL); +} + +EXPORT void +finish_cl_pl_entries() +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct directory *d_entry; + + /* + * If the reloc_dir is hidden (empty), then return + */ + if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) + return; + + s_entry = reloc_dir->contents; + s_entry = s_entry->next->next; /* Skip past . and .. */ + for (; s_entry; s_entry = s_entry->next) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + d_entry = reloc_dir->subdir; + while (d_entry) { + if (d_entry->self == s_entry) + break; + d_entry = d_entry->next; + }; + if (!d_entry) { + comerrno(EX_BAD, + _("Unable to locate directory parent\n")); + }; + + if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) { + char *rr_attr; + + /* + * First fix the PL pointer in the directory in the + * rr_reloc dir + */ + s_entry1 = d_entry->contents->next; + +/* set_733((char *) s_entry1->rr_attributes +*/ +/* s_entry1->total_rr_attr_size - 8,*/ +/* s_entry->filedir->extent); */ + /* + * The line above won't work when entry was read from + * the previous session, because if total_rr_attr_size + * was odd when recording previous session, now we have + * total_rr_attr_size off by 1 due to padding. + * + * So, just search for the attributes by name + */ + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "PL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, s_entry->filedir->extent); + + + /* + * Now fix the CL pointer + */ + s_entry1 = s_entry->parent_rec; + +/* set_733((char *) s_entry1->rr_attributes +*/ +/* s_entry1->total_rr_attr_size - 8, d_entry->extent); */ + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "CL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, d_entry->extent); + } + s_entry->filedir = reloc_dir; /* Now we can fix this */ + } + /* + * We would need to modify the NLINK terms in the assorted root + * directory records to account for the presence of the RR_MOVED + * directory. We do not do this here because we do it later when + * we correct the link count for all direstories in the tree. + */ + + + finish_cl_pl_for_prev_session(); +} + +LOCAL void +dir_nesting_warn(this_dir, path, contflag) + struct directory *this_dir; + char *path; + int contflag; +{ + static BOOL did_hint = FALSE; + + errmsgno(EX_BAD, + _("Directories too deep for '%s' (%d) max is %d%s.\n"), + path, this_dir->depth, RR_relocation_depth, + contflag?_("; ignored - continuing"):""); + if (!did_hint) { + did_hint = TRUE; + errmsgno(EX_BAD, _("To include the complete directory tree,\n")); + errmsgno(EX_BAD, _("use Rock Ridge extensions via -R or -r,\n")); + errmsgno(EX_BAD, _("or allow deep ISO9660 directory nesting via -D.\n")); + } +} + +/* + * Function: scan_directory_tree + * + * Purpose: Walk through a directory on the local machine + * filter those things we don't want to include + * and build our representation of a dir. + * + * Notes: + */ +EXPORT int +scan_directory_tree(this_dir, path, de) + struct directory *this_dir; + char *path; + struct directory_entry *de; +{ + DIR *current_dir; + char whole_path[2*PATH_MAX]; /* Avoid stat buffer overflow */ + struct dirent *d_entry; + int dflag; +extern BOOL nodesc; + + if (nodesc) + return (1); + + if (verbose > 1) { + fprintf(stderr, _("Scanning %s\n"), path); + } +/*#define check_needed*/ +#ifdef check_needed + /* + * Trying to use this to avoid directory loops from hard links + * or followed symlinks does not work. It would prevent us from + * implementing merge directories. + */ + if (this_dir->dir_flags & DIR_WAS_SCANNED) { + fprintf(stderr, _("Already scanned directory %s\n"), path); + return (1); /* It's a directory */ + } +#endif + this_dir->dir_flags |= DIR_WAS_SCANNED; + + errno = 0; /* Paranoia */ + current_dir = opendir(path); + d_entry = NULL; + + /* + * Apparently NFS sometimes allows you to open the directory, but then + * refuses to allow you to read the contents. Allow for this + */ + if (current_dir) { + errno = 0; + d_entry = readdir(current_dir); + } + + if (!current_dir || (!d_entry && errno != 0)) { + int ret = 1; + + errmsg(_("Unable to open directory %s\n"), path); + + if (errno == ENOTDIR) { + /* + * Mark as not a directory + */ + de->isorec.flags[0] &= ~ISO_DIRECTORY; + ret = 0; + } + if (current_dir) + closedir(current_dir); + return (ret); + } + + /* + * Set up the struct for the current directory, and insert it into + * the tree + */ +#ifdef VMS + vms_path_fixup(path); +#endif + + /* + * if entry for this sub-directory is hidden, then hide this directory + */ + if (de->de_flags & INHIBIT_ISO9660_ENTRY) + this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; + + if (de->de_flags & INHIBIT_JOLIET_ENTRY) + this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; + +#ifdef SORTING + /* + * set any sort weighting from it's own directory entry - if a + * directory is given a weighting, then all the contents will use + * this as the default weighting + */ + this_dir->sort = de->sort; +#endif /* SORTING */ + + /* + * Now we scan the directory itself, and look at what is inside of it. + */ + whole_path[0] = '\0'; + dflag = -2; + while (1 == 1) { + char *d_name; + + if (dflag < 0) { + /* + * Some filesystems do not deliver "." and ".." at all, + * others (on Linux) deliver them in the wrong order. + * Make sure we add "." and ".." before all other + * entries. + */ + if (dflag < -1) + d_name = "."; + else + d_name = ".."; + dflag++; + } else { + /* + * The first time through, skip this, since we already + * asked for the first entry when we opened the + * directory. + */ + if (dflag > 0) { + d_entry = readdir(current_dir); + } else { + dflag++; + } + if (!d_entry) + break; + d_name = d_entry->d_name; + } + + /* + * OK, got a valid entry + * + * If we do not want all files, then pitch the backups. + */ + if (!all_files) { + if (strchr(d_name, '~') || + strchr(d_name, '#') || + rstr(d_name, ".bak")) { + if (verbose > 0) { + fprintf(stderr, + _("Ignoring file %s\n"), + d_name); + } + continue; + } + } +#ifdef APPLE_HYB + if (apple_both) { + /* + * exclude certain HFS type files/directories for the + * time being + */ + if (hfs_exclude(d_name)) + continue; + } +#endif /* APPLE_HYB */ + + if (strlen(path) + strlen(d_name) + 2 > sizeof (whole_path)) { + errmsgno(EX_BAD, _("Path name %s/%s too long.\n"), + path, d_name); + comerrno(EX_BAD, _("Overflow of stat buffer\n")); + }; + + /* + * Generate the complete ASCII path for this file + */ + strlcpy(whole_path, path, sizeof (whole_path)); +#ifndef VMS + if (whole_path[strlen(whole_path) - 1] != '/') + strcat(whole_path, "/"); +#endif + strcat(whole_path, d_name); + + /* + * Should we exclude this file ? + * Do no check "." and ".." + */ + if (!(d_name[0] == '.' && (d_name[1] == '\0' || + (d_name[1] == '.' && d_name[2] == '\0'))) && + (matches(d_name) || matches(whole_path))) { + if (verbose > 1) { + fprintf(stderr, + _("Excluded by match: %s\n"), whole_path); + } + continue; + } + if (generate_tables && + strcmp(d_name, trans_tbl) == 0) { + /* + * Ignore this entry. We are going to be generating + * new versions of these files, and we need to ignore + * any originals that we might have found. + */ + if (verbose > 1) { + fprintf(stderr, _("Excluded: %s\n"), whole_path); + } + continue; + } + /* + * If we already have a '.' or a '..' entry, then don't insert + * new ones. + */ + if (strcmp(d_name, ".") == 0 && + this_dir->dir_flags & DIR_HAS_DOT) { + continue; + } + if (strcmp(d_name, "..") == 0 && + this_dir->dir_flags & DIR_HAS_DOTDOT) { + continue; + } +#if 0 + if (verbose > 1) + fprintf(stderr, "%s\n", whole_path); +#endif + /* + * This actually adds the entry to the directory in question. + */ + insert_file_entry(this_dir, whole_path, d_name, NULL, 0); + } + closedir(current_dir); + +#ifdef APPLE_HYB + /* + * if we cached the HFS info stuff for this directory, then delete it + */ + if (this_dir->hfs_info) { + del_hfs_info(this_dir->hfs_info); + this_dir->hfs_info = 0; + } +#endif /* APPLE_HYB */ + + return (1); +} + +LOCAL struct directory_entry * +dup_relocated_dir(this_dir, s_entry, whole_path, short_name, statp) + struct directory *this_dir; + struct directory_entry *s_entry; + char *whole_path; + char *short_name; + struct stat *statp; +{ + struct directory_entry *s_entry1; + + if (!reloc_dir) + generate_reloc_directory(); + init_fstatbuf(); + + /* + * Replicate the entry for this directory. The old one will + * stay where it is, and it will be neutered so that it no + * longer looks like a directory. The new one will look like + * a directory, and it will be put in the reloc_dir. + */ + s_entry1 = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry1, s_entry, sizeof (struct directory_entry)); + s_entry1->table = NULL; + s_entry1->name = e_strdup(short_name); + s_entry1->whole_name = e_strdup(whole_path); + s_entry1->next = reloc_dir->contents; + reloc_dir->contents = s_entry1; + s_entry1->priority = 32768; + s_entry1->parent_rec = this_dir->contents; + set_723(s_entry1->isorec.volume_sequence_number, + volume_sequence_number); + s_entry1->filedir = this_dir; + iso9660_date(s_entry1->isorec.date, fstatbuf.st_mtime); + + if (use_XA || use_RockRidge) { + generate_xa_rr_attributes(whole_path, + short_name, s_entry1, + statp, statp, NEED_RE); + } + + statp->st_size = (off_t)0; + statp->st_mode &= 0777; + set_733((char *)s_entry->isorec.size, 0); + s_entry->size = 0; + s_entry->isorec.flags[0] = ISO_FILE; + s_entry->inode = UNCACHED_INODE; + s_entry->dev = UNCACHED_DEVICE; + s_entry->de_flags |= RELOCATED_DIRECTORY; + + return (s_entry1); +} + + +/* + * Function: insert_file_entry + * + * Purpose: Insert one entry into our directory node. + * + * Note: + * This function inserts a single entry into the directory. It + * is assumed that all filtering and decision making regarding what + * we want to include has already been made, so the purpose of this + * is to insert one entry (file, link, dir, etc), into this directory. + * Note that if the entry is a dir (or if we are following links, + * and the thing it points to is a dir), then we will scan those + * trees before we return. + */ +EXPORT int +insert_file_entry(this_dir, whole_path, short_name, statp, have_rsrc) + struct directory *this_dir; + char *whole_path; + char *short_name; + struct stat *statp; + int have_rsrc; +{ + struct stat statbuf, + lstatbuf; + struct directory_entry *s_entry, + *s_entry1; + int lstatus; + int status; + int deep_flag; +#ifdef USE_NO_SCANDIR + int no_scandir = 0; +#endif + +#ifdef APPLE_HYB + int x_hfs = 0; + int htype = TYPE_NONE; + +#endif /* APPLE_HYB */ + + if (statp) { + status = lstatus = 0; + lstatbuf = *statp; + if (S_ISLNK(lstatbuf.st_mode)) { + status = stat_filter(short_name, &statbuf); + } else { + statbuf = *statp; + } + } else { + status = stat_filter(whole_path, &statbuf); + + lstatus = lstat_filter(whole_path, &lstatbuf); + } + + if ((status == -1) && (lstatus == -1)) { + /* + * This means that the file doesn't exist, or isn't accessible. + * Sometimes this is because of NFS permissions problems. + */ + errmsg(_("Non-existent or inaccessible: %s\n"), whole_path); + return (0); + } + if (S_ISDIR(statbuf.st_mode) && + (this_dir->depth > RR_relocation_depth) && !use_RockRidge && + strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0) { + dir_nesting_warn(this_dir, whole_path, TRUE); + return (0); + } + if (this_dir == root && strcmp(short_name, ".") == 0) + root_statbuf = statbuf; /* Save this for later on */ + + /* + * We do this to make sure that the root entries are consistent + */ + if (this_dir == root && strcmp(short_name, "..") == 0) { + statbuf = root_statbuf; + lstatbuf = root_statbuf; + } + if (S_ISLNK(lstatbuf.st_mode)) { + /* + * Here we decide how to handle the symbolic links. Here we + * handle the general case - if we are not following links or + * there is an error, then we must change something. If RR + * is in use, it is easy, we let RR describe the file. If + * not, then we punt the file. + */ + if ((status || !follow_links)) { +#ifdef UDF + if (use_RockRidge || use_udf) { +#else + if (use_RockRidge) { +#endif + status = 0; + STAT_INODE(statbuf) = UNCACHED_INODE; + statbuf.st_dev = UNCACHED_DEVICE; +#ifdef UDF + if (create_udfsymlinks) { + char symlinkcontents[2048]; + off_t size = sizeof (symlinkcontents); + + if (udf_get_symlinkcontents(whole_path, + symlinkcontents, &size) == -1) { + statbuf.st_size = (off_t)0; + statbuf.st_mode = + (statbuf.st_mode & ~S_IFMT) | S_IFREG; + } else { + statbuf.st_size = size; + statbuf.st_mode = lstatbuf.st_mode; + } + } else { +#endif + statbuf.st_size = (off_t)0; + statbuf.st_mode = + (statbuf.st_mode & ~S_IFMT) | S_IFREG; +#ifdef UDF + } +#endif + } else { + if (follow_links) { + /* XXX errno may be wrong! */ + errmsg(_("Unable to stat file %s - ignoring and continuing.\n"), + whole_path); + } else { + errmsgno(EX_BAD, + _("Symlink %s ignored - continuing.\n"), + whole_path); + return (0); /* Non Rock Ridge discs */ + /* - ignore all symlinks */ + } + } + } + /* + * Here we handle a different kind of case. Here we have a + * symlink, but we want to follow symlinks. If we run across + * a directory loop, then we need to pretend that we are not + * following symlinks for this file. If this is the first + * time we have seen this, then make this seem as if there was + * no symlink there in the first place + */ + if (follow_links && + S_ISDIR(statbuf.st_mode)) { + if (strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (find_directory_hash(statbuf.st_dev, + STAT_INODE(statbuf))) { + if (!use_RockRidge) { + fprintf(stderr, + _("Already cached directory seen (%s)\n"), + whole_path); + return (0); + } + lstatbuf = statbuf; + /* + * XXX when this line was active, + * XXX mkisofs did not include all + * XXX files if it was called with '-f' + * XXX (follow symlinks). + * XXX Now scan_directory_tree() + * XXX checks if the directory has + * XXX already been scanned via the + * XXX DIR_WAS_SCANNED flag. + */ +/* no_scandir = 1;*/ + } else { + lstatbuf = statbuf; + add_directory_hash(statbuf.st_dev, + STAT_INODE(statbuf)); + } + } + } + /* + * For non-directories, we just copy the stat information over + * so we correctly include this file. + */ + if (follow_links && + !S_ISDIR(statbuf.st_mode)) { + lstatbuf = statbuf; + } + } + /* + * Add directories to the cache so that we don't waste space even if + * we are supposed to be following symlinks. + */ + if (follow_links && + strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0 && + S_ISDIR(statbuf.st_mode)) { + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + } +#ifdef VMS + if (!S_ISDIR(lstatbuf.st_mode) && (statbuf.st_fab_rfm != FAB$C_FIX && + statbuf.st_fab_rfm != FAB$C_STMLF)) { + fprintf(stderr, + _("Warning - file %s has an unsupported VMS record format (%d)\n"), + whole_path, statbuf.st_fab_rfm); + } +#endif + + if (S_ISREG(lstatbuf.st_mode) && + ((statp != NULL && (status = access(short_name, R_OK))) || + (statp == NULL && (status = access(whole_path, R_OK))))) { + errmsg(_("File %s is not readable - ignoring\n"), + whole_path); + return (0); + } +#ifdef USE_LARGEFILES + if (S_ISREG(lstatbuf.st_mode) && (lstatbuf.st_size >= maxnonlarge) && + !do_largefiles) { +#else + /* + * >= is required by the large file summit standard. + */ + if (S_ISREG(lstatbuf.st_mode) && (lstatbuf.st_size >= (off_t)0x7FFFFFFF)) { +#endif +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else + errno = EFBIG; +#endif + errmsg(_("File %s is too large for current mkisofs settings (-iso-level 3 or more required) - ignoring\n"), + whole_path); + return (0); + } + /* + * Add this so that we can detect directory loops with hard links. + * If we are set up to follow symlinks, then we skip this checking. + */ + if (!follow_links && + S_ISDIR(lstatbuf.st_mode) && + strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) { +/* comerrno(EX_BAD,*/ +/* _("Directory loop - fatal goof (%s %lx %lu).\n"),*/ + errmsgno(EX_BAD, + _("Warning: Directory loop (%s dev: %lx ino: %lu).\n"), + whole_path, (unsigned long) statbuf.st_dev, + (unsigned long) STAT_INODE(statbuf)); + } + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + } + if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && + !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) && + !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && + !S_ISDIR(lstatbuf.st_mode)) { + fprintf(stderr, + _("Unknown file type (%s) %s - ignoring and continuing.\n"), + filetype((int)lstatbuf.st_mode), whole_path); + return (0); + } + /* + * Who knows what trash this is - ignore and continue + */ + if (status) { + errmsg(_("Unable to stat file %s - ignoring and continuing.\n"), + whole_path); + return (0); + } + +#if !defined(__MINGW32__) && !defined(_MSC_VER) +#define is_archive(st) ((st).st_dev == archive_dev && (st).st_ino == archive_ino) + if (archive_isreg && is_archive(statbuf)) { + errmsgno(EX_BAD, + _("'%s' is the archive. Not dumped.\n"), whole_path); + return (0); + } +#endif + + /* + * Check to see if we have already seen this directory node. If so, + * then we don't create a new entry for it, but we do want to recurse + * beneath it and add any new files we do find. + */ + if (S_ISDIR(statbuf.st_mode)) { + int dflag; + + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, short_name) == 0) { + break; + } + } + if (s_entry != NULL && + strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + struct directory *child; + + /* + * This should not create a new directory + */ + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + for (s_entry = reloc_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, short_name) + == 0) { + break; + } + } + child = find_or_create_directory(reloc_dir, + whole_path, + s_entry, 1); + } else { + child = find_or_create_directory(this_dir, + whole_path, + s_entry, 1); + /* + * If unable to scan directory, mark this as a + * non-directory + */ + } +/* if (no_scandir)*/ + if (0) + dflag = 1; + else + dflag = scan_directory_tree(child, + whole_path, s_entry); + if (!dflag) { + lstatbuf.st_mode = + (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; + } + return (0); + } + } +#ifdef APPLE_HYB + /* + * Should we exclude this HFS file ? - only works with -hfs + */ + if (!have_rsrc && apple_hyb && strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if ((x_hfs = (hfs_matches(short_name) || + hfs_matches(whole_path))) == 1) { + if (verbose > 1) { + fprintf(stderr, _("Hidden from HFS tree: %s\n"), + whole_path); + } + } + } + /* + * check we are a file, using Apple extensions and have a .resource + * part and not excluded + */ + if (S_ISREG(lstatbuf.st_mode) && !have_rsrc && apple_both && !x_hfs) { + char rsrc_path[PATH_MAX]; /* rsrc fork filename */ + + /* + * Construct the resource full path + */ + htype = get_hfs_rname(whole_path, short_name, rsrc_path); + /* + * Check we can read the resouce fork + */ + if (htype) { + struct stat rstatbuf, + rlstatbuf; + + /* + * Some further checks on the file + */ + status = stat_filter(rsrc_path, &rstatbuf); + + lstatus = lstat_filter(rsrc_path, &rlstatbuf); + +/* if (!status && !lstatus && S_ISREG(rlstatbuf.st_mode)*/ +/* && rlstatbuf.st_size > (off_t)0) { */ + if (!status && !lstatus && S_ISREG(rstatbuf.st_mode) && + rstatbuf.st_size > (off_t)0) { + + /* + * have a resource file - insert it into the + * current directory but flag that we have a + * resource fork + */ + insert_file_entry(this_dir, rsrc_path, + short_name, NULL, htype); + } + } + } +#endif /* APPLE_HYB */ + + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + /* memset the whole struct, not just the isorec.extent part JCP */ + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = this_dir->contents; +/* memset(s_entry->isorec.extent, 0, 8); */ + this_dir->contents = s_entry; + deep_flag = 0; + s_entry->table = NULL; + + s_entry->name = e_strdup(short_name); + s_entry->whole_name = e_strdup(whole_path); + + s_entry->de_flags = 0; + if (S_ISLNK(lstatbuf.st_mode)) + s_entry->de_flags |= IS_SYMLINK; + + /* + * If the current directory is hidden, then hide all it's members + * otherwise check if this entry needs to be hidden as well + */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; + } else if (strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (i_matches(short_name) || i_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + _("Hidden from ISO9660 tree: %s\n"), + whole_path); + } + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; + } + if (h_matches(short_name) || h_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + _("Hidden ISO9660 attribute: %s\n"), + whole_path); + } + s_entry->de_flags |= HIDDEN_FILE; + } + } + if (this_dir != reloc_dir && + this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + } else if (strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (j_matches(short_name) || j_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + _("Hidden from Joliet tree: %s\n"), + whole_path); + } + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + } + } + if (this_dir != reloc_dir && + this_dir->dir_flags & INHIBIT_UDF_ENTRY) { + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + } else if (strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (u_matches(short_name) || u_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + _("Hidden from UDF tree: %s\n"), + whole_path); + } + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + } + } + +#ifdef SORTING + /* + * Inherit any sort weight from parent directory + */ + s_entry->sort = this_dir->sort; + +#ifdef DVD_AUD_VID + /* + * No use at all to do a sort if we don't make a dvd video/audio + */ + /* + * Assign special weights to VIDEO_TS and AUDIO_TS files. + * This can't be done with sort_matches for two reasons: + * first, we need to match against the destination (DVD) + * path rather than the source path, and second, there are + * about 2400 different file names to check, each needing + * a different priority, and adding that many patterns to + * sort_matches would slow things to a crawl. + */ + + if (dvd_aud_vid_flag) { + s_entry->sort = assign_dvd_weights(s_entry->name, this_dir, s_entry->sort); + /* + * Turn on sorting if necessary, regardless of cmd-line options + */ + if ((s_entry->sort != this_dir->sort) && do_sort == 0) + do_sort++; + } +#endif + + /* + * See if this entry should have a new weighting + */ + if (do_sort && strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + s_entry->sort = sort_matches(whole_path, s_entry->sort); + } +#endif /* SORTING */ + + s_entry->filedir = this_dir; + s_entry->isorec.flags[0] = ISO_FILE; + if (s_entry->de_flags & HIDDEN_FILE) + s_entry->isorec.flags[0] |= ISO_EXISTENCE; + s_entry->isorec.ext_attr_length[0] = 0; + iso9660_date(s_entry->isorec.date, statbuf.st_mtime); + s_entry->isorec.file_unit_size[0] = 0; + s_entry->isorec.interleave[0] = 0; + +#ifdef APPLE_HYB + if (apple_both && !x_hfs) { + s_entry->hfs_ent = NULL; + s_entry->assoc = NULL; + s_entry->hfs_off = (off_t)0; + s_entry->hfs_type = htype; + if (have_rsrc) { + /* associated (rsrc) file */ + s_entry->isorec.flags[0] |= ISO_ASSOCIATED; + /* set the type of HFS file */ + s_entry->hfs_type = have_rsrc; + /* + * don't want the rsrc file to be included in any + * Joliet/UDF tree + */ + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + } else if (s_entry->next) { + /* + * if previous entry is an associated file, + * then "link" it to this file i.e. we have a + * data/resource pair + */ + if (s_entry->next->isorec.flags[0] & ISO_ASSOCIATED) { + s_entry->assoc = s_entry->next; + /* + * share the same HFS parameters + */ + s_entry->hfs_ent = s_entry->next->hfs_ent; + s_entry->hfs_type = s_entry->next->hfs_type; + } + } + /* + * Allocate HFS entry if required + */ + if (apple_both && strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + if (!s_entry->hfs_ent) { + hfsdirent *hfs_ent; + + hfs_ent = + (hfsdirent *) e_malloc(sizeof (hfsdirent)); + + /* + * Sill in the defaults + */ + memset(hfs_ent, 0, sizeof (hfsdirent)); + + s_entry->hfs_ent = hfs_ent; + } + /* + * the resource fork is processed first, but the + * data fork's time info is used in preference + * i.e. time info is set from the resource fork + * initially, then it is set from the data fork + */ + if (have_rsrc) { + /* + * Set rsrc size + */ + s_entry->hfs_ent->u.file.rsize = lstatbuf.st_size; + /* + * This will be overwritten - but might as + * well set it here ... + */ + s_entry->hfs_ent->crdate = lstatbuf.st_ctime; + s_entry->hfs_ent->mddate = lstatbuf.st_mtime; + } else { + /* + * Set data size + */ + s_entry->hfs_ent->u.file.dsize = lstatbuf.st_size; + s_entry->hfs_ent->crdate = lstatbuf.st_ctime; + s_entry->hfs_ent->mddate = lstatbuf.st_mtime; + } + } + } +#endif /* APPLE_HYB */ + + if (strcmp(short_name, ".") == 0) { + this_dir->dir_flags |= DIR_HAS_DOT; + } + if (strcmp(short_name, "..") == 0) { + this_dir->dir_flags |= DIR_HAS_DOTDOT; + } + if (this_dir->parent && + this_dir->parent == reloc_dir && + strcmp(short_name, "..") == 0) { + s_entry->inode = UNCACHED_INODE; + s_entry->dev = UNCACHED_DEVICE; + deep_flag = NEED_PL; + } else +#ifdef APPLE_HYB + if (have_rsrc) { + /* + * don't want rsrc files to be cached + */ + s_entry->de_flags |= RESOURCE_FORK; + s_entry->inode = UNCACHED_INODE; + s_entry->dev = UNCACHED_DEVICE; + } else +#endif /* APPLE_HYB */ + { + s_entry->inode = STAT_INODE(statbuf); + s_entry->dev = statbuf.st_dev; + } + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); + s_entry->rr_attr_size = 0; + s_entry->total_rr_attr_size = 0; + s_entry->rr_attributes = NULL; + + /* + * Directories are assigned sizes later on + */ + if (!S_ISDIR(statbuf.st_mode)) { + if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || + S_ISFIFO(lstatbuf.st_mode) || + S_ISSOCK(lstatbuf.st_mode) || +#ifdef UDF + (S_ISLNK(lstatbuf.st_mode) && !create_udfsymlinks)) { +#else + FALSE) { +#endif + s_entry->size = (off_t)0; + statbuf.st_size = (off_t)0; + } else { + s_entry->size = statbuf.st_size; + } + + set_733((char *)s_entry->isorec.size, statbuf.st_size); + } else { + s_entry->isorec.flags[0] |= ISO_DIRECTORY; + } +#ifdef APPLE_HYB + /* + * If the directory is HFS excluded, then we don't have an hfs_ent + */ + if (apple_both && s_entry->hfs_ent && + (s_entry->isorec.flags[0] & ISO_DIRECTORY)) { + /* + * Get the Mac directory name + */ + get_hfs_dir(whole_path, short_name, s_entry); + + /* + * If required, set ISO directory name from HFS name + */ + if (use_mac_name) + iso9660_file_length(s_entry->hfs_ent->name, s_entry, 1); + } +#endif /* APPLE_HYB */ + + if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0 && + S_ISDIR(statbuf.st_mode) && + this_dir->depth > RR_relocation_depth) { + struct directory *child; + + /* + * Replicate the entry for this directory. The old one will + * stay where it is, and it will be neutered so that it no + * longer looks like a directory. The new one will look like + * a directory, and it will be put in the reloc_dir. + */ + s_entry1 = dup_relocated_dir(this_dir, s_entry, + whole_path, short_name, &statbuf); + + /* + * We need to set this temporarily so that the parent to this + * is correctly determined. + */ + s_entry1->filedir = reloc_dir; + child = find_or_create_directory(reloc_dir, whole_path, + s_entry1, 0); + free(child->de_path); /* allocated in this case */ + set_de_path(this_dir, child); + + +/* if (!no_scandir)*/ + if (!0) + scan_directory_tree(child, whole_path, s_entry1); + s_entry1->filedir = this_dir; + deep_flag = NEED_CL; + } + if (generate_tables && + strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + + char buffer[SECTOR_SIZE]; + int nchar; + + switch (lstatbuf.st_mode & S_IFMT) { + case S_IFDIR: + sprintf(buffer, "D\t%s\n", + s_entry->name); + break; + +/* + * extra for WIN32 - if it doesn't have the major/minor defined, then + * S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... + * code similar to that in rock.c + */ +#if 0 +/* + * Use the device handling code from + */ +#ifndef major +#define major(dev) (sizeof (dev_t) <= 2 ? ((dev) >> 8) : \ + (sizeof (dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ + (((dev) >> 16) >> 16))) +#define minor(dev) (sizeof (dev_t) <= 2 ? (dev) & 0xff : \ + (sizeof (dev_t) <= 4 ? (dev) & 0xffff : \ + (dev) & 0xffffffff)) +#endif +#endif + +#ifdef S_IFBLK + case S_IFBLK: + sprintf(buffer, "B\t%s\t%lu %lu\n", + s_entry->name, + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: + sprintf(buffer, "P\t%s\n", + s_entry->name); + break; +#endif +#ifdef S_IFCHR + case S_IFCHR: + sprintf(buffer, "C\t%s\t%lu %lu\n", + s_entry->name, + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; +#endif +#ifdef S_IFLNK + case S_IFLNK: +#ifdef HAVE_READLINK + nchar = readlink(statp?short_name:whole_path, + (char *)symlink_buff, + sizeof (symlink_buff)-1); + if (nchar < 0) { + errmsg(_("Cannot read link '%s'.\n"), + statp?short_name:whole_path); + } +#else + nchar = -1; +#endif + symlink_buff[nchar < 0 ? 0 : nchar] = 0; + sprintf(buffer, "L\t%s\t%s\n", + s_entry->name, symlink_buff); + break; +#endif +#ifdef S_IFSOCK + case S_IFSOCK: + sprintf(buffer, "S\t%s\n", + s_entry->name); + break; +#endif + case S_IFREG: + default: + sprintf(buffer, "F\t%s\n", + s_entry->name); + break; + }; + s_entry->table = e_strdup(buffer); + } + if (S_ISDIR(statbuf.st_mode)) { + int dflag; + + if (strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + struct directory *child; + + child = find_or_create_directory(this_dir, whole_path, + s_entry, 1); +#ifdef USE_NO_SCANDIR + if (no_scandir) + dflag = 1; + else +#endif + dflag = scan_directory_tree(child, whole_path, + s_entry); + + if (!dflag) { + lstatbuf.st_mode = + (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; + if (child->contents == NULL) { + delete_directory(this_dir, child); + } + } + } + /* If unable to scan directory, mark this as a non-directory */ + } + if (use_RockRidge && this_dir == root && + strcmp(s_entry->name, ".") == 0) { + deep_flag |= NEED_CE | NEED_SP; /* For extension record */ + } + /* + * Now figure out how much room this file will take in the directory + */ + +#ifdef APPLE_HYB + /* + * Ff the file is HFS excluded, then we don't have an hfs_ent + */ + if (apple_both && !have_rsrc && s_entry->hfs_ent) { + if (S_ISREG(lstatbuf.st_mode)) { /* it's a regular file */ + + /* + * Fill in the rest of the HFS entry + */ + get_hfs_info(whole_path, short_name, s_entry); + + /* + * If required, set ISO directory name from HFS name + */ + if (use_mac_name) + iso9660_file_length(s_entry->hfs_ent->name, + s_entry, 0); + + /* + * Print details about the HFS file + */ + if (verbose > 2) + print_hfs_info(s_entry); + + /* + * copy the new ISO9660 name to the rsrc fork + * - if it exists + */ + if (s_entry->assoc) + strcpy(s_entry->assoc->isorec.name, + s_entry->isorec.name); + + /* + * we can't handle hard links in the hybrid case, so we + * "uncache" the file. The downside to this is that + * hard linked files are added to the output image + * more than once (we've already done this for rsrc + * files) + */ + if (apple_hyb && have_rsrc) { + s_entry->de_flags |= RESOURCE_FORK; + s_entry->inode = UNCACHED_INODE; + s_entry->dev = UNCACHED_DEVICE; + } + } else if (!(s_entry->isorec.flags[0] & ISO_DIRECTORY)) { + /* not a directory .. */ + + /* + * no mac equivalent, so ignore - have to be careful + * here, the hfs_ent may be also be for a relocated + * directory + */ + if (s_entry->hfs_ent && + !(s_entry->de_flags & RELOCATED_DIRECTORY) && + (s_entry->isorec.flags[0] & ISO_MULTIEXTENT) == 0) { + free(s_entry->hfs_ent); + } + s_entry->hfs_ent = NULL; + } + /* + * if the rsrc size is zero, then we don't need the entry, so + * we might as well delete it - this will only happen if we + * didn't know the rsrc size from the rsrc file size + */ + if (s_entry->assoc && s_entry->assoc->size == 0) + delete_rsrc_ent(s_entry); + } + if (apple_ext && s_entry->assoc) { + /* + * Need Apple extensions for the resource fork as well + */ + generate_xa_rr_attributes(whole_path, + short_name, s_entry->assoc, + &statbuf, &lstatbuf, deep_flag | (statp?DID_CHDIR:0)); + } + /* leave out resource fork for the time being */ + /* + * XXX This is most likely wrong and should just be: + * XXX if (use_XA || use_RockRidge) { + */ +/* if ((use_XA || use_RockRidge) && !have_rsrc) {*/ + if (use_XA || use_RockRidge) { +#else + if (use_XA || use_RockRidge) { +#endif /* APPLE_HYB */ + generate_xa_rr_attributes(whole_path, + short_name, s_entry, + &statbuf, &lstatbuf, deep_flag | (statp?DID_CHDIR:0)); + + } +#ifdef UDF + /* set some info used for udf */ + s_entry->mode = lstatbuf.st_mode; + s_entry->rdev = lstatbuf.st_rdev; + s_entry->uid = lstatbuf.st_uid; + s_entry->gid = lstatbuf.st_gid; + s_entry->atime.tv_sec = lstatbuf.st_atime; + s_entry->atime.tv_nsec = stat_ansecs(&lstatbuf); + s_entry->mtime.tv_sec = lstatbuf.st_mtime; + s_entry->mtime.tv_nsec = stat_mnsecs(&lstatbuf); + s_entry->ctime.tv_sec = lstatbuf.st_ctime; + s_entry->ctime.tv_nsec = stat_cnsecs(&lstatbuf); +#endif + +#ifdef USE_LARGEFILES +#ifndef MAX_EXTENT + /* + * Allow to #define MAX_EXTENT from outside for debug purposes. + */ +#ifdef PROTOTYPES +#define LARGE_EXTENT ((off_t)0xFFFFF800UL) +#define MAX_EXTENT ((off_t)0xFFFFFFFEUL) +#else +#define LARGE_EXTENT ((off_t)0xFFFFF800L) +#define MAX_EXTENT ((off_t)0xFFFFFFFEL) +#endif +#else /* MAX_EXTENT */ +#define LARGE_EXTENT MAX_EXTENT & ~(off_t)2047L +#endif /* !MAX_EXTENT */ + /* + * Break up files greater than (4GB -2) into multiple extents. + * The original entry, with ->size untouched, remains for UDF. + * Each of the new file sections will get its own entry. + * The file sections are the only entries actually written out to the + * disk. The UDF entry will use "mxroot" to get the same start + * block as the first file section, and all the sections will end up + * in the ISO9660 directory in the correct order by "mxpart", + * which the directory sorting routine knows about. + * + * If we ever need to be able to find mxpart == 1 after sorting, + * we need to add another pointer to s_entry or to be very careful + * with the loops above where the ISO-9660 name is copied back to + * all multi-extent parts. + */ + if (s_entry->size > MAX_EXTENT) { + off_t size; + + s_entry->de_flags |= MULTI_EXTENT; + s_entry->isorec.flags[0] |= ISO_MULTIEXTENT; + s_entry->mxroot = s_entry; + s_entry->mxpart = 0; + set_733((char *)s_entry->isorec.size, LARGE_EXTENT); + s_entry1 = dup_directory_entry(s_entry); + s_entry->next = s_entry1; + + /* + * full size UDF version + */ + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY|INHIBIT_JOLIET_ENTRY; + if (s_entry->size > (((off_t)190)*0x3FFFF800)) { +#ifndef EOVERFLOW +#define EOVERFLOW EFBIG +#endif + errmsgno(EOVERFLOW, + _("File %s is too large - hiding from UDF tree.\n"), + whole_path); + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + } + + /* + * Prepare the first file multi-extent section of the file. + */ + s_entry = s_entry1; + s_entry->de_flags |= INHIBIT_UDF_ENTRY; + size = s_entry->size; + s_entry->size = LARGE_EXTENT; + s_entry->mxpart++; + + /* + * Additional extents, as needed + */ + while (size > MAX_EXTENT) { + s_entry1 = dup_directory_entry(s_entry); + s_entry->next = s_entry1; + + s_entry = s_entry1; + s_entry->mxpart++; + size -= LARGE_EXTENT; + } + /* + * That was the last one. + */ + s_entry->isorec.flags[0] &= ~ISO_MULTIEXTENT; + s_entry->size = size; + set_733((char *)s_entry->isorec.size, (UInt32_t)s_entry->size); + } +#endif /* USE_LARGEFILES */ + + return (1); +} + +EXPORT struct directory_entry * +dup_directory_entry(s_entry) + struct directory_entry *s_entry; +{ + struct directory_entry *s_entry1; + + s_entry1 = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry1, s_entry, sizeof (struct directory_entry)); + + if (s_entry->rr_attributes) { + s_entry1->rr_attributes = + e_malloc(s_entry->total_rr_attr_size); + memcpy(s_entry1->rr_attributes, s_entry->rr_attributes, + s_entry->total_rr_attr_size); + } + if (s_entry->name) + s_entry1->name = e_strdup(s_entry->name); + if (s_entry->whole_name) + s_entry1->whole_name = e_strdup(s_entry->whole_name); +#ifdef APPLE_HYB + /* + * If we also duplicate s_entry->hfs_ent, we would need to change + * free_one_directory() and other calls to free(s_entry->hfs_ent) too. + */ +#endif + return (s_entry1); +} + +EXPORT void +generate_iso9660_directories(node, outfile) + struct directory *node; + FILE *outfile; +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if (dpnt->extent > session_start) { + generate_one_directory(dpnt, outfile); + } + if (dpnt->subdir) + generate_iso9660_directories(dpnt->subdir, outfile); + dpnt = dpnt->next; + } +} + +/* + * XXX This may need some work for the MVS port. + */ +LOCAL void +set_de_path(parent, this) + struct directory *parent; + struct directory *this; +{ + char *p; + size_t len; + + if (parent == NULL) { /* We are just creating root */ + this->de_path = this->whole_name; + return; + } else if (parent == root) { /* full path == component */ + this->de_path = this->de_name; + return; + } + len = strlen(parent->de_path)+1+strlen(this->de_name)+1; + p = e_malloc(len); + js_snprintf(p, len, "%s/%s", parent->de_path, this->de_name); + this->de_path = p; +} + +/* + * Function: find_or_create_directory + * + * Purpose: Locate a directory entry in the tree, create if needed. + * + * Arguments: parent & de are never NULL at the same time. + */ +EXPORT struct directory * +find_or_create_directory(parent, path, de, flag) + struct directory *parent; + char *path; + struct directory_entry *de; + int flag; +{ + struct directory *child = 0; + struct directory *dpnt; + struct directory_entry *orig_de; + struct directory *next_brother; + const char *cpnt; + const char *pnt; + int deep_flag = 0; + + orig_de = de; + + /* + * XXX It seems that the tree that has been read from the + * XXX previous session does not carry whole_name entries. + * XXX We provide a hack in multi.c:find_or_create_directory() + * XXX that should be removed when a reasonable method could + * XXX be found. + */ + if (path == NULL) { + error(_("Warning: missing whole name for: '%s'\n"), de->name); + path = de->name; + if (path == NULL) + comerrno(EX_BAD, _("Panic no node name.\n")); + } + pnt = strrchr(path, PATH_SEPARATOR); + if (pnt == NULL) { + pnt = path; + } else { + pnt++; + } + + if (parent != NULL) { + + dpnt = parent->subdir; + if (dpnt == NULL) { + struct directory_entry *s_entry; + + for (s_entry = parent->contents; s_entry; + s_entry = s_entry->next) { + if ((strcmp(s_entry->name, pnt) == 0) && + (s_entry->de_flags & RELOCATED_DIRECTORY)) { + return (find_or_create_directory( + reloc_dir, path, de, + flag)); + } + } + } + + while (dpnt) { + /* + * Weird hack time - if there are two directories by + * the same name in the reloc_dir, they are not + * treated as the same thing unless the entire path + * matches completely. + */ + if (flag && strcmp(dpnt->de_name, pnt) == 0) { + + /* + * XXX Remove test? + * XXX dpnt->de_path should always be != NULL + */ + if (dpnt->de_path != NULL && + strcmp(dpnt->de_path, path) == 0) + return (dpnt); + + if (parent != reloc_dir && + strcmp(dpnt->de_name, pnt) == 0) + return (dpnt); + } + dpnt = dpnt->next; + } + } + /* + * We don't know if we have a valid directory entry for this one yet. + * If not, we need to create one. + */ + if (de == NULL) { + de = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(de, 0, sizeof (struct directory_entry)); + de->next = parent->contents; + parent->contents = de; + de->name = e_strdup(pnt); + de->whole_name = e_strdup(path); + de->filedir = parent; + de->isorec.flags[0] = ISO_DIRECTORY; + de->priority = 32768; + de->inode = UNCACHED_INODE; + de->dev = UNCACHED_DEVICE; + set_723(de->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(pnt, de, 1); + + init_fstatbuf(); +#ifdef APPLE_HYB + if (apple_both) { + /* + * Give the directory an HFS entry + */ + hfsdirent *hfs_ent; + + hfs_ent = (hfsdirent *) e_malloc(sizeof (hfsdirent)); + + /* + * Fill in the defaults + */ + memset(hfs_ent, 0, sizeof (hfsdirent)); + hfs_ent->crdate = fstatbuf.st_ctime; + hfs_ent->mddate = fstatbuf.st_mtime; + + de->hfs_ent = hfs_ent; + + /* + * Get the Mac directory name + */ + get_hfs_dir((char *)path, (char *)pnt, de); + } +#endif /* APPLE_HYB */ + } + /* + * If we don't have a directory for this one yet, then allocate it now, + * and patch it into the tree in the appropriate place. + */ + dpnt = (struct directory *)e_malloc(sizeof (struct directory)); + memset(dpnt, 0, sizeof (struct directory)); + dpnt->next = NULL; + dpnt->subdir = NULL; + dpnt->self = de; + dpnt->contents = NULL; + dpnt->whole_name = e_strdup(path); + cpnt = strrchr(path, PATH_SEPARATOR); + if (cpnt) + cpnt++; + else + cpnt = path; + dpnt->de_name = e_strdup(cpnt); + dpnt->de_path = NULL; + set_de_path(parent, dpnt); + dpnt->size = 0; + dpnt->extent = 0; + dpnt->jextent = 0; + dpnt->jsize = 0; +#ifdef APPLE_HYB + dpnt->hfs_ent = de->hfs_ent; +#endif /* APPLE_HYB */ + + if (orig_de == NULL) { + struct stat xstatbuf; + int sts; + + /* + * Now add a . and .. entry in the directory itself. This is a + * little tricky - if the real directory exists, we need to + * stat it first. Otherwise, we use the fictitious fstatbuf + * which points to the time at which mkisofs was started. + */ + if (parent == NULL || parent->whole_name[0] == '\0') + sts = -1; + else + sts = stat_filter(parent->whole_name, &xstatbuf); + if (debug && parent) { + error(_("stat parent->whole_name: '%s' -> %d.\n"), + parent->whole_name, sts); + } + if (sts == 0) { + attach_dot_entries(dpnt, NULL, &xstatbuf); + } else { + attach_dot_entries(dpnt, NULL, NULL); + } + } + if (!parent || parent == root) { + if (!root) { + root = dpnt; /* First time through for root */ + /* directory only */ + root->depth = 0; + root->parent = root; + } else { + dpnt->depth = 1; + if (!root->subdir) { + root->subdir = dpnt; + } else { + next_brother = root->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = dpnt; + } + dpnt->parent = parent; + } + } else { + struct directory_entry *s_entry1; + + /* + * Come through here for normal traversal of tree + */ +#ifdef DEBUG + fprintf(stderr, "%s(%d) ", path, dpnt->depth); +#endif + + if (parent->depth > RR_relocation_depth && use_RockRidge) { + /* + * We come here in case that a graft-point needs to + * create a new relocated (deep) directory. + * + * Replicate the entry for this directory. The old one + * will stay where it is, and it will be neutered so + * that it no longer looks like a directory. The new + * one will look like a directory, and it will be put + * in the reloc_dir. + */ + s_entry1 = dup_relocated_dir(parent, de, path, + dpnt->de_name, &fstatbuf); + child = find_or_create_directory(reloc_dir, path, + s_entry1, 0); + free(child->de_path); /* allocated in this case */ + set_de_path(parent, child); + + deep_flag |= NEED_CL; + } + if (parent->depth > RR_relocation_depth && !use_RockRidge) { + dir_nesting_warn(parent, path, FALSE); + exit(EX_BAD); + } + dpnt->parent = parent; + dpnt->depth = parent->depth + 1; + + if ((deep_flag & NEED_CL) == 0) { + /* + * Do not add this directory to the list of subdirs if + * this is a relocated directory. + */ + if (!parent->subdir) { + parent->subdir = dpnt; + } else { + next_brother = parent->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = dpnt; + } + } + } + /* + * It doesn't exist for real, so we cannot add any + * XA or Rock Ridge attributes. + */ + if (orig_de == NULL || (parent == NULL && path[0] == '\0')) { + init_fstatbuf(); + fstatbuf.st_mode = new_dir_mode | S_IFDIR; + fstatbuf.st_nlink = 2; + if ((use_XA || use_RockRidge) && + !(parent == NULL && path[0] == '\0')) { + /* + * We cannot set up RR attrubutes for the real + * ISO-9660 root directory. This is why we + * check for parent == NULL && path[0] == '\0'. + */ + generate_xa_rr_attributes("", + (char *)pnt, de, + &fstatbuf, + &fstatbuf, deep_flag); + } +#ifdef UDF + /* set some info used for udf */ + de->mode = fstatbuf.st_mode; + de->uid = fstatbuf.st_uid; + de->gid = fstatbuf.st_gid; + de->atime.tv_sec = fstatbuf.st_atime; + de->atime.tv_nsec = stat_ansecs(&fstatbuf); + de->mtime.tv_sec = fstatbuf.st_mtime; + de->mtime.tv_nsec = stat_mnsecs(&fstatbuf); + de->ctime.tv_sec = fstatbuf.st_ctime; + de->ctime.tv_nsec = stat_cnsecs(&fstatbuf); +#endif + iso9660_date(de->isorec.date, fstatbuf.st_mtime); + } + if (child) + return (child); /* Return reloaction target */ + + return (dpnt); +} + +/* + * Function: delete_directory + * + * Purpose: Locate a directory entry in the tree, create if needed. + * + * Arguments: + */ +LOCAL void +delete_directory(parent, child) + struct directory *parent; + struct directory *child; +{ + struct directory *tdir; + + if (child == NULL) + return; + if (child->contents != NULL) { + comerrno(EX_BAD, _("Unable to delete non-empty directory\n")); + } + free(child->whole_name); + child->whole_name = NULL; + + free(child->de_name); + child->de_name = NULL; + +#ifdef APPLE_HYB + if (apple_both && child->hfs_ent) + free(child->hfs_ent); +#endif /* APPLE_HYB */ + + if (parent->subdir == child) { + parent->subdir = child->next; + } else { + for (tdir = parent->subdir; tdir != NULL && tdir->next != NULL; + tdir = tdir->next) { + if (tdir->next == child) { + tdir->next = child->next; + break; + } + } + if (tdir == NULL || tdir->next != child->next) { + comerrno(EX_BAD, + _("Unable to locate child directory in parent list\n")); + } + } + free(child); +} + +EXPORT int +sort_tree(node) + struct directory *node; +{ + struct directory *dpnt; + int ret = 0; + + dpnt = node; + + while (dpnt) { + ret = sort_n_finish(dpnt); + if (ret) { + break; + } + if (dpnt->subdir) + sort_tree(dpnt->subdir); + dpnt = dpnt->next; + } + return (ret); +} + +EXPORT void +dump_tree(node) + struct directory *node; +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + fprintf(stderr, "%4d %5d %s\n", + dpnt->extent, dpnt->size, dpnt->de_name); + if (dpnt->subdir) + dump_tree(dpnt->subdir); + dpnt = dpnt->next; + } +} + +/* + * something quick and dirty to locate a file given a path + * recursively walks down path in filename until it finds the + * directory entry for the desired file + */ +EXPORT struct directory_entry * +search_tree_file(node, filename) + struct directory *node; + char *filename; +{ + struct directory_entry *depnt; + struct directory *dpnt; + char *p1; + char *rest; + char *subdir; + + /* + * Strip off next directory name from filename: + */ + subdir = e_strdup(filename); + + if ((p1 = strchr(subdir, '/')) == subdir) { + fprintf(stderr, + _("call to search_tree_file with an absolute path, stripping\n")); + fprintf(stderr, + _("initial path separator. Hope this was intended...\n")); + memmove(subdir, subdir + 1, strlen(subdir) - 1); + p1 = strchr(subdir, '/'); + } + /* + * Do we need to find a subdirectory? + */ + if (p1) { + *p1 = '\0'; + +#ifdef DEBUG_TORITO + fprintf(stderr, _("Looking for subdir called %s\n"), p1); +#endif + + rest = p1 + 1; + +#ifdef DEBUG_TORITO + fprintf(stderr, _("Remainder of path name is now %s\n"), rest); +#endif + + dpnt = node->subdir; + while (dpnt) { +#ifdef DEBUG_TORITO + fprintf(stderr, + "%4d %5d %s\n", dpnt->extent, dpnt->size, + dpnt->de_name); +#endif + if (strcmp(subdir, dpnt->de_name) == 0) { +#ifdef DEBUG_TORITO + fprintf(stderr, + _("Calling next level with filename = %s\n"), rest); +#endif + return (search_tree_file(dpnt, rest)); + } + dpnt = dpnt->next; + } + + /* + * If we got here means we couldn't find the subdir. + */ + return (NULL); + } else { + /* + * Look for a normal file now + */ + depnt = node->contents; + while (depnt) { +#ifdef DEBUG_TORITO + fprintf(stderr, "%4d %5d %s\n", depnt->isorec.extent, + depnt->size, depnt->name); +#endif + if (strcmp(filename, depnt->name) == 0) { +#ifdef DEBUG_TORITO + fprintf(stderr, _("Found our file %s"), filename); +#endif + return (depnt); + } + depnt = depnt->next; + } + /* + * If we got here means we couldn't find the subdir. + */ + return (NULL); + } +#ifdef ERIC_FUN + fprintf(stderr, _("We cant get here in search_tree_file :-/ \n")); +#endif +} + +EXPORT void +init_fstatbuf() +{ + struct timeval current_time; + + if (fstatbuf.st_ctime == 0) { + gettimeofday(¤t_time, NULL); + if (rationalize_uid) + fstatbuf.st_uid = uid_to_use; + else + fstatbuf.st_uid = getuid(); + if (rationalize_gid) + fstatbuf.st_gid = gid_to_use; + else + fstatbuf.st_gid = getgid(); + + current_time.tv_usec *= 1000; + fstatbuf.st_ctime = current_time.tv_sec; + stat_set_ansecs(&fstatbuf, current_time.tv_usec); + fstatbuf.st_mtime = current_time.tv_sec; + stat_set_mnsecs(&fstatbuf, current_time.tv_usec); + fstatbuf.st_atime = current_time.tv_sec; + stat_set_cnsecs(&fstatbuf, current_time.tv_usec); + } +} diff --git a/reactos/sdk/tools/mkisofs/schilytools/mkisofs/write.c b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/write.c new file mode 100644 index 00000000000..17a57c32a7f --- /dev/null +++ b/reactos/sdk/tools/mkisofs/schilytools/mkisofs/write.c @@ -0,0 +1,3017 @@ +/* @(#)write.c 1.144 16/10/10 joerg */ +#include +#ifndef lint +static UConst char sccsid[] = + "@(#)write.c 1.144 16/10/10 joerg"; +#endif +/* + * Program write.c - dump memory structures to file for iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-2016 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#include "mkisofs.h" +#include +#include +#ifdef SORTING +#include "match.h" +#endif /* SORTING */ +#include +#include +#include +#ifdef DVD_AUD_VID +#include "dvd_reader.h" +#include "dvd_file.h" +#include "ifo_read.h" +#endif +#ifdef APPLE_HYB +#include +#endif + +#ifdef VMS +#include "vms.h" +#endif + +#define SIZEOF_UDF_EXT_ATTRIBUTE_COMMON 50 + +/* Max number of sectors we will write at one time */ +#define NSECT 32 + +#define INSERTMACRESFORK 1 + +/* Counters for statistics */ + +LOCAL int table_size = 0; +LOCAL int total_dir_size = 0; +LOCAL int rockridge_size = 0; +LOCAL struct directory **pathlist; +LOCAL int next_path_index = 1; +LOCAL int sort_goof; + +LOCAL int is_rr_dir = 0; + +struct output_fragment *out_tail; +struct output_fragment *out_list; + +EXPORT struct iso_primary_descriptor vol_desc; +LOCAL int vol_desc_sum; + +#ifndef APPLE_HFS_HYB + char *hfs_error = __("no error"); +#endif + +LOCAL int xawrite __PR((void *buffer, int size, int count, + FILE *file, int submode, BOOL islast)); +EXPORT void xfwrite __PR((void *buffer, int size, int count, + FILE *file, int submode, BOOL islast)); +LOCAL int assign_directory_addresses __PR((struct directory *node)); +#if defined(APPLE_HYB) || defined(USE_LARGEFILES) +LOCAL void write_one_file __PR((char *filename, off_t size, + FILE *outfile, off_t off, + int isrfile, unsigned rba)); +#else +LOCAL void write_one_file __PR((char *filename, off_t size, + FILE *outfile)); +#endif +#ifdef UDF +LOCAL void write_udf_symlink __PR((char *filename, off_t size, + FILE *outfile)); +#endif +LOCAL void write_files __PR((FILE *outfile)); +#if 0 +LOCAL void dump_filelist __PR((void)); +#endif +LOCAL int compare_dirs __PR((const void *rr, const void *ll)); +EXPORT int sort_directory __PR((struct directory_entry **sort_dir, + int rr)); +LOCAL int root_gen __PR((void)); +LOCAL BOOL assign_file_addresses __PR((struct directory *dpnt, BOOL isnest)); +LOCAL void free_one_directory __PR((struct directory *dpnt)); +LOCAL void free_directories __PR((struct directory *dpnt)); +EXPORT void generate_one_directory __PR((struct directory *dpnt, + FILE *outfile)); +LOCAL void build_pathlist __PR((struct directory *node)); +LOCAL int compare_paths __PR((void const *r, void const *l)); +LOCAL int generate_path_tables __PR((void)); +EXPORT void memcpy_max __PR((char *to, char *from, int max)); +EXPORT void outputlist_insert __PR((struct output_fragment *frag)); +LOCAL int file_write __PR((FILE *outfile)); +LOCAL int pvd_write __PR((FILE *outfile)); +LOCAL int xpvd_write __PR((FILE *outfile)); +LOCAL int evd_write __PR((FILE *outfile)); +LOCAL int vers_write __PR((FILE *outfile)); +LOCAL int graftcp __PR((char *to, char *from, char *ep)); +LOCAL int pathcp __PR((char *to, char *from, char *ep)); +LOCAL int pathtab_write __PR((FILE *outfile)); +LOCAL int exten_write __PR((FILE *outfile)); +EXPORT int oneblock_size __PR((UInt32_t starting_extent)); +LOCAL int pathtab_size __PR((UInt32_t starting_extent)); +LOCAL int startpad_size __PR((UInt32_t starting_extent)); +LOCAL int interpad_size __PR((UInt32_t starting_extent)); +LOCAL int endpad_size __PR((UInt32_t starting_extent)); +LOCAL int file_gen __PR((void)); +LOCAL int dirtree_dump __PR((void)); +LOCAL int dirtree_fixup __PR((UInt32_t starting_extent)); +LOCAL int dirtree_size __PR((UInt32_t starting_extent)); +LOCAL int ext_size __PR((UInt32_t starting_extent)); +LOCAL int dirtree_write __PR((FILE *outfile)); +LOCAL int dirtree_cleanup __PR((FILE *outfile)); +LOCAL int startpad_write __PR((FILE *outfile)); +LOCAL int interpad_write __PR((FILE *outfile)); +LOCAL int endpad_write __PR((FILE *outfile)); +#ifdef APPLE_HYB +LOCAL int hfs_pad; +LOCAL int hfs_get_parms __PR((char *key)); +LOCAL void hfs_file_gen __PR((UInt32_t start_extent)); +LOCAL void gen_prepboot __PR((void)); +EXPORT Ulong get_adj_size __PR((int Csize)); +EXPORT int adj_size __PR((int Csize, UInt32_t start_extent, int extra)); +EXPORT void adj_size_other __PR((struct directory *dpnt)); +LOCAL int hfs_hce_write __PR((FILE *outfile)); +EXPORT int insert_padding_file __PR((int size)); +#endif /* APPLE_HYB */ + +#ifdef SORTING +LOCAL int compare_sort __PR((const void *rr, const void *ll)); +LOCAL void reassign_link_addresses __PR((struct directory *dpnt)); +LOCAL int sort_file_addresses __PR((void)); +#endif /* SORTING */ + +/* + * Routines to actually write the disc. We write sequentially so that + * we could write a tape, or write the disc directly + */ +#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof (vol_desc.X)) + +EXPORT void +xfwrite(buffer, size, count, file, submode, islast) + void *buffer; + int size; + int count; + FILE *file; + int submode; + BOOL islast; +{ + /* + * This is a hack that could be made better. + * XXXIs this the only place? + * It is definitely needed on Operating Systems that do not allow to + * write files that are > 2GB. If the system is fast enough to be able + * to feed 1400 KB/s writing speed of a DVD-R drive, use stdout. + * If the system cannot do this reliable, you need to use this hacky + * option. + */ + static int idx = 0; + +#ifdef XFWRITE_DEBUG + if (count != 1 || (size % 2048) != 0) + error(_("Count: %d, size: %d\n"), count, size); +#endif + if (count == 0 || size == 0) { + errmsgno(EX_BAD, + _("Implementation botch, write 0 bytes (size %d count %d).\n"), + size, count); + abort(); + } + + if (split_output != 0 && + (idx == 0 || ftell(file) >= ((off_t)1024 * 1024 * 1024))) { + char nbuf[512]; + extern char *outfile; + + if (idx == 0) + unlink(outfile); + sprintf(nbuf, "%s_%02d", outfile, idx++); + file = freopen(nbuf, "wb", file); + if (file == NULL) { + comerr(_("Cannot open '%s'.\n"), nbuf); + } + } + while (count) { + int got; + + seterrno(0); + if (osecsize != 0) + got = xawrite(buffer, size, count, file, submode, islast); + else + got = fwrite(buffer, size, count, file); + + if (got <= 0) { + comerr(_("cannot fwrite %d*%d\n"), size, count); + } + /* + * This comment is in hope to prevent silly people from + * e.g. SuSE (who did not yet learn C but believe that + * they need to patch other peoples code) from changing the + * next cast into an illegal lhs cast expression. + * The cast below is the correct way to handle the problem. + * The (void *) cast is to avoid a GCC warning like: + * "warning: dereferencing type-punned pointer will break \ + * strict-aliasing rules" + * which is wrong this code. (void *) introduces a compatible + * intermediate type in the cast list. + */ + count -= got, *(char **)(void *)&buffer += size * got; + } +} + +LOCAL int +xawrite(buffer, size, count, file, submode, islast) + void *buffer; + int size; + int count; + FILE *file; + int submode; + BOOL islast; +{ + register char *p = buffer; + register int amt = size * count; + register int n; + struct xa_subhdr subhdr[2]; + + if (osecsize == 2048) + return (fwrite(buffer, size, count, file)); + + if (amt % 2048) + comerrno(EX_BAD, + _("Trying to write %d bytes (not a multiple of 2048).\n"), + amt); + + subhdr[0].file_number = subhdr[1].file_number = 0; + subhdr[0].channel_number = subhdr[1].channel_number = 0; + subhdr[0].coding = subhdr[1].coding = 0; + + while (amt > 0) { +#ifdef LATER + if (submode < 0) + subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA; + else + subhdr[0].sub_mode = subhdr[1].sub_mode = submode; +#else + subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA; +#endif + + if ((amt <= 2048) && islast) { + subhdr[0].sub_mode = subhdr[1].sub_mode + |= (XA_SUBH_EOR|XA_SUBH_EOF); + } + n = fwrite(subhdr, sizeof (subhdr), 1, file); + if (n <= 0) + return (n); + + n = fwrite(p, 2048, 1, file); + if (n <= 0) + return (n); + + p += 2048; + amt -= 2048; + } + return (1); +} + +#ifdef APPLE_HYB +/* + * use the deferred_write struct to store info about the hfs_boot_file + */ +LOCAL struct deferred_write mac_boot; + +#endif /* APPLE_HYB */ +LOCAL struct deferred_write *dw_head = NULL, + *dw_tail = NULL; + +UInt32_t last_extent_written = 0; +LOCAL Uint path_table_index; +EXPORT time_t begun; +EXPORT struct timeval tv_begun; + +/* + * We recursively walk through all of the directories and assign extent + * numbers to them. We have already assigned extent numbers to everything that + * goes in front of them + */ +LOCAL int +assign_directory_addresses(node) + struct directory *node; +{ + int dir_size; + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + /* skip if it's hidden */ + if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { + dpnt = dpnt->next; + continue; + } + /* + * If we already have an extent for this (i.e. it came from a + * multisession disc), then don't reassign a new extent. + */ + dpnt->path_index = next_path_index++; + if (dpnt->extent == 0) { + dpnt->extent = last_extent; + dir_size = ISO_BLOCKS(dpnt->size); + + last_extent += dir_size; + + /* + * Leave room for the CE entries for this directory. + * Keep them close to the reference directory so that + * access will be quick. + */ + if (dpnt->ce_bytes) { + last_extent += ISO_BLOCKS(dpnt->ce_bytes); + } + } + if (dpnt->subdir) { + assign_directory_addresses(dpnt->subdir); + } + dpnt = dpnt->next; + } + return (0); +} + +#if defined(APPLE_HYB) || defined(USE_LARGEFILES) +LOCAL void +write_one_file(filename, size, outfile, off, isrfile, rba) + char *filename; + off_t size; + FILE *outfile; + off_t off; + int isrfile; + unsigned rba; +#else +LOCAL void +write_one_file(filename, size, outfile) + char *filename; + off_t size; + FILE *outfile; +#endif /* APPLE_HYB || USE_LARGEFILES */ +{ + /* + * It seems that there are still stone age C-compilers + * around. + * The Metrowerks C found on BeOS/PPC does not allow + * more than 32kB of local vars. + * As we do not need to call write_one_file() recursively + * we make buffer static. + */ +#ifdef __BEOS__ +static char buffer[SECTOR_SIZE * NSECT]; +#else + char buffer[SECTOR_SIZE * NSECT]; +#endif + FILE *infile; + off_t remain; + int use; + int unroundeduse; + int bytestowrite = 0; /* Dummy init. to serve GCC bug */ + int correctedsize = 0; + + + if ((infile = fopen(filename, "rb")) == NULL) { + if (!errhidden(E_OPEN, filename)) { + if (!errwarnonly(E_OPEN, filename)) + ; + errmsg(_("Cannot open '%s'.\n"), filename); + (void) errabort(E_OPEN, filename, TRUE); + } + } +#if defined(APPLE_HYB) || defined(USE_LARGEFILES) + if (infile) + fseek(infile, off, SEEK_SET); +#if defined(INSERTMACRESFORK) && defined(UDF) + if (isrfile && use_udf) { + memset(buffer, 0, sizeof (buffer)); + udf_set_extattr_freespace((Uchar *)buffer, size, rba); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, XA_SUBH_DATA, 1); + last_extent_written++; + + memset(buffer, 0, sizeof (buffer)); + udf_set_extattr_macresfork((Uchar *)buffer, size, rba); + xfwrite(buffer, SIZEOF_UDF_EXT_ATTRIBUTE_COMMON, 1, outfile, XA_SUBH_DATA, 1); + correctedsize = SIZEOF_UDF_EXT_ATTRIBUTE_COMMON; + } +#endif +#endif /* APPLE_HYB || USE_LARGEFILES */ + remain = size; + + while (remain > 0) { + int amt; + + unroundeduse = use = (remain > SECTOR_SIZE * NSECT - 1 ? + NSECT * SECTOR_SIZE : remain); + use = ISO_ROUND_UP(use); /* Round up to nearest sector */ + /* boundary */ + memset(buffer, 0, use); + seterrno(0); + if (infile) { +#ifdef VMS + amt = fread(buffer, 1, use, infile); +#else + amt = ffileread(infile, buffer, use); +#endif + } else { + amt = use; + } + if (amt < use && amt != remain) { + /* + * Note that mkisofs is not star and no 100% archiver. + * We only detect file growth if the new size does not + * match 'use' at the last read. + */ + if (geterrno() == 0) { + if (!errhidden(amt > remain ? E_GROW:E_SHRINK, filename)) { + if (!errwarnonly(amt < remain ? E_SHRINK:E_GROW, filename)) { + errmsgno(EX_BAD, + _("Try to use the option -data-change-warn\n")); + errmsgno(EX_BAD, + _("Files should not change while mkisofs is running.\n")); + } + errmsgno(EX_BAD, + _("File '%s' did %s.\n"), + filename, + amt < remain ? + _("shrink"):_("grow")); + (void) errabort(amt < remain ? + E_SHRINK:E_GROW, + filename, TRUE); + } + } else if (!errhidden(E_READ, filename)) { + if (!errwarnonly(E_READ, filename)) + ; + errmsg(_("Cannot read from '%s'\n"), filename); + (void) errabort(E_READ, filename, TRUE); + } + amt = remain; /* Fake success */ + if (infile) { + fclose(infile); /* Prevent furthe failure */ + infile = NULL; + } + } +#if defined(APPLE_HYB) && defined(INSERTMACRESFORK) && defined(UDF) + if (unroundeduse == remain && isrfile && use_udf && correctedsize) { + /* adjust the last block to write according to correctedsize */ + if (use - unroundeduse == correctedsize) { + bytestowrite = use; + correctedsize = 0; + } else if (use - unroundeduse > correctedsize) { + bytestowrite = use - correctedsize; + correctedsize = 0; + } else if (use - unroundeduse < correctedsize) { + bytestowrite = unroundeduse; + correctedsize -= use - unroundeduse; + } + } else { + bytestowrite = use; + } +#else + bytestowrite = use; +#endif + + xfwrite(buffer, bytestowrite, 1, outfile, + XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT)); + last_extent_written += use / SECTOR_SIZE; +#if 0 + if ((last_extent_written % 1000) < use / SECTOR_SIZE) { + fprintf(stderr, "%d..", last_extent_written); + } +#else + if (verbose > 0 && + (int)(last_extent_written % (gui ? 500 : 5000)) < + use / SECTOR_SIZE) { + time_t now; + time_t the_end; + double frac; + + time(&now); + frac = last_extent_written / (1.0 * last_extent); + the_end = begun + (now - begun) / frac; +#ifndef NO_FLOATINGPOINT + fprintf(stderr, _("%6.2f%% done, estimate finish %s"), + frac * 100., ctime(&the_end)); +#else + fprintf(stderr, _("%3d.%-02d%% done, estimate finish %s"), + (int)(frac * 100.), + (int)((frac+.00005) * 10000.)%100, + ctime(&the_end)); +#endif + fflush(stderr); + } +#endif + remain -= use; + } +#ifdef APPLE_HYB +#if defined(INSERTMACRESFORK) && defined(UDF) + if (isrfile && use_udf && correctedsize) { + if (ISO_ROUND_UP(size) < ISO_ROUND_UP(size + SIZEOF_UDF_EXT_ATTRIBUTE_COMMON)) { + memset(buffer, 0, sizeof (buffer)); + xfwrite(buffer, SECTOR_SIZE - correctedsize, 1, outfile, XA_SUBH_DATA, 1); + last_extent_written++; + } + } +#endif +#endif + if (infile) + fclose(infile); +} /* write_one_file(... */ + +#ifdef UDF +LOCAL void +write_udf_symlink(filename, size, outfile) + char *filename; + off_t size; + FILE *outfile; +{ + static char buffer[SECTOR_SIZE * NSECT]; + off_t remain = sizeof (buffer); + int use; + + if (udf_get_symlinkcontents(filename, buffer, &remain) < 0) { + comerr(_("Cannot open smylink '%s'\n"), filename); + } + if (remain != size) { + comerrno(EX_BAD, _("Symlink '%s' did %s.\n"), + filename, + size > remain ? + _("shrink"):_("grow")); + } + use = (remain > SECTOR_SIZE * NSECT - 1 ? + NSECT * SECTOR_SIZE : remain); + use = ISO_ROUND_UP(use); + xfwrite(buffer, use, 1, outfile, + XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT)); + last_extent_written += use / SECTOR_SIZE; + +} /* write_udf_symlink(... */ +#endif + +LOCAL void +write_files(outfile) + FILE *outfile; +{ + struct deferred_write *dwpnt, + *dwnext; + unsigned rba = 0; + + dwpnt = dw_head; + while (dwpnt) { +/*#define DEBUG*/ +#ifdef DEBUG + fprintf(stderr, + _("The file name is %s and pad is %d, size is %lld and extent is %d\n"), + dwpnt->name, dwpnt->pad, + (Llong)dwpnt->size, dwpnt->extent); +#endif + if (dwpnt->table) { + xfwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1, + outfile, + XA_SUBH_DATA, TRUE); + last_extent_written += ISO_BLOCKS(dwpnt->size); + table_size += dwpnt->size; +/* fprintf(stderr, _("Size %lld "), (Llong)dwpnt->size); */ + free(dwpnt->table); + dwpnt->table = NULL; + } else { + +#ifdef VMS + vms_write_one_file(dwpnt->name, dwpnt->size, outfile); +#else +#ifdef UDF + if ((dwpnt->dw_flags & IS_SYMLINK) && use_udf && create_udfsymlinks) { + write_udf_symlink(dwpnt->name, dwpnt->size, outfile); + } else { +#endif /* UDF */ +#ifdef APPLE_HYB +#if defined(INSERTMACRESFORK) && defined(UDF) + if (file_is_resource(dwpnt->name, dwpnt->hfstype) && (dwpnt->size > 0) && use_udf) { + rba = dwpnt->extent; + } else { + rba = 0; + } +#endif /* INSERTMACRESFORK && UDF */ + write_one_file(dwpnt->name, dwpnt->size, outfile, dwpnt->off, + file_is_resource(dwpnt->name, dwpnt->hfstype) && (dwpnt->size > 0), rba); +#else +#ifdef USE_LARGEFILES + write_one_file(dwpnt->name, dwpnt->size, outfile, dwpnt->off, 0, 0); +#else + write_one_file(dwpnt->name, dwpnt->size, outfile); +#endif +#endif /* APPLE_HYB */ +#ifdef UDF + } +#endif +#endif /* VMS */ + free(dwpnt->name); + dwpnt->name = NULL; + } + + +#ifndef DVD_AUD_VID +#define dvd_aud_vid_flag 0 +#endif + +#ifndef APPLE_HYB +#define apple_hyb 0 +#endif + +#if defined(APPLE_HYB) || defined(DVD_AUD_VID) + + if ((apple_hyb && !donotwrite_macpart) || (dvd_aud_vid_flag & DVD_SPEC_VIDEO)) { + /* + * we may have to pad out ISO files to work with HFS + * clump sizes + */ + char blk[SECTOR_SIZE]; + Uint i; + + for (i = 0; i < dwpnt->pad; i++) + xfwrite(blk, SECTOR_SIZE, 1, outfile, 0, FALSE); + + last_extent_written += dwpnt->pad; + } +#endif /* APPLE_HYB || DVD_AUD_VID */ + + + dwnext = dwpnt; + dwpnt = dwpnt->next; + free(dwnext); + dwnext = NULL; + } +} /* write_files(... */ + +#if 0 +LOCAL void +dump_filelist() +{ + struct deferred_write *dwpnt; + + dwpnt = dw_head; + while (dwpnt) { + fprintf(stderr, _("File %s\n"), dwpnt->name); + dwpnt = dwpnt->next; + } + fprintf(stderr, "\n"); +} + +#endif + +LOCAL int +compare_dirs(rr, ll) + const void *rr; + const void *ll; +{ + char *rpnt, + *lpnt; + struct directory_entry **r, + **l; + + r = (struct directory_entry **)rr; + l = (struct directory_entry **)ll; + rpnt = (*r)->isorec.name; + lpnt = (*l)->isorec.name; + +#ifdef APPLE_HYB + /* + * resource fork MUST (not sure if this is true for HFS volumes) be + * before the data fork - so force it here + */ + if ((*r)->assoc && (*r)->assoc == (*l)) + return (1); + if ((*l)->assoc && (*l)->assoc == (*r)) + return (-1); +#endif /* APPLE_HYB */ + + /* + * If the names are the same, multiple extent sections of the same file + * are sorted by part number. If the part numbers do not differ, this + * is an error. + */ + if (strcmp(rpnt, lpnt) == 0) { +#ifdef USE_LARGEFILES + if ((*r)->mxpart < (*l)->mxpart) + return (-1); + else if ((*r)->mxpart > (*l)->mxpart) + return (1); +#endif + errmsgno(EX_BAD, + _("Error: '%s' and '%s' have the same ISO9660 name '%s'.\n"), + (*r)->whole_name, (*l)->whole_name, + rpnt); + sort_goof++; + } + /* Check we don't have the same RR name */ + if (use_RockRidge && !is_rr_dir) { + /* + * entries *can* have the same RR name in the "rr_moved" + * directory so skip checks if we're in reloc_dir + */ + if (strcmp((*r)->name, (*l)->name) == 0) { + errmsgno(EX_BAD, + _("Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n"), + (*r)->whole_name, (*l)->whole_name, + (*r)->name); + sort_goof++; + } + } + /* + * Put the '.' and '..' entries on the head of the sorted list. For + * normal ASCII, this always happens to be the case, but out of band + * characters cause this not to be the case sometimes. + * FIXME(eric) - these tests seem redundant, in that the name is never + * assigned these values. It will instead be \000 or \001, and thus + * should always be sorted correctly. I need to figure out why I + * thought I needed this in the first place. + */ +#if 0 + if (strcmp(rpnt, ".") == 0) + return (-1); + if (strcmp(lpnt, ".") == 0) + return (1); + + if (strcmp(rpnt, "..") == 0) + return (-1); + if (strcmp(lpnt, "..") == 0) + return (1); +#else + /* + * The code above is wrong (as explained in Eric's comment), leading to + * incorrect sort order iff the -L option ("allow leading dots") is in + * effect and a directory contains entries that start with a dot. + * (TF, Tue Dec 29 13:49:24 CET 1998) + */ + if ((*r)->isorec.name_len[0] == 1 && *rpnt == 0) + return (-1); /* '.' */ + if ((*l)->isorec.name_len[0] == 1 && *lpnt == 0) + return (1); + + if ((*r)->isorec.name_len[0] == 1 && *rpnt == 1) + return (-1); /* '..' */ + if ((*l)->isorec.name_len[0] == 1 && *lpnt == 1) + return (1); +#endif + + while (*rpnt && *lpnt) { + if (*rpnt == ';' && *lpnt != ';') + return (-1); + if (*rpnt != ';' && *lpnt == ';') + return (1); + + if (*rpnt == ';' && *lpnt == ';') + return (0); + + if (*rpnt == '.' && *lpnt != '.') + return (-1); + if (*rpnt != '.' && *lpnt == '.') + return (1); + + if ((unsigned char) *rpnt < (unsigned char) *lpnt) + return (-1); + if ((unsigned char) *rpnt > (unsigned char) *lpnt) + return (1); + rpnt++; + lpnt++; + } + if (*rpnt) + return (1); + if (*lpnt) + return (-1); + return (0); +} + +/* + * Function: sort_directory + * + * Purpose: Sort the directory in the appropriate ISO9660 + * order. + * + * Notes: Returns 0 if OK, returns > 0 if an error occurred. + */ +EXPORT int +sort_directory(sort_dir, rr) + struct directory_entry **sort_dir; + int rr; +{ + int dcount = 0; + int xcount = 0; + int j; + int i, + len; + struct directory_entry *s_entry; + struct directory_entry **sortlist; + + /* need to keep a count of how many entries are hidden */ + s_entry = *sort_dir; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + xcount++; + dcount++; + s_entry = s_entry->next; + } + + if (dcount == 0) { + return (0); + } + /* OK, now we know how many there are. Build a vector for sorting. */ + sortlist = (struct directory_entry **) + e_malloc(sizeof (struct directory_entry *) * dcount); + + j = dcount - xcount; + dcount = 0; + s_entry = *sort_dir; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + /* put any hidden entries at the end of the vector */ + sortlist[j++] = s_entry; + } else { + sortlist[dcount] = s_entry; + dcount++; + } + len = s_entry->isorec.name_len[0]; + s_entry->isorec.name[len] = 0; + s_entry = s_entry->next; + } + + /* Each directory is required to contain at least . and .. */ + if (dcount < 2) { + errmsgno(EX_BAD, + _("Directory size too small (. or .. may be missing)\n")); + sort_goof = 1; + + } else { + /* only sort the non-hidden entries */ + sort_goof = 0; + is_rr_dir = rr; +#ifdef PROTOTYPES + qsort(sortlist, dcount, sizeof (struct directory_entry *), + (int (*) (const void *, const void *)) compare_dirs); +#else + qsort(sortlist, dcount, sizeof (struct directory_entry *), + compare_dirs); +#endif + + /* + * Now reassemble the linked list in the proper sorted order + * We still need the hidden entries, as they may be used in + * the Joliet tree. + */ + for (i = 0; i < dcount + xcount - 1; i++) { + sortlist[i]->next = sortlist[i + 1]; + } + + sortlist[dcount + xcount - 1]->next = NULL; + *sort_dir = sortlist[0]; + } + + free(sortlist); + sortlist = NULL; + return (sort_goof); +} + +LOCAL int +root_gen() +{ + init_fstatbuf(); + + root_record.length[0] = 1 + + offsetof(struct iso_directory_record, name[0]); + root_record.ext_attr_length[0] = 0; + set_733((char *)root_record.extent, root->extent); + set_733((char *)root_record.size, ISO_ROUND_UP(root->size)); + iso9660_date(root_record.date, root_statbuf.st_mtime); + root_record.flags[0] = ISO_DIRECTORY; + root_record.file_unit_size[0] = 0; + root_record.interleave[0] = 0; + set_723(root_record.volume_sequence_number, volume_sequence_number); + root_record.name_len[0] = 1; + return (0); +} + +#ifdef SORTING +/* + * sorts deferred_write entries based on the sort weight + */ +LOCAL int +compare_sort(rr, ll) + const void *rr; + const void *ll; +{ + struct deferred_write **r; + struct deferred_write **l; + int r_sort; + int l_sort; + + r = (struct deferred_write **)rr; + l = (struct deferred_write **)ll; + r_sort = (*r)->s_entry->sort; + l_sort = (*l)->s_entry->sort; + + if (r_sort != l_sort) + return (r_sort < l_sort ? 1 : -1); + else + return ((*r)->extent - (*l)->extent); +} + +/* + * reassign start extents to files that are "hard links" to + * files that may have been sorted + */ +LOCAL void +reassign_link_addresses(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) { + /* link files have already been given the weight NOT_SORTED */ + if (s_entry->sort != NOT_SORTED) + continue; + + /* update the start extent */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + set_733((char *)s_entry->isorec.extent, s_hash->starting_block); + s_entry->starting_block = s_hash->starting_block; + } + } + if (dpnt->subdir) { + reassign_link_addresses(dpnt->subdir); + } + + dpnt = dpnt->next; + } +} + +/* + * sort files in order of the given sort weight + */ +LOCAL int +sort_file_addresses() +{ + struct deferred_write *dwpnt; + struct deferred_write **sortlist; + struct directory_entry *s_entry; + UInt32_t start_extent; + int num = 0; + int i; + + /* need to store start extents for linked files */ + flush_hash(); + + /* find out how many files we have */ + dwpnt = dw_head; + while (dwpnt) { + num++; + dwpnt = dwpnt->next; + } + + /* return if we have none */ + if (num == 0) { + return (1); + } + + /* save the start extent of the first file */ + start_extent = dw_head->extent; + + /* set up vector to store entries */ + sortlist = (struct deferred_write **) + e_malloc(sizeof (struct deferred_write *) * num); + + for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) + sortlist[i] = dwpnt; + + /* sort the list */ +#ifdef PROTOTYPES + qsort(sortlist, num, sizeof (struct deferred_write *), + (int (*)(const void *, const void *))compare_sort); +#else + qsort(sortlist, num, sizeof (struct deferred_write *), compare_sort); +#endif + + /* reconstruct the linked list */ + for (i = 0; i < num-1; i++) { + sortlist[i]->next = sortlist[i+1]; + } + + sortlist[num-1]->next = NULL; + dw_head = sortlist[0]; + + free(sortlist); + + /* set the new start extents for the sorted list */ + for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) { + s_entry = dwpnt->s_entry; + dwpnt->extent = s_entry->starting_block = start_extent; + + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + UInt32_t ext = start_extent; + + /* + * For unknown reason, we sometimes get mxroot as + * part of the chain and sometime it's missing. + * Be careful to distinct between the mxroot entry and + * others to select both corectly in a conservative way. + */ + s_entry->mxroot->starting_block = start_extent; + set_733((char *)s_entry->mxroot->isorec.extent, + start_extent); + start_extent += ISO_BLOCKS(s_entry->mxroot->size); + + for (s_e = s_entry; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + if (s_e == s_entry->mxroot) + continue; + + set_733((char *)s_e->isorec.extent, ext); + s_entry->starting_block = ext; + ext += ISO_BLOCKS(s_e->size); + } + } else { + set_733((char *)s_entry->isorec.extent, start_extent); + start_extent += ISO_BLOCKS(s_entry->size); + } +#ifdef DVD_AUD_VID + /* + * Shouldn't this be done for every type of sort? Otherwise + * we will loose every pad info we add if we sort the files + */ + if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) { + start_extent += dwpnt->pad; + } +#endif /* DVD_AUD_VID */ + + /* cache start extents for any linked files */ + add_hash(s_entry); + } + + return (0); +} +#endif /* SORTING */ + + + +LOCAL BOOL +assign_file_addresses(dpnt, isnest) + struct directory *dpnt; + BOOL isnest; +{ + struct directory *finddir; + struct directory_entry *s_entry; + struct file_hash *s_hash; + struct deferred_write *dwpnt; + char whole_path[PATH_MAX]; +#ifdef DVD_AUD_VID + char dvd_path[PATH_MAX]; + title_set_info_t *title_set_info = NULL; + char *p; +#endif + BOOL ret = FALSE; + + while (dpnt) { +#ifdef DVD_AUD_VID + if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO) && root == dpnt->parent && + ((p = strstr(dpnt->whole_name, "VIDEO_TS")) != 0)&& + strcmp(p, "VIDEO_TS") == 0) { + int maxlen = strlen(dpnt->whole_name)-8+1; + + if (maxlen > sizeof (dvd_path)) + maxlen = sizeof (dvd_path); + strlcpy(dvd_path, dpnt->whole_name, maxlen); +#ifdef DEBUG + fprintf(stderr, _("Found 'VIDEO_TS', the path is %s \n"), dvd_path); +#endif + title_set_info = DVDGetFileSet(dvd_path); + if (title_set_info == 0) { + /* + * Do not switch off -dvd-video but let is fail later. + */ +/* dvd_aud_vid_flag &= ~DVD_SPEC_VIDEO;*/ + errmsgno(EX_BAD, _("Unable to parse DVD-Video structures.\n")); + } else { + ret = TRUE; + } + } +#endif /* DVD_AUD_VID */ + + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + /* + * If we already have an extent for this entry, then + * don't assign a new one. It must have come from a + * previous session on the disc. Note that we don't + * end up scheduling the thing for writing either. + */ + if (get_733(s_entry->isorec.extent) != 0) { + continue; + } + /* + * This saves some space if there are symlinks present. + * If this is a multi-extent file, we get mxpart == 1 + * from find_hash(). + */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + if (verbose > 2) { + fprintf(stderr, _("Cache hit for '%s%s%s'\n"), + s_entry->filedir->de_name, + SPATH_SEPARATOR, + s_entry->name); + } + s_entry->starting_block = s_hash->starting_block; + set_733((char *)s_entry->isorec.extent, + s_hash->starting_block); + set_733((char *)s_entry->isorec.size, + s_hash->size); +#ifdef USE_LARGEFILES + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + unsigned int ext = s_hash->starting_block; + + /* + * Skip the multi extent root entry. + */ + if (s_entry->mxpart == 0) + continue; + /* + * The directory is sorted, so we should + * see s_entry->mxpart == 1 first. + */ + if (s_entry->mxpart != 1) { + comerrno(EX_BAD, + _("Panic: Multi extent parts for %s not sorted.\n"), + s_entry->whole_name); + } + s_entry->mxroot->starting_block = ext; + for (s_e = s_entry; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + set_733((char *)s_e->isorec.extent, + ext); + ext += ISO_BLOCKS(s_e->size); + } + } +#endif + +#ifdef SORTING + /* check for non-directory files */ + if (do_sort && ((s_entry->isorec.flags[0] & ISO_DIRECTORY) == 0)) { + /* make sure the real file has the highest weighting */ + s_hash->de->sort = MAX(s_entry->sort, s_hash->de->sort); + /* flag this as a potential non-sorted file */ + s_entry->sort = NOT_SORTED; + } +#endif /* SORTING */ + continue; + } + /* + * If this is for a directory that is not a . or + * a .. entry, then look up the information for the + * entry. We have already assigned extents for + * directories, so we just need to fill in the blanks + * here. + */ + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0 && + s_entry->isorec.flags[0] & ISO_DIRECTORY) { + finddir = dpnt->subdir; + while (finddir && finddir->self != s_entry) { + finddir = finddir->next; + } + if (!finddir) { +#ifdef DVD_AUD_VID + if (title_set_info != 0) { + DVDFreeFileSet(title_set_info); + } +#endif + comerrno(EX_BAD, + _("Fatal goof - could not find dir entry for '%s'\n"), + s_entry->name); + } + set_733((char *)s_entry->isorec.extent, + finddir->extent); + s_entry->starting_block = finddir->extent; + s_entry->size = ISO_ROUND_UP(finddir->size); + total_dir_size += s_entry->size; + add_hash(s_entry); + set_733((char *)s_entry->isorec.size, + ISO_ROUND_UP(finddir->size)); + continue; + } + /* + * If this is . or .., then look up the relevant info + * from the tables. + */ + if (strcmp(s_entry->name, ".") == 0) { + set_733((char *)s_entry->isorec.extent, + dpnt->extent); + + /* + * Set these so that the hash table has the + * correct information + */ + s_entry->starting_block = dpnt->extent; + s_entry->size = ISO_ROUND_UP(dpnt->size); + + add_hash(s_entry); + s_entry->starting_block = dpnt->extent; + set_733((char *)s_entry->isorec.size, + ISO_ROUND_UP(dpnt->size)); + continue; + } + if (strcmp(s_entry->name, "..") == 0) { + if (dpnt == root) { + total_dir_size += root->size; + } + set_733((char *)s_entry->isorec.extent, + dpnt->parent->extent); + + /* + * Set these so that the hash table has the + * correct information + */ + s_entry->starting_block = dpnt->parent->extent; + s_entry->size = + ISO_ROUND_UP(dpnt->parent->size); + + add_hash(s_entry); + s_entry->starting_block = dpnt->parent->extent; + set_733((char *)s_entry->isorec.size, + ISO_ROUND_UP(dpnt->parent->size)); + continue; + } + /* + * Some ordinary non-directory file. Just schedule + * the file to be written. This is all quite + * straightforward, just make a list and assign + * extents as we go. Once we get through writing all + * of the directories, we should be ready write out + * these files + */ + if (s_entry->size) { + dwpnt = (struct deferred_write *) + e_malloc(sizeof (struct deferred_write)); + /* save this directory entry for later use */ + dwpnt->s_entry = s_entry; + /* set the initial padding to zero */ + dwpnt->pad = 0; + dwpnt->dw_flags = 0; +#ifdef DVD_AUD_VID + if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO) && (title_set_info != 0)) { + int pad; + + pad = DVDGetFilePad(title_set_info, s_entry->name); + if (pad < 0) { + errmsgno(EX_BAD, + _("Implementation botch. Video pad for file %s is %d\n"), + s_entry->name, pad), + comerrno(EX_BAD, + _("Either the *.IFO file is bad or you found a mkisofs bug.\n")); + } + dwpnt->pad = pad; + if (verbose > 0 && pad != 0) { + fprintf(stderr, + _("The pad was %d for file %s\n"), + dwpnt->pad, s_entry->name); + } + } +#endif /* DVD_AUD_VID */ +#ifdef APPLE_HYB + /* + * maybe an offset to start of the real + * file/fork + */ + dwpnt->off = s_entry->hfs_off; + dwpnt->hfstype = s_entry->hfs_type; +#else + dwpnt->off = (off_t)0; +#endif /* APPLE_HYB */ + if (s_entry->inode == TABLE_INODE) { + dwpnt->table = s_entry->table; + dwpnt->name = NULL; + sprintf(whole_path, "%s%s%s", + s_entry->filedir->whole_name, + SPATH_SEPARATOR, trans_tbl); + } else { + dwpnt->table = NULL; + strlcpy(whole_path, + s_entry->whole_name, + sizeof (whole_path)); + dwpnt->name = e_strdup(whole_path); + } + dwpnt->next = NULL; + dwpnt->size = s_entry->size; + dwpnt->extent = last_extent; + set_733((char *)s_entry->isorec.extent, + last_extent); + s_entry->starting_block = last_extent; +#ifdef USE_LARGEFILES + /* + * Update the entries for multi-section files + * as we now know the starting extent numbers. + */ + if (s_entry->de_flags & MULTI_EXTENT) { + struct directory_entry *s_e; + unsigned int ext = last_extent; + + /* + * Skip the multi extent root entry. + */ + if (s_entry->mxpart == 0) { + if (dwpnt->name) + free(dwpnt->name); + free(dwpnt); + continue; + } + /* + * The directory is sorted, so we should + * see s_entry->mxpart == 1 first. + */ + if (s_entry->mxpart != 1) { + comerrno(EX_BAD, + _("Panic: Multi extent parts for %s not sorted.\n"), + s_entry->whole_name); + } + dwpnt->size = s_entry->mxroot->size; + s_entry->mxroot->starting_block = ext; + /* + * Set the mxroot (mxpart == 0) to allow + * the UDF code to fetch the starting + * extent number. + */ + set_733((char *)s_entry->mxroot->isorec.extent, ext); + for (s_e = s_entry; + s_e && s_e->mxroot == s_entry->mxroot; + s_e = s_e->next) { + if (s_e->mxpart == 0) + continue; + set_733((char *)s_e->isorec.extent, + ext); + ext += ISO_BLOCKS(s_e->size); + } + add_hash(s_entry); + } +#endif + if (dw_tail) { + dw_tail->next = dwpnt; + dw_tail = dwpnt; + } else { + dw_head = dwpnt; + dw_tail = dwpnt; + } + add_hash(s_entry); + /* + * The cache holds the full size of the file + */ + last_extent += ISO_BLOCKS(dwpnt->size); + dwpnt->dw_flags = s_entry->de_flags; +#ifdef APPLE_HYB +#if defined(INSERTMACRESFORK) && defined(UDF) + if (file_is_resource(dwpnt->name, dwpnt->s_entry->hfs_type) && (dwpnt->size > 0) && use_udf) { + last_extent++; + if (ISO_ROUND_UP(dwpnt->size) < + ISO_ROUND_UP(dwpnt->size + SIZEOF_UDF_EXT_ATTRIBUTE_COMMON)) { + last_extent++; + } + } +#endif +#endif /* APPLE_HYB */ +#ifdef DVD_AUD_VID + /* Shouldn't we always add the pad info? */ + if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) { + last_extent += dwpnt->pad; + } +#endif /* DVD_AUD_VID */ + if (verbose > 2) { + fprintf(stderr, "%u %d %s\n", + s_entry->starting_block, + last_extent - 1, whole_path); + } +#ifdef DBG_ISO + if (ISO_BLOCKS(s_entry->size) > 500) { + fprintf(stderr, + _("Warning: large file '%s'\n"), + whole_path); + fprintf(stderr, + _("Starting block is %d\n"), + s_entry->starting_block); + fprintf(stderr, + _("Reported file size is %lld\n"), + (Llong)s_entry->size); + + } +#endif +#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ + + if (last_extent > (800000000 >> 11)) { + /* More than 800Mb? Punt */ + fprintf(stderr, + _("Extent overflow processing file '%s'\n"), + whole_path); + fprintf(stderr, + _("Starting block is %d\n"), + s_entry->starting_block); + fprintf(stderr, + _("Reported file size is %lld\n"), + (Llong)s_entry->size); + exit(1); + } +#endif + continue; + } + /* + * This is for zero-length files. If we leave the + * extent 0, then we get screwed, because many readers + * simply drop files that have an extent of zero. + * Thus we leave the size 0, and just assign the + * extent number. + */ + set_733((char *)s_entry->isorec.extent, last_extent); + } + if (dpnt->subdir) { + if (assign_file_addresses(dpnt->subdir, TRUE)) + ret = TRUE; + } + dpnt = dpnt->next; + } +#ifdef DVD_AUD_VID + if (title_set_info != NULL) { + DVDFreeFileSet(title_set_info); + } + if ((dvd_aud_vid_flag & DVD_SPEC_VIDEO)&& !ret && !isnest) { + errmsgno(EX_BAD, + _("Could not find correct 'VIDEO_TS' directory.\n")); + } +#endif /* DVD_AUD_VID */ + return (ret); +} /* assign_file_addresses(... */ + +LOCAL void +free_one_directory(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry_d; + + s_entry = dpnt->contents; + while (s_entry) { + s_entry_d = s_entry; + s_entry = s_entry->next; + + if (s_entry_d->rr_attributes) { + free(s_entry_d->rr_attributes); + s_entry_d->rr_attributes = NULL; + } + if (s_entry_d->name != NULL) { + free(s_entry_d->name); + s_entry_d->name = NULL; + } + if (s_entry_d->whole_name != NULL) { + free(s_entry_d->whole_name); + s_entry_d->whole_name = NULL; + } +#ifdef APPLE_HYB + if (apple_both && s_entry_d->hfs_ent && !s_entry_d->assoc && + (s_entry_d->isorec.flags[0] & ISO_MULTIEXTENT) == 0) { + free(s_entry_d->hfs_ent); + } +#endif /* APPLE_HYB */ + + free(s_entry_d); + s_entry_d = NULL; + } + dpnt->contents = NULL; +} /* free_one_directory(... */ + +LOCAL void +free_directories(dpnt) + struct directory *dpnt; +{ + while (dpnt) { + free_one_directory(dpnt); + if (dpnt->subdir) + free_directories(dpnt->subdir); + dpnt = dpnt->next; + } +} + +EXPORT void +generate_one_directory(dpnt, outfile) + struct directory *dpnt; + FILE *outfile; +{ + unsigned int ce_address = 0; + char *ce_buffer; + unsigned int ce_index = 0; + unsigned int ce_size; + unsigned int dir_index; + char *directory_buffer; + int new_reclen; + struct directory_entry *s_entry; + struct directory_entry *s_entry_d; + unsigned int total_size; + + total_size = ISO_ROUND_UP(dpnt->size); + directory_buffer = (char *)e_malloc(total_size); + memset(directory_buffer, 0, total_size); + dir_index = 0; + + ce_size = ISO_ROUND_UP(dpnt->ce_bytes); + ce_buffer = NULL; + + if (ce_size > 0) { + ce_buffer = (char *)e_malloc(ce_size); + memset(ce_buffer, 0, ce_size); + + ce_index = 0; + + /* Absolute sector address of CE entries for this directory */ + ce_address = last_extent_written + (total_size >> 11); + } + s_entry = dpnt->contents; + while (s_entry) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + /* + * We do not allow directory entries to cross sector + * boundaries. Simply pad, and then start the next entry at + * the next sector + */ + new_reclen = s_entry->isorec.length[0]; + if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= + SECTOR_SIZE) { + dir_index = ISO_ROUND_UP(dir_index); + } + memcpy(directory_buffer + dir_index, &s_entry->isorec, + offsetof(struct iso_directory_record, name[0]) + + s_entry->isorec.name_len[0]); + dir_index += offsetof(struct iso_directory_record, name[0]) + + s_entry->isorec.name_len[0]; + + /* Add the Rock Ridge attributes, if present */ + if (s_entry->rr_attr_size) { + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + /* + * If the RR attributes were too long, then write the + * CE records, as required. + */ + if (s_entry->rr_attr_size != s_entry->total_rr_attr_size) { + struct iso_xa_dir_record *xadp; + unsigned char *pnt; + int len, + nbytes; + + /* + * Go through the entire record, first skip + * the XA record and then fix up the + * CE entries so that the extent and offset + * are correct + */ + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + } + } + + while (len > 3) { +#ifdef DEBUG + if (ce_size <= 0) { + fprintf(stderr, + _("Warning: ce_index(%d) && ce_address(%d) not initialized\n"), + ce_index, ce_address); + } +#endif + + if (pnt[0] == 'C' && pnt[1] == 'E') { + nbytes = get_733((char *)pnt + 20); + + if ((ce_index & (SECTOR_SIZE - 1)) + nbytes >= + SECTOR_SIZE) { + ce_index = ISO_ROUND_UP(ce_index); + } + set_733((char *)pnt + 4, + ce_address + (ce_index >> 11)); + set_733((char *)pnt + 12, + ce_index & (SECTOR_SIZE - 1)); + + + + /* + * Now store the block in the + * ce buffer + */ + memcpy(ce_buffer + ce_index, + pnt + pnt[2], nbytes); + ce_index += nbytes; + if (ce_index & 1) { + ce_index++; + } + } + len -= pnt[2]; + pnt += pnt[2]; + } + + } + rockridge_size += s_entry->total_rr_attr_size; + memcpy(directory_buffer + dir_index, + s_entry->rr_attributes, + s_entry->rr_attr_size); + dir_index += s_entry->rr_attr_size; + } + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + s_entry_d = s_entry; + s_entry = s_entry->next; + + /* + * Joliet doesn't use the Rock Ridge attributes, so we free + * it here. + */ + if (s_entry_d->rr_attributes) { + free(s_entry_d->rr_attributes); + s_entry_d->rr_attributes = NULL; + } + } + + if (dpnt->size != dir_index) { + errmsgno(EX_BAD, + _("Unexpected directory length %lld expected: %d '%s'\n"), + (Llong)dpnt->size, + dir_index, dpnt->de_name); + } + xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE); + last_extent_written += total_size >> 11; + free(directory_buffer); + directory_buffer = NULL; + + if (ce_size > 0) { + if (ce_index != dpnt->ce_bytes) { + errmsgno(EX_BAD, + _("Continuation entry record length mismatch %d expected: %d.\n"), + ce_index, dpnt->ce_bytes); + } + xfwrite(ce_buffer, ce_size, 1, outfile, 0, FALSE); + last_extent_written += ce_size >> 11; + free(ce_buffer); + ce_buffer = NULL; + } +} /* generate_one_directory(... */ + +LOCAL void +build_pathlist(node) + struct directory *node; +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + /* skip if it's hidden */ + if ((dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) + pathlist[dpnt->path_index] = dpnt; + + if (dpnt->subdir) + build_pathlist(dpnt->subdir); + dpnt = dpnt->next; + } +} /* build_pathlist(... */ + +LOCAL int +compare_paths(r, l) + void const *r; + void const *l; +{ + struct directory const *ll = *(struct directory * const *) l; + struct directory const *rr = *(struct directory * const *) r; + + if (rr->parent->path_index < ll->parent->path_index) { + return (-1); + } + if (rr->parent->path_index > ll->parent->path_index) { + return (1); + } + return (strcmp(rr->self->isorec.name, ll->self->isorec.name)); + +} /* compare_paths(... */ + +LOCAL int +generate_path_tables() +{ + struct directory_entry *de = NULL; + struct directory *dpnt; + int fix; + int i; + int j; + int namelen; + char *npnt; + char *npnt1; + int tablesize; + + /* First allocate memory for the tables and initialize the memory */ + tablesize = path_blocks << 11; + path_table_m = (char *)e_malloc(tablesize); + path_table_l = (char *)e_malloc(tablesize); + memset(path_table_l, 0, tablesize); + memset(path_table_m, 0, tablesize); + + /* + * Now start filling in the path tables. Start with root directory + */ + + path_table_index = 0; + pathlist = (struct directory **)e_malloc(sizeof (struct directory *) + *next_path_index); + memset(pathlist, 0, sizeof (struct directory *) * next_path_index); + build_pathlist(root); + + do { + fix = 0; +#ifdef PROTOTYPES + qsort(&pathlist[1], next_path_index - 1, + sizeof (struct directory *), + (int (*) (const void *, const void *)) compare_paths); +#else + qsort(&pathlist[1], next_path_index - 1, + sizeof (struct directory *), + compare_paths); +#endif + + for (j = 1; j < next_path_index; j++) { + if (pathlist[j]->path_index != j) { + pathlist[j]->path_index = j; + fix++; + } + } + } while (fix); + + for (j = 1; j < next_path_index; j++) { + dpnt = pathlist[j]; + if (!dpnt) { + comerrno(EX_BAD, _("Entry %d not in path tables\n"), j); + } + npnt = dpnt->de_name; + + /* So the root comes out OK */ + if ((*npnt == 0) || (dpnt == root)) { + npnt = "."; + } + npnt1 = strrchr(npnt, PATH_SEPARATOR); + if (npnt1) { + npnt = npnt1 + 1; + } + de = dpnt->self; + if (!de) { + comerrno(EX_BAD, + _("Fatal ISO9660 goof - directory has amnesia\n")); + } + namelen = de->isorec.name_len[0]; + + path_table_l[path_table_index] = namelen; + path_table_m[path_table_index] = namelen; + path_table_index += 2; + + set_731(path_table_l + path_table_index, dpnt->extent); + set_732(path_table_m + path_table_index, dpnt->extent); + path_table_index += 4; + + set_721(path_table_l + path_table_index, + dpnt->parent->path_index); + set_722(path_table_m + path_table_index, + dpnt->parent->path_index); + + if (dpnt->parent->path_index > 0xffff) { + static int warned = 0; + + if (!warned) { + warned++; + errmsgno(EX_BAD, + _("Unable to generate sane path tables - too many directories (%u)\n"), + dpnt->parent->path_index); + if (!nolimitpathtables) + errmsgno(EX_BAD, + _("Try to use the option -no-limit-pathtables\n")); + } + if (!nolimitpathtables) + exit(EX_BAD); + /* + * Let it point to the root directory instead. + */ + set_721(path_table_l + path_table_index, 1); + set_722(path_table_m + path_table_index, 1); + } + + path_table_index += 2; + + for (i = 0; i < namelen; i++) { + path_table_l[path_table_index] = de->isorec.name[i]; + path_table_m[path_table_index] = de->isorec.name[i]; + path_table_index++; + } + if (path_table_index & 1) { + path_table_index++; /* For odd lengths we pad */ + } + } + + free(pathlist); + pathlist = NULL; + if (path_table_index != path_table_size) { + errmsgno(EX_BAD, + _("Path table lengths do not match %d expected: %d\n"), + path_table_index, + path_table_size); + } + return (0); +} /* generate_path_tables(... */ + +EXPORT void +memcpy_max(to, from, max) + char *to; + char *from; + int max; +{ + int n = strlen(from); + + if (n > max) { + n = max; + } + memcpy(to, from, n); + +} /* memcpy_max(... */ + +EXPORT void +outputlist_insert(frag) + struct output_fragment *frag; +{ + struct output_fragment *nfrag; + + nfrag = e_malloc(sizeof (*frag)); + movebytes(frag, nfrag, sizeof (*frag)); + nfrag->of_start_extent = 0; + + if (out_tail == NULL) { + out_list = out_tail = nfrag; + } else { + out_tail->of_next = nfrag; + out_tail = nfrag; + } +} + +LOCAL int +file_write(outfile) + FILE *outfile; +{ + Uint should_write; + +#ifdef APPLE_HYB + char buffer[SECTOR_SIZE]; + + memset(buffer, 0, sizeof (buffer)); + + if (apple_hyb && !donotwrite_macpart) { + + int i; + + /* + * write out padding to round up to HFS allocation block + */ + for (i = 0; i < hfs_pad; i++) + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + + last_extent_written += hfs_pad; + } +#endif /* APPLE_HYB */ + + /* + * OK, all done with that crap. Now write out the directories. This is + * where the fur starts to fly, because we need to keep track of each + * file as we find it and keep track of where we put it. + */ + should_write = last_extent - session_start; + + if (verbose > 2) { +#ifdef DBG_ISO + fprintf(stderr, + _("Total directory extents being written = %u\n"), + last_extent); +#endif + +#ifdef APPLE_HYB + if (apple_hyb && !donotwrite_macpart) + fprintf(stderr, + _("Total extents scheduled to be written (inc HFS) = %u\n"), + last_extent - session_start); + else +#endif /* APPLE_HYB */ + + fprintf(stderr, + _("Total extents scheduled to be written = %u\n"), + last_extent - session_start); + } + /* Now write all of the files that we need. */ + write_files(outfile); + +#ifdef APPLE_HYB + /* write out extents/catalog/dt file */ + if (apple_hyb && !donotwrite_macpart) { + + xfwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, outfile, 0, FALSE); + + /* round up to a whole CD block */ + if (HFS_ROUND_UP(hce->hfs_tot_size) - + hce->hfs_tot_size * HFS_BLOCKSZ) { + xfwrite(buffer, + HFS_ROUND_UP(hce->hfs_tot_size) - + hce->hfs_tot_size * HFS_BLOCKSZ, 1, outfile, 0, FALSE); + } + last_extent_written += ISO_ROUND_UP(hce->hfs_tot_size * + HFS_BLOCKSZ) / SECTOR_SIZE; + + /* write out HFS boot block */ + if (mac_boot.name) + write_one_file(mac_boot.name, mac_boot.size, outfile, + mac_boot.off, 0, 0); + } +#endif /* APPLE_HYB */ + + /* The rest is just fluff. */ + if (verbose == 0) { + return (0); + } +#ifdef APPLE_HYB + if (apple_hyb && !donotwrite_macpart) { + fprintf(stderr, + _("Total extents actually written (inc HFS) = %u\n"), + last_extent_written - session_start); + fprintf(stderr, _("(Size of ISO volume = %d, HFS extra = %d)\n"), + last_extent_written - session_start - hfs_extra, + hfs_extra); + } else +#else + fprintf(stderr, _("Total extents actually written = %d\n"), + last_extent_written - session_start); +#endif /* APPLE_HYB */ + + /* Hard links throw us off here */ + if (should_write != (last_extent - session_start)) { + fprintf(stderr, + _("Number of extents written not what was predicted. Please fix.\n")); + fprintf(stderr, _("Predicted = %d, written = %d\n"), + should_write, last_extent); + } + fprintf(stderr, _("Total translation table size: %d\n"), table_size); + fprintf(stderr, _("Total rockridge attributes bytes: %d\n"), + rockridge_size); + fprintf(stderr, _("Total directory bytes: %d\n"), total_dir_size); + fprintf(stderr, _("Path table size(bytes): %d\n"), path_table_size); + +#ifdef DEBUG + fprintf(stderr, + "next extent, last_extent, last_extent_written %d %d %d\n", + next_extent, last_extent, last_extent_written); +#endif + + return (0); + +} /* iso_write(... */ + +/* + * Function to write the PVD for the disc. + */ +LOCAL int +pvd_write(outfile) + FILE *outfile; +{ + char iso_time[17]; + int should_write; + int i; + int s; + Uchar *cp; +extern ldate modification_date; + + + iso9660_ldate(iso_time, tv_begun.tv_sec, tv_begun.tv_usec * 1000, -100); + + /* Next we write out the primary descriptor for the disc */ + memset(&vol_desc, 0, sizeof (vol_desc)); + vol_desc.type[0] = ISO_VD_PRIMARY; + strncpy(vol_desc.id, ISO_STANDARD_ID, sizeof (vol_desc.id)); + vol_desc.version[0] = 1; + + memset(vol_desc.system_id, ' ', sizeof (vol_desc.system_id)); + memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); + + memset(vol_desc.volume_id, ' ', sizeof (vol_desc.volume_id)); + memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); + + should_write = last_extent - session_start; + set_733((char *)vol_desc.volume_space_size, should_write); + set_723(vol_desc.volume_set_size, volume_set_size); + set_723(vol_desc.volume_sequence_number, volume_sequence_number); + set_723(vol_desc.logical_block_size, SECTOR_SIZE); + + /* + * The path tables are used by DOS based machines to cache directory + * locations + */ + set_733((char *)vol_desc.path_table_size, path_table_size); + set_731(vol_desc.type_l_path_table, path_table[0]); + set_731(vol_desc.opt_type_l_path_table, path_table[1]); + set_732(vol_desc.type_m_path_table, path_table[2]); + set_732(vol_desc.opt_type_m_path_table, path_table[3]); + + /* Now we copy the actual root directory record */ + memcpy(vol_desc.root_directory_record, &root_record, + offsetof(struct iso_directory_record, name[0]) + 1); + + /* + * The rest is just fluff. It looks nice to fill in many of these + * fields, though. + */ + FILL_SPACE(volume_set_id); + if (volset_id) + memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); + + FILL_SPACE(publisher_id); + if (publisher) + memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); + + FILL_SPACE(preparer_id); + if (preparer) + memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); + + FILL_SPACE(application_id); + if (appid) + memcpy_max(vol_desc.application_id, appid, strlen(appid)); + + FILL_SPACE(copyright_file_id); + if (copyright) + memcpy_max(vol_desc.copyright_file_id, copyright, + strlen(copyright)); + + FILL_SPACE(abstract_file_id); + if (abstract) + memcpy_max(vol_desc.abstract_file_id, abstract, + strlen(abstract)); + + FILL_SPACE(bibliographic_file_id); + if (biblio) + memcpy_max(vol_desc.bibliographic_file_id, biblio, + strlen(biblio)); + + FILL_SPACE(creation_date); + FILL_SPACE(modification_date); + FILL_SPACE(expiration_date); + FILL_SPACE(effective_date); + vol_desc.file_structure_version[0] = 1; + FILL_SPACE(application_data); + + iso9660_ldate(vol_desc.modification_date, + modification_date.l_sec, + modification_date.l_usec * 1000, + modification_date.l_gmtoff); + + memcpy(vol_desc.creation_date, iso_time, 17); + memcpy(vol_desc.expiration_date, "0000000000000000", 17); + memcpy(vol_desc.effective_date, iso_time, 17); + + if (use_XA) { + char *xap = &((char *)&vol_desc)[1024]; + + memcpy(&xap[0], "CD-XA001", 8); /* XA Sign. */ + memcpy(&xap[8], "\0\0", 2); /* XA flags */ + memcpy(&xap[10], "\0\0\0\0\0\0\0\0", 8); /* Start dir */ + memcpy(&xap[18], "\0\0\0\0\0\0\0\0", 8); /* Reserved */ + } + + /* + * Compute a checksum to be used as a fingerprint in case we + * include correct inode/link-count information in the current image. + */ + for (i = 0, s = 0, cp = (Uchar *)&vol_desc; i < SECTOR_SIZE; i++) { + s += cp[i] & 0xFF; + } + vol_desc_sum = s; + + /* if not a bootable cd do it the old way */ + xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Function to write the Extended PVD for the disc. + */ +LOCAL int +xpvd_write(outfile) + FILE *outfile; +{ + vol_desc.type[0] = ISO_VD_SUPPLEMENTARY; + vol_desc.version[0] = 2; + vol_desc.file_structure_version[0] = 2; + + /* if not a bootable cd do it the old way */ + xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Function to write the EVD for the disc. + */ +LOCAL int +evd_write(outfile) + FILE *outfile; +{ + struct iso_primary_descriptor evol_desc; + + /* + * Now write the end volume descriptor. Much simpler than the other + * one + */ + memset(&evol_desc, 0, sizeof (evol_desc)); + evol_desc.type[0] = (unsigned char) ISO_VD_END; + strncpy(evol_desc.id, ISO_STANDARD_ID, sizeof (evol_desc.id)); + evol_desc.version[0] = 1; + xfwrite(&evol_desc, SECTOR_SIZE, 1, outfile, 0, TRUE); + last_extent_written += 1; + return (0); +} + +/* + * Function to write the version information for the disc. + * Warning: Do not disable or change this function. The data created by this + * function is used to tell the filesystem driver in the OS kernel that this + * mkisofs version includes correct inode information. + */ +LOCAL int +vers_write(outfile) + FILE *outfile; +{ + char vers[SECTOR_SIZE+1]; + int X_ac; + char **X_av; + char *cp; + int i; + int idx = 4; + int len; + extern char version_string[]; + extern int path_ind; + + /* Now write the version descriptor. */ + memset(vers, 0, sizeof (vers)); + strcpy(vers, "MKI "); /* strcpy() OK here */ + + cp = vers; + X_ac = saved_ac(); + X_av = saved_av(); + strlcpy(&cp[idx], ctime(&begun), 26); + idx += 25; + strlcpy(&cp[idx], version_string, SECTOR_SIZE - idx); + idx += strlen(version_string); + for (i = 1; i < X_ac; i++) { + len = strlen(X_av[i]); + if ((idx + len + 2) >= SECTOR_SIZE) + break; + cp[idx++] = ' '; + /* + * Do not give away secret information when not in debug mode. + */ + if (debug) + strlcpy(&cp[idx], X_av[i], SECTOR_SIZE - idx); + else if (i >= path_ind) + len = graftcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]); + else if (X_av[i][0] == '/') + len = pathcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]); + else + strlcpy(&cp[idx], X_av[i], SECTOR_SIZE - idx); + idx += len; + } + + cp[SECTOR_SIZE - 1] = '\0'; + len = 0; + if (correct_inodes) { + /* + * Only add this fingerprint in case we include correct + * inode/link-count information in the current image. + */ + len = vol_desc_sum; + } + cp = &vers[SECTOR_SIZE - 1]; + *(Uchar *)cp = len % 256; + len /= 256; + *(Uchar *)--cp = len % 256; + len /= 256; + *(Uchar *)--cp = len % 256; + + xfwrite(vers, SECTOR_SIZE, 1, outfile, 0, TRUE); + last_extent_written += 1; + return (0); +} + +/* + * Avoid to write unwanted information into the version info string. + */ +LOCAL int +graftcp(to, from, ep) + char *to; + char *from; + char *ep; +{ + int len = strlen(from); + char *node = NULL; + + if (use_graft_ptrs) + node = findgequal(from); + + if (node == NULL) { + len = 0; + node = from; + } else { + len = node - from; + *node = '\0'; + strncpy(to, from, ep - to); + *node++ = '='; + to += len++; + *to++ = '='; + } + return (len + pathcp(to, node, ep)); +} + +LOCAL int +pathcp(to, from, ep) + char *to; + char *from; + char *ep; +{ + int len = strlen(from); + char *p; + + p = strrchr(from, '/'); + if (p == NULL) { + strncpy(to, from, ep - to); + } else { + if (p[1] == '\0') { + --p; + while (p > from && *p != '/') + --p; + } + len = 0; + if (*p == '/') { + strncpy(to, "...", ep - to); + to += 3; + len = 3; + } + if (to < ep) { + strncpy(to, p, ep - to); + len += strlen(to); + } + } + return (len); +} + + +/* + * Function to write the path table for the disc. + */ +LOCAL int +pathtab_write(outfile) + FILE *outfile; +{ + /* Next we write the path tables */ + xfwrite(path_table_l, path_blocks << 11, 1, outfile, 0, FALSE); + xfwrite(path_table_m, path_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += 2 * path_blocks; + free(path_table_l); + free(path_table_m); + path_table_l = NULL; + path_table_m = NULL; + return (0); +} + +LOCAL int +exten_write(outfile) + FILE *outfile; +{ + xfwrite(extension_record, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Functions to describe padding block at the start of the disc. + */ +EXPORT int +oneblock_size(starting_extent) + UInt32_t starting_extent; +{ + last_extent++; + return (0); +} + +/* + * Functions to describe path table size. + */ +LOCAL int +pathtab_size(starting_extent) + UInt32_t starting_extent; +{ + path_table[0] = starting_extent; + + path_table[1] = 0; + path_table[2] = path_table[0] + path_blocks; + path_table[3] = 0; + last_extent += 2 * path_blocks; + return (0); +} + +/* + * Functions to describe padding blocks before PVD. + */ +LOCAL int +startpad_size(starting_extent) + UInt32_t starting_extent; +{ + last_extent = session_start + 16; + return (0); +} + +/* + * Functions to describe padding blocks between sections. + */ +LOCAL int +interpad_size(starting_extent) + UInt32_t starting_extent; +{ + int emod = 0; + +#ifdef needed + starting_extent += 16; /* First add 16 pad blocks */ +#endif + if ((emod = starting_extent % 16) != 0) { + starting_extent += 16 - emod; /* Now pad to mod 16 # */ + } + last_extent = starting_extent; + return (0); +} + +/* + * Functions to describe padding blocks at end of disk. + */ +LOCAL int +endpad_size(starting_extent) + UInt32_t starting_extent; +{ + starting_extent += 150; /* 150 pad blocks (post gap) */ + last_extent = starting_extent; + return (0); +} + +LOCAL int +file_gen() +{ +#ifdef APPLE_HYB + UInt32_t start_extent = last_extent; /* orig ISO files start */ + +#endif /* APPLE_HYB */ + + if (!assign_file_addresses(root, FALSE)) { +#ifdef DVD_AUD_VID + if (dvd_aud_vid_flag & DVD_SPEC_VIDEO) { + comerrno(EX_BAD, _("Unable to make a DVD-Video image.\n")); + } +#else + ; + /* EMPTY */ +#endif + } + + +#ifdef SORTING + if (do_sort) { + if (sort_file_addresses() == 0) + reassign_link_addresses(root); + } +#endif /* SORTING */ + +#ifdef APPLE_HYB + /* + * put this here for the time being - may when I've worked out how to + * use Eric's new system for creating/writing parts of the image it + * may move to it's own routine + */ + if (apple_hyb && !donotwrite_macpart) + hfs_file_gen(start_extent); +#ifdef PREP_BOOT + else if (use_prep_boot || use_chrp_boot) + gen_prepboot(); +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + + /* + * Do inode/hard link related stuff for non-directory type files. + */ + do_inode(root); + return (0); +} + +LOCAL int +dirtree_dump() +{ + if (verbose > 2) { + dump_tree(root); + } + return (0); +} + +LOCAL int +dirtree_fixup(starting_extent) + UInt32_t starting_extent; +{ + if (use_RockRidge && reloc_dir) + finish_cl_pl_entries(); + + /* + * Set the link count for directories to 2 + number of sub-directories. + */ + if (use_RockRidge) + do_dir_nlink(root); + return (0); +} + +LOCAL int +dirtree_size(starting_extent) + UInt32_t starting_extent; +{ + assign_directory_addresses(root); + return (0); +} + +LOCAL int +ext_size(starting_extent) + UInt32_t starting_extent; +{ + extern int extension_record_size; + struct directory_entry *s_entry; + + extension_record_extent = starting_extent; + s_entry = root->contents; + set_733((char *)s_entry->rr_attributes + s_entry->rr_attr_size - 24, + extension_record_extent); + set_733((char *)s_entry->rr_attributes + s_entry->rr_attr_size - 8, + extension_record_size); + last_extent++; + return (0); +} + +LOCAL int +dirtree_write(outfile) + FILE *outfile; +{ + generate_iso9660_directories(root, outfile); + return (0); +} + +LOCAL int +dirtree_cleanup(outfile) + FILE *outfile; +{ + free_directories(root); + return (0); +} + +LOCAL int +startpad_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int i; + int npad; + + memset(buffer, 0, sizeof (buffer)); + + npad = session_start + 16 - last_extent_written; + + for (i = 0; i < npad; i++) { + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + } + + last_extent_written += npad; + return (0); +} + +LOCAL int +interpad_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int i; + int npad = 0; + + memset(buffer, 0, sizeof (buffer)); + +#ifdef needed + npad = 16; +#endif + if ((i = last_extent_written % 16) != 0) + npad += 16 - i; + + for (i = 0; i < npad; i++) { + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + } + + last_extent_written += npad; + return (0); +} + +LOCAL int +endpad_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int i; + + memset(buffer, 0, sizeof (buffer)); + + for (i = 0; i < 150; i++) { + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + } + + last_extent_written += 150; + return (0); +} + +#ifdef APPLE_HYB + +/* + * hfs_get_parms: get HFS parameters from the command line + */ + +LOCAL int +hfs_get_parms(key) + char *key; +{ + int ret = 0; + char *p; + + if (hfs_parms == NULL) + return (ret); + + if ((p = strstr(hfs_parms, key)) != NULL) { + p += strlen(key) + 1; + sscanf(p, "%d", &ret); + } + + return (ret); +} + +/* + * hfs_file_gen: set up "fake" HFS volume using the ISO9660 tree + */ +LOCAL void +hfs_file_gen(start_extent) + UInt32_t start_extent; +{ + int Csize; /* clump size for HFS vol */ + int loop; + UInt32_t last_extent_save = last_extent; + char *p; + + /* allocate memory for the libhfs/mkisofs extra info */ + hce = (hce_mem *) e_malloc(sizeof (hce_mem)); + + hce->error = (char *)e_malloc(1024); + + /* mark as unallocated for use later */ + hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0; + + /* reserve space for the label partition - if it is needed */ +#ifdef PREP_BOOT + /* a PReP bootable partition needs the map.. */ + if (gen_pt || use_prep_boot || use_chrp_boot) +#else + if (gen_pt) +#endif /* PREP_BOOT */ + hce->hfs_map_size = HFS_MAP_SIZE; + else + hce->hfs_map_size = 0; + + /* set the HFS parameter string to upper case */ + if (hfs_parms) { + for (p = hfs_parms; *p; p++) + *p = toupper((*p & 0xFF)); + } + + /* set the initial factor to increase Catalog file size */ + if ((hce->ctc_size = hfs_get_parms("CTC")) == 0) + hce->ctc_size = CTC; + + /* set the max size of the Catalog file */ + if ((hce->max_XTCsize = hfs_get_parms("MAX_XTCSIZE")) == 0) + hce->max_XTCsize = MAX_XTCSIZE; + + /* set the number of time to try to make an HFS volume */ + if ((loop = hfs_get_parms("CTC_LOOP")) == 0) + loop = CTC_LOOP; + + /* + * "create" the HFS volume (just the header, catalog/extents files) if + * there's a problem with the Catalog file being too small, we keep on + * increasing the size (up to CTC_LOOP) times and try again. + * Unfortunately I don't know enough about the inner workings of HFS, + * so I can't workout the size of the Catalog file in advance (and I + * don't want to "grow" as is is normally allowed to), therefore, this + * approach is a bit over the top as it involves throwing away the + * "volume" we have created and trying again ... + */ + do { + hce->error[0] = '\0'; + + /* attempt to create the Mac volume */ +#ifdef APPLE_HFS_HYB + Csize = make_mac_volume(root, start_extent); +#else + Csize = -1; +#endif + + /* if we have a problem ... */ + if (Csize < 0) { + /* + * we've made too many attempts, or got some other + * error + */ + if (loop == 0 || errno != HCE_ERROR) { + /* HCE_ERROR is not a valid errno value */ + if (errno == HCE_ERROR) + errno = 0; + + /* exit with the error */ + if (*hce->error) + fprintf(stderr, "%s\n", hce->error); + perr(hfs_error); + } else { + /* increase Catalog file size factor */ + hce->ctc_size *= CTC; + + /* + * reset the initial "last_extent" and try + * again + */ + last_extent = last_extent_save; + } + } else { + /* everything OK - just carry on ... */ + loop = 0; + } + } + while (loop--); + + hfs_extra = HFS_ROUND_UP(hce->hfs_tot_size) / SECTOR_SIZE; + + last_extent += hfs_extra; + + /* generate the Mac label and HFS partition maps */ + mac_boot.name = hfs_boot_file; + + /* + * only generate the partition tables etc. if we are making a bootable + * CD - or if the -part option is given + */ + if (gen_pt) { + if (gen_mac_label(&mac_boot)) { + if (*hce->error) + fprintf(stderr, "%s\n", hce->error); + perr(hfs_error); + } + } + /* set Autostart filename if required */ + if (autoname) { + if (autostart()) + perr("Autostart filename must less than 12 characters"); + } + /* finished with any HFS type errors */ + free(hce->error); + hce->error = 0; + + /* + * the ISO files need to start on a multiple of the HFS allocation + * blocks, so find out how much padding we need + */ + + /* + * take in accout alignment of files wrt HFS volume start - remove any + * previous session as well + */ + start_extent -= session_start; + hfs_pad = ROUND_UP(start_extent*SECTOR_SIZE + + (hce->hfs_hdr_size + hce->hfs_map_size) * HFS_BLOCKSZ, + Csize) / SECTOR_SIZE; + + hfs_pad -= (start_extent + (hce->hfs_hdr_size + hce->hfs_map_size) / + HFS_BLK_CONV); + +#ifdef PREP_BOOT + gen_prepboot_label(hce->hfs_map); +#endif /* PREP_BOOT */ + +} + +#ifdef PREP_BOOT +LOCAL void +gen_prepboot() +{ + /* + * we need to allocate the hce struct since hce->hfs_map is used to + * generate the fdisk partition map required for PReP booting + */ + hce = (hce_mem *) e_malloc(sizeof (hce_mem)); + + /* mark as unallocated for use later */ + hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0; + + /* reserve space for the label partition - if it is needed */ + hce->hfs_map_size = HFS_MAP_SIZE; + + hce->hfs_map = (unsigned char *) e_malloc(hce->hfs_map_size * HFS_BLOCKSZ); + gen_prepboot_label(hce->hfs_map); +} + +#endif /* PREP_BOOT */ + +/* + * get_adj_size: get the ajusted size of the volume with the HFS + * allocation block size for each file + */ +EXPORT Ulong +get_adj_size(Csize) + int Csize; +{ + struct deferred_write *dw; + Ulong size = 0; + int count = 0; + + /* loop through all the files finding the new total size */ + for (dw = dw_head; dw; dw = dw->next) { + size += (ROUND_UP(dw->size, Csize)/HFS_BLOCKSZ); + count++; + } + + /* + * crude attempt to prevent overflows - HFS can only cope with a + * maximum of about 65536 forks (actually less) - this will trap cases + * when we have far too many files + */ + + if (count >= 65536) + return (-1); + else + return (size); +} + +/* + * adj_size: adjust the ISO record entries for all files + * based on the HFS allocation block size + */ +EXPORT int +adj_size(Csize, start_extent, extra) + int Csize; + UInt32_t start_extent; + int extra; +{ + struct deferred_write *dw; + struct directory_entry *s_entry; + int size; + + /* get the adjusted start_extent (with padding) */ + /* take in accout alignment of files wrt HFS volume start */ + + start_extent -= session_start; + + start_extent = ROUND_UP(start_extent*SECTOR_SIZE + extra*HFS_BLOCKSZ, + Csize) / SECTOR_SIZE; + + start_extent -= (extra / HFS_BLK_CONV); + + start_extent += session_start; + + /* initialise file hash */ + flush_hash(); + + /* + * loop through all files changing their starting blocks and finding + * any padding needed to written out latter + */ + for (dw = dw_head; dw; dw = dw->next) { + s_entry = dw->s_entry; + s_entry->starting_block = dw->extent = start_extent; + set_733((char *)s_entry->isorec.extent, start_extent); + size = ROUND_UP(dw->size, Csize) / SECTOR_SIZE; + dw->pad = size - ISO_ROUND_UP(dw->size) / SECTOR_SIZE; + + /* + * cache non-HFS files - as there may be multiple links to + * these files (HFS files can't have multiple links). We will + * need to change the starting extent of the other links later + */ + if (!s_entry->hfs_ent) + add_hash(s_entry); + + start_extent += size; + } + + return (start_extent); +} + +/* + * adj_size_other: adjust any non-HFS files that may be linked + * to an existing file (i.e. not have a deferred_write + * entry of it's own + */ +EXPORT void +adj_size_other(dpnt) + struct directory *dpnt; +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + /* + * if it's an HFS file or a directory - then ignore + * (we're after non-HFS files) + */ + if (s_entry->hfs_ent || + (s_entry->isorec.flags[0] & ISO_DIRECTORY)) + continue; + + /* + * find any cached entry and assign new starting + * extent + */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + set_733((char *)s_entry->isorec.extent, + s_hash->starting_block); + /* not vital - but tidy */ + s_entry->starting_block = + s_hash->starting_block; + } + } + if (dpnt->subdir) { + adj_size_other(dpnt->subdir); + } + dpnt = dpnt->next; + } + + /* clear file hash */ + flush_hash(); +} + +/* + * hfs_hce_write: write out the HFS header stuff + */ +LOCAL int +hfs_hce_write(outfile) + FILE *outfile; +{ + char buffer[SECTOR_SIZE]; + int n = 0; + int r; /* HFS hdr output */ + int tot_size = hce->hfs_map_size + hce->hfs_hdr_size; + + memset(buffer, 0, sizeof (buffer)); + + /* + * hack time ... if the tot_size is greater than 32Kb then + * it won't fit in the first 16 blank SECTORS (64 512 byte + * blocks, as most of this is padding, we just truncate this + * data to 64x4xHFS_BLOCKSZ ... hope this is OK ... + */ + + if (tot_size > 64) tot_size = 64; + + /* get size in CD blocks == 4xHFS_BLOCKSZ == 2048 */ + n = tot_size / HFS_BLK_CONV; + r = tot_size % HFS_BLK_CONV; + + /* write out HFS volume header info */ + xfwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, outfile, 0, FALSE); + + /* fill up to a complete CD block */ + if (r) { + xfwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, outfile, 0, FALSE); + n++; + } + last_extent_written += n; + return (0); +} + +/* + * insert_padding_file : insert a dumy file to make volume at least + * 800k + * + * XXX If we ever need to write more then 2 GB, make size off_t + */ +EXPORT int +insert_padding_file(size) + int size; +{ + struct deferred_write *dwpnt; + + /* get the size in bytes */ + size *= HFS_BLOCKSZ; + + dwpnt = (struct deferred_write *) + e_malloc(sizeof (struct deferred_write)); + dwpnt->s_entry = 0; + /* set the padding to zero */ + dwpnt->pad = 0; + /* set offset to zero */ + dwpnt->off = (off_t)0; + dwpnt->dw_flags = 0; +#ifdef APPLE_HYB + dwpnt->hfstype = TYPE_NONE; +#endif + + /* + * don't need to wory about the s_entry stuff as it won't be touched# + * at this point onwards + */ + + /* insert the entry in the list */ + if (dw_tail) { + dw_tail->next = dwpnt; + dw_tail = dwpnt; + } else { + dw_head = dwpnt; + dw_tail = dwpnt; + } + + /* aloocate memory as a "Table" file */ + dwpnt->table = e_malloc(size); + dwpnt->name = NULL; + + dwpnt->next = NULL; + dwpnt->size = size; + dwpnt->extent = last_extent; + last_extent += ISO_BLOCKS(size); + + /* retune the size in HFS blocks */ + return (ISO_ROUND_UP(size) / HFS_BLOCKSZ); +} + +struct output_fragment hfs_desc = {NULL, NULL, NULL, hfs_hce_write, "HFS volume header"}; + +#endif /* APPLE_HYB */ + +struct output_fragment startpad_desc = {NULL, startpad_size, NULL, startpad_write, "Initial Padblock"}; +struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write, "Primary Volume Descriptor"}; +struct output_fragment xvoldesc_desc = {NULL, oneblock_size, NULL, xpvd_write, "Enhanced Volume Descriptor"}; +struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write, "End Volume Descriptor" }; +struct output_fragment version_desc = {NULL, oneblock_size, NULL, vers_write, "Version block" }; +struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write, "Path table"}; +struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write, "Directory tree" }; +struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup, "Directory tree cleanup" }; +struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write, "Extension record" }; +struct output_fragment files_desc = {NULL, NULL, file_gen, file_write, "The File(s)"}; +struct output_fragment interpad_desc = {NULL, interpad_size, NULL, interpad_write, "Intermediate Padblock"}; +struct output_fragment endpad_desc = {NULL, endpad_size, NULL, endpad_write, "Ending Padblock"};