From d658408736f8dacb4da85093e8f59b314cfb6314 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 16 Sep 2016 12:36:11 +0000 Subject: [PATCH] Branching for libisoburn release 1.4.6 --- libisoburn/branches/1.4.6/AUTHORS | 3 + libisoburn/branches/1.4.6/CONTRIBUTORS | 0 libisoburn/branches/1.4.6/COPYING | 280 + libisoburn/branches/1.4.6/COPYRIGHT | 18 + libisoburn/branches/1.4.6/ChangeLog | 751 + libisoburn/branches/1.4.6/INSTALL | 237 + libisoburn/branches/1.4.6/Makefile.am | 297 + libisoburn/branches/1.4.6/README | 324 + libisoburn/branches/1.4.6/TODO | 11 + libisoburn/branches/1.4.6/acinclude.m4 | 378 + libisoburn/branches/1.4.6/bootstrap | 11 + libisoburn/branches/1.4.6/configure.ac | 495 + libisoburn/branches/1.4.6/doc/comments | 85 + libisoburn/branches/1.4.6/doc/doxygen.conf.in | 1270 ++ libisoburn/branches/1.4.6/doc/faq.wiki | 407 + .../doc/grub-mkrescue_reserved_commands.txt | 47 + .../branches/1.4.6/doc/partition_offset.wiki | 232 + .../branches/1.4.6/doc/qemu_xorriso.wiki | 518 + .../branches/1.4.6/doc/startup_file.txt | 22 + .../branches/1.4.6/frontend/README-tcltk | 127 + .../1.4.6/frontend/frontend_pipes_xorriso.c | 980 + .../1.4.6/frontend/grub-mkrescue-sed.sh | 271 + .../1.4.6/frontend/sh_on_named_pipes.sh | 304 + .../branches/1.4.6/frontend/xorriso-tcltk | 5929 +++++ .../branches/1.4.6/frontend/xorriso_broker.sh | 222 + libisoburn/branches/1.4.6/libisoburn-1.pc.in | 12 + .../branches/1.4.6/libisoburn/burn_wrap.c | 2155 ++ .../branches/1.4.6/libisoburn/data_source.c | 370 + .../branches/1.4.6/libisoburn/isoburn.c | 1957 ++ .../branches/1.4.6/libisoburn/isoburn.h | 818 + .../branches/1.4.6/libisoburn/isofs_wrap.c | 718 + .../branches/1.4.6/libisoburn/libisoburn.h | 2640 +++ .../branches/1.4.6/libisoburn/libisoburn.ver | 350 + libisoburn/branches/1.4.6/releng/CHECKLIST | 27 + libisoburn/branches/1.4.6/releng/README | 297 + libisoburn/branches/1.4.6/releng/TODO | 42 + libisoburn/branches/1.4.6/releng/auto_cxx | 88 + .../branches/1.4.6/releng/auto_isocontent | 400 + .../branches/1.4.6/releng/auto_printsize | 149 + .../branches/1.4.6/releng/change_shell_to_use | 39 + .../1.4.6/releng/codesamples/api_3lib.cpp | 34 + .../1.4.6/releng/codesamples/api_xorriso.cpp | 30 + .../1.4.6/releng/inc/releng_getopts.inc | 198 + .../1.4.6/releng/inc/test_releng_getopt | 20 + .../branches/1.4.6/releng/jigdo-gen-md5-list | 175 + .../1.4.6/releng/jigdo-gen-md5-list.1 | 30 + libisoburn/branches/1.4.6/releng/manual_burn | 256 + .../branches/1.4.6/releng/manual_devices | 188 + .../branches/1.4.6/releng/manual_isojigdo | 288 + libisoburn/branches/1.4.6/releng/run_all_auto | 247 + libisoburn/branches/1.4.6/releng/template_new | 135 + libisoburn/branches/1.4.6/test/compare_file.c | 307 + libisoburn/branches/1.4.6/test/test.c | 312 + libisoburn/branches/1.4.6/version.h.in | 6 + .../1.4.6/xorriso/AUTHORS_gnu_xorriso | 15 + .../1.4.6/xorriso/COPYING_gnu_xorriso | 674 + .../1.4.6/xorriso/COPYRIGHT_gnu_xorriso | 34 + .../branches/1.4.6/xorriso/README_gnu_xorriso | 528 + .../branches/1.4.6/xorriso/aux_objects.c | 1032 + .../branches/1.4.6/xorriso/aux_objects.h | 185 + libisoburn/branches/1.4.6/xorriso/base_obj.c | 772 + libisoburn/branches/1.4.6/xorriso/base_obj.h | 31 + .../branches/1.4.6/xorriso/changelog.txt | 18652 ++++++++++++++++ .../branches/1.4.6/xorriso/check_media.c | 1123 + .../branches/1.4.6/xorriso/check_media.h | 180 + .../branches/1.4.6/xorriso/cmp_update.c | 1021 + .../branches/1.4.6/xorriso/cmp_update.h | 45 + .../branches/1.4.6/xorriso/compile_xorriso.sh | 231 + .../branches/1.4.6/xorriso/configure_ac.txt | 542 + .../1.4.6/xorriso/convert_man_to_html.sh | 14 + libisoburn/branches/1.4.6/xorriso/disk_ops.c | 2167 ++ libisoburn/branches/1.4.6/xorriso/disk_ops.h | 120 + libisoburn/branches/1.4.6/xorriso/drive_mgt.c | 3453 +++ libisoburn/branches/1.4.6/xorriso/drive_mgt.h | 42 + libisoburn/branches/1.4.6/xorriso/emulators.c | 2685 +++ libisoburn/branches/1.4.6/xorriso/emulators.h | 37 + libisoburn/branches/1.4.6/xorriso/filters.c | 717 + libisoburn/branches/1.4.6/xorriso/filters.h | 31 + libisoburn/branches/1.4.6/xorriso/findjob.c | 1297 ++ libisoburn/branches/1.4.6/xorriso/findjob.h | 458 + libisoburn/branches/1.4.6/xorriso/iso_img.c | 2859 +++ libisoburn/branches/1.4.6/xorriso/iso_img.h | 44 + libisoburn/branches/1.4.6/xorriso/iso_manip.c | 4486 ++++ libisoburn/branches/1.4.6/xorriso/iso_manip.h | 81 + libisoburn/branches/1.4.6/xorriso/iso_tree.c | 2707 +++ libisoburn/branches/1.4.6/xorriso/iso_tree.h | 97 + libisoburn/branches/1.4.6/xorriso/lib_mgt.c | 1015 + libisoburn/branches/1.4.6/xorriso/lib_mgt.h | 73 + .../branches/1.4.6/xorriso/make_docs.sh | 15 + .../branches/1.4.6/xorriso/make_timestamp.sh | 9 + .../branches/1.4.6/xorriso/make_xorriso_1.c | 531 + .../1.4.6/xorriso/make_xorriso_standalone.sh | 386 + .../1.4.6/xorriso/man_xorrecord_to_html.sh | 76 + .../1.4.6/xorriso/man_xorriso_to_html.sh | 127 + .../1.4.6/xorriso/man_xorrisofs_to_html.sh | 83 + libisoburn/branches/1.4.6/xorriso/match.c | 786 + libisoburn/branches/1.4.6/xorriso/match.h | 74 + .../branches/1.4.6/xorriso/misc_funct.c | 1313 ++ .../branches/1.4.6/xorriso/misc_funct.h | 99 + libisoburn/branches/1.4.6/xorriso/opts_a_c.c | 2735 +++ libisoburn/branches/1.4.6/xorriso/opts_d_h.c | 2520 +++ libisoburn/branches/1.4.6/xorriso/opts_i_o.c | 1724 ++ libisoburn/branches/1.4.6/xorriso/opts_p_z.c | 2285 ++ .../branches/1.4.6/xorriso/parse_exec.c | 3289 +++ .../branches/1.4.6/xorriso/parse_exec.h | 108 + libisoburn/branches/1.4.6/xorriso/read_run.c | 2206 ++ libisoburn/branches/1.4.6/xorriso/read_run.h | 70 + libisoburn/branches/1.4.6/xorriso/sfile.c | 957 + libisoburn/branches/1.4.6/xorriso/sfile.h | 145 + libisoburn/branches/1.4.6/xorriso/sort_cmp.c | 732 + libisoburn/branches/1.4.6/xorriso/sort_cmp.h | 62 + libisoburn/branches/1.4.6/xorriso/text_io.c | 4685 ++++ libisoburn/branches/1.4.6/xorriso/text_io.h | 117 + .../1.4.6/xorriso/unite_html_b_line.c | 124 + libisoburn/branches/1.4.6/xorriso/write_run.c | 3163 +++ libisoburn/branches/1.4.6/xorriso/write_run.h | 57 + libisoburn/branches/1.4.6/xorriso/xorrecord.1 | 872 + .../branches/1.4.6/xorriso/xorrecord.info | 1029 + .../branches/1.4.6/xorriso/xorrecord.texi | 1198 + libisoburn/branches/1.4.6/xorriso/xorriso.1 | 6098 +++++ libisoburn/branches/1.4.6/xorriso/xorriso.h | 2183 ++ .../branches/1.4.6/xorriso/xorriso.info | 5780 +++++ .../branches/1.4.6/xorriso/xorriso.texi | 7162 ++++++ .../1.4.6/xorriso/xorriso_bootstrap.txt | 10 + .../1.4.6/xorriso/xorriso_buildstamp.h | 3 + .../1.4.6/xorriso/xorriso_buildstamp_none.h | 3 + .../branches/1.4.6/xorriso/xorriso_eng.html | 831 + .../branches/1.4.6/xorriso/xorriso_main.c | 301 + .../1.4.6/xorriso/xorriso_makefile_am.txt | 360 + .../branches/1.4.6/xorriso/xorriso_pc_in.txt | 12 + .../branches/1.4.6/xorriso/xorriso_private.h | 845 + .../1.4.6/xorriso/xorriso_timestamp.h | 1 + .../branches/1.4.6/xorriso/xorrisoburn.h | 653 + libisoburn/branches/1.4.6/xorriso/xorrisofs.1 | 2122 ++ .../branches/1.4.6/xorriso/xorrisofs.info | 2358 ++ .../branches/1.4.6/xorriso/xorrisofs.texi | 2789 +++ 136 files changed, 136043 insertions(+) create mode 100644 libisoburn/branches/1.4.6/AUTHORS create mode 100644 libisoburn/branches/1.4.6/CONTRIBUTORS create mode 100644 libisoburn/branches/1.4.6/COPYING create mode 100644 libisoburn/branches/1.4.6/COPYRIGHT create mode 100644 libisoburn/branches/1.4.6/ChangeLog create mode 100644 libisoburn/branches/1.4.6/INSTALL create mode 100644 libisoburn/branches/1.4.6/Makefile.am create mode 100644 libisoburn/branches/1.4.6/README create mode 100644 libisoburn/branches/1.4.6/TODO create mode 100644 libisoburn/branches/1.4.6/acinclude.m4 create mode 100755 libisoburn/branches/1.4.6/bootstrap create mode 100644 libisoburn/branches/1.4.6/configure.ac create mode 100644 libisoburn/branches/1.4.6/doc/comments create mode 100644 libisoburn/branches/1.4.6/doc/doxygen.conf.in create mode 100644 libisoburn/branches/1.4.6/doc/faq.wiki create mode 100644 libisoburn/branches/1.4.6/doc/grub-mkrescue_reserved_commands.txt create mode 100644 libisoburn/branches/1.4.6/doc/partition_offset.wiki create mode 100644 libisoburn/branches/1.4.6/doc/qemu_xorriso.wiki create mode 100644 libisoburn/branches/1.4.6/doc/startup_file.txt create mode 100644 libisoburn/branches/1.4.6/frontend/README-tcltk create mode 100644 libisoburn/branches/1.4.6/frontend/frontend_pipes_xorriso.c create mode 100755 libisoburn/branches/1.4.6/frontend/grub-mkrescue-sed.sh create mode 100755 libisoburn/branches/1.4.6/frontend/sh_on_named_pipes.sh create mode 100755 libisoburn/branches/1.4.6/frontend/xorriso-tcltk create mode 100755 libisoburn/branches/1.4.6/frontend/xorriso_broker.sh create mode 100644 libisoburn/branches/1.4.6/libisoburn-1.pc.in create mode 100644 libisoburn/branches/1.4.6/libisoburn/burn_wrap.c create mode 100644 libisoburn/branches/1.4.6/libisoburn/data_source.c create mode 100644 libisoburn/branches/1.4.6/libisoburn/isoburn.c create mode 100644 libisoburn/branches/1.4.6/libisoburn/isoburn.h create mode 100644 libisoburn/branches/1.4.6/libisoburn/isofs_wrap.c create mode 100644 libisoburn/branches/1.4.6/libisoburn/libisoburn.h create mode 100644 libisoburn/branches/1.4.6/libisoburn/libisoburn.ver create mode 100644 libisoburn/branches/1.4.6/releng/CHECKLIST create mode 100644 libisoburn/branches/1.4.6/releng/README create mode 100644 libisoburn/branches/1.4.6/releng/TODO create mode 100755 libisoburn/branches/1.4.6/releng/auto_cxx create mode 100755 libisoburn/branches/1.4.6/releng/auto_isocontent create mode 100755 libisoburn/branches/1.4.6/releng/auto_printsize create mode 100755 libisoburn/branches/1.4.6/releng/change_shell_to_use create mode 100644 libisoburn/branches/1.4.6/releng/codesamples/api_3lib.cpp create mode 100644 libisoburn/branches/1.4.6/releng/codesamples/api_xorriso.cpp create mode 100644 libisoburn/branches/1.4.6/releng/inc/releng_getopts.inc create mode 100755 libisoburn/branches/1.4.6/releng/inc/test_releng_getopt create mode 100755 libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list create mode 100644 libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list.1 create mode 100755 libisoburn/branches/1.4.6/releng/manual_burn create mode 100755 libisoburn/branches/1.4.6/releng/manual_devices create mode 100755 libisoburn/branches/1.4.6/releng/manual_isojigdo create mode 100755 libisoburn/branches/1.4.6/releng/run_all_auto create mode 100755 libisoburn/branches/1.4.6/releng/template_new create mode 100644 libisoburn/branches/1.4.6/test/compare_file.c create mode 100644 libisoburn/branches/1.4.6/test/test.c create mode 100644 libisoburn/branches/1.4.6/version.h.in create mode 100644 libisoburn/branches/1.4.6/xorriso/AUTHORS_gnu_xorriso create mode 100644 libisoburn/branches/1.4.6/xorriso/COPYING_gnu_xorriso create mode 100644 libisoburn/branches/1.4.6/xorriso/COPYRIGHT_gnu_xorriso create mode 100644 libisoburn/branches/1.4.6/xorriso/README_gnu_xorriso create mode 100644 libisoburn/branches/1.4.6/xorriso/aux_objects.c create mode 100644 libisoburn/branches/1.4.6/xorriso/aux_objects.h create mode 100644 libisoburn/branches/1.4.6/xorriso/base_obj.c create mode 100644 libisoburn/branches/1.4.6/xorriso/base_obj.h create mode 100644 libisoburn/branches/1.4.6/xorriso/changelog.txt create mode 100644 libisoburn/branches/1.4.6/xorriso/check_media.c create mode 100644 libisoburn/branches/1.4.6/xorriso/check_media.h create mode 100644 libisoburn/branches/1.4.6/xorriso/cmp_update.c create mode 100644 libisoburn/branches/1.4.6/xorriso/cmp_update.h create mode 100755 libisoburn/branches/1.4.6/xorriso/compile_xorriso.sh create mode 100644 libisoburn/branches/1.4.6/xorriso/configure_ac.txt create mode 100755 libisoburn/branches/1.4.6/xorriso/convert_man_to_html.sh create mode 100644 libisoburn/branches/1.4.6/xorriso/disk_ops.c create mode 100644 libisoburn/branches/1.4.6/xorriso/disk_ops.h create mode 100644 libisoburn/branches/1.4.6/xorriso/drive_mgt.c create mode 100644 libisoburn/branches/1.4.6/xorriso/drive_mgt.h create mode 100644 libisoburn/branches/1.4.6/xorriso/emulators.c create mode 100644 libisoburn/branches/1.4.6/xorriso/emulators.h create mode 100644 libisoburn/branches/1.4.6/xorriso/filters.c create mode 100644 libisoburn/branches/1.4.6/xorriso/filters.h create mode 100644 libisoburn/branches/1.4.6/xorriso/findjob.c create mode 100644 libisoburn/branches/1.4.6/xorriso/findjob.h create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_img.c create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_img.h create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_manip.c create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_manip.h create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_tree.c create mode 100644 libisoburn/branches/1.4.6/xorriso/iso_tree.h create mode 100644 libisoburn/branches/1.4.6/xorriso/lib_mgt.c create mode 100644 libisoburn/branches/1.4.6/xorriso/lib_mgt.h create mode 100755 libisoburn/branches/1.4.6/xorriso/make_docs.sh create mode 100755 libisoburn/branches/1.4.6/xorriso/make_timestamp.sh create mode 100644 libisoburn/branches/1.4.6/xorriso/make_xorriso_1.c create mode 100755 libisoburn/branches/1.4.6/xorriso/make_xorriso_standalone.sh create mode 100755 libisoburn/branches/1.4.6/xorriso/man_xorrecord_to_html.sh create mode 100755 libisoburn/branches/1.4.6/xorriso/man_xorriso_to_html.sh create mode 100755 libisoburn/branches/1.4.6/xorriso/man_xorrisofs_to_html.sh create mode 100644 libisoburn/branches/1.4.6/xorriso/match.c create mode 100644 libisoburn/branches/1.4.6/xorriso/match.h create mode 100644 libisoburn/branches/1.4.6/xorriso/misc_funct.c create mode 100644 libisoburn/branches/1.4.6/xorriso/misc_funct.h create mode 100644 libisoburn/branches/1.4.6/xorriso/opts_a_c.c create mode 100644 libisoburn/branches/1.4.6/xorriso/opts_d_h.c create mode 100644 libisoburn/branches/1.4.6/xorriso/opts_i_o.c create mode 100644 libisoburn/branches/1.4.6/xorriso/opts_p_z.c create mode 100644 libisoburn/branches/1.4.6/xorriso/parse_exec.c create mode 100644 libisoburn/branches/1.4.6/xorriso/parse_exec.h create mode 100644 libisoburn/branches/1.4.6/xorriso/read_run.c create mode 100644 libisoburn/branches/1.4.6/xorriso/read_run.h create mode 100644 libisoburn/branches/1.4.6/xorriso/sfile.c create mode 100644 libisoburn/branches/1.4.6/xorriso/sfile.h create mode 100644 libisoburn/branches/1.4.6/xorriso/sort_cmp.c create mode 100644 libisoburn/branches/1.4.6/xorriso/sort_cmp.h create mode 100644 libisoburn/branches/1.4.6/xorriso/text_io.c create mode 100644 libisoburn/branches/1.4.6/xorriso/text_io.h create mode 100644 libisoburn/branches/1.4.6/xorriso/unite_html_b_line.c create mode 100644 libisoburn/branches/1.4.6/xorriso/write_run.c create mode 100644 libisoburn/branches/1.4.6/xorriso/write_run.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrecord.1 create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrecord.info create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrecord.texi create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso.1 create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso.info create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso.texi create mode 100755 libisoburn/branches/1.4.6/xorriso/xorriso_bootstrap.txt create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_buildstamp.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_buildstamp_none.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_eng.html create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_main.c create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_makefile_am.txt create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_pc_in.txt create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_private.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorriso_timestamp.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrisoburn.h create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrisofs.1 create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrisofs.info create mode 100644 libisoburn/branches/1.4.6/xorriso/xorrisofs.texi diff --git a/libisoburn/branches/1.4.6/AUTHORS b/libisoburn/branches/1.4.6/AUTHORS new file mode 100644 index 00000000..0547ea18 --- /dev/null +++ b/libisoburn/branches/1.4.6/AUTHORS @@ -0,0 +1,3 @@ +Thomas Schmitt +Vreixo Formoso Lopes + diff --git a/libisoburn/branches/1.4.6/CONTRIBUTORS b/libisoburn/branches/1.4.6/CONTRIBUTORS new file mode 100644 index 00000000..e69de29b diff --git a/libisoburn/branches/1.4.6/COPYING b/libisoburn/branches/1.4.6/COPYING new file mode 100644 index 00000000..5a965fbc --- /dev/null +++ b/libisoburn/branches/1.4.6/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/libisoburn/branches/1.4.6/COPYRIGHT b/libisoburn/branches/1.4.6/COPYRIGHT new file mode 100644 index 00000000..202be574 --- /dev/null +++ b/libisoburn/branches/1.4.6/COPYRIGHT @@ -0,0 +1,18 @@ +Mario Danic , +Vreixo Formoso +Thomas Schmitt +libisoburn is Copyright (C) 2007-2014 Vreixo Formoso, Thomas Schmitt +xorriso is Copyright (C) 2007-2014 Thomas Schmitt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + or later 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; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA diff --git a/libisoburn/branches/1.4.6/ChangeLog b/libisoburn/branches/1.4.6/ChangeLog new file mode 100644 index 00000000..58510177 --- /dev/null +++ b/libisoburn/branches/1.4.6/ChangeLog @@ -0,0 +1,751 @@ + +SVN trunk (to become libisoburn-1.4.6 or higher) +=============================================================================== +* Bug fix: The default setting of -compliance did not apply rec_mtime to + Joliet and ISO:1999. mkisofs emulation was not affected by this bug. +* New command -use_immed_bit, new -as cdrecord option use_immed_bit= +* New -volume_date mode "all_file_dates" +* New -as mkisofs option --set_all_file_dates +* New bootspec "gpt_disk_guid=", new -as mkisofs option --gpt_disk_guid +* New -report_system_area modes "gpt_disk_guid", "make_guid" +* New environment variable SOURCE_DATE_EPOCH +* New -find action "set_to_mtime" + +libisoburn-1.4.4.tar.gz Fri Jul 01 2016 +=============================================================================== +* Bug fix: -as mkisofs did not unescape "\=" in the source part of pathspecs +* Bug fix: -boot_image "any" "system_area=/dev/zero" did not zeroize loaded + data +* Bug fix: -pathspecs "on" did not properly handle "\\=" +* Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT +* Bug fix: HFS+ directories could announce more children than they actually have +* Bug fix: The HFS+ filesystem was not marked by in GPT of GRUB2 hybrid layout +* Bug fix: When reading an ISO filesystem, the presence of + --protective-msdos-label was not recognized if a partition is + appended +* Bug fix: xorrisofs option --protective-msdos-label did not work if no + system area data were given by option -G or alike +* Bug fix: -modesty_on_drive properties timeout_sec, min_usec, max_usec + read wrong numbers from the parameter text +* Letting -as mkisofs --norock revoke the special effect of -r +* Letting -blank on overwritable media invalidate UDF extended descriptors +* New -pathspecs mode "as_mkisofs" +* New -boot_image setting mbr_force_bootable=, -as mkisofs --mbr-force-bootable +* New -boot_image bootspecs appended_part_as=apm, part_like_isohybrid=on +* New -as mkisofs options -appended_part_as_apm, -part_like_isohybrid +* New command -scsi_dev_family, new -as cdrecord option drive_scsi_dev_family= + +libisoburn-1.4.2.tar.gz Sat Nov 28 2015 +=============================================================================== +* Bug fix: -backslash_codes "on" did not work outside quotes + and with showing "\r" +* New API calls isoburn_ropt_set_truncate_mode() isoburn_ropt_get_truncate_mode() +* New options with isoburn_ropt_set_extensions(): isoburn_ropt_map_* +* New command -modesty_on_drive, + new -as cdrecord -immed, minbuf=, modesty_on_drive= +* New command -ecma119_map +* New command -read_fs +* New -boot_image action "replay" +* New command -file_name_limit, -as mkisofs -file_name_limit +* New -find test -name_limit_blocker. +* Result of a Coverity audit: 50+ code changes, but no easy-to-trigger bugs + +libisoburn-1.4.0.tar.gz Sun May 17 2015 +=============================================================================== +* Bug fix: -dev or -indev of medium with non-ISO data caused SIGSEGV by NULL +* New API calls isoburn_igopt_set_appended_as_gpt(), + isoburn_igopt_get_appended_as_gpt() +* New API call isoburn_igopt_set_part_flag() and libisofs interval reader flags +* New -find action "show_stream_id" +* Optional libisofs interval reader with -append_partition and System Area +* New -boot_image bootspec "appended_part_as=", + new -as mkisofs option -appended_part_as_gpt +* New -report_system_area formats "cmd" and "as_mkisofs" + +libisoburn-1.3.8.tar.gz Sat Jun 28 2014 +=============================================================================== +* Bug fix: -boot_image grub grub2_mbr= did not work + (but -as mkisofs --grub2-mbr did work) +* Bug fix: -boot_image grub2_mbr= prevented -boot_image partition_table=on +* Bug fix: libburn: A final fsync(2) was performed with stdio drives, + even if -stdio_sync was set to "off". +* Bug fix: libburn: Wrong stack usage caused SIGBUS on sparc when compiled + by gcc -O2 +* Bug fix: -blank force:all on DVD+RW had no effect +* Enabled use of libedit as alternative to libreadline +* Enabled recording and restoring of extattr on NetBSD +* New API calls isoburn_igopt_set_stdio_endsync() and + isoburn_igopt_get_stdio_endsync +* New bootspecs hppa_*, new -as mkisofs options -hppa-* for HP-PA via PALO +* New -find pseudo tests -use_pattern , -or_use_pattern +* New -find action report_sections +* New command -concat +* New commands -report_system_area and -report_el_torito + +libisoburn-1.3.6.pl01.tar.gz Tue Mar 18 2014 +=============================================================================== +* Bug fix: Command -status produced FAILURE event if no drive was acquired + Regression introduced by release 1.3.6 +* Bug fix: libburn : Compilation warning for unsupported systems mutated + into an error. Regression introduced by release 1.3.6. +* Bug fix: libburn : CD TAO with add-on sessions could cause a buffer overrun. + Introduced 7 years ago by release 0.3.2. + +libisoburn-1.3.6.tar.gz Tue Mar 04 2014 +=============================================================================== +* Bug fix: libisofs: Division by zero if HFS+ was combined with TOC emulation + for overwritable media. +* Bug fix: -list_speeds did not work any more with old CD drives. + Regression introduced by release 1.3.4 +* Bug fix: -check_media marked untested sectors in sector map as valid +* Bug fix: Paths with symbolic links preceding ".." were not interpreted + properly +* New isoburn_igopt_set_relaxed() relaxation isoburn_igopt_joliet_utf16 +* New -compliance rule joliet_utf16, new -as mkisofs option -joliet-utf16 +* New -find test -bad_outname, new -find action print_outname +* New API call isoburn_conv_name_chars() +* libburn: New system adapter for NetBSD + +libisoburn-1.3.4.tar.gz Thu Dec 12 2013 +=============================================================================== +* Bug fix: Command -blank "as_needed" formatted blank BD-R. +* Bug fix: -as mkisofs option -log-file put the log file into the image +* Bug fix: -cut_out did not add x-permission to r-permission of directory +* Bug fix: Command -zisofs did not accept all options emitted by + -status -zisofs +* Bug fix: -blank force:... failed on appendable or closed media +* Bug fix: libburn: Drive LG BH16NS40 stalled on inspection of unformatted + DVD+RW +* libisofs: Default sort weight of El Torito boot images is now 2 +* libisofs: Encoding HFS+ names in UTF-16 rather than UCS-2 +* New command -read_speed +* New -close mode "as_needed", new -as cdrecord option --multi_if_possible +* New -alter_date types: a-c , m-c , b-c , c + +libisoburn-1.3.2.tar.gz Wed Aug 07 2013 +=============================================================================== +* Bug fix: -find -exec "sort_weight" did not mark the image as having + pending changes +* Bug fix: -backslash_codes "with_program_arguments" was interpreted too late +* Bug fix: Missing or empty parameter with -dus was interpreted as "*" rather + than "." +* Bug fix: readline history was spammed by -msg_op parsing and pipe loops +* Bug fix: xorriso aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU +* Improved granularity of SCSI log time measurement, now with timestamp +* New -pacifier behavior code "interval=" +* New -as mkisofs options --sort-weight-list and --sort-weight-patterns +* New -format mode "without_spare" (for BD-RE) +* New command -named_pipe_loop +* New command -sh_style_result +* New -msg_op opcodes "parse_silently" and "parse_bulk_silently" +* New command -application_use and new -as mkisofs option --application_use + +libisoburn-1.3.0.tar.gz Fri May 17 2013 +=============================================================================== +* Bug fix: Disk paths with components '.' or '..' could be mistaken for + directories. +* Bug fix: -as mkisofs -print-size failed with -isohybrid-mbr and a single + boot image. Regression introduced by libisoburn-1.2.8. +* Bug fix: -as mkisofs -path-list did not switch to --no-emul-toc by default. +* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was + represented by 0-bytes rather than ASCII '0' digits. +* Bug fix: Reserved and unused fields of APM entries were not zeroed. +* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92. +* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1. +* New -boot_image bootspecs grub2_mbr= and grub2_boot_info= +* New -boot_image bootspec grub2_sparc_core= +* New -as mkisofs options --grub2-mbr , --grub2-boot-info , --grub2-sparc-core +* New -hardlinks mode "lsl_count" / "no_lsl_count" + +libisoburn-1.2.8.tar.gz Mon Mar 18 2013 +=============================================================================== +* Bug fix: -tell_media_space altered the pointers to MD5 of data files + which stem from a previous session. This produced false + mismatches with -check_md5_r. +* Bug fix: CD tracks were reported with the sizes of the tracks in the + first session. +* Bug fix: -check_media use=outdev sector_map= stored TOC of input drive +* Bug fix: -hide hfsplus and -as mkisofs -hide-hfsplus had no effect. + Thanks to Davy Ho. +* Bug fix: ./configure did not abort if libburn.h or libisofs.h were missing +* New command -move +* New -as mkisofs options -eltorito-id , -eltorito-selcrit + +libisoburn-1.2.6.tar.gz Tue Jan 08 2013 +=============================================================================== +* Bug fix: SIGSEGV by uninitialized local variable with + -check_media patch_lba0="on". Regression by version 1.0.6 +* Bug fix: -partition_offset 16 kept -isohybrid-gpt-basdat from writing + MBR partition table entries of type 0xef +* Bug fix: -rollback did not work if indev and outdev were empty +* New API calls Xorriso_parse_line() and Xorriso__dispose_words() +* New API calls Xorriso_fetch_outlists() and Xorriso_peek_outlists() +* New API call Xorriso_start_msg_watcher() +* New API calls Xorriso__severity_cmp() and Xorriso__severity_list() +* New API calls Xorriso_sieve_add_filter, Xorriso_sieve_get_result, + Xorriso_sieve_clear_results, Xorriso_sieve_dispose, Xorriso_sieve_big +* New -boot_image partition_cyl_align mode "all" +* New -blank mode prefix "force:" +* New -osirrox settings "blocked" and "unblock" +* New command -lns for creating symbolic links +* New command -toc_of +* New command -msg_op +* New command -launch_frontend +* Proof-of-concept of a GUI frontend program: xorriso-tcltk written in Tcl/Tk. + +libisoburn-1.2.4.tar.gz Fri Jul 20 2012 +=============================================================================== +* New API call isoburn_igopt_set_hfsp_serial_number() +* New API calls isoburn_igopt_set_prep_partition, isoburn_igopt_set_efi_bootp +* New API calls isoburn_igopt_set_hfsp_block_size() and isoburn_igopt_get_hfsp_block_size() +* New -check_media option async_chunks= +* New xorriso command -write_type +* New xorriso command -rockridge +* New xorriso command -hfsplus +* New -find tests -has_hfs_crtp, has_hfs_bless +* New -find actions set/get_hfs_crtp, set/get_hfs_bless +* New -find test -disk_path +* New -boot_image bootspec hfsplus_serial= +* New -boot_image bootspecs hfsplus_block_size= and apm_block_size= +* New -boot_image bootspecs efi_boot_part, prep_boot_part, chrp_boot_part +* Command -hide allows hiding in HFS+ filesystem +* New -as cdrecord options -tao -sao -dao +* New -as mkisofs option -log-file +* New -as mkisofs option --norock +* New -as mkisofs option -hfsplus +* New -as mkisofs option -hfsplus-file-creator-type +* New -as mkisofs options -hfs-bless and -hfs-bless-by +* New -as mkisofs option -hfsplus-serial-no +* New -as mkisofs options -hfsplus-block-size and -apm-block-size +* New -as mkisofs option -hide-hfsplus, -hide-hfsplus-list +* New -as mkisofs options -prep-boot-part, -efi-boot-part, -chrp-boot-part +* New -as mkisofs options -isohybrid-gpt-basdat, -isohybrid-gpt-hfsplus, -isohybrid-apm-hfsplus +* Bug fix: Memory corruption when reading bootable image that was truncated +* Bug fix: -update deleted MD5 of files of which only attributes had changed + +libisoburn-1.2.2.tar.gz Mon Apr 02 2012 +=============================================================================== +* New API calls isoburn_get_attached_start_lba(), isoburn_attach_start_lba() +* New API calls isoburn_igopt_set_rr_reloc(), isoburn_igopt_get_rr_reloc() +* New API calls isoburn_ropt_set_data_cache(), isoburn_ropt_get_data_cache() +* New commands -x, -list_arg_sorting +* New command -rr_reloc_dir +* New command -data_cache_size +* New -as mkisofs option -rr_reloc, implemented option -hide-rr-moved +* Now ignoring -as mkisofs -no-split-symlink-components -no-split-symlink-fields +* Bug fix: -osirrox on:sort_lba_on -extract from / restored nearly nothing +* Bug fix: -as mkisofs without -graft-points could not handle names with "=" +* Bug fix: Relaxation options joliet_rec_mtime and iso1999_rec_mtime had wrong values + +libisoburn-1.2.0.tar.gz Sat Jan 28 2012 +=============================================================================== +* Bug fix: mkisofs emulation did not record mtime in ECMA-119 directories +* Bug fix: Program abort while drive tray is loading led to endless loop +* Bug fix: Solaris adapter mishandled write commands which failed on first try +* Bug fix: libisoburn.ver had a duplicate function entry +* New relaxations isoburn_igopt_joliet_rec_mtime, + isoburn_igopt_iso1999_rec_mtime +* Made -compliance "rec_mtime" default for xorriso + +libisoburn-1.1.8.tar.gz Mon Nov 21 2011 +=============================================================================== +* Info document and man page for xorrecord +* New option -sleep +* Enabled recognition of QEMU DVD-ROM 0.12 +* Enabled out-of the box use of xorriso on Linux guest on qemu virtio-blk-pci + +libisoburn-1.1.6.tar.gz Tue Sep 27 2011 +=============================================================================== +* Bug fix: -extract_single extracted directory content +* Bug fix: -extract was not immediately aborted if -abort_on was triggered +* Bug fix: xorriso did not write to files in filesystems with >= 4 TB free space +* Bug fix: libisofs: ACL entries of groups and of user id 0 were not properly + recorded and cannot be restored +* Bug fix: libisofs: No ACLs were recorded on FreeBSD +* Enabled recording and restoring of extattr on FreeBSD. +* New option -list_extras +* New -osirrox option strict_acl +* New -find and -findx action list_extattr +* Workaround for collision with Linux udev which lets device links vanish + +libisoburn-1.1.4.tar.gz Mon Aug 8 2011 +=============================================================================== +* Bug fix: xorriso native mode on some drives wrote unreadble ISO images to CD +* Bug fix: -assert_volid did not work. Regression since version 1.1.0. +* Bug fix: -acl or -xattr worked with -extract only on Linux and FreeBSD +* New option -device_links + +libisoburn-1.1.2.tar.gz Fri Jul 8 2011 +=============================================================================== +* Bug fix: Since 1.0.6: Unreadable image produced by: xorrisofs ... >image.iso +* Bug fix: -update_r scheduled non-existing files for hardlink update +* Enabled extraction of the boot catalog file to disk filesystem +* New option -list_speeds + +GNU xorriso-1.1.0.pl01.tar.gz Mon Jun 20 2011 +=============================================================================== +* Bug fix: Due to a bug in libburn-1.1.0, GNU xorriso-1.1.0 compiled only + on GNU/Linux, FreeBSD, and Solaris, but not on other systems. + +libisoburn-1.1.0.tar.gz Sat Jun 18 2011 +=============================================================================== +* Bug fix: -mount_opts shared worked only with -osirrox o_excl_off +* Bug fix: xorriso command -add_plainly "any" did not add all files to the image +* Bug fix: The attempt to blank already blank DVD-RW was not gracefully blocked +* Bug fix: -as mkisofs -isohybrid-mbr without -no-pad was not cylinder aligned +* New option -signal_handling +* New option -close_damaged +* Dropped suffix .plXY from tarball name + +libisoburn-1.0.8.pl00.tar.gz Thu Apr 14 2011 +=============================================================================== +* Bug fix: mkisofs emulation could ignore options (regression in 0.1.6) + +libisoburn-1.0.6.pl00.tar.gz Sat Apr 9 2011 +=============================================================================== +* Bug fix: -as mkisofs padding did not work (regression in 1.0.4) +* Bug fix: Options -gid and -uid had no effect +* New API call isoburn_set_truncate() +* New relax option isoburn_igopt_joliet_long_names +* New option -early_stdio_test +* New options -print_info and -print_mark +* New -compliance option joliet_long_names +* -as mkisofs option -joliet-long is now fully functional +* Burning DVD-R DAO with 2 kB size granularity rather than 32 kB + +libisoburn-1.0.4.pl00.tar.gz Thu Mar 10 2011 +=============================================================================== +libisoburn novelties: +* New isoburn_ropt_set_extensions() option isoburn_ropt_nomd5tag +xorriso novelties: +* Bug fix: xorrisofs did not work under growisofs -M (version 1.0.0 was ok) +* Bug fix: -as mkisofs -C attempted to read volume header of blank media +* Bug fix: -as mkisofs -old-root did not work with -graft-points +* Bug fix: -as mkisofs -partition_hd_cyl had no effect +* Bug fix: -as mkisofs did not properly unescape target part of pathspecs +* Bug fix: isohybrid image size was not aligned to cylinder boundary +* Bug fix: Compilation without zlib failed +* New -padding modes "included" and "appended" +* New bootspec partition_cyl_align=, new -as mkisofs option -partition_cyl_align +* New -as mkisofs and -as cdrecord option --no_rc +* Own man page and info document for xorrisofs + +libisoburn-1.0.2.pl00.tar.gz Mon Feb 23 2011 +=============================================================================== +libisoburn novelties: +* Removed compiler obstacles of GNU xorriso on Solaris 9 +* New isoburn_igopt_set_extensions() option isoburn_igopt_old_empty +xorriso novelties: +* Bug fix: Images produced with -for_backup might be unreadable and + also fail -check_md5 verification. +* Bug fix: mkisofs emulation options -l , -full-iso9660-filenames did not work. +* Bug fix: Option -mkdir yielded SIGSEGV due to a NULL pointer +* Bug fix: ECMA-119 standards violation with Volume Descriptor Set Terminator +* New options -clone and -cp_clone +* New -find actions update_merge, rm_merge, clear_merge +* New -as mkisofs option -max-iso9660-filenames +* New -as mkisofs option --old-empty +* New -as mkisofs options -root , -old-root +* New -as mkisofs options --old-root-no-md5, --old-root-no-ino, --old-root-dev + +libisoburn-1.0.0.pl00.tar.gz Mon Jan 17 2011 +=============================================================================== +libisoburn novelties: +* New API call isoburn_igopt_set_untranslated_name_len() +xorriso novelties: +* Bug fix: -as mkisofs -print-size did not account for -partition_offset +* Default -abort_on value is now "FAILURE" with batch and "NEVER" with dialog +* New -compliance options untranslated_names , untranslated_name_len= +* New -as mkisofs option -untranslated_name_len +* New -compliance option iso_9660_1999, -as mkisofs option -iso-level 4 +* New -compliance option iso_9660_level=number +* New -compliance option allow_dir_id_ext, -as mkisofs -disallow_dir_id_ext +* Disabled TOC emulation with -as mkisofs. May be re-enabled by --emul-toc. + +libisoburn-0.6.6.pl00.tar.gz Sun Dec 12 2010 +=============================================================================== +libisoburn novelties: +* New API calls isoburn_igopt_set_disc_label(), isoburn_igopt_get_disc_label() +* New API calls isoburn_ropt_set_displacement(), isoburn_ropt_get_displacement() +xorriso novelties: +* Bug fix: -as mkisofs -print-size printed the size but also produced ISO image +* Build problem fix on Linux 2.4 in GNU xorriso libjte/checksum.c +* New -as mkisofs option -joliet-long +* New bootspec sparc_label=, new -as mkisofs options -sparc-boot , -sparc-label +* New option -displacement + +libisoburn-0.6.4.pl00.tar.gz Tue Oct 26 2010 +=============================================================================== +libisoburn novelties: +* New API call isoburn_libjte_req() +* New API calls isoburn_igopt_attach_jte() and isoburn_igopt_detach_jte() +* New API call isoburn_igopt_set_tail_blocks() +* New API call isoburn_libjte_req() +xorriso novelties: +* New option -jigdo +* New -as mkisofs options -jigdo-* and -md5-list as of genisoimage +* New -as mkisofs options -checksum_algorithm_iso, -checksum_algorithm_template +* New bootspecs mips_path= and mipsel_path= for Debian MIPS releases +* New -as mkisofs options -mips-boot and -mipsel-boot +* New option -append_partition, -as mkisofs -append_partition + +libisoburn-0.6.2.pl00.tar.gz Sat Sep 18 2010 +=============================================================================== +libisoburn novelties: +* New API function isoburn_igopt_set_part_offset() +* Hiding all non-API symbols from the linker by use of --version-script +* Now with history of release notes in ./ChangeLog file. +xorriso novelties: +* Bug fix: Regression with -hardlinks and -compliance old_rr, 0.4.2, Aug 2009 +* New option -preparer_id, -as mkisofs options -p and -preparer +* New -boot_image specifier emul_type=none|hard_disk|floppy +* New boot_image boot specs partition_offset,partition_hd_cyl,partition_sec_hd +* Made behavior of -as mkisofs with unknown options more similar to original +* New -as mkisofs option -hard-disk-boot, enabled -b without -no-emul-boot +* New -as mkisofs option -e from Fedora genisoimage +* New -as mkisofs options -partition_offset,-partition_hd_cyl,-partition_sec_hd + +libisoburn-0.6.0.pl00.tar.gz Fri Jul 02 2010 +=============================================================================== +libisoburn novelties: +xorriso novelties: +* New option -read_mkisofsrc interprets .mkisofsrc To be performed before -as + mkisofs. Performed automatically with program alias name "xorrisofs". +* Implemented -as mkisofs options -dir-mode, -file-mode, -abstract, -biblio, + -copyright +* Implemented -as mkisofs options -hide, -hide-joliet, -hide-list, + -hide-joliet-list +* New -as mkisofs option --boot-catalog-hide +* New option -hide, -find action -hide, -find test -hidden +* New -boot_image bootspec cat_hidden=on +* New options -copyright_file , -biblio_file , -abstract_file +* New find test -disk_name +* Enabled use of libreadline on Solaris +* Bug fix: -check_media patch_lba0= could install wrong image size +* Bug fix: -as mkisofs option -volset was wrongly interpreted like -volid + +libisoburn-0.5.8.pl00.tar.gz Mon Jun 14 2010 +=============================================================================== +libisoburn novelties: +* xorriso source split into more modules, object code moved into libisoburn +xorriso novelties: +* New write extension option isoburn_igopt_no_emul_toc +* New -compliance rule no_emul_toc, new -as mkisofs --no-emul-toc +* Implemented -as cdrecord -V +* Implemented -as mkisofs options -U, -N, -l, -d, -allow-lowercase + +libisoburn-0.5.6.pl00.tar.gz Tue May 04 2010 +=============================================================================== +libisoburn novelties: +xorriso novelties: +* Allowing up to 32 boot images +* New -boot_image bootspecs + efi_path=, platform_id=, sel_crit=, id_string=, next +* New -as mkisofs options --efi-boot, -eltorito-alt-boot + +libisoburn-0.5.4.pl00.tar.gz Mon Apr 19 2010 +=============================================================================== +libisoburn novelties: +* New API call isoburn_igopt_set_system_area() +* New API call isoburn_igopt_set_pvd_times() +* New isoburn_igopt_set_relaxed() options: only_iso_versions, no_j_force_dots + xorriso novelties: +* New -boot_image any system_area=, -as mkisofs option -G +* New -boot_image grub partition_table=on, -as mkisofs --protective-msdos-label +* New -boot_image isolinux partition_table=on, -as mkisofs -isohybrid-mbr +* New option -volume_date, -as mkisofs --modification-date= +* New -find action mkisofs_r,-as mkisofs -r +* New -find action sort_weight, -as mkisofs --sort-weight +* New -compliance options only_iso_version, no_j_force_dots avoid + a bug in GRUB 1.96. They are default now. + +libisoburn-0.5.2.pl00.tar.gz Tue Mar 30 2010 +=============================================================================== +xorriso novelties: +* xorriso documentation is now based on a hybrid format of Texinfo and man- + page. Copies included: .texi, .info, .1 (man page) + +libisoburn-0.5.0.pl00.tar.gz Tue Feb 22 2010 +=============================================================================== +xorriso novelties: +* The former xorriso-standalone project is now GNU xorriso under GPLv3+. This + affects some documentation and the generator script, but not the license of + libisoburn or its program xorriso. +* Bug fix: xorriso -update_r could lead to SIGSEGV if applied to a data file + rather than a directory. +* Bug fix on FreeBSD: xorriso could leave the drive tray locked. +* New option -scsi_log + +libisoburn-0.4.8.pl00.tar.gz Tue Jan 26 2010 +=============================================================================== +xorriso novelties: +* Bug fix: xorriso did not blank CD-RW with images that were prepared + on hard disk. +* New configure option --enable-libcdio for system adapter to libcdio-0.83git + +libisoburn-0.4.6.pl00.tar.gz Wed Dec 09 2009 +=============================================================================== +xorriso novelties: +* New options -dvd_obs and -stdio_sync +* New configure option --enable-dvd-obs-64k + +libisoburn-0.4.4.pl00.tar.gz Wed Oct 28 2009 +=============================================================================== +xorriso novelties: +* Bug fix: With -as cdrecord : -xa1 and -xamix were ignored although they do + matter. +* Option -toc now reports the individual media type. E.g. with a DVD+RW: + "Media product: RICOHJPN/W11/49 , Ricoh Company Limited" +* New option -pvd_info displays image id strings. New options -system_id , - + volset_id allow to set such image id strings. +* New option -mount_opts tries to circumvent an eventual ban to mount the same + device twice. Some Linux systems allow to mount two sessions of the same + media only if they get fooled via the loop device. +* New option -scdbackup_tag performs the task of the scdbackup MD5 checksum + filter inside xorriso. +Already fixed by patch releases of xorriso-0.4.2: +* Bug fix: -cut_out deleted previously cut-out pieces of the same file +* Bug fix libisofs: Filenames could lose blanks during a multi-session cycle +* Bug fix: -for_backup did not enable -xattr and -md5 if no drive was chosen + yet +* Bug fix: xorrisofs -help, xorrecord -help displayed original xorriso -help + +libisoburn-0.4.2.pl02.tar.gz Thu Oct 08 2009 +=============================================================================== +* Bug fix: -for_backup did not enable -xattr and -md5 if no drive was chosen + yet +* Bug fix: xorrisofs -help, xorrecord -help displayed original xorriso -help + +Libisoburn 0.4.2.pl01 +=============================================================================== +* Bug fix: xorriso option -cut_out deleted previously cut-out pieces of the + same file. The bug was introduced with release 0.1.4 in March 2008. + +Libisoburn 0.4.2 +=============================================================================== +* New write options isoburn_igopt_session_md5, isoburn_igopt_file_md5, + isoburn_igopt_file_stability allow to record MD5 checksums of session and + single data files. +* New read option isoburn_ropt_nomd5 allows to read those MD5 sums when + importing an ISO image. +xorriso novelties: +* New option -md5, new -as mkisofs option --md5 allow to record in the image + MD5 checksums for the whole session and for each single data file. +* New options -check_md5, -check_md5_r allow to verify the whole session or + single files by comparing their image data with their MD5 sums. +* Options -compare, -compare_r, -update, update_r now can use recorded MD5. +* New -find actions check_md5, get_md5, make_md5 allow to check, to display or + to recompute MD5 checksums of data files. New find test -has_md5 + distinguishes data files which have recorded MD5 from files which have none. +* New -find test -has_any_xattr and action get_any_xattr allow to inspect the + libisofs specific attributes of namespace "isofs". +* Options -lsl and lsdl now display correct link counts if -hardlinks is on. +* New option -calm_drive allows to reduce drive noise if no data reading is + intended for a while. +* New option -list_profiles allows to inquire and process the list of supported + media types. +* Bug fix: xorriso -as mkisofs did not understand the -C option of growisofs + any more. (Already fixed by release 0.4.0.pl01, 20 Jul 2009) + +libisoburn-0.4.0.pl01.tar.gz Mon Jul 20 2009 +=============================================================================== +xorriso novelties: +* New option -hardlinks enables recording and restoring of hard link relations. +* Improved reading performance with -update_r and -extract. +* New option -for_backup as shortcut for -acl -xattr -hardlinks +* Operators with option -find : -not, -or, -and, (, ), -if, -then, -else +* New -find tests -wholename, -prune +* Bug fix: SIGSEGV with option -status and no search string +* Bug fix: -load volid did not perform pattern search +* Bug fix: Copies of overwriteable media on sequential were mistaken in ROM + drives +Libisoburn 0.4.0.pl01 release notes: +* Bug fix: xorriso -as mkisofs did not understand the -C option of growisofs + any more + +libisoburn-0.3.8.pl00.tar.gz Sun Apr 19 2009 +=============================================================================== +libisoburn novelties: +* New API calls isoburn_ropt_set_auto_incharset() and + isoburn_ropt_get_auto_incharset() +xorriso novelties: +* New options -set_filter, -set_filter_r, -find -exec set_filter allow to + manipulate the content of data files on the fly. +* New option -zisofs, built-in filters --zisofs , --gzip , --gunzip enable + compression and decompression of data file content. +* New options -external_filter , -unregister_filter, -close_filter_list allow + arbitrary external processes to do content filtering. +* New options -show_stream, -show_stream_r allow to inspect the origin and the + filters of data files in an emerging image. +* New option -auto_charset based on xattr "isofs.cs" allows to tag an ISO + filesystem image with the character set name that is in use on the current + terminal. + +libisoburn-0.3.6.pl00.tar.gz Mon Mar 16 2009 +=============================================================================== +xorriso novelties: +* Dummy MMC adapter of libburn allows compilation on systems other than Linux, + FreeBSD +* Default of -compliance has been changed to "old_rr", new rule "new_rr" +* New -stream_recording modes with start address or "data". "on" is now 32s. + +libisoburn-0.3.4.pl00.tar.gz Sun Mar 01 2009 +=============================================================================== +* New isoburn_read_opts values: isoburn_ropt_noaaip, isoburn_ropt_noacl, + isoburn_ropt_noea +xorriso novelties: +* New option -acl enables ACL import and export +* New options -getfacl, -getfacl_r, -setfacl, -setfacl_r, -setfacl_list +* New find tests -has_acl, -has_no_acl , new find actions getfacl, setfacl +* New option -xattr enables import and export of Extended Attributes +* New options -getfattr, -getfattr_r, -setfattr, -setfattr_r, -setfattr_list +* New find tests -has_xattr, -has_aaip, new find actions getfattr, setfattr +* New -as mkisofs options --acl and --xattr +* New option -disk_dev_ino accelerates incremental backups + +libisoburn-0.3.2.pl00.tar.gz Tue Jan 06 2009 +=============================================================================== +* New API function isoburn_get_mount_params() +* Now depending on libburn-0.6.0 which supports BD-R media +xorriso novelties: +* Bug fix: Options -extract and -extract_single were enabled with -osirrox off +* New options -mount , -mount_cmd , -session_string +* New -format modes by_size_ and fast_by_size_ +* New option -assert_volid +* New option -drive_class for safety management of pseudo-drive access + +libisoburn-0.3.0.pl00.tar.gz Tue Dec 2 2008 +=============================================================================== +* Now depending on libisofs-0.6.12 and libburn-0.5.6 to ensure use of their + recent bug fixes +xorriso novelties: +* New options -quoted_path_list, -quoted_not_list +* New option -backslash_codes for weird file names and terminal safety +* New options -charset, -in_charset, -out_charset +* New option -local_charset allows to override locale +* New option -application_id +* New option -compliance allows certain deviations from standards +* Suitable ISOLINUX boot images are made alternatively bootable via an MBR +* Bug fix: Forgot exit value registration to -return_with. + Thanks to Steve Dodd. +* Bug fix: -format as_needed did not recognize unformatted BD-RE +* Bug fix: disk patterns with relative addresses were not properly resolved + +libisoburn-0.2.8.pl00.tar.gz Wed Oct 15 2008 +=============================================================================== +* Now depending on libisofs-0.6.10 and libburn-0.5.4 to ensure use of their + recent bug fixes +xorriso novelties: +* Ability to write and maintain bootable ISO images based on ISOLINUX +* New ./configure option --disable-libreadline to make binary more portable +* Bug fix: -as mkisofs -iso-level was accused to be an unknown option +* Bug fix: -follow link attributed random target filenames to looping links + +libisoburn-0.2.6.pl00.tar.gz Sat Sep 20 2008 +=============================================================================== +xorriso novelties: +* Capability to insert and extract files far larger than 4 GB +* New option -file_size_limit, -as mkisofs now supports -iso-level 1 to 3 +* New option -extract_cut +* New -error_behavior "file_extraction" behavior "best_effort" +* New option -check_media_defaults +* New option -list_delimiter +* Bug fix: -format full did not re-format already formatted DVD+RW + +libisoburn-0.2.4.pl00.tar.gz Mo Aug 25 2008 +=============================================================================== +xorriso novelties: +* New option -check_media +* New -find test -damaged, new -find actions "report_damage", "report_lba" +* New -error_behavior occasion "file_extraction" + +libisoburn-0.2.2.pl01.tar.gz Fr Jul 25 2008 +=============================================================================== +Libisoburn 0.2.2 release notes (Jul 19 2008) +* New API function isoburn_prepare_blind_grow() +* New flag bits with isoburn_set_msc1(), isoburn_read_iso_head() +xorriso novelties: +* New option -grow_blindly +* Options -C and -M for -as mkisofs emulation +* Options for -as cdrecord emulation: -multi, -msinfo, -isosize, tsize, -- + grow_overwriteable_iso, write_start_address, +* New option -pacifier, more compatible pacifier with -as mkisofs +* make install creates aliases as symbolic links: osirrox, xorrisofs, xorrecord +* Can serve growisofs if started as xorrisofs, genisofs, mkisofs, genisoimage +pl01 changes (Jul 25 2008): +* Bug fix: Variable DESTDIR was not properly respected during make install + +libisoburn-0.2.0.pl00.tar.gz Mon Jun 23 2008 +=============================================================================== +Libisoburn 0.2.0 release notes: +* New API functions isoburn_set_msgs_submit(), isoburn_drive_set_msgs_submit() +xorriso novelties: +* Bug fix: -chmod unintentionally performed o-x as first operation +* New options -cpax, -cp_rx, -cp_rax, -extract to restore files and trees from + ISO image to disk filesystem. +* New option -paste_in to copy ISO files into parts of disk files +* New options -map_l, -compare_l, -update_l, -extract_l + +libisoburn-0.1.8.pl00.tar.gz Tue Jun 3 2008 +=============================================================================== +* Bug fix: Major,minor numbers of device files appeared as 0,1 in next session +* Bug fix: modifying to overwriteable target yielded unmountable results +xorriso novelties: +* New option -stream_recording for full speed with DVD-RAM and BD-RE +* New options -osirrox and -cpx allow to extract single files from ISO image + +libisoburn-0.1.6.pl00.tar.gz Mon May 19 2008 +=============================================================================== +* Support for BD-RE (by depending on libburn-0.4.8) +* New API wrapper calls isoburn_toc_*() around libburn TOC inquiry calls +* New API call isoburn_read_iso_head() identifies ISO 9660 filesystems +* New API call isoburn_set_msc1() (like mount -o sbsector=) +xorriso novelties: +* Bug fix: -update_r and others did not work properly with relative paths +* New options -map and -map_single +* New options -not_paths, -not_leaf, -not_list, -not_mgt, -as mkisofs -m +* Emulated -toc on overwriteable media, new -toc layout with volume id +* New option -load makes alternative sessions accessible +* New -blank and -format modes 'as_needed' +* New option -list_formats and -format mode 'by_index_' + +libisoburn-0.1.4.pl00.tar.gz Wed Apr 30 2008 +=============================================================================== +* Improved performance with reading directory trees +* xorriso: Improved attribute transfer from disk for target +* xorriso: Incremental backup functionality by new option -update_r +* xorriso: Options -cut_out and split_size map byte intervals of oversized + files into ISO files +* xorriso: Emulation of some basic mkisofs and cdrecord options +* Dynamically linkable with release version 0.6.4 of libisofs + +Version 0.1.2 was not released as libisoburn +but only as xorriso standalone version. Wed Mar 12 2008 +=============================================================================== +* Bug fix: -report_about HINT or higher did not report at all +* Bug fix: speed=number without unit or media type letter was always CD speed +* Bug fix: it was possible to write to appendable media which was not -indev +* Bug fix: -follow param did not work for adding non-directory symbolic links +* Bug fix: It was not possible to -add /THIS=a /b=THIS +* Improved attribute transfer from disk for implicit target directories +* New option -as "cdrecord" emulates a narrow set of cdrecord gestures +* New option -as "mkisofs" emulates a narrow set of mkisofs gestures +* New option -publisher +* New option -errfile_log +* Support for DVD+R/DL media +* New options -compare, -compare_r and according -find -exec action +* New options -update, -update_r and according -find -exec action +* New -find actions "rm", "rm_r", new -findx -type "m" -exec "empty_iso_dir" +* New option -cut_out + +libisoburn-0.1.0.pl01.tar.gz Fri Feb 15 2008 +=============================================================================== +* Initial release of libisoburn/xorriso +* libisoburn connects libisofs and libburn +* libisoburn emulates multi-session on media without session history +* xorriso is an integrated multi-session tool for ISO 9660 Rock Ridge images +* due to a subtle mistake in ABI usage with libisofs this release had to be + restricted to dynamic linking with exactly libisofs-0.6.2 where the mistake + does no harm. A version of libisoburn which is open to all future libisofs + versions will be released shortly after libisofs.0.6.4. + diff --git a/libisoburn/branches/1.4.6/INSTALL b/libisoburn/branches/1.4.6/INSTALL new file mode 100644 index 00000000..a6580e5a --- /dev/null +++ b/libisoburn/branches/1.4.6/INSTALL @@ -0,0 +1,237 @@ + +See file README for libisoburn and xorriso specific installation instructions. +This file here is rather a manual for advanced usage of ./configure + +------------------------------------------------------------------- + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/libisoburn/branches/1.4.6/Makefile.am b/libisoburn/branches/1.4.6/Makefile.am new file mode 100644 index 00000000..957d004c --- /dev/null +++ b/libisoburn/branches/1.4.6/Makefile.am @@ -0,0 +1,297 @@ + +# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4 +# was: pkgconfigdir=$(libdir)/pkgconfig +pkgconfigdir=$(LIBBURNIA_PKGCONFDIR) + +libincludedir=$(includedir)/libisoburn + +lib_LTLIBRARIES = libisoburn/libisoburn.la +ACLOCAL_AMFLAGS = -I ./ + +## ========================================================================= ## + +# Build libraries +libisoburn_libisoburn_la_LDFLAGS = \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS) +libisoburn_libisoburn_la_SOURCES = \ + libisoburn/isoburn.h \ + libisoburn/libisoburn.h \ + libisoburn/burn_wrap.c \ + libisoburn/data_source.c \ + libisoburn/isoburn.c \ + libisoburn/isofs_wrap.c \ +\ + xorriso/xorriso.h \ + xorriso/xorriso_private.h \ + xorriso/sfile.h \ + xorriso/sfile.c \ + xorriso/aux_objects.h \ + xorriso/aux_objects.c \ + xorriso/findjob.h \ + xorriso/findjob.c \ + xorriso/check_media.h \ + xorriso/check_media.c \ + xorriso/misc_funct.h \ + xorriso/misc_funct.c \ + xorriso/text_io.h \ + xorriso/text_io.c \ + xorriso/match.h \ + xorriso/match.c \ + xorriso/emulators.h \ + xorriso/emulators.c \ + xorriso/disk_ops.h \ + xorriso/disk_ops.c \ + xorriso/cmp_update.h \ + xorriso/cmp_update.c \ + xorriso/parse_exec.h \ + xorriso/parse_exec.c \ + xorriso/opts_a_c.c \ + xorriso/opts_d_h.c \ + xorriso/opts_i_o.c \ + xorriso/opts_p_z.c \ +\ + xorriso/xorrisoburn.h \ + xorriso/base_obj.h \ + xorriso/base_obj.c \ + xorriso/lib_mgt.h \ + xorriso/lib_mgt.c \ + xorriso/sort_cmp.h \ + xorriso/sort_cmp.c \ + xorriso/drive_mgt.h \ + xorriso/drive_mgt.c \ + xorriso/iso_img.h \ + xorriso/iso_img.c \ + xorriso/iso_tree.h \ + xorriso/iso_tree.c \ + xorriso/iso_manip.h \ + xorriso/iso_manip.c \ + xorriso/write_run.h \ + xorriso/write_run.c \ + xorriso/read_run.h \ + xorriso/read_run.c \ + xorriso/filters.h \ + xorriso/filters.c \ + xorriso/xorriso_timestamp.h \ + xorriso/xorriso_buildstamp.h + +libisoburn_libisoburn_la_LIBADD = \ + $(THREAD_LIBS) \ + -lisofs \ + -lburn + +libinclude_HEADERS = \ + libisoburn/libisoburn.h \ + xorriso/xorriso.h + +# libisoburn_libisoburn_la_CFLAGS = $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \ +# $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ +# $(XORRISO_DVD_OBS_64K) + +## ========================================================================= ## + + +# This is the reference application of libisoburn. See man xorriso/xorriso.1 +# +bin_PROGRAMS = \ + xorriso/xorriso + +# This looks quite ugly with make install: xorriso.c is compiled twice again +# +# Trying to create a build timestamp file +# +# BUILT_SOURCES = xorriso/xorriso_buildstamp.h +# +# phony targets get rebuilt every time +# +# .PHONY: xorriso/xorriso_buildstamp.h +# xorriso/xorriso_buildstamp.h: +# date -u '+#define Xorriso_build_timestamP "%Y.%m.%d.%H%M%S"' >xorriso/xorriso_buildstamp.h +# cat xorriso/xorriso_buildstamp.h + +xorriso_xorriso_CPPFLAGS = -Ilibisoburn +# xorriso_xorriso_CFLAGS = $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \ +# $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ +# $(XORRISO_DVD_OBS_64K) + +xorriso_xorriso_LDADD = libisoburn/libisoburn.la -lisofs -lburn \ + $(THREAD_LIBS) $(LIBBURN_ARCH_LIBS) + +xorriso_xorriso_SOURCES = \ + xorriso/xorriso.h \ + xorriso/xorriso_main.c + + +# Install symbolic links to the xorriso binary +# +install-exec-hook: + if test -e "$(DESTDIR)$(bindir)"/xorrisofs ; then rm "$(DESTDIR)$(bindir)"/xorrisofs ; else echo ; fi + ln -s xorriso "$(DESTDIR)$(bindir)"/xorrisofs + if test -e "$(DESTDIR)$(bindir)"/osirrox ; then rm "$(DESTDIR)$(bindir)"/osirrox ; else echo ; fi + ln -s xorriso "$(DESTDIR)$(bindir)"/osirrox + if test -e "$(DESTDIR)$(bindir)"/xorrecord ; then rm "$(DESTDIR)$(bindir)"/xorrecord ; else echo ; fi + ln -s xorriso "$(DESTDIR)$(bindir)"/xorrecord + $(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)" + + +# Alternative to the disabled .PHONY above. +# Trying to create a build timestamp file semi-manually: make buildstamped +# +buildstamp: + date -u '+#define Xorriso_build_timestamP "%Y.%m.%d.%H%M%S"' >xorriso/xorriso_buildstamp.h + cat xorriso/xorriso_buildstamp.h + +# For now make buildstamped has to be performed explicitly. +buildstamped: buildstamp + make + + +# "make clean" shall remove a few stubborn .libs directories +# which George Danchev reported Dec 03 2011. +# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean +clean-local: + -rm -rf test/.libs + +# Will be executed by "make check" +check-local: + xorriso/xorriso -no_rc -version -list_extras all + +## Build companion applications +noinst_PROGRAMS = \ + test/compare_file \ + xorriso/make_xorriso_1 + +# A program to compare two files in mirrored trees in mounted filesystems +# To compare tree /media/dvd and /original/dir : +# find /media/dvd -exec test/compare_file '{}' /media/dvd /original/dir ';' +# +test_compare_file_CPPFLAGS = +test_compare_file_CFLAGS = +test_compare_file_LDADD = +test_compare_file_SOURCES = test/compare_file.c + +# Specialized converter from xorriso/xorriso.texi to xorriso/xorriso.1 +# +xorriso_make_xorriso_1_CPPFLAGS = +xorriso_make_xorriso_1_CFLAGS = +xorriso_make_xorriso_1_LDADD = +xorriso_make_xorriso_1_SOURCES = xorriso/make_xorriso_1.c + +# A Proof-of-concept for frontends +bin_SCRIPTS = \ + frontend/xorriso-tcltk + + +## ========================================================================= ## + +## Build documentation (You need Doxygen for this to work) +webhost = http://libburn-api.pykix.org +webpath = / +docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION) + +doc: doc/html + +doc/html: doc/doxygen.conf + if [ -f ./doc/doc.lock ]; then \ + $(RM) -r doc/html; \ + doxygen doc/doxygen.conf; \ + fi + +doc-upload: doc/html + scp -r $ + and Thomas Schmitt +Integrated sub project of libburnia-project.org. +http://files.libburnia-project.org/releases/libisoburn-1.4.4.tar.gz +Copyright (C) 2006-2009 Vreixo Formoso, +Copyright (C) 2006-2016 Thomas Schmitt. +Provided under GPL version 2 or later. +------------------------------------------------------------------------------ + +libisoburn is a frontend for libraries libburn and libisofs which enables +creation and expansion of ISO-9660 filesystems on all CD/DVD/BD media supported +by libburn. This includes media like DVD+RW, which do not support multi-session +management on media level and even plain disk files or block devices. + +The price for that is thorough specialization on data files in ISO-9660 +filesystem images. So libisoburn is not suitable for audio (CD-DA) or any +other CD layout which does not entirely consist of ISO-9660 sessions. + +xorriso is an application of libisoburn, libisofs, and libburn, which reads +commands from program arguments, files, stdin, or readline. +Its features are also available via a C language API of libisoburn. + +Currently they are fully supported on Linux with kernels >= 2.4, +on FreeBSD with ATAPI/CAM support enabled in the kernel, see atapicam(4), +on OpenSolaris (tested with kernel 5.11), +on NetBSD (tested with 6.1.2 and 6.1.3). +On other X/Open compliant systems libburn will only offer POSIX i/o with disk +file objects, but no direct MMC operation on CD/DVD/BD drives. + +By using this software you agree to the disclaimer at the end of this text: +"... without even the implied warranty ..." + + + Compilation, First Glimpse, Installation + +Dynamic library and compile time header requirements for libisoburn-1.4.4 : +- libburn.so.4 , version libburn-1.4.4 or higher +- libisofs.so.6 , version libisofs-1.4.4 or higher +libisoburn and xorriso will not start with libraries which are older than their +include headers seen at compile time. + +Obtain libisoburn-1.4.4.tar.gz, take it to a directory of your choice +and do: + + tar xzf libisoburn-1.4.4.tar.gz + cd libisoburn-1.4.4 + +Within that directory execute: + + ./configure --prefix=/usr + make + +Then become superuser and execute + make install +which will make available libisoburn.so.1 and the program xorriso. + +On GNU/Linux it will try to run program ldconfig with the library installation +directory as only argument. Failure to do so will not abort installation. +One may disable ldconfig by ./configure option --disable-ldconfig-at-install . + + +By use of a version script, the libisoburn.so library exposes no other function +names but those of the API definitions in and +. +If -Wl,--version-script=... makes problems with the local compiler, then +disable this encapsulation feature by + ./configure --disable-versioned-libs + make clean ; make + +The ./configure script of libisoburn can check via pkg-config whether suitable +libburn and libisoburn are installed. Regrettably this test failed on several +systems due to local pkg-config problems. So it is disabled by default and may +be enabled by: + ./configure --enable-pkg-check-modules +In this case, ./configure fails if no suitable installations are found. + + + xorriso + +libisoburn comes with a command line and dialog application named xorriso, +which offers a substantial part of libisoburn features to shell scripts and +users. Its file xorriso/README_gnu_xorriso describes the tarball of the +derived package GNU xorriso as first preference for a statically linked +xorriso installation. +The libisoburn installation described above produces a dynamically linked +xorriso binary depending on libburn.so, libisofs.so, libisoburn.so. + +After installation documentation is available via + man xorriso + man xorrisofs + man xorrecord + +Several alias links point to the xorriso binary: + xorrisofs starts xorriso with -as mkisofs emulation already enabled + xorrecord starts xorriso with -as cdrecord emulation already enabled + osirrox starts with -osirrox image-to-disk copying already enabled + +By default libisoburn will depend on libreadline if the library and its +development header files are present at compile time. If not, then it will +try to depend on libedit and its header file. +Both conditional dependencies can be avoided by running + ./configure --prefix=/usr --disable-libreadline + make clean ; make +Never omit the "make clean" command after switching enabling of libreadline. +Note that depending on libreadline-6 will cause libisoburn's license to +become "GPL version 3 or later". +If you want to explictely allow only the use of libedit, then do + ./configure --prefix=/usr --disable-libreadline --enable-libedit + +Other deliberate dependency reduction options of ./configure are: + --disable-libacl avoid use of ACL functions like acl_to_text() + --disable-xattr avoid use of xattr functions like listxattr() on Linux + or extattr_list_file() on FreeBSD + --disable-zlib avoid use of zlib functions like compress2() + --disable-libjte avoid use of libjte for -jigdo command + +xorriso allows to use external processes as file content filters. This is +a potential security risk which may be avoided by ./configure option + --disable-external-filters +By default the filter feature is disabled if effective user id and real +user id differ. This ban can be lifted by + --enable-external-filters-setuid + +In some situations Linux may deliver a better write performance to DVD drives +if 64 KB rather than 32 KB are transmitted in each write operation. +64k can be made default at configure time by: + --enable-dvd-obs-64k + + + libisoburn, libisofs, and libburn C language API + +For the lower API concepts and calls see + ./libisoburn/libisoburn.h +as well as + /usr/include/libisofs/libisofs.h + /usr/include/libburn/libburn.h + + + xorriso C language API + +Actually the dynamically linked xorriso binary is only a small start program +for the xorriso API that is implemented inside libisoburn. +There are API calls for command readers and interpreters, and there are +API calls for each single command of xorriso. + +Interested programmers should have a look into the API definition at + xorriso/xorriso.h +and the start program + xorriso/xorriso_main.c + +The header file xorriso.h gets installed suitable for + #include + +So after installation of a binary libisoburn package you may find it e.g. as + /usr/include/libisoburn/xorriso.h + + + xorriso under control of a (GUI) frontend process + +The dialog mode allows frontend programs to connect via pipes to the standard +input and output of xorriso. Several commands of xorriso help with receiving +and parsing of reply messages. + +As a proof of concept, there is the Tcl/Tk script xorriso-tcltk which can +be launched by this shell command: + + xorriso-tcltk + +Or in the xorriso build directory, without installation of xorriso: + + xorriso/xorriso -launch_frontend frontend/xorriso-tcltk --stdio -- + +In the running GUI, click with the rightmost mouse button on any GUI element +to get its particular help text. The "Help" button at the upper right corner +gives a short introduction and instructions for some common use cases. +See also file frontend/README-tcltk. +See its Tcl code for getting an idea how this gets achieved. + +The script is part of the tarball and gets installed by make install. If a +xorriso distro package does not install it, you may get it directly from + http://libburnia-project.org/export/head/libisoburn/trunk/frontend/xorriso-tcltk + +Further there is the C program frontend/frontend_pipes_xorriso.c which +forks a xorriso process and shows similar communication gestures as +xorriso-tcltk. +In particular it connects to xorriso via two pipes, sends commands, waits +for all replies of a command, picks info out of the xorriso message sieve, +and parses reply message lines into words. + +The bash script frontend/sh_on_named_pipes.sh forks a xorriso process +connected to two pipes. It then runs a dialog loop, sends commands to xorriso, +and displays the replies. + +The sh script frontend/xorriso_broker.sh is intended to execute xorriso +commands on a permanently running xorriso process. +It gets an id_string by which it looks for named pipes with a running xorriso +process. If no such pipe is found, then it starts a xorriso connected to +newly created pipes. +After this is done, the optionally given xorriso arguments are written into +the stdin pipe from where xorriso will read and execute them. The script will +end but the xorriso process will go on and wait for more commands. + + + Drives and Disk File Objects + +The user of libisoburn applications needs operating system dependent +permissions for the CD/DVD/BD drives which shall be used. +On Linux, FreeBSD, NetBSD this means -rw-permissions, even if only reading is +intended. On Solaris one needs privileges "basic,sys_devices" and r-permission, +even if writing is intended. + +A list of rw-accessible drives can be obtained by + xorriso -devices +or by xorriso API call + Xorriso_option_devices() +or by libburn API call + burn_drive_scan() + +A possible source of problems are hald or other automounters. +If you can spot a process "hald-addon-storage" with the address of +your desired drive, then consider to kill it. +A similar process "udisks-daemon: polling ..." can be seen on newer Linuxes. + +On Debian GNU/Linux 6.0.2 amd64 there is + /lib/udev/rules.d/80-udisks.rules +where one can remove all CD drives ("sr*") from the list of automountable +devices: + KERNEL=="sd*|hd*|mmcblk*|mspblk*", ENV{UDISKS_PRESENTATION_NOPOLICY}="0" + # KERNEL=="sd*|hd*|sr*|mmcblk*|mspblk*", ENV{UDISKS_PRESENTATION_NOPOLICY}="0" +Copying the recognition criterion from + /etc/udev/rules.d/70-persistent-cd.rules +one can prevent automounting a single drive, too. E.g.: + SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", ENV{ID_PATH}=="pci-0000:00:11.0-scsi-2:0:0:0", ENV{UDISKS_PRESENTATION_NOPOLICY}:="1" + +If you cannot get rid of the automounter, try whether it helps to always load +the drive tray manually before starting a write run of xorriso. Wait until the +drive light is off and the mounted media appears. +Then try to unmount the mounted media before a write run. + + +Besides true optical drives, libisoburn can also address disk files as input or +output drives. The addresses of the disk files have to be preceded by "stdio:". +Like: + "stdio:/tmp/pseudo_drive" + +Note: xorriso by default prefixes "stdio:" to addresses outside the /dev tree + if they do not lead to an optical drive device file. + + + Testing + +For automated and manual tests of xorriso's functionality see file + releng/README. + + + Result comparison with self produced ISO images + +We are quite sure that libisofs produces accurate representations of the disk +files. This opinion is founded on a lot of test burns and checks by a little +test program which compares files from the mounted image with the orignals +on disk. It uses the normal POSIX filesystem calls, i.e. no libburnia stuff. + +This program is not installed systemwide but stays in the installation +directory of the libisoburn tarball as test/compare_file . Usually it is +run as -exec payload of a find command. It demands at least three arguments: +The path of the file to compare, the prefix1 to be cut off from path +and the prefix2 which gets prepended afterwards to obtain the path of the +second file to compare. +As further argument there can be -no_ctime which suppresses the comparison +of ctime date stamps. +The exit value is 0 if no difference was detected, non-0 else. + +Example: After + xorriso ... -pathspecs on -add /=/original/dir -- + mount /media/dvd + cd test +compare tree /media/dvd with tree /original/dir : + find /original/dir -exec ./compare_file '{}' /original/dir /media/dvd ';' \ + | less +and vice versa: + find /media/dvd -exec ./compare_file '{}' /media/dvd /original/dir ';' \ + | less + + +------------------------------------------------------------------------------ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 or later + 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; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +------------------------------------------------------------------------------ +Based on and sub project of: +libburnia-project.org +By Mario Danic , + Vreixo Formoso + Thomas Schmitt +Copyright (C) 2006-2015 Mario Danic, Vreixo Formoso, Thomas Schmitt. + +We will not raise any legal protest to dynamic linking of our libraries +with applications that are not under GPL, as long as they fulfill +the condition of offering the library source code used, whether +altered or unaltered, under the GPLv2+, along with the application. +Nevertheless, the safest legal position is not to link libburn with +non-GPL compatible programs. + +libburnia-project.org is inspired by and in other components still containing +parts of old +Libburn. By Derek Foreman and + Ben Jansens +Copyright (C) 2002-2006 Derek Foreman and Ben Jansens +libisoburn does not stem from their code. + diff --git a/libisoburn/branches/1.4.6/TODO b/libisoburn/branches/1.4.6/TODO new file mode 100644 index 00000000..23e3b643 --- /dev/null +++ b/libisoburn/branches/1.4.6/TODO @@ -0,0 +1,11 @@ +[Task] Figure out how to use "Requires" in pc.in (libisoburn and libisofs would benefit) +[Task] Figure out the usage of Libs.private (used in libburn) +[Task] Improve build system +[Task] Investigate build system, so other libburnia components can benefit +[Task] Write Doxygen files +[Task] Explain to Thomas & Vreixo about NEWS importance (all libburnia components + will benefit +[Task] Write a document about ABI & API +[Task] Create following targets for make: Src, Indent, Docs, Test, All [Any other suggestions?) + +All those tasks are currently assigned to Mario. diff --git a/libisoburn/branches/1.4.6/acinclude.m4 b/libisoburn/branches/1.4.6/acinclude.m4 new file mode 100644 index 00000000..d38be8a7 --- /dev/null +++ b/libisoburn/branches/1.4.6/acinclude.m4 @@ -0,0 +1,378 @@ +AC_DEFUN([LIBBURNIA_SET_FLAGS], +[ +case $target_os in +freebsd*) + LDFLAGS="$LDFLAGS -L/usr/local/lib" + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + ;; +netbsd*) + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/pkg/lib" + CPPFLAGS="$CPPFLAGS -I/usr/local/include -I/usr/pkg/include" + ;; +solaris*) + LDFLAGS="$LDFLAGS -L/usr/local/lib" +esac +]) + + +AC_DEFUN([TARGET_SHIZZLE], +[ + ARCH="" + LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig + + AC_MSG_CHECKING([target operating system]) + + LIBBURNIA_SUPP_ACL=none + LIBBURNIA_SUPP_FATTR=none + LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'" + case $target in + *-*-linux*) + ARCH=linux + LIBBURN_ARCH_LIBS= + LIBBURNIA_SUPP_ACL=libacl + LIBBURNIA_SUPP_FATTR=xattr + LIBBURNIA_LDCONFIG_CMD=ldconfig + ;; + *-*-freebsd*) + ARCH=freebsd + LIBBURN_ARCH_LIBS=-lcam + LIBBURNIA_SUPP_ACL=libacl + LIBBURNIA_SUPP_FATTR=extattr + + # This may later be overridden by configure --enable-libdir-pkgconfig + LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig + ;; + *-kfreebsd*-gnu*) + ARCH=freebsd + LIBBURN_ARCH_LIBS=-lcam + ;; + *-solaris*) + ARCH=solaris + LIBBURN_ARCH_LIBS=-lvolmgt + ;; + *) + ARCH= + LIBBURN_ARCH_LIBS= +# AC_ERROR([You are attempting to compile for an unsupported platform]) + ;; + esac + + AC_MSG_RESULT([$ARCH]) +]) + + +dnl LIBBURNIA_CHECK_ICONV is by Thomas Schmitt, libburnia project +dnl It is based on gestures from: +dnl iconv.m4 serial AM7 (gettext-0.18) +dnl Copyright (C) 2000-2002, 2007-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl From Bruno Haible. +dnl +AC_DEFUN([LIBBURNIA_CHECK_ICONV], +[ + + dnl Check whether it is allowed to link with -liconv + AC_MSG_CHECKING([for iconv() in separate -liconv ]) + libburnia_liconv="no" + libburnia_save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [libburnia_liconv="yes"], + [LIBS="$libburnia_save_LIBS"] + ) + AC_MSG_RESULT([$libburnia_liconv]) + + if test x"$libburnia_save_LIBS" = x"$LIBS" + then + dnl GNU iconv has no function iconv() but libiconv() and a macro iconv() + dnl It is not tested whether this is detected by above macro. + AC_CHECK_LIB(iconv, libiconv, , ) + fi + + dnl Check for iconv(..., const char **inbuf, ...) + AC_MSG_CHECKING([for const qualifier with iconv() ]) + AC_TRY_COMPILE([ +#include +#include +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +], [], [libburnia_iconv_const=""], [libburnia_iconv_const="const"] + ) + if test x$libburnia_iconv_const = xconst + then + AC_DEFINE_UNQUOTED([ICONV_CONST], [const]) + else + AC_DEFINE_UNQUOTED([ICONV_CONST], []) + fi + test -z "$libburnia_iconv_const" && libburnia_iconv_const="no" + AC_MSG_RESULT([$libburnia_iconv_const]) +]) + + +dnl LIBBURNIA_ASSERT_ICONV is by Thomas Schmitt, libburnia project +dnl +AC_DEFUN([LIBBURNIA_ASSERT_ICONV], +[ + if test x$XORRISO_ASSUME_ICONV = x + then + dnl Check for the essential gestures of libisofs/util.c + AC_MSG_CHECKING([for iconv() to be accessible now ]) + AC_TRY_LINK([ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ], +[iconv_t cd = iconv_open("",""); +iconv(cd,NULL,NULL,NULL,NULL); +iconv_close(cd); +], [iconv_test="yes"], [iconv_test="no"] + ) + AC_MSG_RESULT([$iconv_test]) + if test x$iconv_test = xno + then + echo >&2 + echo "Cannot get function iconv() to work. Configuration aborted." >&2 + echo "Check whether your system needs a separate libiconv installed." >&2 + echo "If it is installed but not found, try something like" >&2 + echo ' export LDFLAGS="$LDFLAGS -L/usr/local/lib"' >&2 + echo ' export CPPFLAGS="$CPPFLAGS -I/usr/local/include"' >&2 + echo ' export LIBS="$LIBS -liconv"' >&2 + echo "You may override this test by exporting variable" >&2 + echo " XORRISO_ASSUME_ICONV=yes" >&2 + echo >&2 + (exit 1); exit 1; + fi + fi +]) + + +dnl LIBBURNIA_TRY_EDITLINE is by Thomas Schmitt, libburnia project +dnl It performs the actual test compilation for editline. +dnl Variable LIBS has to be set by the caller. +AC_DEFUN([LIBBURNIA_TRY_EDITLINE], +[ + AC_TRY_LINK([ +#include +#include +#include +#include +#include +#include +#include ], +[EditLine *editline_handle; History *editline_history; HistEvent ev; int count; +editline_handle= el_init("dummy", stdin, stdout, stderr); +el_set(editline_handle, EL_EDITOR, "emacs"); +editline_history= history_init(); +history(editline_history, &ev, H_SETSIZE, 1000); +el_gets(editline_handle, &count); +], [editline_test="yes"], [editline_test="no"] + ) +]) + +dnl LIBBURNIA_ASSERT_EDITLINE is by Thomas Schmitt, libburnia project +dnl It disables xorriso editline if not all needed functions are present +AC_DEFUN([LIBBURNIA_ASSERT_EDITLINE], +[ + if test x$XORRISO_ASSUME_EDITLINE = x + then + dnl Check for the essential gestures of xorriso/text_io.c + AC_MSG_CHECKING([for desired functions in libedit]) + libburnia_save_LIBS="$LIBS" + LIBS="$LIBS -ledit" + LIBBURNIA_TRY_EDITLINE + if test x$editline_test = xno + then + LIBS="$libburnia_save_LIBS" + LIBS="$LIBS -ledit" + LIBBURNIA_TRY_EDITLINE + fi + if test x$editline_test = xno + then + READLINE_DEF= + LIBS="$libburnia_save_LIBS" + fi + AC_MSG_RESULT([$editline_test $editline_msg]) + fi +]) + + +dnl LIBBURNIA_TRY_READLINE is by Thomas Schmitt, libburnia project +dnl It performs the actual test compilation for readline. +dnl Variable LIBS has to be set by the caller. +AC_DEFUN([LIBBURNIA_TRY_READLINE], +[ + AC_TRY_LINK([ +#include +#include +#include +#include +#include +#include +#include +#include ], +[HIST_ENTRY **hl; +readline(""); +add_history(""); +hl= history_list(); +], [readline_test="yes"], [readline_test="no"] + ) +]) + +dnl LIBBURNIA_ASSERT_READLINE is by Thomas Schmitt, libburnia project +dnl It disables xorriso readline if not all needed functions are present +AC_DEFUN([LIBBURNIA_ASSERT_READLINE], +[ + if test x$XORRISO_ASSUME_READLINE = x + then + dnl Check for the essential gestures of xorriso/text_io.c + AC_MSG_CHECKING([for desired functions in libreadline]) + readline_msg= + libburnia_save_LIBS="$LIBS" + LIBS="$LIBS -lreadline" + LIBBURNIA_TRY_READLINE + if test x$readline_test = xno + then + LIBS="$libburnia_save_LIBS" + LIBS="$LIBS -lreadline -lcurses" + LIBBURNIA_TRY_READLINE + if test x$readline_test = xyes + then + readline_msg=", with -lcurses" + fi + fi + if test x$readline_test = xno + then + READLINE_DEF= + LIBS="$libburnia_save_LIBS" + fi + AC_MSG_RESULT([$readline_test $readline_msg]) + fi +]) + + +dnl LIBISOBURN_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project +dnl It tests whether -Wl,--version-script=... works with the compiler +AC_DEFUN([LIBISOBURN_ASSERT_VERS_LIBS], +[ + libburnia_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=libisoburn/libisoburn.ver" + AC_TRY_LINK([#include ], [printf("Hello\n");], + [vers_libs_test="yes"], [vers_libs_test="no"]) + if test x$vers_libs_test = xyes + then + LIBLDFLAGS="-Wl,--version-script=libisoburn/libisoburn.ver" + fi + LDFLAGS="$libburnia_save_LDFLAGS" + AC_SUBST(LIBLDFLAGS) +]) + + +dnl LIBBURNIA_SET_PKGCONFIG is by Thomas Schmitt, libburnia project +dnl It determines the install directory for the *.pc file. +dnl Important: Must be performed _after_ TARGET_SHIZZLE +dnl +AC_DEFUN([LIBBURNIA_SET_PKGCONFIG], +[ +### for testing --enable-libdir-pkgconfig on Linux +### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig + +if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig +then + dummy=dummy +else + AC_ARG_ENABLE(libdir-pkgconfig, + [ --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no], + , enable_libdir_pkgconfig="no") + AC_MSG_CHECKING([for --enable-libdir-pkgconfig]) + if test "x$enable_libdir_pkgconfig" = xyes + then + LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig + fi + AC_MSG_RESULT([$enable_libdir_pkgconfig]) +fi + +libburnia_pkgconfig_override="no" +AC_ARG_ENABLE(pkgconfig-path, +[ --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc], +libburnia_pkgconfig_override="yes" , enable_pkgconfig_path="none") +AC_MSG_CHECKING([for overridden pkgconfig directory path]) +if test "x$enable_pkgconfig_path" = xno +then + libburnia_pkgconfig_override="no" +fi +if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes +then + libburnia_pkgconfig_override="invalid argument" +fi +if test "x$libburnia_pkgconfig_override" = xyes +then + LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path" + AC_MSG_RESULT([$LIBBURNIA_PKGCONFDIR]) +else + AC_MSG_RESULT([$libburnia_pkgconfig_override]) +fi +AC_SUBST(LIBBURNIA_PKGCONFDIR) + +dnl For debugging only +### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR]) + +]) + +dnl LIBBURNIA_TRY_TIMEZONE is by Thomas Schmitt, libburnia project +dnl It tests whether the global variable exists and is suitable for +dnl integer arithmetics. +AC_DEFUN([LIBBURNIA_TRY_TIMEZONE], +[ + echo -n "checking for timezone variable ... " + AC_TRY_LINK([ #include ], [long int i; i = 1 - timezone; ], + [LIBBURNIA_TIMEZONE="timezone"], [LIBBURNIA_TIMEZONE="0"] + ) + echo "$LIBBURNIA_TIMEZONE" +]) + +dnl LIBBURNIA_CHECK_ARCH_LIBS is by Thomas Schmitt, libburnia project +dnl It tests whether the OS dependent libraries are available. +dnl With libisoburn they are needed only for the case that indirect linking +dnl does not work. So it is worth a try to omit them. +dnl $1 = "mandatory" or "optional" define the action if test linking fails. +AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS], +[ + libburnia_save_LIBS="$LIBS" + if test "x$LIBBURN_ARCH_LIBS" = x + then + dummy=dummy + else + LIBS="$LIBS $LIBBURN_ARCH_LIBS" + AC_TRY_LINK([#include ], [printf("Hello\n");], + [archlibs_test="yes"], [archlibs_test="no"]) + LIBS="$libburnia_save_LIBS" + if test x$archlibs_test = xno + then + if test x"$1" = xmandatory + then + echo >&2 + echo "FATAL: Test linking with mandatory library options failed: $LIBBURN_ARCH_LIBS" >&2 + echo >&2 + (exit 1); exit 1; + else + echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)" + LIBBURN_ARCH_LIBS="" + fi + else + echo "enabled linking with $LIBBURN_ARCH_LIBS" + fi + fi +]) + diff --git a/libisoburn/branches/1.4.6/bootstrap b/libisoburn/branches/1.4.6/bootstrap new file mode 100755 index 00000000..3e27cf45 --- /dev/null +++ b/libisoburn/branches/1.4.6/bootstrap @@ -0,0 +1,11 @@ +#!/bin/sh -x + +aclocal -I . +libtoolize --copy --force +autoconf + +# Not with libisoburn +# autoheader + +automake --foreign --add-missing --copy --include-deps + diff --git a/libisoburn/branches/1.4.6/configure.ac b/libisoburn/branches/1.4.6/configure.ac new file mode 100644 index 00000000..81f8b554 --- /dev/null +++ b/libisoburn/branches/1.4.6/configure.ac @@ -0,0 +1,495 @@ +AC_INIT([libisoburn], [1.4.5], [http://libburnia-project.org]) +AC_PREREQ([2.50]) +dnl AC_CONFIG_HEADER([config.h]) + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +LIBBURNIA_SET_FLAGS + +AM_INIT_AUTOMAKE([subdir-objects]) +AC_CONFIG_MACRO_DIR([./]) + +dnl Hint: Search list for version code aspects: +dnl /AC_INIT( +dnl /ISOBURN_.*_VERSION +dnl /LT_.* +dnl /LIB.*_REQUIRED + +dnl The API version codes are defined in libisoburn/libisoburn.h +dnl #define isoburn_header_version_* +dnl configure.ac only rules the libtool revision numbering about +dnl LT_CURREN, LT_AGE, LT_REVISION where SONAME becomes LT_CURRENT - LT_AGE +dnl +dnl These three are only copies to provide libtool with unused LT_RELEASE +ISOBURN_MAJOR_VERSION=1 +ISOBURN_MINOR_VERSION=4 +ISOBURN_MICRO_VERSION=5 + +dnl ISOBURN_VERSION=$ISOBURN_MAJOR_VERSION.$ISOBURN_MINOR_VERSION.$ISOBURN_MICRO_VERSION + +AC_SUBST(ISOBURN_MAJOR_VERSION) +AC_SUBST(ISOBURN_MINOR_VERSION) +AC_SUBST(ISOBURN_MICRO_VERSION) +dnl AC_SUBST(ISOBURN_VERSION) + +dnl Libtool versioning +dnl Generate libisoburn.so.1.x.y +dnl SONAME will become LT_CURRENT - LT_AGE +dnl +dnl ts B60701 +dnl (By mistake, 1.4.4 got LT_CURRENT/LT_AGE=101/100 rather than 102/102) +dnl ### This is the release version 1.4.4 = libisoburn.so.1.100.0 +dnl This is the development version after above stable release +dnl LT_CURRENT++, LT_AGE++ have not happened yet. +dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile. +dnl +dnl SONAME = 101 - 100 = 1 . Library name = libisoburn.so.1.100.0 +LT_RELEASE=$ISOBURN_MAJOR_VERSION.$ISOBURN_MINOR_VERSION +LT_CURRENT=101 +LT_AGE=100 +LT_REVISION=0 +LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` + +AC_SUBST(LT_RELEASE) +AC_SUBST(LT_CURRENT) +AC_SUBST(LT_REVISION) +AC_SUBST(LT_AGE) +AC_SUBST(LT_CURRENT_MINUS_AGE) + +AC_PREFIX_DEFAULT([/usr/local]) +test "$prefix" = "NONE" && prefix=$ac_default_prefix + +AM_MAINTAINER_MODE + +AM_PROG_CC_C_O +AC_C_CONST +AC_C_INLINE +AC_C_BIGENDIAN + +dnl Large file support +AC_SYS_LARGEFILE +AC_FUNC_FSEEKO +AC_CHECK_FUNC([fseeko]) +if test ! $ac_cv_func_fseeko; then + AC_ERROR([Libburn requires largefile support.]) +fi + +if test x$LIBISOBURN_OLD_ICONV_CONFIGURE = x +then + +dnl ts B00410 : To detect the need for -liconv and const argument of iconv() + LIBBURNIA_CHECK_ICONV + +else + +dnl Outdated: produces double -liconv and warnings about parameter mismatch +dnl If iconv(3) is in an extra lib, then it gets added to variable LIBS. +dnl If not, then no -liconv will be added. + AC_CHECK_LIB(iconv, iconv, , ) +dnl GNU iconv has no function iconv() but libiconv() and a macro iconv() + AC_CHECK_LIB(iconv, libiconv, , ) + +fi + +AC_PROG_LIBTOOL +AC_SUBST(LIBTOOL_DEPS) +# LIBTOOL="$LIBTOOL --silent" + +AC_PROG_INSTALL + +AC_CHECK_HEADERS() + +dnl Check for tm_gmtoff field in struct tm +AC_CHECK_MEMBER([struct tm.tm_gmtoff], + [AC_DEFINE(HAVE_TM_GMTOFF, 1, + [Define this if tm structure includes a tm_gmtoff entry.])], + , + [#include ]) + +dnl Whether timezone is an integer variable +AH_TEMPLATE([Libburnia_timezonE], [Either timezone or 0]) +LIBBURNIA_TRY_TIMEZONE +if test x$LIBBURNIA_TIMEZONE = xtimezone +then + AC_DEFINE([Libburnia_timezonE], [timezone]) +else + AC_DEFINE([Libburnia_timezonE], [0]) +fi + +THREAD_LIBS=-lpthread +AC_SUBST(THREAD_LIBS) + +TARGET_SHIZZLE +AC_SUBST(ARCH) +AC_SUBST(LIBBURNIA_PKGCONFDIR) +AC_SUBST(LIBBURN_ARCH_LIBS) + +# Do not link libcam or libvolmgt if not available. +# (They are indirect dependency on FreeBSD or Solaris.) +LIBBURNIA_CHECK_ARCH_LIBS(optional) + +dnl Determine target directory for libisoburn-*.pc +dnl Important: Must be performed _after_ TARGET_SHIZZLE +dnl +LIBBURNIA_SET_PKGCONFIG + +AC_ARG_ENABLE(libreadline, +[ --enable-libreadline Enable use of libreadline by xorriso, default=yes], + , enable_libreadline=yes) +if test x$enable_libreadline = xyes; then +dnl Check whether there is readline-devel and readline-runtime. +dnl If not, erase this macro which would enable use of readline(),add_history() + READLINE_DEF="-DXorriso_with_readlinE" + + if test x$XORRISO_OLD_READLINE_CONFIGURE = x + then + +dnl ts B00411 : To disable readline if not all needed functions are present + LIBBURNIA_ASSERT_READLINE + + else +dnl The empty yes case obviously causes -lreadline to be linked + AC_CHECK_HEADER(readline/readline.h, AC_CHECK_LIB(readline, readline, , READLINE_DEF= ), READLINE_DEF= ) +dnl The X= in the yes case prevents that -lreadline gets linked twice + AC_CHECK_HEADER(readline/history.h, AC_CHECK_LIB(readline, add_history, X= , READLINE_DEF= ), READLINE_DEF= ) + fi +else + READLINE_DEF= + echo "disabled libreadline" +fi +if test x$READLINE_DEF = x; then + if test x$enable_libreadline = xyes; then + libedit_deflt=yes + else + libedit_deflt=no + fi + AC_ARG_ENABLE(libedit, +[ --enable-libedit Enable use of libedit by xorriso if not libreadline, + default= setting of --enable-libreadline], + , enable_libedit=$libedit_deflt) + if test x$enable_libedit = xyes; then + READLINE_DEF="-DXorriso_with_editlinE" + + LIBBURNIA_ASSERT_EDITLINE + + else + READLINE_DEF= + echo "disabled libedit" + fi +fi +AC_SUBST(READLINE_DEF) + + +dnl ts A90329 +dnl ACL and xattr do not need to be enabled in libisoburn or xorriso source +dnl but without AC_CHECK_LIB() xorriso will not be linked with -lacl . +dnl On my Linux this does work with an ACL enabled libisofs but in general +dnl it seems not be right. +dnl So for now it seems to be best to do the same configuration for libisoburn +dnl and xorriso as for libisofs. +AC_ARG_ENABLE(libacl, +[ --enable-libacl Enable use of libacl by libisofs, default=yes], + , enable_libacl=yes) +LIBACL_DEF= +if test x$LIBBURNIA_SUPP_ACL = xlibacl +then + if test x$enable_libacl = xyes; then +dnl Check whether there is libacl-devel and libacl-runtime. +dnl If not, erase this macro which would enable use of acl_to_text and others + LIBACL_DEF="-DLibisofs_with_aaip_acL" +dnl The empty yes case obviously causes -lacl to be linked + has_acl_h_but_no_func=0 + AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= ) + if test "$has_acl_h_but_no_libacl" = 1 + then + AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= ) + fi + fi +fi +if test x$LIBACL_DEF = x-DLibisofs_with_aaip_acL +then + if test x$has_acl_h_but_no_libacl = x1 + then + echo "enabled local processing of ACL" + else + echo "enabled libacl, local processing of ACL" + fi +else + echo "disabled local processing of ACL" +fi +AC_SUBST(LIBACL_DEF) + + +AC_ARG_ENABLE(xattr, + [ --enable-xattr Enable use of extended file attributes by libisofs, default=yes], + , enable_xattr=yes) +XATTR_DEF= +if test x"$LIBBURNIA_SUPP_FATTR" = xxattr +then + if test "x$enable_xattr" = xyes; then +dnl Check whether there is the header for Linux xattr. +dnl If not, erase this macro which would enable use of listxattr and others + XATTR_DEF="-DLibisofs_with_aaip_xattR" + AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , + XATTR_DEF= ), XATTR_DEF= ) + fi +elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr +then + if test "x$enable_xattr" = xyes; then + XATTR_DEF="-DLibisofs_with_freebsd_extattR" + AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, + XATTR_DEF= ), XATTR_DEF= ) + fi +fi +if test x$XATTR_DEF = x-DLibisofs_with_aaip_xattR +then + echo "enabled xattr, local processing of extended file attributes Linux style" +elif test x$XATTR_DEF = x-DLibisofs_with_freebsd_extattR +then + echo "enabled extattr, local processing of extended file attributes FreeBSD style" +else + echo "disabled local processing of extended file attributes" +fi +AC_SUBST(XATTR_DEF) + + +dnl ts A90409 +dnl Same situation as with xattr and ACL: libisoburn does not depend directly +dnl on zlib. But if it is enabled in libisofs then it seems wise to link it +dnl with libisoburn apps. +AC_ARG_ENABLE(zlib, +[ --enable-zlib Enable use of zlib by libisofs, default=yes], + , enable_zlib=yes) +if test x$enable_zlib = xyes; then +dnl Check whether there is the header for zlib. +dnl If not, erase this macro which would enable use of compress2() and others. +dnl Linking fails on SuSE 9.0 because zlib has compress2() but lacks +dnl compressBound(). So compressBound is the more modern thing to test. +dnl The empty parameter after "compressBound" causes -lz. + ZLIB_DEF="-DLibisofs_with_zliB" + AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, compressBound, , ZLIB_DEF= ), ZLIB_DEF= ) +else + ZLIB_DEF= +fi +AC_SUBST(ZLIB_DEF) + +dnl ts B00928 +AC_ARG_ENABLE(libjte, +[ --enable-libjte Enable use of libjte by xorriso, default=yes], + , enable_libjte=yes) +if test "x$enable_libjte" = xyes; then + LIBJTE_DEF="-DXorriso_with_libjtE" + AC_CHECK_HEADER(libjte/libjte.h, AC_CHECK_LIB(jte, libjte_new, , LIBJTE_DEF= ), LIBJTE_DEF= ) +else + LIBJTE_DEF= +fi +AC_SUBST(LIBJTE_DEF) + +dnl ts B00107 +dnl Just for the case that it is necessary to give link option -lcdio not only +dnl with libburn but also with libburn apps like xorriso. +dnl On SuSE 10.2 this is not needed. libburn finds libcdio on its own. +case $host_os in + cygwin*|mingw*) + default_libcdio=yes + ;; + *) + default_libcdio=no + ;; +esac +AC_ARG_ENABLE(libcdio, +[ --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows)], + , enable_libcdio=$default_libcdio) +if test x$enable_libcdio = xyes; then +dnl Check whether there is libcdio-devel and libcdio-runtime. +dnl If not, erase this macro + LIBCDIO_DEF="-DLibburn_use_libcdiO" +dnl The empty yes case obviously causes -lcdio to be linked + AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= ) +else + LIBCDIO_DEF= +fi +if test x$LIBCDIO_DEF = x +then + if test x$enable_libcdio = xyes + then + echo "WARNING: could not enable use of libcdio as system adapter" + fi +else + echo "enabled use of libcdio as system adapter" +fi +AC_SUBST(LIBCDIO_DEF) + + +AC_ARG_ENABLE(external-filters, +[ --enable-external-filters Enable use of external filter programs by xorriso, default=yes], + , enable_external_filters=yes) +if test x"$enable_external_filters" = xyes; then + EXTF_DEF="-DXorriso_allow_external_filterS" + echo "enabled xorriso external filter programs" +else + EXTF_DEF= + echo "disabled xorriso external filter programs" +fi +AC_SUBST(EXTF_DEF) + +AC_ARG_ENABLE(external-filters-setuid, +[ --enable-external-filters-setuid Enable xorriso external filter programs under setuid, default=no], + , enable_external_filters_setuid=no) +if test x$enable_external_filters_setuid = xyes; then + EXTF_SUID_DEF="-DXorriso_allow_extf_suiD" + echo "enabled xorriso external filter programs under setuid" +else + EXTF_SUID_DEF= + echo "disabled xorriso external filter programs under setuid" +fi +AC_SUBST(EXTF_SUID_DEF) + + +AC_ARG_ENABLE(launch-frontend, +[ --enable-launch-frontend Enable start of piped frontend program by xorriso, default=yes], + , enable_launch_frontend=yes) +if test x"$enable_launch_frontend" = xyes; then + LFRONT_DEF="-DXorriso_allow_launch_frontenD" + echo "enabled xorriso command -launch_frontend" +else + LFRONT_DEF= + echo "disabled xorriso command -launch_frontend" +fi +AC_SUBST(LFRONT_DEF) + +AC_ARG_ENABLE(launch-frontend-setuid, +[ --enable-launch-frontend-setuid Enable start of piped frontend program under setuid, default=no], + , enable_launch_frontend_setuid=no) +if test x$enable_launch_frontend_setuid = xyes; then + LFRONT_SUID_DEF="-DXorriso_allow_extf_suiD" + echo "enabled xorriso command -launch_frontend under setuid" +else + LFRONT_SUID_DEF= + echo "disabled xorriso command -launch_frontend under setuid" +fi +AC_SUBST(LFRONT_SUID_DEF) + + +AC_ARG_ENABLE(dvd-obs-64k, +[ --enable-dvd-obs-64k 64 KB default size for xorriso DVD writing, default=no], + , enable_dvd_obs_64=no) +if test x$enable_dvd_obs_64k = xyes; then + XORRISO_DVD_OBS_64K="-DXorriso_dvd_obs_default_64K" + echo "enabled xorriso write size default 64 KB on DVD" +else + XORRISO_DVD_OBS_64K= + echo "disabled xorriso write size default 64 KB on DVD" +fi +AC_SUBST(XORRISO_DVD_OBS_64K) + +# Library versioning normally serves a complex purpose. +# Since libisoburn obeys strict ABI backward compatibility, it needs only the +# simple feature to declare function names "global:" or "local:". Only the +# global ones are visible to applications at library load time. +AC_ARG_ENABLE(versioned-libs, +[ --enable-versioned-libs Enable strict symbol encapsulation , default=yes], + , enable_versioned_libs=yes) +if test x$enable_versioned_libs = xyes; then + vers_libs_test=no + LIBISOBURN_ASSERT_VERS_LIBS + if test x$vers_libs_test = xno + then + echo "disabled strict symbol encapsulation (test failed)" + else + echo "enabled strict symbol encapsulation" + fi +else + echo "disabled strict symbol encapsulation" +fi + +AC_ARG_ENABLE(ldconfig-at-install, +[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes], + , ldconfig_at_install=yes) +if test x$ldconfig_at_install = xyes; then + dummy=dummy +else + LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'" + echo "disabled run of ldconfig during installation on GNU/Linux" +fi +AC_SUBST(LIBBURNIA_LDCONFIG_CMD) + + +AC_CHECK_HEADER(libburn/libburn.h, LIBBURNIA_HAVE_LIBBURN=1, LIBBURNIA_HAVE_LIBBURN=0) +AC_CHECK_HEADER(libisofs/libisofs.h, LIBBURNIA_HAVE_LIBISOFS=1, LIBBURNIA_HAVE_LIBISOFS=0) +if test x$LIBBURNIA_HAVE_LIBBURN = x0; then + echo "FATAL: Lacking libburn development header file " 2>&1 + echo "HINT: You first have to install libburn before you can build libisoburn" 2>&1 +fi +if test x$LIBBURNIA_HAVE_LIBISOFS = x0; then + echo "FATAL: Lacking libisofs development header file " 2>&1 + echo "HINT: You first have to install libisofs before you can build libisoburn" 2>&1 +fi +if test x$LIBBURNIA_HAVE_LIBBURN = x0 -o x$LIBBURNIA_HAVE_LIBISOFS = x0; then + echo "ABORT: Lacking mandatory prerequisites" 2>&1 + exit 1 +fi + +# ------- Visible mark in configure : Start of library check + +# Check for proper library versions if this is desired. +# (It fails too often on too many systems.) +AC_ARG_ENABLE(pkg-check-modules, +[ --enable-pkg-check-modules Enable pkg-config check for libburn and libisofs , default=no], + , enable_pkg_check_modules=no) +if test x$enable_pkg_check_modules = xyes; then + +dnl If PKG_CHECK_MODULES is to be used after this if-block, +dnl then it might be necessary to perform PKG_PROG_PKG_CONFIG before the block. + + LIBBURN_REQUIRED=1.4.4 + LIBISOFS_REQUIRED=1.4.4 + PKG_CHECK_MODULES(LIBBURN, libburn-1 >= $LIBBURN_REQUIRED) + PKG_CHECK_MODULES(LIBISOFS, libisofs-1 >= $LIBISOFS_REQUIRED) + if test x$LIBCDIO_DEF = x; then + dummy=dummy + else + LIBCDIO_REQUIRED=0.83 + PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED) + fi +else + echo "checking for LIBBURN... skipped, no --enable-pkg-check-modules" + echo "checking for LIBISOFS... skipped, no --enable-pkg-check-modules" + if test x$LIBCDIO_DEF = x; then + dummy=dummy + else + echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules" + fi +fi + +# ------- Visible mark in configure : End of library check + +dnl Add compiler-specific flags + +dnl See if the user wants aggressive optimizations of the code +AC_ARG_ENABLE(debug, +[ --enable-debug Disable aggressive optimizations [default=yes]], + , enable_debug=yes) +if test x$enable_debug != xyes; then + if test x$GCC = xyes; then + CFLAGS="-O3 $CFLAGS" + CFLAGS="-fexpensive-optimizations $CFLAGS" + fi + CFLAGS="-DNDEBUG $CFLAGS" +else + if test x$GCC = xyes; then + CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS" + fi + CFLAGS="-DDEBUG $CFLAGS" +fi + +CFLAGS="$READLINE_DEF $LIBACL_DEF $XATTR_DEF $EXTF_DEF $EXTF_SUID_DEF $LFRONT_DEF $LFRONT_SUID_DEF $ZLIB_DEF $LIBJTE_DEF $XORRISO_DVD_OBS_64K $CFLAGS" + +AC_CONFIG_FILES([ + Makefile + doc/doxygen.conf + version.h + libisoburn-1.pc + ]) +AC_OUTPUT diff --git a/libisoburn/branches/1.4.6/doc/comments b/libisoburn/branches/1.4.6/doc/comments new file mode 100644 index 00000000..88323c95 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/comments @@ -0,0 +1,85 @@ +/** + @author Mario Danic, Vreixo Formoso, Thomas Schmitt + + @mainpage Libisoburn Documentation Index + + @section intro Introduction + +Libburnia is an open-source project for reading, mastering and writing +optical discs. This page is about its capability to read, manipulate, and +write ISO 9660 filesystems with Rock Ridge extensions. Media can be optical +media or filesystem objects. + +Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD. + +libisoburn is an add-on to libburn and libisofs which coordinates both and +also allows to grow ISO-9660 filesystem images on multi-session media as well +as on overwriteable media via the same API. +All media peculiarities are handled automatically. + +xorriso is an application of all three libraries which creates, loads, +manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. +Manipulation is not only adding or overwriting of files but also deletion, +renaming, and attribute changing. An incremental backup feature is provided. +The xorriso features are accessible via built-in command interpreters and +via a C language API. + + +SONAME: +libisoburn.so.1 (since 0.1.0, February 2008). + + + @section using Using the libraries + +Our build system is based on autotools. +User experience tells us that you will need at least autotools version 1.7. + +To build libisoburn go into its toplevel directory and execute: + +- ./bootstrap (needed if you downloaded from SVN) + +- ./configure + +- make + +To make the library and the xorriso application accessible for running and +software development: + +- make install + + +For direct use as command line tool use the xorriso binary which among many +other features provides a mkisofs emulation via command "-as mkisofs". +See man page xorriso/xorriso.1 or GNU info document xorriso/xorriso.info. + + +If you want to link an own application with libisoburn, you have +two alternative APIs for choice: + +- libisoburn, together with libburn and libisofs. + +- xorriso, a complete representation of xorriso command line options. + It encapsulates the three lower level libraries. + Calls of both API families shall not be mixed. + +For a description of the lbisoburn API read libisoburn/libisoburn.h +See file README for download and installation of a release tarball. +You will also have to install and understand the two libraries of the +Libburnia project which provide fundamental services: +libburn is the library by which preformatted data get onto optical media. +See libburn/libburn.h for its API description. +libisofs is the library to handle ISO 9660 filesystems with Rock Ridge +extensions. Its API is described in libisofs/libisofs.h . + +For xorriso features see its man page xorriso/xorriso.1 or +its GNU info document xorriso/xorriso.info. +For the corresponding C language API see libisoburn/xorriso.h (or +xorriso/xorriso.h in the build directory). +The implementation this API is part of libisoburn. +The xorriso command line tool gets installed as dynamically linked +binary together with libisoburn. + +There is also a statically linked release named GNU xorriso. +See xorriso/README_gnu_xorriso for its download and installation. + +*/ diff --git a/libisoburn/branches/1.4.6/doc/doxygen.conf.in b/libisoburn/branches/1.4.6/doc/doxygen.conf.in new file mode 100644 index 00000000..eb873e02 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/doxygen.conf.in @@ -0,0 +1,1270 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = @PACKAGE_NAME@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @PACKAGE_VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = @top_srcdir@ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = libisoburn \ + doc \ + test + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = libisoburn.h \ + xorriso.h \ + comments + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = test + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = OB \ + OTK \ + _ + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = doc/html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 200 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = DOXYGEN + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +# ts B10415: dot causes sigsegv on Debian buildd +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/libisoburn/branches/1.4.6/doc/faq.wiki b/libisoburn/branches/1.4.6/doc/faq.wiki new file mode 100644 index 00000000..e08da6d2 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/faq.wiki @@ -0,0 +1,407 @@ + +'''Libburnia Frequently Asked Questions''' + +Please post your questions to +[https://lists.gnu.org/mailman/listinfo/bug-xorriso GNU xorriso mailing list]. + +---------------------------------------------------------------------------- +'''Content:''' + +Google favorites: + + [#xorriso_not_found xorriso not found] + + [#xorriso_tutorial xorriso tutorial] + + [#xorriso_create_iso xorriso create ISO image] + +Burning: + + [#diff_cdrskin_xorriso What is the difference between cdrskin and xorriso ?] + + [#scsi_error What does that SCSI error message mean ?] + + [#concurrent_burn Why is simultaneous burning with multiple drives so slow ?] + +Imaging: + + [#edit_files Is there a way to edit files inside the ISO image ?] + + [#boot_arch For which architectures xorriso is able to create bootable images ?] + + [#isohybrid How to enable booting from USB stick ?] + + [#partition_offset What is partition offset feature all about?] + + [#partition_offset_apple Partition offset bad on Apple ?] + +Development: + + [#api_specs Where are the APIs of libburnia libraries described ?] + + [#gui_advise I want to write a GUI on the top of libburnia libraries. Any pointers or recommendations ?] + +Miscellaneous: + + [#example_links Where to see examples ?] + + [#xorriso_aliases What personalities are supported by xorriso ?] + + [#xorriso_dialog_mode What is xorriso dialog mode useful for ?] + + [#version_numbers Why is every second release missing ?] + +---------------------------------------------------------------------------- +'''Google favorites''' +---------------------------------------------------------------------------- + +===== xorriso not found ===== #xorriso_not_found + +This message is issued by programs which use [wiki:Xorriso xorriso] for +producing ISO 9660 filesystem images. E.g. by GRUB2's grub-mkrescue. + +Executable xorriso binaries are normally contained in software packages +named "libisoburn" or "xorriso". + +If your operating system does not offer such a package, then consider +to get the [http://www.gnu.org/software/xorriso#download GNU xorriso] +source tarball. For instructions read in its +[http://www.gnu.org/software/xorriso/README_xorriso README file] +the paragraph "Compilation, First Glimpse, Installation". +With grub-mkrescue it is possible to use the resulting binary without further +installation. Just submit its absolute path with option --xorriso=. E.g.: +{{{ + grub-mkrescue --xorriso=$HOME/xorriso-1.3.8/xorriso/xorriso -o output.iso +}}} + +===== xorriso tutorial ===== #xorriso_tutorial + +There is not much more than the +[http://www.gnu.org/software/xorriso/man_1_xorriso.html#EXAMPLES man xorriso examples]. + +Volunteers are wanted who make a collection of use cases, ask at bug-xorriso +for xorriso instructions to fulfill the needs, and describe both in a +user-readable manner. + +Up to then, the GUI demo [http://svn.libburnia-project.org/libisoburn/trunk/frontend/README-tcltk xorriso-tcltk] +([http://www.gnu.org/software/xorriso/xorriso-tcltk-screen.gif screenshot]) +may serve as interactive exploration tool. It needs xorriso >= 1.2.6, Tcl, +Tk >= 8.4, optionally Tcl / Tk package "BWidget". +{{{ + xorriso-tcltk --script_log_file - +}}} +starts the GUI and will log the essential xorriso commands in the start +terminal. I.e. click on "Scan for drives" and learn that this operation +is triggered by xorriso command "-devices". + +Click the rightmost mouse button while being over any of the GUI elements +in order to get the particular help text for that element. +Have [http://www.gnu.org/software/xorriso/man_1_xorriso.html man xorriso] +ready to learn what the particular commands mean. + + +===== xorriso create ISO image ===== #xorriso_create_iso + +{{{ + xorriso -outdev $HOME/result.iso \ + -map /home/me/sounds /sounds \ + -map /home/me/pictures /pictures +}}} +This points the output to file $HOME/result.iso, which should not yet exist. +Then it maps disk directory /home/me/sounds to ISO directory /sounds, +and /home/me/pictures to /pictures. +At program end, the ISO image gets produced and the contents of the +two directory trees gets copied into the ISO. + +If you have experience with program mkisofs, you may also use its +emulation by xorriso: +{{{ + xorriso -as mkisofs \ + -o $HOME/result.iso \ + -graft-points \ + /sounds=/home/me/sounds \ + /pictures=/home/me/pictures +}}} + +See [http://www.gnu.org/software/xorriso/man_1_xorriso.html man xorriso] +for xorriso native commands. + +See [http://www.gnu.org/software/xorriso/man_1_xorrisofs.html man xorriso] +for its mkisofs emulation. + + + +---------------------------------------------------------------------------- +'''Burning''' +---------------------------------------------------------------------------- + +===== What is the difference between cdrskin and xorriso ? ===== #diff_cdrskin_xorriso + +[wiki:Cdrskin cdrskin] is a dedicated emulator of program cdrecord, based on +libburn. It tries to be as similar to cdrecord as is possible under that +premise. + +[wiki:Xorriso xorriso] is an integrated tool which creates, loads, manipulates, +and writes ISO 9660 filesystem images with Rock Ridge extensions. +It is based on libburn, libisofs, and libisoburn. One of its features is +the emulation of the corresponding tasks as done by mkisofs and cdrecord. + +===== What does that SCSI error message mean ? ===== #scsi_error + +Error messages labled as "SCSI" stem from the drive. They are codes of +three hexadecimal numbers, like [3 0C 00]. The first number gives an overall +classification of the problem. The other two numbers give the particular +error description. + +libburn translates known error codes into text messages. They consist of +two statements: the overall classification and the error description. + +E.g. [3 0C 00] Medium error. Write error. + +The classification allows a guess where the problem cause might sit: + +2 "Drive not ready" : This is a well normal drive state and should be handled +by libburn. If you see this outside of DEBUG messages then it happened +at an unexpected occasion. Either libburn did its job wrong, or the hardware +suffers from blackouts. Hardware can be: drive, cable, bus controller. + +Workaround: Check cables. If possible, try the drive at a different +bus controller. + +3 "Medium error" : This indicates a problem between drive and medium. libburn +cannot directly cause such an error by any mistake. If drive and medium +are balancing on the edge of defect, it is possible that optional settings +can cause or prevent such errors. But in many cases of drive-medium conflicts +it is mere incident whether a burn run succeeds or not. + +Workaround: Try other media or another drive. + +4 "Drive error" : The drive or the bus controller accuse themselves of +doing it wrong. As with "Medium error" this might be aggravated or eased by +optional settings. + +Workaround: Check cables. If possible, try the drive at a different +bus controller. + +5 "Illegal request" : The drive did not like a command sent by libburn. +This may be normal. But if you see this outside of DEBUG messages, then +either the drive does not comply to MMC or libburn does not do its job right. + +Workaround: Submit an error report to +[https://lists.gnu.org/mailman/listinfo/bug-xorriso GNU xorriso mailing list]. + +B "Command aborted" : Seems to be generated by some bus controllers or +operating system SCSI drivers. The newest outbreak is said to be due to USB 3 +and drivers which do not prevent power saving. + +Workaround: Plug USB drives to USB 2 sockets or have a recent operating +system kernel. If this does not help, contact +[https://lists.gnu.org/mailman/listinfo/bug-xorriso GNU xorriso mailing list] +and be ready for experiments. + +===== Why is simultaneous burning with multiple drives so slow ? ===== #concurrent_burn + +It is a known regression of Linux since about 2010 that operating more than +one drive at the same time via SCSI commands shows severe throughput problems. +See [ConcurrentLinuxSr the wiki page about this problem] which offers two +alternative workarounds in userspace, explanantions of the reason, +and a link to a remedy proposal by courageous kernel modification. + +---------------------------------------------------------------------------- +'''Imaging''' +---------------------------------------------------------------------------- + +===== Is there a way to edit files inside the ISO image ? ===== #edit_files + +File content cannot be altered. But files may be replaced by new copies from +the disk filesystem. + +The main method of manipulating an existing ISO image is to append a session +with a new complete directory tree and the file content of the added or +overwritten files. Depending on the media type you get gaps between sessions +of up to 20 MB. So better try to do all foreseeable changes by one add-on +session. + +===== For which architectures xorriso is able to create bootable images ? ===== #boot_arch + +Currently it supports systems with PC-BIOS via El Torito for booting from +CD, DVD, or BD media, and via MBR for booting from memory sticks or hard +disks. Further it supports machines with MIPS processor from SGI (Big Endian) +and DEC (Little Endian), and SUN SPARC machines. +(See [http://bazaar.launchpad.net/%7Elibburnia-team/libisofs/scdbackup/annotate/head%3A/doc/boot_sectors.txt libisofs/doc/boot_sectors.txt] +for technical details.) + +Machines which support EFI may either boot via El Torito or use the files +of the ISO image directly. It is possible to append to the ISO image a +writeable FAT12 partition where files for EFI may be stored and changed. + +===== How to enable booting from USB stick ? ===== #isohybrid + +The ISOLINUX boot loader is normally started from CD, DVD or BD media +by a PC-BIOS via an El Torito boot record. But if the ISO image resides on an +USB stick or another hard-disk-like device, then PC-BIOS ignores El Torito +and rather expects a Master Boot Record (MBR). Both boot record types can +reside in the same ISO image. Therefore it is possible to create an MBR that +starts the boot image file of ISOLINUX which is already target of the El Torito +boot record. This kind of MBR is called "isohybrid". ISOLINUX provides +a program named isohybrid to patch existing images, but libisofs can create an +MBR already when producing the ISO image. See in +[http://www.gnu.org/software/xorriso/man_1_xorriso.html manual page of xorriso] +option -boot_image with arguments "isolinux" "system_area=", +and -as mkisofs option -isohybrid-mbr. + +See [http://en.wikipedia.org/wiki/Master_boot_record Wikipedia on MBR] for +general information about PC-DOS Master Boot Records, and +[http://syslinux.zytor.com/wiki/index.php/ISOLINUX ISOLINUX wiki] for special +information about ISOLINUX. The wiki example with mkisofs can be performed +as well by help of xorriso option -as mkisofs. + +A similar combination of El Torito and MBR is created by GRUB2 tool +grub-mkrescue. See [http://www.gnu.org/software/grub/ homepage of GNU GRUB 2] +for general information. + +===== What is partition offset feature all about? ===== #partition_offset + +If an MBR is present, then it contains a partition table with up to four +entries. The MBR is located at the very start of the ISO image. By +tradition the first partition should begin only after the range of MBR and +eventual supporting data blocks. On hard disk one often sees partition 1 +starting at byte 63*512. Further it is tradition that the payload filesystem +is mountable via one of the partitions. + +The isohybrid MBR has its only partition start at byte 0. Thus it is mountable +but does not obey the tradition to begin only after the MBR. The grub-mkrescue +MBR on the other hand has partition 1 start at byte 512, which makes it +unmountable. Only the unpartitioned base device can be mounted. (On GNU/Linux +e.g. /dev/sdb is the base device whereas /dev/sdb1 is partition 1.) + +The compromise offered by libisofs is to create a second superblock at +address 16*2048 and to let start partition 1 at this address. The second +superblock leads to a second directory tree which takes into account the +address difference between partition 1 and the base device. So the image +gets mountable via both devices and reserves 32 kB for boot manager software +where it may manipulate and augment the MBR. +(See [http://libburnia-project.org/wiki/PartitionOffset Partition Offset Wiki] +for examples.) + +There are reports of machines which will not boot from USB stick if +partition offset is 0. + +===== Partition offset bad on Apple ? ===== #partition_offset_apple + +Apple's "Snow Leopard" operating system refuses to mount Debian CD images +with non-zero partition offset. + +The issue is still under investigation. But for now one has to choose +between mountability on Apple "Snow Leopard" or bootability from USB stick +on Kontron CG2100 "carrier grade server". + +---------------------------------------------------------------------------- +'''Developing''' +---------------------------------------------------------------------------- + +===== Where are the APIs of libburnia libraries described ? ===== #api_specs + +The decisive references are the inclusion headers of the libraries +, , , +and . + +Current SVN versions of these files: +[http://libburnia-project.org/browser/libburn/trunk/libburn/libburn.h libburn/libburn.h] , +[http://bazaar.launchpad.net/%7Elibburnia-team/libisofs/scdbackup/annotate/head%3A/libisofs/libisofs.h libisofs/libisofs.h] , +[http://libburnia-project.org/browser/libisoburn/trunk/libisoburn/libisoburn.h libisoburn/libisoburn.h] , +[http://libburnia-project.org/browser/libisoburn/trunk/xorriso/xorriso.h libisoburn/xorriso.h] + +Doxygen generated API descriptions at +[http://api.libburnia-project.org api.libburnia-project.org] +might be slightly behind the latest developments. + +===== I want to write a GUI on the top of libburnia libraries. Any pointers or recommendations ? ===== #gui_advise + +Most appreciated would be a GUI for xorriso which allows to copy files from +a view of the hard disk filesystem to a view of the ISO filesystem, and vice +versa. The xorriso implementation is located inside libisoburn. + +Each option that is described in +[http://www.gnu.org/software/xorriso/man_1_xorriso.html man 1 xorriso] +can be performed by a corresponding C function that is defined in +[http://libburnia-project.org/browser/libisoburn/trunk/xorriso/xorriso.h xorriso.h]. +Further there are calls for library startup and shutdown, for problem +handling, and for the interpreters of xorriso's command line interface. +The xorriso API encapsulates calls to libisofs, libburn, and libisoburn. + +An alternative to the xorriso C API is xorriso dialog mode. +[#xorriso_dialog_mode See below.] +The script +[http://libburnia-project.org/browser/libisoburn/trunk/frontend/xorriso-tcltk xorriso-tcltk] +demonstrates this approach. It is part of the +libisoburn release tarball and of the GNU xorriso tarball. + +The known existing GUIs [http://www.xfce.org/projects/xfburn/ Xfburn], +[http://projects.gnome.org/brasero/ Brasero], +[http://flburn.sourceforge.net/ FlBurn] +rather use libisofs and libburn directly. +(Please submit an URI if you want your libburnia GUI application mentioned +here.) + +---------------------------------------------------------------------------- +'''Miscellaneous''' +---------------------------------------------------------------------------- + +===== Where to see examples ? ===== #example_links + +[http://www.gnu.org/software/xorriso/man_1_xorriso.html#EXAMPLES xorriso examples] , +[http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#EXAMPLES cdrskin examples] , +[http://libburnia-project.org/browser/libburn/trunk/test/libburner.c libburner.c a minimal but complete burn program] +(also illustrated at the end of [http://api.libburnia-project.org/libburn/ libburn API intro]). + + +===== What personalities are supported by xorriso ? ===== #xorriso_aliases + +The name by which xorriso is started may trigger certain features which +normally would need to be enabled by program options. + +xorrisofs starts up in mkisofs emulation mode, which otherwise would have to +be entered by command -as "mkisofs". + +xorrecord starts up in cdrecord emulation mode, which is normally entered by +command -as "cdrecord". This emulation is only able to write a single data +track as new session to blank or appendable media. No audio. No multiple +tracks in one session. + +osirrox allows to copy files from ISO image to disk and to apply option -mount +to one or more of the existing ISO sessions. This is normally enabled by +option -osirrox "on:o_excl_off". + +===== What is xorriso dialog mode useful for ? ===== #xorriso_dialog_mode + +Dialog mode is initiated if -dialog "on" is among the program arguments. +It can be used to inspect and exploit existing ISO 9660 images or +to explore xorriso's behavior in order to develop the command sequence +for a batch run. + +Frontend programmers may fork xorriso initiating a xorriso dialog session +(-dialog "on" -use_readline "off" -pkt_output "on" -mark "done"), +and interact with it from their own program via pipes connected to +xorriso's stdin and stdout. This is more efficient than forking xorriso +every now and then to perform various commands in order to complete +complex tasks like image size prediction. + +The script +[http://libburnia-project.org/browser/libisoburn/trunk/frontend/xorriso-tcltk xorriso-tcltk] +demonstrates this approach. It is part of the +libisoburn release tarball and of the GNU xorriso tarball. + +===== Why is every second release missing ? ===== #version_numbers + +Releases have an even third version number. Like 0.5.6 or 1.0.4. +During development the next higher odd number is used. E.g. 0.5.7 or 1.0.5. + +The content of release tarballs does not get changed without changing +their name. The development tarballs of xorriso and cdrskin may change +their content without notice. + +---------------------------------------------------------------------------- +Site maintainer: Do not edit this wiki directly but rather the SVN version +of libisoburn/trunk/doc/faq.wiki. When done, paste it into the wiki editor. + diff --git a/libisoburn/branches/1.4.6/doc/grub-mkrescue_reserved_commands.txt b/libisoburn/branches/1.4.6/doc/grub-mkrescue_reserved_commands.txt new file mode 100644 index 00000000..e252bd99 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/grub-mkrescue_reserved_commands.txt @@ -0,0 +1,47 @@ +The argument names listed here have been reserved by Vladimir Serbinenko +for grub-mkrescue. +Do not use them as options of -as mkisofs or as generic commands. +Keep in mind with generic commands: +Leading '-' is ignored, inner '-' is mapped to '_'. + +http://lists.gnu.org/archive/html/grub-devel/2015-04/msg00122.html + +Date: Wed, 29 Apr 2015 16:05:04 +0200 +From: Vladimir '?-coder/phcoder' Serbinenko +Subject: Re: grub-mkrescue problems in argp_parse +------------------------------------------------------------------- +--arcs-boot +--compress +--core-compress +--directory +--fonts +--grub-glue-efi +--grub-mkimage +--grub-render-label +--install-modules +--label-bgcolor +--label-color +--label-font +--locale-directory +--locales +--modules +--output +--override-directory +--product-name +--product-version +--pubkey +--rom-directory +--sparc-boot +--themes +--themes-directory +--verbose +--xorriso +-? +-k +------------------------------------------------------------------- +Known traditional collisions: +------------------------------------------------------------------- +-o intentionally overloaded +-v unintentional +-d unintentional + diff --git a/libisoburn/branches/1.4.6/doc/partition_offset.wiki b/libisoburn/branches/1.4.6/doc/partition_offset.wiki new file mode 100644 index 00000000..40434b57 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/partition_offset.wiki @@ -0,0 +1,232 @@ + +The partition offset feature of libisofs can produce ISO 9660 images which bear +a quite conventional partition table if copied onto a USB stick. The first +partition marks the size of the ISO image but starts at a non-zero address. +Thus it marks a small part of the device as unclaimed by partitions and +available for storing boot loader code. + +Nevertheless the USB stick is mountable via its overall device file as well as +via the partition device file. E.g. on GNU/Linux: /dev/sdb and /dev/sdb1. +This is achieved by two distinct sets of meta-data which refer to the same +file content. + +The dual-mount feature supports Rock Ridge and Joliet too. +It is capable of multi-session. + +Currently only offset 32 kB seems to make sense. Smaller offsets are prohibited +by fundamental assumptions of libisofs and libisoburn. Larger offsets would +extend the unclaimed area into vital blocks of the ISO image. + +-------------------------------------------------------------------------- + +Meanwhile Debian +[http://cdimage.debian.org/cdimage/daily-builds/daily/current/ daily] +and [http://cdimage.debian.org/cdimage/weekly-builds/ weekly] builds make +use of this feature with their bootable ISO images for i386. E.g. +[http://cdimage.debian.org/cdimage/daily-builds/daily/current/i386/iso-cd/debian-testing-i386-netinst.iso debian-testing-i386-netinst.iso]. + +According to a +[http://syslinux.zytor.com/archives/2011-March/016201.html thread of march 2011] +on Syslinux mailing list this enabled booting of a Kontron CG2100 server +from USB stick, which otherwise failed. + +Regrettably the feature seems to prevent mounting of ISO 9660 images on +Apple "Snow Leopard" systems. +At least this is the outcome of a +[http://lists.debian.org/debian-cd/2011/04/msg00029.html debian-cd thread of april 2011]. + +-------------------------------------------------------------------------- + +Example: + +Testing mountability and ISOLINUX bootability from USB stick and CD. + +Overview: + +The test image was derived from one year old RIPLinux-9.3-non-X.iso which +has an isohybrid MBR. Syslinux version seems to be 3.82. That MBR and the file +tree from the mounted RIPLinux image was used to build a new ISO image +with 16 * 2kB partition offset. Isohybrid MBR patching was done by xorriso. + +Details: + +The first 32 kB of an ISO 9660 image are called System Area and may host any +byte pattern. The first 512 bytes of RIPLinux-9.3-non-X.iso contain the +isohybrid capable MBR, which will be re-used in this example. +{{{ + dd if=RIPLinux-9.3-non-X.iso bs=512 count=1 of=RIPLinux-9.3-non-X.mbr +}}} +Normally the isohybrid MBR is provided by the Syslinux +installation under the name isohdp[fp]x*.bin . +E.g. /usr/lib/syslinux/isohdpfx.bin + +The files of the image are made accessible for reading +{{{ + mount -o loop RIPLinux-9.3-non-X.iso /mnt +}}} + +A new ISO image gets composed. The first three lines of arguments are taken +from the prescriptions of ISOLINUX wiki and adapted to the names used in +RIPLinux-9.3-non-X.iso. +Option -isohybrid-mbr imports the copied MBR and patches it +according to rules published by hpa on Syslinux mailing list. +Option -partition_offset 16 causes the first partition to start at 2 kB block +number 16. It also prepares the image to be mountable by this partition, too. +{{{ + xorriso -as mkisofs \ + -o new_image.iso \ + -b boot/isolinux/isolinux.bin -c boot/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -isohybrid-mbr RIPLinux-9.3-non-X.mbr \ + -partition_offset 16 \ + /mnt +}}} +The image was copied onto a USB stick +{{{ + dd if=new_image.iso of=/dev/sdc +}}} +and plugged into a Debian system. +{{{ + fdisk -lu /dev/sdb +}}} +yields +{{{ + Device Boot Start End Blocks Id System +/dev/sdb1 * 64 120831 60384 17 Hidden HPFS/NTFS +}}} + +I can mount /dev/sdb and /dev/sdb1 alike: +{{{ + mount /dev/sdb1 /mnt1 + mount -o loop /dev/sdb /mnt +}}} +-o loop avoids failure with "mount: /dev/sdb already mounted or /mnt busy". +A comparison by +{{{ + diff -r /mnt /mnt1 +}}} +reports no difference. +Human readable files look ok. +Test-reading all content by +{{{ + tar cf - /mnt | wc +}}} +yields a reasonable byte count of 60743680 and no errors. + +The machine boots RIPLinux from this USB stick with no visible problems. +It can then mount /dev/sdb as well as /dev/sdb1. +The ISO image boots from CD too. + +Mounting the partition can be simulated with an image file on hard disk by +cutting off the first partition_offset blocks of 2 KB: +{{{ + dd if=new_image.iso of=partition_image.iso bs=2048 skip=16 + mount -o loop partition_image.iso /mnt1 +}}} + +-------------------------------------------------------------------------- + +Another test was made with GRUB 2 by downloading +{{{ + bzr branch http://bzr.savannah.gnu.org/r/grub/trunk/grub +}}} + +Before building GRUB 2, the file +{{{ + util/grub-mkrescue.in +}}} +was edited to replace in the options of the xorriso command: +{{{ + --protective-msdos-label +}}} +by +{{{ + -partition_offset 16 -no-pad +}}} +Then GRUB 2 was built and installed. + +The resulting image from +{{{ + ./grub-mkrescue -o image.iso +}}} +was put onto USB stick. It passed the same tests on Debian +as above RIPLinux example. It boots to a GRUB prompt. + +Due to option -no-pad the image is about 250 kB smaller than +the image produced by original grub-mkrescue. Else it would have grown by +about 50 kB. + +Unpadded ISO images are safe except for burning on CD in TAO mode. +In this case problems may occur with reading the last few data blocks. +So when burning onto CD make sure to require SAO mode and/or to +require padding by 300 kB. +Burning on DVD or BD needs no such caution. Neither does copying +on USB stick or hard disk. + +Program fdisk will complain about "different physical/logical" addresses. +This can be silenced by adding option +{{{ + -partition_cyl_align on +}}} +at the cost of image padding up to the next full MB. +E.g. by 402 kB to 2 MB. + +-------------------------------------------------------------------------- + +Open questions: + +- Shall the partition of an isohybrid image be marked bootable ? +Currently xorriso keeps the 0x80 mark of an imported MBR +and the 0x80 mark which xorriso sets by its own MBR +preparations. + - If not to be marked bootable: + What equipment would the partition need to justify having the mark ? + +------------------------------------------------------------------------ + +Application: + +The partition offset feature can be controlled by libisofs API calls +{{{ +int iso_write_opts_set_part_offset(IsoWriteOpts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, + int heads_per_cyl); + +int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768], + int options, int flag); +}}} +or by libisoburn calls +{{{ +int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, int heads_per_cyl); + +int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts, + uint32_t *block_offset_2k, + int *secs_512_per_head, int *heads_per_cyl); + +int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *o, + char data[32768], int options); + +int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *o, + char data[32768], int *options); +}}} +or by xorriso options +{{{ + -boot_image any partition_offset=(2kb_block_adr) + -boot_image any partition_sec_hd=(number) + -boot_image any partition_hd_cyl=(number) + -boot_image any partition_cyl_align(on|auto|off) + + -as mkisofs ... -partition_offset (2kb_block_adr) \ + -partition_hd_cyl (number) \ + -partition_sec_hd (number) \ + -partition_cyl_align (on|auto|off) ... +}}} + +As stated above, an offset larger than 16 would expose vital parts of the +ISO image as unclaimed space. Values smaller than 16 are not accepted. +So use either an offset of 16 blocks or keep the feature disabled by +offset 0. + diff --git a/libisoburn/branches/1.4.6/doc/qemu_xorriso.wiki b/libisoburn/branches/1.4.6/doc/qemu_xorriso.wiki new file mode 100644 index 00000000..d457493e --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/qemu_xorriso.wiki @@ -0,0 +1,518 @@ + +This text describes how to set up a qemu virtual machine so that xorriso +on its guest GNU/Linux can operate a CD, DVD or BD recorder of the host +system. + +The options follow proposals of Paolo Bonzini on qemu-devel mailing list. +My compliments for his patient guidance. + +Basic knowledge about Debian and qemu was learned from +[http://www.gnu.org/s/hurd/hurd/running/qemu.html GNU Hurd qemu page]. + +---------------------------------------------------------------------- +This start command works with qemu-1.0-rc3: + +{{{ + $ qemu \ + -enable-kvm \ + -nographic \ + -m 512 \ + -net nic,model=ne2k_pci \ + -net user,hostfwd=tcp::5557-:22 \ + -hda /dvdbuffer/i386-install.qemu \ + -drive file=/dev/sr0,if=none,id=scsicd,format=raw \ + -device virtio-blk-pci,drive=scsicd,logical_block_size=2048,physical_block_size=2048 \ + -cdrom .../some_image.iso +}}} + +This start command works with qemu-2.1.2: + +{{{ + $ qemu \ + -enable-kvm \ + -nographic \ + -m 512 \ + -net nic,model=ne2k_pci \ + -net user,hostfwd=tcp::5557-:22 \ + -hda /dvdbuffer/i386-install.qemu \ + -cdrom .../some_image.iso \ + -drive file=/dev/sr0,index=2,if=virtio +}}} + +With these setups of -drive and -device it is necessary to have a +medium in the drive, when qemu gets started. Else it will refuse. + +The guest system is accessible via ssh and scp at port 5557 of the +host system. + +'''/dev/sr0''' is the address of the DVD drive which is handed over to the +guest system. + +'''.../some_image.iso''' may be any readable file which shall serve as +virtual DVD-ROM. qemu is not happy without such a thing. + +'''/dvdbuffer/i386-install.qemu''' is the disk image, where the guest operating +system was installed by: +{{{ + $ qemu-img create /dvdbuffer/i386-install.qemu 8G + $ qemu \ + -enable-kvm \ + -m 512 \ + -net nic,model=ne2k_pci \ + -hda /dvdbuffer/i386-install.qemu \ + -cdrom debian-6.0.3-i386-netinst.iso \ + -boot d +}}} + +Host system of my qemu-1.0-rc3 test is Debian GNU/Linux 6.0.2 amd64. +With qemu-2.1.2 it is Debian 8.1 amd64. +Both had access to the Internet when the guest was installed. + +---------------------------------------------------------------------- + +Preparations on guest system Debian GNU/Linux 6.0.3 i386 + +There appears no /dev/sr for the passthrough drive. Thus libburn will not +list it by its drive search function. One may use it nevertheless. But +xorriso will only do so if prefix "mmc:" is used with the address: +{{{ + -dev mmc:/dev/vda +}}} +The drive will be listed by libburn if there is a symbolic link /dev/sr* +pointing to it. On Debian 6, this link persists only if it is created +by an udev rule. + +In /lib/udev/rules.d/50-udev-default.rules: +{{{ + KERNEL=="vda", SYMLINK+="sr1" +}}} + +libburn on Linux needs rw-permission for the drive's device node. +The virtual device /dev/vda is in group "disk". Usual for CD drives is +group "cdrom", to which i (or the Debian installer ?) have added my +normal user when i installed the guest system. +Like with the symbolic link, such a change persists on Debian 6 only as +udev rule. + +In /lib/udev/rules.d/91-permissions.rules: +{{{ + KERNEL=="vda", GROUP="cdrom" +}}} + +This should yield +{{{ + lrwxrwxrwx 1 root root 3 Nov 8 11:19 /dev/sr1 -> vda + brw-rw---- 1 root cdrom 254, 0 Nov 8 11:19 /dev/vda +}}} + +xorriso version must be >= 1.1.8 +{{{ + $ xorriso -version +}}} +tells the versions of its components on stdout: +{{{ + ... + xorriso version : 1.1.8 + ... +}}} + +If your distro's xorriso is too old, consider to get and build GNU xorriso. +{{{ + http://ftpmirror.gnu.org/xorriso/xorriso-1.1.8.tar.gz +}}} +Do +{{{ + $ tar xzf xorriso-1.1.8.tar.gz + $ cd xorriso-1.1.8 + $ ./configure && make +}}} +Either do as superuser +{{{ + # make install +}}} +or execute it where it was built as +{{{ + $ ./xorriso/xorriso ...arguments... +}}} +After compilation, this binary does not depend on files in the build +directory. You may move it to any other location. + +For details about the following xorriso commands, read +{{{ + man xorriso + man ./xorriso/xorriso.1 +}}} +or with the same content +{{{ + info xorriso + info ./xorriso/xorriso.info +}}} +Or read the [http://scdbackup.sourceforge.net/man_1_xorriso_devel.html online man page of xorriso]. + + +Note that the sequence of xorriso arguments matters. They are commands +which get performed one after the other. +This differs from the behavior of mkisofs, cdrecord, et.al., +which parse all arguments and then perform actions in a hardcoded +sequence. + +Writing happens automatically if ISO filetree changes are pending +at the end of the program run. This is like with other burn tools. +(There is a command -commit for intermediate writing e.g. in dialog +mode.) + +---------------------------------------------------------------------- + +Listing accessible drives: +{{{ + $ xorriso -devices +}}} +shows on stdout: +{{{ + 0 -dev '/dev/sr0' rwrw-- : 'QEMU ' 'QEMU DVD-ROM' + 1 -dev '/dev/sr1' rwrw-- : 'Optiarc ' 'BD RW BD-5300S' +}}} + +---------------------------------------------------------------------- + +The burn tests are presented here for unformatted DVD-RW media. +The xorriso commands apply also to other types of optical media. +See "Other applicable media types:" further below. + +---------------------------------------------------------------------- + +Inspecting drive and medium: +{{{ + $ xorriso -outdev /dev/sr1 -toc +}}} +should show on stdout something like +{{{ + Drive current: -dev '/dev/sr1' + Drive type : vendor 'Optiarc' product 'BD RW BD-5300S' revision '1.04' + Media current: DVD-RW sequential recording + Media product: RITEKW04 , Ritek Corp + Media status : is written , is closed + Media blocks : 306592 readable , 0 writable , 2298496 overall + TOC layout : Idx , sbsector , Size , Volume Id + ISO session : 1 , 0 , 106696s , ISOIMAGE + ISO session : 2 , 135536 , 108385s , ISOIMAGE + ISO session : 3 , 250240 , 56202s , ISOIMAGE + Media summary: 3 sessions, 271744 data blocks, 531m data, 0 free +}}} + +---------------------------------------------------------------------- + +Blanking to single session capability: + +This medium has to be blanked before further writing. For the DAO +test, one can save time by fast blanking, which xorriso normally +dislikes because the result is not capable of multi-session: +{{{ + $ xorriso -outdev /dev/sr1 -blank deformat_quickest +}}} +should report on stderr +{{{ + ... + xorriso : UPDATE : Blanking ( 1.0% done in 2 seconds ) + ... + xorriso : UPDATE : Blanking ( 95.4% done in 36 seconds ) + xorriso : UPDATE : Blanking ( 99.0% done in 37 seconds ) + ... + Media current: DVD-RW sequential recording + Media status : is blank + Media summary: 0 sessions, 0 data blocks, 0 data, 4489m free +}}} +Do not worry if the pacifier messages show no neat percentage progress. +Some drives report "1.0%" until they are done. Some report "1.0%" +after "99%". + +---------------------------------------------------------------------- + +Writing a DAO session: + +Use one or more moderately sized directories as input. Here: /usr/bin. +Terminate the list of -add arguments by argument "--". +It is important to have command -close "on" among the arguments. +{{{ + $ xorriso -md5 on -outdev /dev/sr1 -close on -add /usr/bin -- +}}} +should report on stderr +{{{ + ... + xorriso : UPDATE : 594 files added in 1 seconds + ... + xorriso : UPDATE : Thank you for being patient. Working since 2 seconds. + xorriso : UPDATE : Writing: 32s 0.1% fifo 100% buf 0% 0.1xD + ... + xorriso : UPDATE : Writing: 2704s 5.1% fifo 11% buf 0% 3.9xD + ... + xorriso : UPDATE : Writing: 20208s 38.2% fifo 52% buf 99% 4.0xD + ... + xorriso : UPDATE : Writing: 52885s 100.0% fifo 0% buf 99% 0.0xD + ISO image produced: 52735 sectors + Written to media : 52885 sectors at LBA 0 + Writing to '/dev/sr1' completed successfully. +}}} +Do not worry if there is no progress to see for a few dozen seconds +at the beginning. +The run will last at least as long as writing of 1 GB would need. +If you write less data, then there will be a lot of zero progress +messages at the end of writing. + +---------------------------------------------------------------------- + +Checkreading the result: +{{{ + $ xorriso -md5 on -indev /dev/sr1 -check_md5_r sorry / -- +}}} +The word "sorry" sets the severity class of the event message, which is +emitted in case of MD5 mismatch. (See man xorriso, "Exception processing".) + +This should report on stderr +{{{ + ... + Drive current: -indev '/dev/sr1' + Media current: DVD-RW sequential recording + Media status : is written , is closed + Media summary: 1 session, 52885 data blocks, 103m data, 0 free + Volume id : 'ISOIMAGE' + xorriso : UPDATE : 568079 content bytes read in 5 seconds + xorriso : UPDATE : 17074k content bytes read in 10 seconds + ... + xorriso : UPDATE : 103.7m content bytes read in 35 seconds + File contents and their MD5 checksums match. +}}} +and the exit value should be 0, if no mismatch was reported. + +A mismatch message would look like +{{{ + ... + MD5 MISMATCH: '/usr/bin/ncursesw5-config' + ... + Mismatch detected between file contents and MD5 checksums. + xorriso : SORRY : Event triggered by MD5 comparison mismatch + xorriso : NOTE : Tolerated problem event of severity 'SORRY' + xorriso : NOTE : -return_with SORRY 32 triggered by problem severity SORRY +}}} +and the exit value would be non-zero. + +---------------------------------------------------------------------- + +Blanking to multi-session capability: +{{{ + $ xorriso -outdev /dev/sr1 -blank as_needed +}}} +This will need as long as writing the DVD-RW up to its end. +Blanking option "as_needed" lets xorriso decide what to do in order +to make the medium writable from scratch. With DVD-RW it will decide for +-blank "all". + +The report on stderr should end by +{{{ + ... + xorriso : UPDATE : Blanking ( 98.9% done in 902 seconds ) + xorriso : UPDATE : Blanking ( 99.0% done in 903 seconds ) + xorriso : UPDATE : Blanking ( 99.0% done in 904 seconds ) + Blanking done + xorriso : NOTE : Re-assessing -outdev '/dev/sr1' + Drive current: -outdev '/dev/sr1' + Media current: DVD-RW sequential recording + Media status : is blank + Media summary: 0 sessions, 0 data blocks, 0 data, 4489m free +}}} + +---------------------------------------------------------------------- + +Writing multiple sessions (DVD-RW write type Incremental): + +This time do not perform command -close "on", so that the medium +stays writable: +{{{ + $ xorriso -md5 on -dev /dev/sr1 -add /usr/lib -- + ... + xorriso : UPDATE : Writing: 105280s 98.6% fifo 0% buf 77% 3.5xD + xorriso : UPDATE : Writing: 106796s 100.0% fifo 0% buf 62% 2.2xD + xorriso : UPDATE : Closing track/session. Working since 44 seconds + ... + xorriso : UPDATE : Closing track/session. Working since 77 seconds + ISO image produced: 106646 sectors + Written to media : 106800 sectors at LBA 0 + Writing to '/dev/sr1' completed successfully. +}}} +Checkread like after the DAO test: +{{{ + $ xorriso -md5 on -indev /dev/sr1 -check_md5_r sorry / -- + ... + xorriso : UPDATE : 204.0m content bytes read in 63 seconds + File contents and their MD5 checksums match. +}}} +Writing the second session looks like the first one. Just use another +set of input files to get a visible change in the ISO 9660 file tree: +{{{ + $ xorriso -md5 on -dev /dev/sr1 -add /usr/bin -- + ... + Written to media : 53408 sectors at LBA 135488 + Writing to '/dev/sr1' completed successfully. +}}} +And checkread the whole tree of files (i.e. both sessions): +{{{ + $ xorriso -md5 on -indev /dev/sr1 -check_md5_r sorry / -- + ... + xorriso : UPDATE : 307.8m content bytes read in 89 seconds + File contents and their MD5 checksums match. +}}} +At the end of writing a final session, the medium can be closed. +It will not take more writing unless it gets blanked or formatted. +So use command -close "on" to demand closing after writing. +{{{ + $ xorriso -md5 on -dev /dev/sr1 -close on -add /usr/sbin -- + ... + Written to media : 16160 sectors at LBA 195056 + Writing to '/dev/sr1' completed successfully. +}}} +Checkread +{{{ + $ xorriso -md5 on -indev /dev/sr1 -check_md5_r sorry / -- + ... + Media current: DVD-RW sequential recording + Media status : is written , is closed + Media summary: 3 sessions, 176368 data blocks, 344m data, 4064m free + ... + xorriso : UPDATE : 337.7m content bytes read in 97 seconds + File contents and their MD5 checksums match. +}}} + +----------------------------------------------------------------------------- + +If the drive tray can move by itself, you may now eject the medium: +{{{ + $ xorriso -outdev /dev/sr1 -eject all +}}} + +----------------------------------------------------------------------------- + +Other applicable media types: + +These test runs for sequential DVD-RW may be performed on CD-RW with the +same xorriso arguments. Be aware that /usr/lib will hardly fit on a CD. +So choose smaller directories for CD. + +-blank "deformat_quickest" addresses a peculiarity of DVD-RW. +It will work on other media like -blank "fast". + +Except the blanking runs, the tests may also be performed on BD-R, DVD-R, +DVD+R, and CD-R. But you would waste two media by this. + +The first session on CD will always be written with write type SAO, +further sessions will be written with TAO. + +CD-R and DVD-R have a simulation mode. It can be enabled by xorriso +command -dummy "on", but of course it will not produce readable results. +So this simulation is usable only for first sessions on blank media. + +----------------------------------------------------------------------------- + +Now for formatted overwritable media: + +All blank, write and check runs of above tests "Writing multiple sessions" +may also be performed with DVD+RW, DVD-RAM, formatted DVD-RW, and BD-RE. +There is no way to close formatted media. The command -close "on" +gets silently ignored. + +The write methods and states of formatted media differ from those of +sequential media. But xorriso presents to the user a unified +multi-session usage model, under the assumption that all emulated +sessions contain ISO 9660 filesystem images, which successively +build on each other. + +So from the view of xorriso commands, the only task which makes +them differ from sequential media, is to apply optional formatting +or re-formatting. +A special case are BD-R, which xorriso may format but will not bring +into (pseudo-) overwritable state. Formatted BD-R perform Defect +Management by default, which checkreads during writing and replaces +bad block. + +The mandatory formatting of unused DVD+RW and BD-RE is done by xorriso +automatically. Just start a normal write run. DVD-RAM are sold formatted. + +xorriso treats overwritable media with a valid ISO 9660 filesystem as +appendable media. To make then writable from scratch, apply +-blank "as_needed", which will actually write a few bytes into the PVD +(superblock) of the ISO filesystem to invalidate it. + +De-formatting is only possible with DVD-RW. E.g. by -blank "deformat". + +----------------------------------------------------------------------------- + +Format DVD-RW for overwriting without intermediate blanking, +or format BD-R for Defect Management: +{{{ + $ xorriso -outdev /dev/sr1 -format as_needed +}}} +should report on stderr +{{{ + ... + xorriso : UPDATE : Formatting ( 99.0% done in 912 seconds ) + Formatting done + xorriso : NOTE : Re-assessing -outdev '/dev/sr1' + Drive current: -outdev '/dev/sr1' + Media current: DVD-RW restricted overwrite + Media status : is blank + Media summary: 0 sessions, 0 data blocks, 0 data, 4488m free +}}} +As with blanking, one should not worry if the progress messages show +unplausible percentages. Some drives are more equal than others. + +Formatting is said to be much stress to the medium. -format option +"as_needed" applies it only to yet unformatted media. + +When performing above write tests, take care to use -blank "as_needed" +rather than -blank "deformat_quickest". Else you will get a sequential +unformatted DVD-RW rather than a formatted DVD-RW which xorriso is +willing to write from scratch. +There is no use in a separate "DAO" test on overwritable media anyway. + +----------------------------------------------------------------------------- + +Change the formatted size of a BD-RE: + +First learn about formatted size and proposals of other sizes. +(One can issue own wishes, too. See in man xorriso, command -format.) +{{{ + $ xorriso -outdev /dev/sr1 -list_formats +}}} +should tell on stdout +{{{ + ... + Format status: formatted, with 23610.0 MiB + BD Spare Area: 0 blocks consumed, 131072 blocks available + Format idx 0 : 00h , 11826176s , 23098.0 MiB + Format idx 1 : 01h , 11564032s , 22586.0 MiB + Format idx 2 : 30h , 11826176s , 23098.0 MiB + Format idx 3 : 30h , 11564032s , 22586.0 MiB + Format idx 4 : 30h , 12088320s , 23610.0 MiB + Format idx 5 : 31h , 12219392s , 23866.0 MiB +}}} +So lets go back from 23610.0 MiB to the default size of 23098.0 MiB +{{{ + $ xorriso -outdev /dev/sr1 -format by_index_2 -blank as_needed + ... + Media summary: 2 sessions, 105470 data blocks, 206m data, 22.4g free +}}} +Although the heads of the old sessions might remain readable after +-format, better do not rely on this and a append -blank "as_needed" to +avoid any data corruption. +If you want to keep the data, then make at least a checkread run. + +Check whether the size has changed: +{{{ + $ xorriso -outdev /dev/sr1 -list_formats +}}} +should tell on stdout +{{{ + ... + Format status: formatted, with 23098.0 MiB + BD Spare Area: 0 blocks consumed, 393216 blocks available + ... +}}} diff --git a/libisoburn/branches/1.4.6/doc/startup_file.txt b/libisoburn/branches/1.4.6/doc/startup_file.txt new file mode 100644 index 00000000..2c15d484 --- /dev/null +++ b/libisoburn/branches/1.4.6/doc/startup_file.txt @@ -0,0 +1,22 @@ +# This is an example for a xorriso startup file. +# If found at one of the following addresses then its text lines will get +# executed by xorriso as commands before any of its program arguments: +# /etc/default/xorriso +# /etc/opt/xorriso/rc +# /etc/xorriso/xorriso.conf +# $HOME/.xorrisorc +# Note: Command -no_rc as first program argument prevents this execution. + + +# Disallow the use of hard disk /dev/sda and its partitions as +# pseudo-drive (e.g. as output target of an ISO image). + +-drive_class banned /dev/sda* + + +# Allow the use of /dev/sdb, /dev/sdc, and /dev/sdd as pseudo-drives +# without the prefix "stdio:" which is usually required for device addresses +# which begin by "/dev/" but represent no CD drives. + +-drive_class harmless /dev/sd[bcd] + diff --git a/libisoburn/branches/1.4.6/frontend/README-tcltk b/libisoburn/branches/1.4.6/frontend/README-tcltk new file mode 100644 index 00000000..f1bf1050 --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/README-tcltk @@ -0,0 +1,127 @@ +------------------------------------------------------------------------------ + xorriso-tcltk +------------------------------------------------------------------------------ +Copyright (C) 2012 - 2013 +Thomas Schmitt , libburnia-project.org +Provided under BSD license: Use, modify, and distribute as you like. +------------------------------------------------------------------------------ + +xorriso-tcltk is mainly a proof of concept for a frontend that operates +xorriso in dialog mode. + +Dependencies: +- xorriso ISO 9660 Rock Ridge filesystem manipulator and CD/DVD/BD burn program +- Tcl programming language +- Tk widget toolkit +- optionally the Tcl/Tk package BWidget + +It exercises several fundamental gestures of communication: +- connecting via two pipes +- sending commands +- receiving replies +- inquiring the xorriso message sieve +- using the xorriso parsing service + +Note that any other language than Tcl/Tk could be used, if it only can +do i/o via standard input and standard output or via named pipes. +Further it has to perform integer arithmetics and string manipulations. +And, well, a graphical widget set would be nice. + +See man xorriso for a documentation of xorriso concepts and commands. +See man xorrecord for details of the burn image file feature. + + + Quick start + +In the xorriso build directory, without installation of xorriso: + + xorriso/xorriso -launch_frontend frontend/xorriso-tcltk --stdio -- + +After installation of xorriso by make install: + + xorriso-tcltk + + + Overview of GUI + +The window is separated into three main areas: +- Connection to xorriso. +- Management of drives and image files. +- Inspection, manipulation, and exploitation of xorriso ISO image model. + +Click the rightmost mouse button while being over any of the GUI elements +in order to get the particular help text for that element. +There is no need to close the help window. Just click another element to +get another help text. + +The "Help" button in the upper right corner gives a short overview and +instructions for several common use cases. + + + Program start options + +The Tcl shell "wish" is allergic to options which start by "-h". +So here is the output of xorriso-tcltk --help : +------------------------------------------------------------------------ + +Usage: + frontend/xorriso-tcltk [options] +Options: + All options must be given with two dashes ("--option") in + order to distinguish them from any options of the Tcl shell. + --help + Print this text and exit. + --stdio + Establish connection to xorriso via stdin and stdout. + E.g. when letting xorriso start this frontend program: + xorriso -launch_frontend $(which xorriso-tcltk) --stdio -- + --named_pipes cmd_fifo reply_fifo + Establish connection to a xorriso process started by: + xorriso -dialog on reply_fifo + which is then ready for a run of: + xorriso-tcltk --named_pipes cmd_fifo reply_fifo + It is important that the parent of xorriso and of this + tcl/tk frontend opens the named pipe for commands before + it opens the named pipe for replies. This avoids deadlock. + --silent_start + Do not issue the start message xorriso-tcltk-version. + This works only if --silent_start is the first argument. + --no_extract + Do not allow extraction of files from ISO filesystem to + hard disk. This is not revokable during the program run. + --no_bwidget + Do not try to load the Tcl/Tk package BWidget which is + a prerequisite for the "/" file browser buttons. + --geometry {+|-}X{+|-}Y + Sets the position of the main window. + --click_to_focus + Chooses that input fields and list boxes get the keyboard + focus only when being clicked by the mouse. (Default) + --auto_focus + Chooses that the keyboard focus is where the mouse + pointer is. + --pipe_log_file path + Set a file address for logging of xorriso commands and + reply messages and enable this logging. + The log lines will be appended. Path "-" means stderr. + --script_log_file path + Set a file address for logging of essential xorriso + commands and enable this logging. + The log lines will be appended. Path "-" means stderr. + --script_log_all_commands + With logging of commands log non-essential commands too. + --use_command_move + Use xorriso command -move for the "Move to: button + if xorriso version is >= 1.2.8 + --use_command_mv + Use xorriso command -mv for the "Move to:" button. + +If neither --stdio nor --named_pipes is given, then this script +will try to locate itself in the filesystem and start a xorriso +run that launches it again. + +In the running GUI, click with the rightmost mouse button on +any GUI element to get its particular help text. + +------------------------------------------------------------------------ + diff --git a/libisoburn/branches/1.4.6/frontend/frontend_pipes_xorriso.c b/libisoburn/branches/1.4.6/frontend/frontend_pipes_xorriso.c new file mode 100644 index 00000000..9ffe642e --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/frontend_pipes_xorriso.c @@ -0,0 +1,980 @@ + +/* Beefed-up example from man 2 pipe + to illustrate how xorriso is to be used by frontend programs via two pipes. + Additionally there is a standalone implementation of Xorriso_parse_line(). + + Copyright 2012 Thomas Schmitt, + Unaltered provided under BSD license. + You may issue licenses of your choice for derived code, provided that they + do not infringe anybody's right to do the same for this original code. + + Build: + cc -g -o frontend_pipes_xorriso frontend_pipes_xorriso.c + + Usage: + ./frontend_pipes_xorriso [path_to_xorriso_binary | -h] + +*/ + +#include +#include +#include +#include +#include +#include +#include + + +static int usage() +{ + static char helptext[][80] = { +"usage: frontend_pipes_xorriso [path_to_xorriso|-h]", +"", +"Forks a process that runs xorriso and communicates with it via two pipes.", +"The command pipe sends payload commands and -mark commands. The reply pipe", +"receives -pkt_output lines which it dispatches to stdout and stderr.", +"The communication between both processes is made synchronous by the parent", +"awaiting the -mark message of the child.", +"Optionally the reply lines can be parsed into words. This is initiated by", +"meta command", +" @parse [prefix [separators [max_words [flag]]]]", +"which sets the four parameters for a function equivalent to", +"Xorriso_parse_line() (see xorriso.h). All reply will then be parsed and", +"non-empty word arrays are displayed. Meta command", +" @noparse", +"ends this mode.", +"Meta command", +" @drain_sieve", +"reports all recorded results of all installed message sieve filter rules.", +"For illustration perform this xorriso command sequence", +" -msg_op start_sieve - -outdev /dev/sr0 -msg_op clear_sieve - -toc", +"and then @drain_sieve.", +"@END@" + }; + int i; + + for (i = 0; strcmp(helptext[i], "@END@") != 0; i++) + fprintf(stderr, "%s\n", helptext[i]); + return(1); +} + + +/* Local helpers of parent process */ + +struct boss_state { + /* What the parent needs to know about its connection to xorriso */ + + /* The ends of the dialog pipes */ + int command_fd; + int reply_fd; + + /* For synchronization between boss and xorriso */ + int mark_count; + char pending_mark[16]; + + /* Parsing_parameters. See xorriso.h Xorriso_parse_line */ + int do_parse; + char progname[1024]; + char prefix[1024]; + char separators[256]; + int max_words; + int flag; + + /* A primitive catcher for result lines */ + int reply_lines_size; /* 0= catching disabled */ + char **reply_lines; + int reply_lines_count; +}; + +#define Frontend_xorriso_max_resulT 1000 + + +/* Some basic gestures of this program: */ + +static int prompt_for_command(struct boss_state *boss, + char *line, int line_size); + +static int transmit_command(struct boss_state *boss, char *line); + +static int await_all_replies(struct boss_state *boss); + +static int de_pkt_result(struct boss_state *boss); + +static int drain_sieve(struct boss_state *boss); + +int parse_line(char *progname, char *line, + char *prefix, char *separators, int max_words, + int *argc, char ***argv, int flag); + +int dispose_parsed_words(int *argc, char ***argv); + + + +/* Parent and child */ +int main(int argc, char *argv[]) +{ + int command_pipe[2], reply_pipe[2]; + pid_t cpid; + char *xorriso_path = "/usr/bin/xorriso"; + + if (argc > 1) { + if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0 || + strcmp(argv[1], "--help") == 0) { + usage(); + exit(0); + } + xorriso_path = argv[1]; + } + + if (pipe(command_pipe) == -1) + { perror("pipe"); exit(1); } + if (pipe(reply_pipe) == -1) + { perror("pipe"); exit(1); } + + cpid = fork(); + if (cpid == -1) + { perror("fork"); exit(2); } + + if (cpid == 0) { + /* Child redirects stdin and stdout. Then it becomes xorriso. */ + + char *xargv[8]; + + close(command_pipe[1]); /* Close unused write end */ + close(reply_pipe[0]); /* Close unused read end */ + + /* Attach pipe ends to stdin and stdout */ + close(0); + if (dup2(command_pipe[0], 0) == -1) + { perror("dup2(,0)"); exit(1); } + close(1); + if (dup2(reply_pipe[1], 1) == -1) + { perror("dup2(,1)"); exit(1); } + + xargv[0] = xorriso_path; + xargv[1] = "-dialog"; + xargv[2] = "on"; + xargv[3] = "-pkt_output"; + xargv[4] = "on"; + xargv[5] = "-mark"; + xargv[6] = "0"; /* corresponds to mark_count = 0 in parent */ + xargv[7] = NULL; + execv(xorriso_path, xargv); + perror("execv"); exit(1); + + } else { + /* Parent prompts user for command lines and prints xorriso replies. + It knows when all reply text of the pending command line has arrived + by watching for -mark reply pending_mark. + */ + + int ret; + char line[4096]; + struct boss_state boss; + + close(command_pipe[0]); /* Close unused read end */ + close(reply_pipe[1]); /* Close unused write end */ + + memset(&boss, 0, sizeof(boss)); + boss.command_fd = command_pipe[1]; + boss.reply_fd = reply_pipe[0]; + strcpy(boss.progname, argv[0]); + boss.reply_lines = NULL; + + /* Dialog loop */ + sprintf(boss.pending_mark, "%d", boss.mark_count); + while (1) { + + /* Wait for pending mark and print all replies */ + ret = await_all_replies(&boss); + if (ret < 0) + break; + + /* Prompt for command line */ + ret = prompt_for_command(&boss, line, sizeof(line)); + if (ret <= 0) + break; + + /* Send line and -mark command */ + ret = transmit_command(&boss, line); + if (ret <= 0) + break; + } + + + /* >>> if child is still operational: send -rollback_end */; + + /* >>> wait a short while */; + + /* >>> if not yet ended: kill child */; + + wait(NULL); /* Wait for child */ + exit(0); + } +} + + +/* ------------------- Local helpers of parent process -------------------- */ + +static int show_parsed(struct boss_state *boss, char *line); +static int record_reply_line(struct boss_state *boss, char *line); +static int make_reply_lines(struct boss_state *boss); +static int input_interpreter(char *line, struct boss_state *boss); + + +/* Ask the user for command input and trigger processing of meta commands. +*/ +static int prompt_for_command(struct boss_state *boss, + char *line, int line_size) +{ + int l, ret; + char *line_res; + + while (1) { + fprintf(stderr, "+++ Enter a command and its parameters :\n"); + line_res = fgets(line, line_size - 1, stdin); + if (line_res == NULL) + return(0); + l = strlen(line); + if (l == 0) { + line[0] = '\n'; + line[1] = 0; + } else if (line[l - 1] != '\n') { + line[l] = '\n'; + line[l + 1] = 0; + } + /* Interpret meta commands which begin by @ */ + ret = input_interpreter(line, boss); + if (ret == 0) + return(1); + if (ret < 0) + return(-1); + } +} + + +/* Transmit a command (which must end by white space, e.g. newline) + and its unique synchronization mark. +*/ +static int transmit_command(struct boss_state *boss, char *line) +{ + int ret; + char mark_line[32]; + + ret = write(boss->command_fd, line, strlen(line)); + if (ret == -1) { + perror("write"); + return(0); + } + /* Produce new unique -mark text to watch for */ + (boss->mark_count)++; + sprintf(boss->pending_mark, "%d", boss->mark_count); + sprintf(mark_line, "-mark %s\n", boss->pending_mark); + ret = write(boss->command_fd, mark_line, strlen(mark_line)); + if (ret == -1) { + perror("write"); + return(0); + } + return(1); +} + + +/* Read reply messages from xorriso and wait for the expected synchronization + mark. Messages can be printed or collected in boss->reply_lines. +*/ +static int await_all_replies(struct boss_state *boss) +{ + int count, remainder = 0, ret; + char buf[32769], *line, *npt; + + while (1) { + count = read(boss->reply_fd, buf + remainder, + sizeof(buf) - 1 - remainder); + if (count == -1) { + perror("read"); + return(-1); + } + if (count == 0) { + fprintf(stderr, "+++ EOF encounterd by Master process\n"); + return(-2); + } + for (npt = buf + remainder; npt < buf + count; npt++) { + if (*npt == 0) { + fprintf(stderr, + "+++ Protocol error : Reply contains 0-chars\n"); + return(-1); + } + } + + /* Split buf into lines */ + buf[remainder + count] = 0; /* for convenience */ + line = buf; + while (1) { + npt = strchr(line, '\n'); + if (npt == NULL) { + /* Move line to start of buffer and set remainder */ + if (line != buf) { + remainder = 0; + for (npt = line; *npt; npt++) + buf[remainder++] = *npt; + } + /* Now read more data in the hope to get a newline char */ + break; + } + /* Interpret line */ + *npt = 0; + if (line[0] == 'M') { + /* M-replies will be outdated until the pending command line + is completely done and the appended -mark command gets + into effect. + */ + if (strlen(line) < 6) { + fprintf(stderr, + "+++ Protocol error : M-channel line shorter than 6 chars\n"); + return(-1); + } + if (strcmp(line + 5, boss->pending_mark) == 0) { + if ((line - buf) + strlen(line) + 1 < count) { + fprintf(stderr, + "+++ Protocol error : Surplus reply data after M-match\n"); + fprintf(stderr, "%s\n", line + strlen(line) + 1); + return(-1); + } + return (1); /* Expected mark has arrived */ + } + } else if (line[0] == 'R') { + /* R-replies are result lines of inquiry commands, like -ls. + They should be handled by specialized code which knows + how to parse and interpret them. + */ + if (boss->reply_lines_count < boss->reply_lines_size) { + ret = record_reply_line(boss, line); + if (ret <= 0) + return(ret); + } else + printf("%s\n", line); + } else { + /* I-replies are pacifiers, notifications, warnings, or + error messages. They should be handled by a general + message interpreter which determines their severity + and decides whether to bother the user. + */ + if (boss->reply_lines_count < boss->reply_lines_size) { + ret = record_reply_line(boss, line); + if (ret <= 0) + return(ret); + } else + fprintf(stderr, "%s\n", line); + } + + /* Parse line and show words */ + if (strlen(line) >= 5) + show_parsed(boss, line + 5); + + line = npt + 1; + } + } + return(1); +} + + +/* Throw away I channel. + Unpack and reconstruct payload of R channel lines. +*/ +static int de_pkt_result(struct boss_state *boss) +{ + int i, l, w; + char *payload = NULL, *new_payload = NULL; + + w = 0; + for (i = 0; i < boss->reply_lines_count; i++) { + if (boss->reply_lines[i][0] != 'R' || + strlen(boss->reply_lines[i]) < 5) + continue; + + if (payload == NULL) { + payload = strdup(boss->reply_lines[i] + 5); + } else { + l = strlen(payload); + new_payload = calloc(l + strlen(boss->reply_lines[i] + 5) + 1, 1); + if (new_payload == NULL) + goto no_mem; + strcpy(new_payload, payload); + strcpy(new_payload + l, boss->reply_lines[i] + 5); + free(payload); + payload = new_payload; + } + if (payload == NULL) + goto no_mem; + l = strlen(payload); + if (l > 0) + if (payload[l - 1] == '\n') + payload[l - 1] = 0; + + if (boss->reply_lines[i][2] != '0') { + free(boss->reply_lines[w]); + boss->reply_lines[w] = payload; + w++; + payload = NULL; + } + } + for (i = w ; i < boss->reply_lines_count; i++) { + free(boss->reply_lines[i]); + boss->reply_lines[i] = NULL; + } + boss->reply_lines_count = w; + return(1); +no_mem:; + fprintf(stderr, "FATAL: Out of memory !\n"); + return(-1); +} + + +/* Inquire and print all recorded message sieve results. +*/ +static int drain_sieve(struct boss_state *boss) +{ + int ret, i, j, names_size = 0, names_count = 0, first_result; + int number_of_strings, available, xorriso_ret, number_of_lines, k, r; + char **names = NULL, line[1024]; + + /* Install catcher for reply_lines */ + ret = make_reply_lines(boss); + if (ret <= 0) + goto ex; + boss->reply_lines_size = Frontend_xorriso_max_resulT; + boss->reply_lines_count = 0; + + /* Get list of filter rule names from -msg_op show_sieve */ + ret = transmit_command(boss, "-msg_op show_sieve -\n"); + if (ret <= 0) + goto ex; + ret = await_all_replies(boss); + if (ret <= 0) + goto ex; + ret = de_pkt_result(boss); + if (ret <= 0) + goto ex; + + names = boss->reply_lines; + boss->reply_lines = NULL; + names_size = Frontend_xorriso_max_resulT; + names_count= boss->reply_lines_count; + ret = make_reply_lines(boss); + if (ret <= 0) + goto ex; + boss->reply_lines_size = Frontend_xorriso_max_resulT; + + /* Inquire caught results of each name by -msg_op read_sieve + until return value is <= 0 + */ + printf("--------------------------------------------------\n"); + for (i = 0; i < names_count; i++) { + available = 1; + first_result = 1; + while (available > 0) { + boss->reply_lines_count = 0; + sprintf(line, "-msg_op read_sieve '%s'\n", names[i]); + ret = transmit_command(boss, line); + if (ret <= 0) + goto ex; + ret = await_all_replies(boss); + if (ret <= 0) + goto ex; + ret = de_pkt_result(boss); + if (ret <= 0) + goto ex; + + if (boss->reply_lines_count < 2) { + fprintf(stderr, "drain_sieve: illegible result reply\n"); + {ret= 0; goto ex;} + } + xorriso_ret = -1; + sscanf(boss->reply_lines[0], "%d", &xorriso_ret); + if(xorriso_ret <= 0) + break; + number_of_strings = -1; + sscanf(boss->reply_lines[1], "%d", &number_of_strings); + if(xorriso_ret < 0) + break; + if (first_result) + printf(" '%s' |\n", names[i]); + first_result = 0; + for (j = 0; names[i][j] != 0; j++) + printf("-"); + printf("-----\n"); + r = 2; + for (j = 0; j < number_of_strings && r < boss->reply_lines_count; + j++) { + number_of_lines = -1; + sscanf(boss->reply_lines[r], "%d", &number_of_lines); + r++; + printf("|"); + for (k = 0; k < number_of_lines + && r < boss->reply_lines_count; k++) { + printf("%s%s", boss->reply_lines[r], + k < number_of_lines - 1 ? "\n" : ""); + r++; + } + printf("|\n"); + } + } + if (first_result == 0) + printf("--------------------------------------------------\n"); + } + + /* Dispose all recorded results */ + ret = transmit_command(boss, "-msg_op clear_sieve -\n"); + if (ret <= 0) + goto ex; + ret = await_all_replies(boss); + if (ret <= 0) + goto ex; + + ret = 1; +ex:; + /* Disable result catcher */ + boss->reply_lines_size = 0; + if (names != NULL) + dispose_parsed_words(&names_size, &names); + return(ret); +} + + +/* ------------------------- Helpers of local helpers ---------------------- */ + + +static int show_parsed(struct boss_state *boss, char *line) +{ + int argc, ret = 0, i; + char **argv = NULL; + + if (!boss->do_parse) + return(2); + ret = parse_line(boss->progname, line, boss->prefix, boss->separators, + boss->max_words, &argc, &argv, boss->flag); + if (ret <= 0 || argc <= 0) + return(0); + fprintf(stderr, "-----------------------------------------------------\n"); + fprintf(stderr, "parse_line returns %d, argc = %d\n", ret, argc); + for (i = 0; i < argc; i++) + fprintf(stderr, "%2d : %s\n", i, argv[i]); + fprintf(stderr, "-----------------------------------------------------\n"); + dispose_parsed_words(&argc, &argv); /* release memory */ + return(1); +} + + +static int make_reply_lines(struct boss_state *boss) +{ + int i; + + if (boss->reply_lines != NULL) + return(1); + + boss->reply_lines = calloc(Frontend_xorriso_max_resulT, + sizeof(char *)); + if (boss->reply_lines == 0) { + fprintf(stderr, "FATAL: Out of memory !\n"); + return(-1); + } + boss->reply_lines_count = 0; + boss->reply_lines_size = 0; + for (i = 0; i < Frontend_xorriso_max_resulT; i++) + boss->reply_lines[i] = NULL; + return(1); +} + + +static int record_reply_line(struct boss_state *boss, char *line) +{ + if (boss->reply_lines[boss->reply_lines_count] != NULL) + free(boss->reply_lines[boss->reply_lines_count]); + boss->reply_lines[boss->reply_lines_count] = strdup(line); + if (boss->reply_lines[boss->reply_lines_count] == NULL) { + fprintf(stderr, "FATAL: Out of memory !\n"); + return(-1); + } + boss->reply_lines_count++; + return(1); +} + + +static int input_interpreter(char *line, struct boss_state *boss) +{ + int argc, ret = 0; + char **argv = NULL; + + ret = parse_line(boss->progname, line, "", "", 6, &argc, &argv, 0); + if (ret <= 0 || argc <= 0) + return(0); + if (strcmp(argv[0], "@parse") == 0) { + boss->do_parse = 1; + boss->prefix[0] = 0; + if (argc > 1) + strcpy(boss->prefix, argv[1]); + boss->separators[0] = 0; + if (argc > 2) + strcpy(boss->separators, argv[2]); + boss->max_words = 0; + if (argc > 3) + sscanf(argv[3], "%d", &(boss->max_words)); + boss->max_words = 0; + if (argc > 4) + sscanf(argv[4], "%d", &(boss->flag)); + ret = 1; + } else if(strcmp(argv[0], "@noparse") == 0) { + boss->do_parse = 0; + ret = 1; + } else if(strcmp(argv[0], "@drain_sieve") == 0) { + ret= drain_sieve(boss); + } else { + ret = 0; + } + dispose_parsed_words(&argc, &argv); /* release memory */ + return ret; +} + + +/* -------- Line-to-word parser equivalent to Xorriso_parse_line() -------- */ + + +static int Sfile_sep_make_argv(char *progname, char *line, char *separators, + int max_words, int *argc, char ***argv, int flag); + + +int parse_line(char *progname, char *line, + char *prefix, char *separators, int max_words, + int *argc, char ***argv, int flag) +{ + int ret, bsl_mode; + char *to_parse; + + *argc = 0; + *argv = NULL; + + to_parse = line; + bsl_mode = (flag >> 1) & 15; + if (prefix[0]) { + if (strncmp(line, prefix, strlen(prefix)) == 0) { + to_parse = line + strlen(prefix); + } else { + ret = 2; goto ex; + } + } + ret = Sfile_sep_make_argv(progname, to_parse, separators, + max_words, argc, argv, + (!(flag & 32)) | 4 | (bsl_mode << 5)); + if (ret < 0) { + fprintf(stderr, + "%s : Severe lack of resources during command line parsing\n", + progname); + goto ex; + } + if (ret == 0) { + fprintf(stderr, + "%s : Incomplete quotation in %s line: %s\n", + progname, (flag & 32) ? "command" : "parsed", to_parse); + goto ex; + } +ex:; + if (ret <= 0) + Sfile_sep_make_argv("", "", "", 0, argc, argv, 2); /* release memory */ + return(ret); +} + + +int dispose_parsed_words(int *argc, char ***argv) +{ + Sfile_sep_make_argv("", "", "", 0, argc, argv, 2); + return(1); +} + + +/* -------------- Some helpers copied from xorriso/sfile.c ----------------- */ + + +static int Sfile_destroy_argv(int *argc, char ***argv, int flag) +{ + int i; + + if(*argc>0 && *argv!=NULL){ + for(i=0;i<*argc;i++){ + if((*argv)[i]!=NULL) + free((*argv)[i]); + } + free((char *) *argv); + } + *argc= 0; + *argv= NULL; + return(1); +} + + +/* Converts backslash codes into single characters: + \a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 , + \t HT 9 , \v VT 11 , \\ \ 92 + \[0-9][0-9][0-9] octal code , \x[0-9a-f][0-9a-f] hex code , + \cX control-x (ascii(X)-64) + @param upto maximum number of characters to examine for backslash. + The scope of a backslash (0 to 3 characters) is not affected. + @param eaten returns the difference in length between input and output + @param flag bit0= only determine *eaten, do not convert + bit1= convert \000 to binary 0 +*/ +static int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag) +{ + char *rpt, *wpt, num_text[8], wdummy[8]; + unsigned int num= 0; + + *eaten= 0; + wpt= text; + for(rpt= text; *rpt != 0 && rpt - text < upto; rpt++) { + if(flag & 1) + wpt= wdummy; + if(*rpt == '\\') { + rpt++; + (*eaten)++; + if(*rpt == 'a') { + *(wpt++)= 7; + } else if(*rpt == 'b') { + *(wpt++)= 8; + } else if(*rpt == 'e') { + *(wpt++)= 27; + } else if(*rpt == 'f') { + *(wpt++)= 12; + } else if(*rpt == 'n') { + *(wpt++)= 10; + } else if(*rpt == 'r') { + *(wpt++)= 13; + } else if(*rpt == 't') { + *(wpt++)= 9; + } else if(*rpt == 'v') { + *(wpt++)= 11; + } else if(*rpt == '\\') { + *(wpt++)= '\\'; + } else if(rpt[0] >= '0' && rpt[0] <= '7' && + rpt[1] >= '0' && rpt[1] <= '7' && + rpt[2] >= '0' && rpt[2] <= '7') { + num_text[0]= '0'; + num_text[1]= *(rpt + 0); + num_text[2]= *(rpt + 1); + num_text[3]= *(rpt + 2); + num_text[4]= 0; + sscanf(num_text, "%o", &num); + if((num > 0 || (flag & 2)) && num <= 255) { + rpt+= 2; + (*eaten)+= 2; + *(wpt++)= num; + } else + goto not_a_code; + } else if(rpt[0] == 'x' && + ((rpt[1] >= '0' && rpt[1] <= '9') || + (rpt[1] >= 'A' && rpt[1] <= 'F') || + (rpt[1] >= 'a' && rpt[1] <= 'f')) + && + ((rpt[2] >= '0' && rpt[2] <= '9') || + (rpt[2] >= 'A' && rpt[2] <= 'F') || + (rpt[2] >= 'a' && rpt[2] <= 'f')) + ) { + num_text[0]= *(rpt + 1); + num_text[1]= *(rpt + 2); + num_text[2]= 0; + sscanf(num_text, "%x", &num); + if(num > 0 && num <= 255) { + rpt+= 2; + (*eaten)+= 2; + *(wpt++)= num; + } else + goto not_a_code; + } else if(*rpt == 'c') { + if(rpt[1] > 64 && rpt[1] < 96) { + *(wpt++)= rpt[1] - 64; + rpt++; + (*eaten)++; + } else + goto not_a_code; + } else { +not_a_code:; + *(wpt++)= '\\'; + rpt--; + (*eaten)--; + } + } else + *(wpt++)= *rpt; + } + *wpt= *rpt; + return(1); +} + + +#define SfileadrL 4096 + +static int Sfile_sep_make_argv(char *progname, char *line, char *separators, + int max_words, int *argc, char ***argv, int flag) +/* + bit0= read progname as first argument from line + bit1= just release argument list argv and return + bit2= abort with return(0) if incomplete quotes are found + bit3= eventually prepend missing '-' to first argument read from line + bit4= like bit2 but only check quote completeness, do not allocate memory + bit5+6= interpretation of backslashes: + 0= no interpretation, leave unchanged + 1= only inside double quotes + 2= outside single quotes + 3= everywhere + bit7= append a NULL element to argv +*/ +{ + int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc, bsl_mode, ret= 0, eaten; + char *cpt,*start; + char *buf= NULL; + + Sfile_destroy_argv(argc,argv,0); + if(flag&2) + {ret= 1; goto ex;} + + if(flag & 16) + flag|= 4; + bsl_mode= (flag >> 5) & 3; + + buf= calloc(strlen(line) + SfileadrL, 1); + if(buf == NULL) + {ret= -1; goto ex;} + for(pass=0;pass<2;pass++) { + cpt= line-1; + if(!(flag&1)){ + argzaehl= line_start_argc= 1; + if(pass==0) + maxl= strlen(progname); + else + strcpy((*argv)[0],progname); + } else { + argzaehl= line_start_argc= 0; + if(pass==0) maxl= 0; + } + while(*(++cpt)!=0){ + if(*separators) { + if(strchr(separators, *cpt) != NULL) + continue; + } else if(isspace(*cpt)) + continue; + start= cpt; + buf[0]= 0; + cpt--; + + if(max_words > 0 && argzaehl >= max_words && *cpt != 0) { + /* take uninterpreted up to the end */ + cpt+= strlen(cpt) - 1; + } + + while(*(++cpt)!=0) { + if(*separators) { + if(strchr(separators, *cpt) != NULL) + break; + } else if(isspace(*cpt)) + break; + if(*cpt=='"'){ + l= cpt-start; bufl= strlen(buf); + if(l>0) { + strncpy(buf + bufl, start, l); buf[bufl + l]= 0; + if(bsl_mode >= 3) { + ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); + if(ret <= 0) + goto ex; + } + } + l= strlen(buf); + start= cpt+1; + while(*(++cpt)!=0) if(*cpt=='"') break; + if((flag&4) && *cpt==0) + {ret= 0; goto ex;} + l= cpt-start; bufl= strlen(buf); + if(l>0) { + strncpy(buf + bufl, start, l); + buf[bufl + l]= 0; + if(bsl_mode >= 1) { + ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0); + if(ret <= 0) + goto ex; + } + } + start= cpt+1; + }else if(*cpt=='\''){ + l= cpt-start; bufl= strlen(buf); + if(l>0) { + strncpy(buf + bufl, start, l); buf[bufl + l]= 0; + if(bsl_mode >= 3) { + ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); + if(ret <= 0) + goto ex; + } + } + l= strlen(buf); + start= cpt+1; + while(*(++cpt)!=0) if(*cpt=='\'') break; + if((flag&4) && *cpt==0) + {ret= 0; goto ex;} + l= cpt-start; bufl= strlen(buf); + if(l>0) { + strncat(buf,start,l);buf[bufl+l]= 0; + if(bsl_mode >= 2) { + ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0); + if(ret <= 0) + goto ex; + } + } + start= cpt+1; + } + if(*cpt==0) break; + } + l= cpt-start; + bufl= strlen(buf); + if(l>0) { + strncpy(buf + bufl, start, l); buf[bufl + l]= 0; + if(bsl_mode >= 3) { + ret= Sfile_bsl_interpreter(buf, l, &eaten, 0); + if(ret <= 0) + goto ex; + } + } + l= strlen(buf); + if(pass==0){ + if(argzaehl==line_start_argc && (flag&8)) + if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#') + l++; + if(l>maxl) maxl= l; + }else{ + strcpy((*argv)[argzaehl],buf); + if(argzaehl==line_start_argc && (flag&8)) + if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#') + sprintf((*argv)[argzaehl],"-%s", buf); + } + argzaehl++; + if(*cpt==0) break; + } + if(pass==0){ + if(flag & 16) + {ret= 1; goto ex;} + *argc= argzaehl; + if(argzaehl>0 || (flag & 128)) { + *argv= (char **) calloc((argzaehl + !!(flag & 128)), sizeof(char *)); + if(*argv==NULL) + {ret= -1; goto ex;} + } + for(i=0;i<*argc;i++) { + (*argv)[i]= (char *) calloc(maxl + 1, 1); + if((*argv)[i]==NULL) + {ret= -1; goto ex;} + } + if(flag & 128) + (*argv)[*argc]= NULL; + } + } + ret= 1; +ex: + if(buf != NULL) + free(buf); + return(ret); +} + diff --git a/libisoburn/branches/1.4.6/frontend/grub-mkrescue-sed.sh b/libisoburn/branches/1.4.6/frontend/grub-mkrescue-sed.sh new file mode 100755 index 00000000..93a548e0 --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/grub-mkrescue-sed.sh @@ -0,0 +1,271 @@ +#!/bin/sh + +# Copyright (C) 2015 - 2016 +# Thomas Schmitt , libburnia-project.org +# Provided under BSD license: Use, modify, and distribute as you like. + +echo >&2 +echo "frontend/grub-mkrescue-sed.sh manipulating xorriso arguments" >&2 +echo >&2 + +# This script may be handed by its absolute path to grub-mkrescue +# via option --xorriso= . E.g. +# +# mkdir minimal +# touch minimal/empty-file.txt +# grub-mkrescue -o output.iso minimal \ +# --xorriso=/home/thomas/xorriso-1.4.3./frontend/grub-mkrescue-sed.sh +# +# It will manipulate the xorriso arguments before they get executed by a +# xorriso program. Default is the neighboring ../../xorriso/xorriso program or, +# if that neighbor cannot be found, the system-wide installed xorriso. +# +# The mode "mjg" implements a layout which resembles Fedora LiveCD and Debian +# ISOs which are bootable by ISOLINUX for BIOS and GRUB2 for EFI. +# Its GPT is considered to be surplus, according to UEFI specs. +# +# The mode "mbr_only" implements an alternative layout according to UEFI 2.4, +# section 2.5.1 and table 16. No GTP, HFS+, or APM. +# +# The mode "mbr_hfs" is like "mbr_only" but with HFS+ mentioned in APM. +# It is still compliant to UEFI with no potentially deceiving GPT. +# If you add xorrisofs option -part_like_isohybrid then no gap fillig APM +# partition will emerge. +# +# These modes avoid duplicate storing of the EFI system partition "efi.img" +# by xorrisofs option -e "--interval:appended_partition_${partno}:all::" +# which is new to xorriso-1.4.3 with timestamp after 2015.12.30.175951. +# If "_copy" is appended to the mode name, then the file /efi.img will +# appear in the ISO 9660 filesystem and traditional -e "/efi.img" is used. +# +# "mbr_only_copy" is supposed to work with unmodified xorriso >= 1.3.2 + +# +# Variation settings +# +# The environment variables MKRESCUE_SED_* override the following +# default settings: + +# Manipulation mode: +# "mjg" = ESP in MBR+GPT+APM, with HFS+ +# "mbr_only" = ESP in MBR, without HFS+ +# "mbr_hfs" = ESP in MBR, HFS+ in APM +# $mode"_copy" = one of above modes, ESP in ISO and as appended partition +# "original" = pass arguments unchanged +mode="mjg" +if test -n "$MKRESCUE_SED_MODE" +then + mode="$MKRESCUE_SED_MODE" +fi + +# First argument of -append_partition with mode "mjg". Values: 1 or 2. +partno=1 +if test -n "$MKRESCUE_SED_PARTNO" +then + partno="$MKRESCUE_SED_PARTNO" +fi + +# Replacement for option --protective-msdos-label. Either itself or empty text. +# If the environment variable contains the word "no", this means empty. +protective="--protective-msdos-label" +if test -n "$MKRESCUE_SED_PROTECTIVE" +then + if test x"$MKRESCUE_SED_PROTECTIVE" = xno + then + protective="" + elif test x"$MKRESCUE_SED_PROTECTIVE" = xyes + then + protective="--protective-msdos-label" + else + protective="$MKRESCUE_SED_PROTECTIVE" + fi +fi + +# "yes" shows xorriso arguments, "extra" additionally shows all input files. +debug=no +if test -n "$MKRESCUE_SED_DEBUG" +then + debug="$MKRESCUE_SED_DEBUG" +fi + +# The path to the program that will be executed with the converted arguments. +if test -n "$MKRESCUE_SED_XORRISO" +then + xorriso="$MKRESCUE_SED_XORRISO" +else + # Prefer neighboring xorriso binary over system-wide installed one. + self_dir="$(dirname $(dirname "$0") )" + if test -x "$self_dir"/xorriso/xorriso + then + xorriso="$self_dir"/xorriso/xorriso + else + xorriso="xorriso" + fi +fi + +# MKRESCUE_SED_XORRISO_ARGS will be used as first arguments of the xorriso run. +# (Trailing xorriso arguments may be simply added to the grub-mkrescue +# command line.) +# Each argument must be a single word. No whitespace. No quotation marks. + + +# +# Do the work +# + +# grub-mkrescue inquires features by running these arguments +if test "$*" = "-as mkisofs -help" +then + "$xorriso" "$@" + exit $? +fi + +echo "frontend/grub-mkrescue-sed.sh mode: $mode" >&2 +echo >&2 + +if test x"$debug" = xyes -o x"$debug" = xextra +then + # Show arguments + echo "##### Begin of received arguments" >&2 + echo "$0" >&2 + for i in "$@" + do + echo "$i" >&2 + done + echo "##### End of received arguments" >&2 + echo >&2 +fi + +# Look for the name of the /tmp directory with the GRUB2 files. +# It is the next argument after -r. But as default accept any /tmp/grub.* +next_is_dir=0 +dir="." +for i in "$@" +do + if test x"$i" = x"-r" + then + next_is_dir=1 + elif test $next_is_dir = 1 + then + next_is_dir=0 + if echo "$i" | grep '^/tmp/grub.' >/dev/null 2>&1 + then + test -d "$i" && dir="$i" + fi + elif test "$dir" = "." + then + if echo "$i" | grep '^/tmp/grub.' >/dev/null 2>&1 + then + test -d "$i" && dir="$i" + fi + fi +done + +if test x"$debug" = xextra +then + # Show files on disk + find "$dir" +fi + +efi_tmp_name= +if test x"$mode" = xmjg +then + # Exchange arguments for the experimental GRUB2 mjg layout + efi_tmp_name=grub-mkrescue-sed-efi-img.$$ + mv "$dir"/efi.img /tmp/$efi_tmp_name + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition $partno 0xef \/tmp\/$efi_tmp_name/" \ + -e "s/--efi-boot efi\.img/-eltorito-alt-boot -e --interval:appended_partition_${partno}:all:: -no-emul-boot -isohybrid-gpt-basdat/" \ + -e "s/--protective-msdos-label/$protective -part_like_isohybrid/" \ + ) + +elif test x"$mode" = xmjg_copy +then + # Exchange arguments for the experimental GRUB2 mjg layout + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition $partno 0xef \/tmp\/$(basename "$dir")\/efi.img/" \ + -e "s/--efi-boot efi\.img/-eltorito-alt-boot -e efi.img -no-emul-boot -isohybrid-gpt-basdat/" \ + -e "s/--protective-msdos-label/$protective -part_like_isohybrid/" \ + ) + +elif test x"$mode" = xmbr_only +then + # Exchange arguments for no-HFS MBR-only layout + efi_tmp_name=grub-mkrescue-sed-efi-img.$$ + mv "$dir"/efi.img /tmp/$efi_tmp_name + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition 2 0xef \/tmp\/$efi_tmp_name/" \ + -e "s/--efi-boot efi\.img/-eltorito-alt-boot -e --interval:appended_partition_2:all:: -no-emul-boot/" \ + -e "s/-hfsplus .*CoreServices\/boot.efi//" \ + -e "s/--protective-msdos-label/$protective/" \ + ) + +elif test x"$mode" = xmbr_only_copy +then + # Exchange arguments for no-HFS MBR-only layout + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition 2 0xef \/tmp\/$(basename "$dir")\/efi.img/" \ + -e "s/-hfsplus .*CoreServices\/boot.efi//" \ + -e "s/--protective-msdos-label/$protective/" \ + ) + +elif test x"$mode" = xmbr_hfs +then + # Exchange arguments for MBR and HFS+ layout + efi_tmp_name=grub-mkrescue-sed-efi-img.$$ + mv "$dir"/efi.img /tmp/$efi_tmp_name + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition 2 0xef \/tmp\/$efi_tmp_name/" \ + -e "s/--efi-boot efi\.img/-eltorito-alt-boot -e --interval:appended_partition_2:all:: -no-emul-boot/" \ + -e "s/--protective-msdos-label/$protective/" \ + ) + +elif test x"$mode" = xmbr_hfs_copy +then + # Exchange arguments for MBR and HFS+ layout + x=$(echo " $*" | sed \ + -e "s/-efi-boot-part --efi-boot-image/-no-pad -append_partition 2 0xef \/tmp\/$(basename "$dir")\/efi.img/" \ + -e "s/--protective-msdos-label/$protective/" \ + ) + +elif test x"$mode" = xoriginal +then + # Pass arguments unchanged + x=" $*" + +else + echo >&2 + echo "$0 : FATAL : Unknown manipulation mode '$mode'." >&2 + echo >&2 + exit 1 +fi + +if test x"$debug" = xyes -o x"$debug" = xextra +then + echo "+ converted xorriso arguments:" >&2 + echo " $x" >&2 + echo >&2 +fi + +# Run xorriso binary with the converted arguments +use_gdb=no +if test "$use_gdb" = yes +then + gdb_file=/tmp/grub-mkrescue-sed-gdb + echo b assess_appended_gpt >$gdb_file + echo run $MKRESCUE_SED_XORRISO_ARGS $x >>$gdb_file + gdb -x $gdb_file "$xorriso" + ret=0 +else + "$xorriso" $MKRESCUE_SED_XORRISO_ARGS $x + ret=$? +fi + +# Move back the ESP if it was separated +if test -n "$efi_tmp_name" -a -e /tmp/$efi_tmp_name +then + mv /tmp/$efi_tmp_name "$dir"/efi.img +fi + +exit $ret + diff --git a/libisoburn/branches/1.4.6/frontend/sh_on_named_pipes.sh b/libisoburn/branches/1.4.6/frontend/sh_on_named_pipes.sh new file mode 100755 index 00000000..3f35700c --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/sh_on_named_pipes.sh @@ -0,0 +1,304 @@ +#!/bin/bash +# +# Demo of a shell frontend that communicates with a xorriso slave via +# two named pipes. +# +# This script creates two named pipes and starts xorriso with command +# -named_pipes_loop cleanup /tmp/xorriso_stdin_pipe_$$ xorriso_stdin_pipe_$$ - +# Its main loop prompts the user for commands, sends them to xorriso, +# receives the replies, and parses them by xorriso command +# -msg_op parse_silently. The resulting words are printed to stdout. +# +# xorriso removes the two pipes when it finishes execution of -named_pipes_loop +# regularly. (E.g. because of commands -end or -rollback_end or because of +# name loop control message "end_named_pipe_loop".) +# The vanishing of the pipe files tells this script that xorriso is gone. +# +# +# Copyright (C) 2013 +# Thomas Schmitt , libburnia-project.org +# Provided under BSD license: Use, modify, and distribute as you like. +# + +# What xorriso program to use +xorriso=xorriso +if test o"$1" = o"-xorriso" +then + xorriso="$2" +fi + +# Version of xorriso and minimum requirement by this script +export xorriso_version= +export xorriso_version_req=1.3.1 + +# Info about the xorriso slave process +export xorriso_is_running=0 +export xorriso_pid=0 +export xorriso_will_end=0 + +# Will be set to 1 before this script ends normally +export normal_end=0 + + +# ---------------- An interpreter for quoted xorriso replies ---------------- + +# xorriso commands like -lsl wrap filenames into quotation marks in order +# to unambigously represent any character byte except the 0-byte. +# This piece of code parses input strings into words by letting xorriso +# command -msg_op "parse_silently" do the hard work. +# The input strings should be composed by concatenating input lines with +# newline characters between them. Begin by submitting a single line (without +# newline at its end) and retry with an appended further line, if +# xorriso_parse +# returns 1. See below xorriso_cmd_and_handle_result() for an example. + + +# The parsed reply words. +# Valid are reply_array[0] to reply_array[reply_count-1)] +export reply_array +export reply_count + + +# Interpret reply of -msg_op parse +xorriso_recv_parse_reply() { + reply_count=0 + unset reply_array + export reply_array + ret=-1 + read ret + if test "$ret" -lt 0 -o -z "$ret" + then + echo "Unexpected text as first reply line of -msg_op parse" >&2 + xorriso_is_running=0 + return 2 + fi + test "$ret" = 0 && return "1" + read num_strings + string_count=0 + while true + do + test "$string_count" -ge "$num_strings" && break + read num_lines + line_count=0 + acc= + while true + do + test "$line_count" -ge "$num_lines" && break + read line + test "$line_count" -gt 0 && acc="$acc"$'\n' + acc="$acc""$line" + line_count=$(($line_count + 1)) + done + reply_array["$string_count"]="$acc" + string_count=$(($string_count + 1)) + done + reply_count="$num_strings" + return 0 +} + + +# Parse a quoted multi-line string into words +xorriso_parse() { + # $1 : The string which shall be parsed + # $2 : The number of concatenated input lines (= number of newlines + 1) + # return: 0= array is valid , 1= line incomplete , 2= other error + + test "$xorriso_is_running" = 0 && return 1 + xorriso_send_cmd "msg_op parse_silently "'"'"'' '' 0 0 $2"'"'$'\n'"$1" || \ + return 2 + xorriso_recv_parse_reply <"$result_pipe" || xorriso_is_running=0 + ret=$? + test "$xorriso_is_running" = 0 && ret=2 + return "$ret" +} + + +# ------------- End of interpreter for quoted xorriso replies -------------- + + +# Send one or more command lines to xorriso +xorriso_send_cmd() { + # $1 : the lines to send + + # >>> is it possible to have a timeout on echo ? + + if test -p "$cmd_pipe" + then + echo -E "$1" >"$cmd_pipe" + else + xorriso_is_running=0 + return 1 + fi +} + + +# Make filenames safe for transport by wrapping them in quotes and +# escaping quotes in their text +xorriso_esc() { + echo -n "'" + echo -n "$1" | sed -e "s/'/'"'"'"'"'"'"'/g" + echo -n "'" +} + + +# A handler function for xorriso_cmd_and_handle_result +xorriso_reply_to_stdout() { + echo "${reply_array[*]}" +} + + +# Let a handler inspect the result lines of a xorriso command line +xorriso_cmd_and_handle_result() { + # $1: handler command word and possibly argument words + # $2: command line for xorriso + + if test "$xorriso_is_running" = 0 + then + return 1 + fi + + handler="$1" + xorriso_send_cmd "$2" || return 1 + res=$(cat "$result_pipe") + ret=$? + if test "$xorriso_will_end" = 1 -o "$xorriso_is_running" = 0 -o "$ret" -ne 0 + then + test -n "$res" && echo -n "$res" + xorriso_is_running=0 + test "$ret" = 0 || return 1 + return 0 + fi + test -z "$res" && return 0 + echo "$res" | \ + while read line + do + line_count=1 + while true + do + xorriso_parse "$line" "$line_count" + ret=$? + test "$ret" = 0 && break + if test "$ret" = 2 + then + return 1 + fi + read addon + line="$line"$'\n'"$addon" + line_count=$(expr "$line_count" + 1) + done + # One can now make use of reply_array[0...(reply_count-1)] + $handler + done + return 0 +} + + +# Execute -version and let xorriso_version_handler interpret reply +xorriso_check_version() { + lookfor='^xorriso version : ' + xorriso_version=$("$xorriso" -version 2>/dev/null | grep "$lookfor" | \ + sed -e "s/${lookfor}//") + ret=$? + if test "$ret" -ne 0 -o "$xorriso_version" = "" + then + echo "SORRY: Program run '${xorriso}' -version did not yield a result." >&2 + echo >&2 + exit 2 + fi + smallest=$((echo "$xorriso_version_req" ; echo "$xorriso_version" ) | \ + sort | head -1) + test "$smallest" = "$xorriso_version_req" && return 0 + echo "SORRY: xorriso version too old: ${xorriso_version} . Need at least xorriso-${xorriso_version_req} ." >&2 + echo >&2 + exit 2 +} + + +# To be executed on exit +xorriso_cleanup() { + + send_end_cmd=0 + if test -p "$cmd_pipe" -a "$xorriso_is_running" = 1 + then + if test "$normal_end" = 0 + then + echo "Checking whether xorriso is still running ..." >&2 + set -x + # Give xorriso time to abort + sleep 1 + if ps | grep '^'"$xorriso_pid" >/dev/null + then + + # >>> try to further confirm xorriso identity + + send_end_cmd=1 + fi + else + send_end_cmd=1 + fi + fi + test "$normal_end" = 0 && set -x + if test "$send_end_cmd" = 1 + then + echo "Sending xorriso an -end command ..." >&2 + xorriso_send_cmd "end" && \ + test -p "$result_pipe" && cat "$result_pipe" >/dev/null + fi + test -p "$cmd_pipe" && rm "$cmd_pipe" + test -p "$result_pipe" && rm "$result_pipe" +} + + +# ---------------------------------- main --------------------------------- + +# Choose pipe names +export cmd_pipe=/tmp/xorriso_stdin_pipe_$$ +export result_pipe=/tmp/xorriso_stdout_pipe_$$ + +# Check the program whether it is modern enough +xorriso_check_version "$xorriso" + +# Prepare for then end of this script +trap xorriso_cleanup EXIT + +# Create the pipes and start xorriso +mknod "$cmd_pipe" p +mknod "$result_pipe" p +"$xorriso" -abort_on NEVER -for_backup \ + -named_pipe_loop cleanup:buffered "$cmd_pipe" "$result_pipe" "-" & +xorriso_pid=$! +xorriso_is_running=1 + +# Get a sign of life from xorriso before issuing the loop prompt +xorriso_cmd_and_handle_result xorriso_reply_to_stdout \ + "print_info 'xorriso process ${xorriso_pid} started by $0'" +echo >&2 + + +# Now get commands from the user, send them to xorriso and display them +# via the simple handler xorriso_reply_to_stdout() +while test "$xorriso_is_running" = 1 +do + if test -p "$cmd_pipe" + then + echo -n "xorriso> " >&2 + else + echo "$0 : Lost contact to xorriso process $xorriso_pid" >&2 + xorriso_is_running=0 + break + fi + read line + if echo "$line" | grep '^-*end$' >/dev/null + then + break + fi + if echo "$line" | grep '^-*rollback_end$' >/dev/null + then + xorriso_will_end=1 + fi + xorriso_cmd_and_handle_result xorriso_reply_to_stdout "$line" +done + +# Prevent set -x in the exit handler +normal_end=1 + diff --git a/libisoburn/branches/1.4.6/frontend/xorriso-tcltk b/libisoburn/branches/1.4.6/frontend/xorriso-tcltk new file mode 100755 index 00000000..0412e655 --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/xorriso-tcltk @@ -0,0 +1,5929 @@ +#!/usr/bin/wish +# +# xorriso-tcltk +# Copyright (C) 2012 - 2016 +# Thomas Schmitt , libburnia project. +# Provided under BSD license: Use, modify, and distribute as you like. +# +# This is mainly a proof of concept for xorriso serving under a frontend. +# It exercises several fundamental gestures of communication: +# - connecting via two named pipes +# - sending commands +# - receiving replies +# - inquiring the xorriso message sieve +# - using the xorriso parsing service + +# Note that any other language than Tcl/Tk could be used, if it only can +# do i/o via standard input and standard output or via named pipes. +# Further it has to perform integer arithmetics and string manipulations. +# And, well, a graphical widget set would be nice. + + +set own_version "1.4.5" + +# Minimum version of xorriso to be used as backend process. +# Older versions of xorriso do not offer commands -msg_op and -launch_frontend +set min_xorriso_version "1.2.6" + + +proc print_usage {argv0} { + puts stderr "Usage:" + puts stderr " $argv0 \[options\]" + puts stderr "Options:" + puts stderr " All options must be given with two dashes (\"--option\") in" + puts stderr " order to distinguish them from any options of the Tcl shell." + puts stderr " --help" + puts stderr " Print this text and exit." + puts stderr " --stdio" + puts stderr " Establish connection to xorriso via stdin and stdout." + puts stderr " E.g. when letting xorriso start this frontend program:" + puts stderr " xorriso -launch_frontend \$(which xorriso-tcltk) --stdio --" + puts stderr " --named_pipes cmd_fifo reply_fifo" + puts stderr " Establish connection to a xorriso process started by:" + puts stderr " xorriso -dialog on reply_fifo" + puts stderr " which is then ready for a run of:" + puts stderr " xorriso-tcltk --named_pipes cmd_fifo reply_fifo" + puts stderr " It is important that the parent of xorriso and of this" + puts stderr " tcl/tk frontend opens the named pipe for commands before" + puts stderr " it opens the named pipe for replies. This avoids deadlock." + puts stderr " --silent_start" + puts stderr " Do not issue the start message xorriso-tcltk-version." + puts stderr " This works only if --silent_start is the first argument." + puts stderr " --no_extract" + puts stderr " Do not allow extraction of files from ISO filesystem to" + puts stderr " hard disk. This is not revokable during the program run." + puts stderr " --no_bwidget" + puts stderr " Do not try to load the Tcl/Tk package BWidget which is" + puts stderr " a prerequisite for the \"/\" file browser buttons." + puts stderr " --geometry {+|-}X{+|-}Y" + puts stderr " Sets the position of the main window." + puts stderr " --click_to_focus" + puts stderr " Chooses that input fields and list boxes get the keyboard" + puts stderr " focus only when being clicked by the mouse. (Default)" + puts stderr " --auto_focus" + puts stderr " Chooses that the keyboard focus is where the mouse" + puts stderr " pointer is." + puts stderr " --pipe_log_file path" + puts stderr " Set a file address for logging of xorriso commands and" + puts stderr " reply messages and enable this logging." + puts stderr " The log lines will be appended. Path \"-\" means stderr." + puts stderr " --script_log_file path" + puts stderr " Set a file address for logging of essential xorriso" + puts stderr " commands and enable this logging." + puts stderr " The log lines will be appended. Path \"-\" means stderr." + puts stderr " --script_log_all_commands" + puts stderr " With logging of commands log non-essential commands too." + puts stderr " --use_command_move" + puts stderr " Use xorriso command -move for the \"Move to:\" button" + puts stderr " if xorriso version is >= 1.2.8" + puts stderr " --use_command_mv" + puts stderr " Use xorriso command -mv for the \"Move to:\" button." + puts stderr "" + puts stderr "If neither --stdio nor --named_pipes is given, then this script" + puts stderr "will try to locate itself in the filesystem and start a xorriso" + puts stderr "run that launches it again." + puts stderr "" + puts stderr "In the running GUI, click with the rightmost mouse button on" + puts stderr "any GUI element to get its particular help text." + puts stderr "" +} + + +# ------------------------------- the frontend ---------------------------- +# +# Connects to a xorriso process, sends commands, receives replies, +# prepares replies for GUI + +# Connection to xorriso +set cmd_conn "" +set reply_conn "" + +# The addresses of the named pipes, if such are used (see option -named_pipe) +set cmd_pipe_adr "" +set reply_pipe_adr "" + +# The command to send (or the command most recently sent) +set cmdline "" +# Wether to clear the cmdline after sending +set cmdline_clear true +# Command counter +set cmd_sent 0 +# Current -mark synchronization text +set mark_count 0 + +# Results of most recent await_all_replies +set info_list "" +set info_count 0 +set emerging_info "" +set result_list "" +set result_count 0 +set emerging_result "" + +# Highest severities encountered in total and with most recent command +set highest_total_sev ALL +set highest_total_sev_msg "" +set highest_cmd_sev ALL +set highest_cmd_sev_msg "" +# This one registers like highest_cmd_sev with threshold ALL +set highest_seen_cmd_sev ALL + +# State of last read_sieve command +set sieve_ret 0 + +# How many texts to pass with one parse_bulk command +set bulk_parse_max_chunk 200 +# Parse parameters +set bulk_parse_prefix "" +set bulk_parse_separators "" +set bulk_parse_max_words "" +set bulk_parse_flag "" +# The announced number of texts to parse +set bulk_parse_num_texts "" + +# Whether to complain on stderr about broken pipes. +# This may be expected when xorriso is being shut down by this frontend. +set expect_broken_pipes "0" + +# Whether to use command -move rather than -mv. Possible since xorriso-1.2.8. +set use_command_move 1 + +# Whether to enable -hardlinks mode "on". Too slow before xorriso-1.3.0. +set use_command_hardlinks_on 1 + + +# Local copies of xorriso state + +# Addresses of drives (or image files) as shown by their text fields in the GUI +set outdev_adr "" +set indev_adr "" + +# Addresses of drives (or image files) as set in xorriso (after inquire_dev) +set eff_outdev_adr "" +set eff_indev_adr "" + +# Whether the medium is blank, appendable, closed, missing +set indev_medium_status "missing" +set outdev_medium_status "missing" + +# What kind of medium is presented by the drive +set indev_profile "" +set outdev_profile "" + +# List of known drive addresses +set devlist "" + +# Intermediate storage for messages until the GUI is up with .msglist box +set pre_msglist "" + +# Whether overwriting of files in the ISO model is allowed +set overwrite_iso_files 1 + +# If overwrite_iso_files is 1: Wether overwriting of ISO directories is allowed +set overwrite_iso_dirs 0 + +# Whether overwriting of files on disk is allowed +set overwrite_disk_files 0 + +# The file where to log commands and replies for debugging purposes +set debug_log_file "" +set debug_log_conn stderr + +# Whether to log all commands and replies to the debug_log_file +set debug_logging 0 + +# The result of the most recent isofs_ls run +set isofs_ls_result "" + +# The result of the most recent localfs_ls run +set localfs_ls_result "" + +# The communication channel where to log files (if it is not the empty text) +set cmd_log_conn "" + +# The address under which cmd_log_conn was opened +set cmd_log_target "" + +# Whether to log essential commands: 0=off , 1=no extract , 2=with extract +set cmd_logging_mode 0 + +# Whether to log all commands if cmd_logging_mode is 1: 0=off , 1=on +set cmd_logging_all 0 + +# The last logged -cd path. Used to prevent redundant logging of -cd. +set recent_cd_path "" + +# The file address and the channel for xorriso command script execution +set execute_script_adr "" +set execute_script_conn "" + +# Whether extraction to disk shall be allowed in scripts +set script_with_osirrox 0 + +# Whether extraction to disk is allowed +set osirrox_allowed 1 + + +# xorriso specific constants + +# List of severities (gets later overridden by -msg_op list_sev -) +set xorriso_severity_list { + ALL DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER +} +set scan_event_threshold HINT + + +# --------- Communication between frontend and xorriso ---------- + + +# Open the connection to a pair of named pipes. Program option -named_pipes +# +proc init_frontend_named_pipes {cmd_pipe reply_pipe} { + global cmd_conn + global reply_conn + + set cmd_conn [open $cmd_pipe w] + set reply_conn [open $reply_pipe r] + + # Note: disencouraged flags would be necessary for opening idle fifo + # set reply_conn [open $reply_pipe {RDONLY NONBLOCK}] + +} + + +# Send a command line to the xorriso process. Do not wait for reply. +# +proc send_async_cmd {cmd} { + global cmd_sent cmd_conn debug_logging debug_log_conn + + display_busy 1 + log_command $cmd 0 + + debug_log_puts \ + " ==============================================================" + debug_log_puts " $cmd" + display_msg "======> $cmd" + incr cmd_sent + puts $cmd_conn $cmd + flush $cmd_conn +} + + +# Send a command line and a -mark command to xorriso. Wait until the +# mark message confirms that all command output has been received. +# +proc send_marked_cmd {cmd} { + global cmd_conn mark_count + + send_async_cmd $cmd + incr mark_count + set mark_cmd "-mark $mark_count" + debug_log_puts " $mark_cmd" + puts $cmd_conn $mark_cmd + flush $cmd_conn + await_all_replies +} + + +# Send a command and make it a candidate for the log script +# +proc send_loggable_cmd {cmd} { + log_command $cmd 1 + send_marked_cmd $cmd +} + + +# Send a command that shall not be displayed in the message log +# +proc send_silent_cmd {cmd} { + set disp_en_mem [set_display_msg 0] + send_marked_cmd $cmd + set_display_msg $disp_en_mem +} + + +# Wait for the currently pending mark message to arrive. +# Buffer all received result lines and info messages. +# +proc await_all_replies {} { + global reply_conn mark_count result_count result_list + global info_count info_list expect_broken_pipes + global .busy_text + + clear_reply_lists + + while {1} { + set ret [gets $reply_conn line] + if {$ret < 0} { + if {$expect_broken_pipes != 1} { + puts stderr "EOF at reply pipe" + } + break + } + debug_log_puts $line + if {[string range $line 0 0] == "M"} { + if {[string range $line 5 end] == $mark_count} { + break + } else { + # outdated mark message + continue + } + } + + de_pkt_line $line + } + + display_busy 0 +} + + +# Decode -pkt_output format to complete lines and buffer them. +# +proc de_pkt_line {line} { + global info_list + global info_count + global emerging_info + global result_list + global result_count + global emerging_result + + # Distinguish R and I + set ch [string range $line 0 0] + + set payload [string range $line 5 end] + if {$ch == "R"} { + set emerging_result "$emerging_result$payload" + } else { if {$ch == "I"} { + set emerging_info "$emerging_info$payload" + } else { + return "" + }} + + # if line end : add to list + if {[string range $line 2 2] == "1"} { + if {$ch == "R"} { + lappend result_list $emerging_result + incr result_count + display_msg $emerging_result + set emerging_result "" + } else { + lappend info_list $emerging_info + incr info_count + display_msg $emerging_info + scan_info_for_event $emerging_info + set emerging_info "" + } + } +} + + +# Search in the decoded info messages for the most severe event reports. +# +proc scan_info_for_event {line} { + global highest_total_sev highest_total_sev_msg + global highest_cmd_sev highest_cmd_sev_msg highest_seen_cmd_sev + global scan_event_threshold + global display_msg_enabled + + # check for word : CAPS : text ... + set ret [regexp {[a-z][a-z]*[ ]*: [A-Z][A-Z]* :} $line] + + if {$ret != 1} {return ""} + + # retrieve severity + set pos [string first ":" $line] + set sev [string range $line [expr $pos+2] end] + set pos [string first ":" $sev] + set sev [string range $sev 0 [expr $pos-2]]; + + if {[compare_sev $sev $highest_seen_cmd_sev] > 0} { + set highest_seen_cmd_sev $sev + } + + if {[compare_sev $sev $scan_event_threshold] < 0} {return ""} + + if {$display_msg_enabled == 0} { + set display_msg_enabled 1 + display_msg $line + set display_msg_enabled 0 + } + if {[compare_sev $sev $highest_total_sev] >= 0} { + set highest_total_sev $sev + set highest_total_sev_msg [escape_newline $line 0] + } + if {[compare_sev $sev $highest_cmd_sev] >= 0} { + set highest_cmd_sev $sev + set highest_cmd_sev_msg [escape_newline $line 0] + } +} + + +# Unpack the output format of -msg_op read_sieve into a result_list +# of strings which each hold one parsed word. +# +proc de_sieve {} { + global result_list + global sieve_ret + + set sieve_ret [lindex $result_list 0] + set sieve_result_count [lindex $result_list 1] + + set payload "" + set sieve_result_count 0 + for {set i 2} {$i < [llength $result_list]} {incr i} { + set line "" + set num_lines [lindex $result_list $i] + for {set j 0} {$j < $num_lines} {incr j} { + incr i + set line "$line[lindex $result_list $i]" + if {$j < $num_lines - 1} { + set line "$line\n" + } else { + lappend payload $line + incr sieve_result_count + } + } + } + set result_list $payload + set result_count $sieve_result_count +} + + +# Alternative to proc await_all_replies. It waits for a line at one of the +# three channels and displays all lines which it receives before that line. +# Used before this frontend had the opportunity to set up xorriso by commands +# like -pkt_output "on". +# +proc wait_for_msg {prefix channel} { + global reply_conn + + if {$channel == "M"} { + set channel_prefix "M:0: " + } else { + set channel_prefix "$channel:1: " + } + + set prefix_l [string length $prefix] + while {1} { + + # >>> Have a timeout + + set ret [gets $reply_conn line] + if {$ret < 0} { + break + } + debug_log_puts $line + if {[string length $line] < $prefix_l} { + display_msg $line + continue + } + if {[string range $line 0 [expr $prefix_l-1]] == $prefix} { + return [string range $line $prefix_l end] + } + if {[string length $line] >= [expr $prefix_l+5]} { + if {[string range $line 0 4] == $channel_prefix} { + if {[string range $line 5 [expr $prefix_l+4]] == $prefix} { + return [string range $line [expr $prefix_l+5] end] + } + } + } + display_msg $line + } +} + + +# Reset the buffer for result lines and info messages. +# +proc clear_reply_lists {} { + global info_list + global info_count + global emerging_info + global result_list + global result_count + global emerging_result + + set info_list "" + set info_count 0 + set emerging_info "" + set result_list "" + set result_count 0 + set emerging_result "" +} + + +# Reset the register of the most severe event for command sequences. +# Typically this is done before executing the commands of a procedure +# that is triggered by the user interface. +# +proc reset_highest_cmd_sev {} { + global highest_cmd_sev highest_cmd_sev_msg highest_seen_cmd_sev + + set highest_cmd_sev ALL + set highest_cmd_sev_msg "" + set highest_seen_cmd_sev ALL +} + + +# Clear the recordings of the xorriso message sieve. +# +proc clear_sieve {} { + send_silent_cmd "-msg_op clear_sieve -" +} + + +# Obtain a recorded item from the xorriso message sieve. +# +proc read_sieve {name} { + send_silent_cmd "-msg_op read_sieve '$name'" + de_sieve +} + + +# ------- Inquiring xorriso status ------- + + +# Get more information about drive that was inquired by recent -toc_of. +# +proc obtain_drive_info {dev} { + global result_list + global sieve_ret + global indev_medium_status outdev_medium_status + global indev_profile outdev_profile + + set line "" + + if {$dev == "in"} { + set indev_medium_status "missing" + set indev_profile "" + } else { + set outdev_medium_status "missing" + set outdev_profile "" + } + read_sieve "Media status :" + if {$sieve_ret > 0} { + set reply [lindex $result_list 0] + foreach i {blank appendable closed} { + if {[string first $i $reply] != -1} { + set line "$i " + if {$dev == "in"} { + set indev_medium_status $i + } else { + set outdev_medium_status $i + } + break + } + } + } + read_sieve "Media current:" + if {$sieve_ret > 0} { + set profile [lindex $result_list 0] + if {$profile == "is not recognizable"} { + set profile "no recognizable medium" + set line "$line$profile" + return $line + } else { + set line "$line$profile, " + if {$dev == "in"} { + set indev_profile $profile + } else { + set outdev_profile $profile + } + } + } + read_sieve "Media summary:" + if {$sieve_ret > 0} { + set line "$line[lindex $result_list 0] sessions, " + if {$dev == "in"} { + set line "$line[lindex $result_list 2] used" + } else { + set line "$line[lindex $result_list 3] free" + } + } + return $line +} + + +# Inquire whether changes of the ISO image are pending. +# This is a precondition for writing the session. Vice versa pending changes +# block a change of the input drive or the program end. +# +proc changes_are_pending {} { + global result_count result_list + + send_silent_cmd "-changes_pending show_status" + if {$result_count >= 1} { + if {[lindex $result_list 0] == "-changes_pending no"} { + return "0" + } + return "1" + } + return "" +} + + +# Inquire whether an ISO image model has been created inside xorriso. +# This is a precondition for inserting files into the ISO tree model. +# +proc assert_iso_image {with_msg} { + global highest_seen_cmd_sev scan_event_threshold + + set highest_seen_cmd_sev "" + set set_mem $scan_event_threshold + set scan_event_threshold "FATAL" + send_silent_cmd "-lsd / --" + set scan_event_threshold $set_mem + if {[compare_sev $highest_seen_cmd_sev "FAILURE"] >= 0} { + if {$with_msg == 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : First you need to create or load an ISO image by selecting a drive or an image file" + } + return "0" + } + return "1" +} + + +# Obtain the list of possible event severity names, sorted in ascending order +# +proc inquire_severity_list {} { + global xorriso_severity_list + global result_list + + set disp_en_mem [set_display_msg 0] + send_marked_cmd "-msg_op list_sev -" + set_display_msg $disp_en_mem + if {[lindex $result_list 0] != ""} { + set xorriso_severity_list [split [lindex $result_list 0] " "] + } +} + + +# Parse-by-xorriso handler function for proc inquire_dev +# +proc set_inquired_dev {} { + global result_list eff_indev_adr eff_outdev_adr + + if {[llength $result_list] < 2} {return ""} + set what [lindex $result_list 0] + if {$what == "-dev" || $what == "-indev"} { + set eff_indev_adr [lindex $result_list 1] + } + if {$what == "-dev" || $what == "-outdev"} { + set eff_outdev_adr [lindex $result_list 1] + } +} + + +# Inquire -indev and -outdev from xorriso and install in eff_indev_adr +# and eff_outdev_adr. +# (This could be done by -toc_of like in proc refresh_indev. But here +# i demonstrate the use of command -status and parsing its result by +# help of xorriso.) +# +proc inquire_dev {} { + set disp_en_mem [set_display_msg 0] + send_marked_cmd "-status -dev" + handle_result_list set_inquired_dev "''" "''" 2 0 + set_display_msg $disp_en_mem + update idletasks + return "" +} + + +# Inquire -indev and -outdev from xorriso and install in indev_adr +# and outdev_adr. +# +proc update_dev_var {} { + global result_list eff_indev_adr eff_outdev_adr indev_adr outdev_adr + + inquire_dev + set indev_adr $eff_indev_adr + set outdev_adr $eff_outdev_adr +} + + +# Parse-by-xorriso handler function for proc isofs_ls +# +proc isofs_ls_handler {} { + global result_list isofs_ls_result + + if {[lindex $result_list 0] == "total"} {return ""} + lappend isofs_ls_result \ + "[string range [lindex $result_list 0] 0 0] [lindex $result_list 8]" +} + + +# Produce a list of all files in a directory of the ISO model +# +proc isofs_ls {dir} { + global isofs_ls_result + + set isofs_ls_result "" + set disp_en_mem [set_display_msg 0] + send_marked_cmd "-lsl [make_text_shellsafe $dir]" + handle_result_list isofs_ls_handler "''" "''" 0 0 + set_display_msg $disp_en_mem + return $isofs_ls_result +} + + +# Tells the file type of an absolute path in the ISO model. +# Indicator characters like with ls -l. Empty text means non existing file. +# +proc isofs_filetype {path} { + global result_list result_count scan_event_threshold + + set scan_event_mem $scan_event_threshold + set scan_event_threshold "SORRY" + send_silent_cmd "-lsdl [make_text_shellsafe $path]" + set scan_event_threshold $scan_event_mem + if {$result_count < 1} {return ""} + return [string range [lindex $result_list 0] 0 0] +} + + +# Inspection of hard disk is done via xorriso. +# The xorriso commands have the advantage to be always available and to +# need no unescaping. On the other hand, shell and tcl lstat would be +# faster with large directories. + +# Parse-by-xorriso handler function for proc localfs_ls +# +proc localfs_ls_handler {} { + global result_list localfs_ls_result + + if {[lindex $result_list 0] == "total"} {return ""} + lappend localfs_ls_result \ + "[string range [lindex $result_list 0] 0 0] [lindex $result_list 8]" +} + + +# Return the list of files of a hard disk filesystem directory +# +proc localfs_ls {dir} { + global localfs_ls_result + + set localfs_ls_result "" + if {[localfs_filetype $dir] != "d"} {return ""} + + set disp_en_mem [set_display_msg 0] + send_marked_cmd "-lslx [make_text_shellsafe $dir]" + handle_result_list localfs_ls_handler "''" "''" 0 0 + set_display_msg $disp_en_mem + return $localfs_ls_result +} + + +# Tells the file type of an absolute path in the ISO model. +# Indicator characters like with ls -l. Empty text means non existing file. +# +proc localfs_filetype {path} { + global result_list result_count scan_event_threshold + + set scan_event_mem $scan_event_threshold + set scan_event_threshold "SORRY" + send_silent_cmd "-lsdlx [make_text_shellsafe $path]" + set scan_event_threshold $scan_event_mem + if {[llength $result_list] < 1} {return ""} + return [string range [lindex $result_list 0] 0 0] +} + + +# Verify that the connected process runs a xorriso program that is modern +# enough. This is done before sending xorriso the setup commands. +# +proc check_xorriso_version {} { + global sieve_ret result_list pre_msglist xorriso_version min_xorriso_version + global use_command_move use_command_hardlinks_on + global reply_conn + + set version "0.0.0 (= unknown)" + + set disp_en_mem [set_display_msg 0] + + # In order to see the pre-frontend messages of xorriso + # set an individual -mark and use send_async_cmd + + set mark_text "xorriso-tcltk-version-check-[clock seconds]" + send_async_cmd "-mark [make_text_shellsafe $mark_text]" + set_display_msg $disp_en_mem + wait_for_msg $mark_text "M" + + set_display_msg 0 + send_async_cmd "-version" + + set xorriso_version [wait_for_msg "xorriso version : " "R"] + + if {$xorriso_version < $min_xorriso_version} { + puts stderr "xorriso-tcltk: xorriso-$xorriso_version is too old." + puts stderr "xorriso-tcltk: Need at least version $min_xorriso_version" + window_ack \ + "xorriso-$xorriso_version is too old. Need at least version $min_xorriso_version" \ + "red" "embedded" + central_exit 2 + } + if {$xorriso_version < "1.2.8"} { + set use_command_move 0 + } + if {$xorriso_version < "1.3.0"} { + set use_command_hardlinks_on 0 + } + set_display_msg $disp_en_mem +} + + +# Commands which bring the connected xorriso process into the state that +# is expected by this frontend. +# +proc setup_xorriso {} { + global osirrox_allowed + + set cmd "" + + # Invalidate possible -mark 1 + set cmd "$cmd -mark 0" + + # Make replies digestible for await_all_replies + set cmd "$cmd -pkt_output on" + + # Report version early + set cmd "$cmd -version" + + # This frontend relies heavily on the message sieve + set cmd "$cmd -msg_op start_sieve -" + + # -reassure questions from xorriso would not be properly handled by + # this frontend + set cmd "$cmd -reassure off" + + set cmd "$cmd -abort_on NEVER" + set cmd "$cmd -return_with ABORT 32" + set cmd "$cmd -report_about UPDATE" + set cmd "$cmd -iso_rr_pattern off" + set cmd "$cmd -disk_pattern off" + + if {$osirrox_allowed == 0} { + set cmd "$cmd -osirrox banned" + } + + set cmd "$cmd [xorriso_loggable_init_cmds]" + + send_marked_cmd $cmd + inquire_severity_list +} + + +# Commands which should also be at the start of a log script +# +proc xorriso_loggable_init_cmds {} { + global use_command_hardlinks_on + + set cmd "-for_backup" + + # Before xorriso-1.3.0 there is a performance problem with -hardlinks "on" + # and image manipulations before xorriso-1.3.0. + if {$use_command_hardlinks_on == 0} { + set cmd "$cmd -hardlinks off" + } else { + set cmd "$cmd -hardlinks on" + } + + set cmd "$cmd -backslash_codes on" + set cmd "$cmd -follow mount:limit=100" + return $cmd +} + + +proc effectuate_permission_policy {} { + global permission_policy + + if {$permission_policy == "readable"} { + send_loggable_cmd \ + "-find / -exec chmod a+r -- -find / -type d -exec chmod a+x --" + } + if {$permission_policy == "readonly"} { + send_loggable_cmd \ + "-find / -exec chmod a=r -- -find / -type d -exec chmod a+x --" + } + if {$permission_policy == "mkisofs_r"} { + send_loggable_cmd \ + "-find / -exec mkisofs_r" + } +} + + +# ------ Parsing by help of xorriso ------ + +# Parsing by xorriso takes from the frontend the burden to understand +# and implement the quoting rules of xorriso input and output. +# Lines which are supposed to consist of several words get sent to +# xorriso command -msg_op. The result lines of this command encode +# the words unambigously in one or more text lines. +# This is supposed to be safe for even the weirdest file names. +# Only NUL characters cannot be part of names. + + +# Start a bulk parser job by which xorriso shall split the output of e.g. -lsl +# into single words from which this frontend can pick information. +# +proc start_bulkparse {prefix separators max_words flag num_lines} { + global bulk_parse_prefix bulk_parse_separators + global bulk_parse_max_words bulk_parse_flag bulk_parse_num_texts + + if {$num_lines <= 0} {return ""} + + set bulk_parse_prefix $prefix + set bulk_parse_separators $separators + set bulk_parse_max_words $max_words + set bulk_parse_flag $flag + set bulk_parse_num_texts $num_lines + set cmd "-msg_op parse_bulk \"$prefix $separators $max_words $flag $num_lines\"" + send_async_cmd $cmd + # Do not wait for mark +} + + +# Submit a new input line to the xorriso bulk parser job. +# +proc submit_bulkparse {text} { + global cmd_conn reply_conn + global result_list result_count + global bulk_parse_prefix bulk_parse_separators + global bulk_parse_max_words bulk_parse_flag + + set disp_en_mem [set_display_msg 0] + + set num_lines [expr [count_newlines $text] + 1] + + debug_log_puts ">>>>> $num_lines" + puts $cmd_conn $num_lines + debug_log_puts ">>>>> $text" + puts $cmd_conn $text + flush $cmd_conn + set_display_msg $disp_en_mem +} + + +# Read the expected number of bulk parsing replies into the result buffer +# and call handler_proc to inspect them. +# Each input line of the parser yields one reply buffer full of parsed words. +# +proc read_bulkparse {handler_proc num_texts} { + set disp_en_mem [set_display_msg 0] + for {set i 0} {$i < $num_texts} {incr i} { + clear_reply_lists + read_parse_reply + $handler_proc + } + set_display_msg $disp_en_mem +} + + +# Read and decode the xorriso parser reply for one input line. +# +proc read_parse_reply {} { + global reply_conn + global result_list result_count + + set sieve_result_count 0 + set payload "" + set num_lines 0 + set acc "" + set loop_limit 2 + while {$result_count < $loop_limit} { + set ret [gets $reply_conn line] + if {$ret < 0} { return ""} + debug_log_puts $line + de_pkt_line $line + set line [lindex $result_list [expr $result_count-1]] + if {$result_count == 1} { + set parse_ret $line + } else { if {$result_count == 2} { + set num_replies $line + # The minimum number of lines + set loop_limit [expr "$num_replies * 2 + 2"] + } else { + if {$num_lines <= 0} { + set num_lines $line + if {$num_lines > 1} { + # Need to read extra lines + incr loop_limit [expr $num_lines-1] + } + set acc "" + } else { + incr num_lines -1 + if {$acc != ""} { + set acc "$acc\n$line" + } else { + set acc $line + } + if {$num_lines <= 0} { + lappend payload $acc + incr sieve_result_count + } + } + }} + } + set result_list $payload + set result_count $sieve_result_count +} + + +# Let xorriso parse the lines in the result buffer and call handler_proc +# with the parse result of each line. +# This is used to split the result lines of -lsl into words from which +# handler proc isolist_parse_handler picks the info which it displays +# in .stbox isolist . +# Note that all parameters must be xorriso words. E.g. empty prefix or +# separator have to be submitted as tcl string "''" rather than "". +# +proc handle_result_list {handler_proc \ + prefix separators max_words flag } { + global result_list + global bulk_parse_max_chunk + + set raw_list $result_list + set raw_line_count [expr [llength $raw_list]] + if {$raw_line_count > $bulk_parse_max_chunk} { + set chunk_size $bulk_parse_max_chunk + } else { + set chunk_size $raw_line_count + } + start_bulkparse $prefix $separators $max_words $flag $chunk_size + set submit_count 0 + set submit_in_chunk_count 0 + foreach i $raw_list { + submit_bulkparse $i + incr submit_count + incr submit_in_chunk_count + if {$submit_in_chunk_count == $chunk_size} { + read_bulkparse $handler_proc $chunk_size + set todo [expr "$raw_line_count - $submit_count"] + if {$todo <= 0} { + break + } + if {$todo > $bulk_parse_max_chunk} { + set chunk_size $bulk_parse_max_chunk + } else { + set chunk_size $todo + } + start_bulkparse $prefix $separators $max_words $flag \ + $chunk_size + set submit_in_chunk_count 0 + } + } + display_busy 0 +} + + +# ------------------------------- the GUI ---------------------------- + +# ------ State variables ------ + +# Whether to display messages in .msglist +set display_msg_enabled 1 + +# Whether a device list is already displayed +set devices_scanned 0 + +# Currently displayed ISO directory +set isodir_adr "" +set isodir_is_pwd 0 + +# The plain names and types matching listbox .isolist +set isolist_names "" +set isolist_types "" + +# The name which to select after isodir_return +set isodir_return_name "" + +# The address where to move selected ISO files +set isomanip_move_target "" + +# Memorized isolist selection +set memorized_isolist_selection "" + +# Image file address for .burn_write_image +set burn_write_image_adr "" + +# Whether to close medium after writing +set burn_write_close 0 + +# Whether to force CD TAO, DVD-R Inremental, DVD+R/BD-R open ended track +set burn_write_tao 0 + +# Whether to engage Defect Management on formatted BD media +set burn_write_defect_mgt 0 + +# Answer of yes/no window +set answer_of_yesno "" + +# Semi-persistent answers of yes/no window +set yesno_to_all 0 + +# The hard disk filesystem address to be mapped into isodir_adr +set insert_from_adr "" + +# Whether to insert with leafname of insert_from_adr underneath isodir_adr +# (else: -map $insert_from_adr $isodir_adr) +set insert_underneath 1 + +# Whether to insert at or under the selected .isolist item +# rather than isodir_adr +set insert_at_selected 0 + +# The hard disk filesystem address to which to extract from isodir_adr +set extract_to_adr "" + +# Whether to insert with leafname of insert_from_adr underneath isodir_adr +# (else: -map $insert_from_adr $isodir_adr) +set extract_underneath 1 + +# Whether to insert at or under the selected .isolist item +set extract_from_selected 1 + +# Whether to temporarily enforce rwx permissions for target directories on disk +set extract_auto_chmod 0 + +# Whether the display label .busy_text is already usable +set busy_text_exists 0 + +# Whether to demand a click before focus goes to entry or listbox +set click_to_focus 1 + +# Whether .ack_window , .yesno_window , .help_window, .main_help_window +# are already displayed. +set ack_window_is_active 0 +set yesno_window_is_active 0 +set help_window_is_active 0 +set main_help_window_is_active 0 + +# Positions of above windows when they were last closed +set yesno_window_geometry "" +set ack_window_geometry "" +set help_window_geometry "" +set main_help_window_geometry "" + +# Whether the help window already has a scroll bar +set help_window_has_scroll 0 + +# Whether there is the BWidget package available: 0=unknown, 1=yes, -1=banned +# +set have_bwidget 0 +set bwidget_version "" + +# Whether the .browse_disk_window is already displayed +set browse_disk_window_is_active 0 +set browse_disk_window_var "" +# Position of window when it was last closed +set browse_disk_window_geometry "" +# Whether the window is grabbed +set browse_disk_window_is_grabbed 0 + +# Whether the .browse_iso_window is already displayed +set browse_iso_window_is_active 0 +set browse_iso_window_var "" +# Position of window when it was last closed +set browse_iso_window_geometry "" +# Whether the window is grabbed +set browse_iso_window_is_grabbed 0 + +# Whether to modify the ISO file permissions before writing the ISO session +# Policies: as_is , readable , readonly , mkisofs_r +set permission_policy "as_is" + + +# ------ GUI callback procedures ---- + + +# Called when the Return key is hit in commandline. +# +proc cmdline_return {} { + global cmdline cmdline_clear + global .cmdline .cmdline_text .cmdline_entry + global highest_cmd_sev + global highest_cmd_sev_msg + + reset_highest_cmd_sev + set_display_msg 1 + send_loggable_cmd $cmdline + set cmdline "" + + # To force display of GUI changes now and not some time later + update idletasks +} + + +# Called when the input drive address shall be brought into effect with +# xorriso. +# +proc indev_return {} { + global indev_adr + global .indev_entry + global .outdev_entry + + if {[assert_no_changes] == 0} { + update_dev_var + return "0" + } + reset_highest_cmd_sev + send_loggable_cmd "-indev [make_text_shellsafe $indev_adr]" + set indev_mem_adr $indev_adr + .indev_entry icursor 0 + refresh_indev + return "1" +} + + +# Called when the "Eject" button for the input drive is hit. +# +proc eject_indev {} { + if {[assert_no_changes] == 0} {return ""} + reset_highest_cmd_sev + send_loggable_cmd "-eject indev" + refresh_outdev + refresh_indev +} + + +# Called when the output drive address shall be brought into effect with +# xorriso. +# +proc outdev_return {} { + global outdev_adr indev_adr + global .outdev_entry + + reset_highest_cmd_sev + send_loggable_cmd "-outdev [make_text_shellsafe $outdev_adr]" + set outdev_mem_adr $outdev_adr + .outdev_entry icursor 0 + refresh_outdev + return "1" +} + + +# Called when the "Eject" button for the output drive is hit. +# +proc eject_outdev {} { + global outdev_adr indev_adr + + if {$outdev_adr == $indev_adr} { + if {[assert_no_changes] == 0} {return ""} + } + reset_highest_cmd_sev + send_loggable_cmd "-eject outdev" + refresh_outdev + refresh_indev +} + + +# Called when both drive addresses shall be brought into effect with xorriso. +# +proc dev_return {} { + global outdev_adr indev_adr + global .outdev_entry .indev_entry + + if {$outdev_adr != $indev_adr} { + if {[indev_return] == 0} {return "0"} + outdev_return + } else { + if {[assert_no_changes] == 0} { + update_dev_var + return "0" + } + reset_highest_cmd_sev + send_loggable_cmd "-dev [make_text_shellsafe $outdev_adr]" + .outdev_entry icursor 0 + refresh_outdev + .indev_entry icursor 0 + refresh_indev + } +} + + +# Obtain and display the input drive status. +# Called after the input drive address may have changed. +# +proc refresh_indev {} { + global result_list + global indev_adr + global sieve_ret + global .indev_summary + + .indev_summary configure -text "" + set indev_adr "" + update idletasks + + set disp_en_mem [set_display_msg 0] + clear_sieve + send_marked_cmd "-toc_of in:short" + read_sieve "Drive current:" + set_display_msg $disp_en_mem + if {$sieve_ret > 0} { + set cmd [lindex $result_list 0] + if {$cmd == "-indev" || $cmd == "-dev"} { + set indev_adr [lindex $result_list 1] + } + set line [obtain_drive_info in] + .indev_summary configure -text $line + } + .avail_label configure -text "" + update idletasks + isodir_return "refresh_indev" +} + + +# Obtain and display the output drive status. +# Called after the output drive address may have changed. +# +proc refresh_outdev {} { + global result_list + global outdev_adr + global sieve_ret + + .outdev_summary configure -text "" + set outdev_adr "" + update idletasks + + set disp_en_mem [set_display_msg 0] + clear_sieve + send_marked_cmd "-toc_of out:short" + read_sieve "Drive current:" + set_display_msg $disp_en_mem + if {$sieve_ret > 0} { + set cmd [lindex $result_list 0] + if {$cmd == "-outdev" || $cmd == "-dev"} { + set outdev_adr [lindex $result_list 1] + } + set line [obtain_drive_info out] + .outdev_summary configure -text $line + } + .avail_label configure -text "" + update idletasks +} + + +# Scan the system for optical drives with rw permission +# Called when the "Scan for drives button" is hit. +# +proc scan_for_drives {} { + global .drivelist .drive_drop_both .drive_scan + global sieve_ret result_list devlist devices_scanned indev_adr outdev_adr + + if {[assert_no_changes] == 0} {return ""} + if {$indev_adr != "" || $outdev_adr != ""} { + if {[window_yesno \ + "Really give up acquired drives for scanning a new drive list ?"] \ + != 1} { return "" } + } + + set max_idx [.drivelist index end] + .drivelist delete 0 [expr $max_idx-1] + set devlist "" + + reset_highest_cmd_sev + clear_sieve + send_loggable_cmd "-devices" + set max_idx 0 + while {1} { + read_sieve "? -dev" + if {$sieve_ret > 0} { + .drivelist insert end "[lindex $result_list 0] : [lindex $result_list 2] [lindex $result_list 3]" + lappend devlist [lindex $result_list 0] + } else { + break + } + } + while {1} { + read_sieve "?? -dev" + if {$sieve_ret > 0} { + .drivelist insert end "[lindex $result_list 0] : [lindex $result_list 2] [lindex $result_list 3]" + lappend devlist [lindex $result_list 0] + } else { + break + } + } + set devices_scanned 1 + reset_to_normal_background .drive_scan + + # Command -devices drops all acquired drives + refresh_outdev + refresh_indev +} + + +# Refresh the display after some xorriso may have changed the status +# Called by the "Refresh disp" button and others. +# +proc refresh_state {} { + refresh_indev + refresh_outdev +} + + +# Reset the recorded Worst problem message. +# Called when the "Clear" button is hit. +# +proc clear_total_errmsg {} { + global highest_total_sev + global highest_total_sev_msg + + set highest_total_sev ALL + set highest_total_sev_msg "" + update idletasks +} + + +# Called when the "Pick input drive button" is hit. +# +proc pick_indev {} { + pick_drive indev +} + + +# Called when the "Pick output drive button" is hit. +# +proc pick_outdev {} { + pick_drive outdev +} + + +# Called when the "Pick drive for both roles" button is hit. +# or when an item in the scanned drive list is double-clicked. +# +proc pick_dev {} { + pick_drive dev +} + + +# Perform the actual work of pick_dev, pick_indev, and pick_outdev +# +proc pick_drive {role} { + global .drivelist + global devlist + global highest_cmd_sev_msg outdev_adr indev_adr devices_scanned + + set selected [.drivelist curselection] + if {[llength $selected] != 1} { + set must_scan "" + if {$devices_scanned == 0} { set must_scan " scan and"} + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must$must_scan select a single drive" + return "" + } + set drive_idx [lindex $selected 0] + + if {$role == "dev"} { + set outdev_adr [lindex $devlist $drive_idx] + set indev_adr [lindex $devlist $drive_idx] + dev_return + } + if {$role == "outdev"} { + set outdev_adr [lindex $devlist $drive_idx] + outdev_return + } + if {$role == "indev"} { + set indev_adr [lindex $devlist $drive_idx] + indev_return + } + .drivelist selection clear 0 end +} + + +# Called when the "Give up drives" button is hit. +# +proc give_up_dev {} { + global outdev_adr indev_adr + + if {[assert_no_changes] == 0} {return ""} + set outdev_adr "" + outdev_return + set indev_adr "" + indev_return +} + + +# Obtain and display the content of the current ISO directory. +# Called when the Return key is hit in the .isodir_entry text field +# and by many others which change variable isodir_adr or the +# content of the directory in xorriso's tree model. +# +proc isodir_return {caller} { + global isodir_adr result_list isolist_names isolist_types isodir_return_name + global isodir_is_pwd highest_cmd_sev highest_cmd_sev_msg + global indev_adr outdev_adr eff_indev_adr + global .isolist + global bulk_parse_max_chunk + + set chunk_size 0 + + set max_idx [.isolist index end] + .isolist delete 0 [expr "$max_idx-1"] + update idletasks + set isolist_names "" + set isolist_types "" + + inquire_dev + if {$eff_indev_adr == "" && [changes_are_pending] == "0"} {return ""} + + normalize_isodir_adr + set file_type [isofs_filetype $isodir_adr] + if {$file_type != "d" && $file_type != ""} { + .isolist insert end "@@@ exists but is not a directory @@@" + set isodir_is_pwd 0 + return "" + } + set disp_en_mem [set_display_msg 0] + set highest_cmd_sev_mem $highest_cmd_sev + set highest_cmd_sev_msg_mem $highest_cmd_sev_msg + reset_highest_cmd_sev + send_loggable_cmd "-cd [make_text_shellsafe $isodir_adr]" + if {[compare_sev $highest_cmd_sev "WARNING"] < 0} { + send_marked_cmd "-lsl --" + set isodir_is_pwd 1 + } else { + send_marked_cmd "-lsl [make_text_shellsafe $isodir_adr] --" + set isodir_is_pwd 0 + } + handle_result_list isolist_parse_handler "''" "''" 0 0 + set_display_msg $disp_en_mem + set highest_cmd_sev $highest_cmd_sev_mem + set highest_cmd_sev_msg $highest_cmd_sev_msg_mem + + if {$isodir_return_name != ""} { + set idx [lsearch -exact $isolist_names $isodir_return_name] + if {$idx != -1} { + .isolist see $idx + .isolist selection set $idx + } + set isodir_return_name "" + } + update idletasks +} + + +# The handler procedure that is submitted to proc handle_result_list +# and will be called for every parsed line. +# It records file names and types in separate lists and displays them +# in the .isolist box. +# +proc isolist_parse_handler {} { + global result_list isolist_names isolist_types + global .isolist + + if {[lindex $result_list 0] == "total"} {return ""} + set name [lindex $result_list 8] + set ftype [string range [lindex $result_list 0] 0 0] + lappend isolist_names $name + lappend isolist_types $ftype + .isolist insert end "$ftype $name" +} + + +# Make current the ISO directory that was selected from the .isolist box. +# Called when an item in the .isolist box is double-clicked. +# +proc pick_isodir {} { + global isolist_names isolist_types isodir_adr isodir_return_name + global .isolist + + set selected [.isolist curselection] + if {[llength $selected] != 1} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must select a single directory" + return "" + } + set idx [lindex $selected 0] + if {[lindex $isolist_types $idx] != "d"} { return "" } + if {$isodir_adr == "/"} { + set isodir_adr "" + } + set isodir_adr "$isodir_adr/[lindex $isolist_names $idx]" + set isodir_return_name "" + isodir_return "pick_isodir" +} + + +# Make current the parent directory of the current ISO directory. +# Called when the "Up" button is hit. +# +proc isodir_up {} { + global isodir_adr isodir_return_name + + set isodir_return_name "" + set idx [string last "/" $isodir_adr] + set l [string length $isodir_adr] + if {$idx == -1} { + set isodir_return_name $isodir_adr + set isodir_adr "/" + } else { + if {$idx > 0} { + if {$idx < [expr $l - 1]} { + set isodir_return_name \ + [string range $isodir_adr [expr $idx+1] end] + } + set isodir_adr [string range $isodir_adr 0 [expr $idx - 1]] + } else { + if {$l > 1} { + set isodir_return_name [string range $isodir_adr 1 end] + } + set isodir_adr "/" + } + } + isodir_return "isodir_up" +} + + +# Rename or move the files which are selected in the .isolist box. +# The target is defined by the .isomanip_move_target text field. +# Called when the "Move to:" button is hit. +# +proc isomanip_mv {} { + global .isolist + global isomanip_move_target isolist_names isodir_is_pwd isodir_adr + global isodir_return_name use_command_move + + if {$isomanip_move_target == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must enter a target address" + return "" + } + set selected [.isolist curselection] + set num_selected [llength $selected] + if {$num_selected < 1} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must select one or more ISO files" + return "" + } + + set target $isomanip_move_target + if {$isodir_is_pwd == 0 && [string range $target 0 0] != "/"} { + set target [combine_dir_and_name $isodir_adr $target] + } + set target_ftype [isofs_filetype $target] + + # If more than one selected : target must be directory + if {$num_selected > 1} { + if {$target_ftype != "d" && $target_ftype != ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : If multiple files are selected then the target must be a directory" + return "" + } + if {$target_ftype == ""} { + set isomanip_move_target_mem $isomanip_move_target + set isomanip_move_target $target + isomanip_mkdir + set isomanip_move_target $isomanip_move_target_mem + } + } + + enforce_overwrite_settings "isofs" + reset_highest_cmd_sev + reset_yesno_to_all + set multi_source 0 + if {[llength $selected] != 1} {set multi_source 1} + foreach i $selected { + set name [lindex $isolist_names $i] + if {$isodir_is_pwd == 0} { + set name [combine_dir_and_name $isodir_adr $name] + } + set name_ftype [isofs_filetype $name] + + # Ask for confirmation if overwriting is about to happen + if {$target_ftype == "d" && $use_command_move == 0} { + set eff_target [combine_dir_and_name $target $name] + set eff_target_ftype [isofs_filetype $eff_target] + } else { + set eff_target $target + set eff_target_ftype $target_ftype + } + if {[handle_overwriting "isofs" $eff_target $eff_target_ftype \ + "isofs" $name $name_ftype $multi_source \ + "" "" "replace"] == "0"} { + if {$multi_source == 0} { return "" } + continue + } + if {$use_command_move == 0} { + send_loggable_cmd \ + "-mv [make_text_shellsafe $name] [make_text_shellsafe $target] --" + } else { + send_loggable_cmd \ + "-move [make_text_shellsafe $name] [make_text_shellsafe $target] --" + } + } + + if {[llength $selected] == 1} { + set isodir_return_name [path_touches_isodir $target] + } + browse_iso_refresh + isodir_return "isomanip_mv" +} + + +# Create an empty ISO directory with address given by variable +# isomanip_move_target. +# Called when the "Make dir" button is hit or by other functions. +# +proc isomanip_mkdir {} { + global isomanip_move_target isodir_adr isodir_return_name + + if {$isomanip_move_target == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must enter a target address" + return "" + } + + if {[string range $isomanip_move_target 0 0] == "/"} { + set abs_adr $isomanip_move_target + } else { + set abs_adr [combine_dir_and_name $isodir_adr $isomanip_move_target] + } + reset_highest_cmd_sev + send_loggable_cmd "-mkdir [make_text_shellsafe $abs_adr] --" + + # Refresh only if new dir in isodir_adr + # or if a parent directory of new dir is created in isodir_adr + set touch_name [path_touches_isodir $abs_adr] + if {$touch_name != ""} { + if {[llength [.isolist curselection]] != 0} { + memorize_isolist_selection + set selection_memorized 1 + } else { + set isodir_return_name $touch_name + set selection_memorized 0 + } + isodir_return "isomanip_mkdir" + if {$selection_memorized != 0} { + restore_isolist_selection + } + } + browse_iso_refresh +} + + +# Remove a file or directory tree from the ISO image. +# Called when the "Delete" button is hit. +# +proc isomanip_rm_r {} { + global .isolist + global isomanip_move_target isolist_names isodir_is_pwd isodir_adr + + set selected [.isolist curselection] + if {[llength $selected] < 1} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must select one or more ISO files" + return "" + } + if {[window_yesno "Really delete the selected files from ISO image ?"] \ + != 1} { return "" } + reset_highest_cmd_sev + foreach i $selected { + set name [lindex $isolist_names $i] + if {$isodir_is_pwd == 0} { + set name [combine_dir_and_name $isodir_adr $name] + } + send_loggable_cmd "-rm_r [make_text_shellsafe $name] --" + } + browse_iso_refresh + isodir_return "isomanip_rm_r" +} + + +# Perform a blanking run on the output drive. +# Called when the "Blank" button is hit. +# +proc burn_blank {} { + global outdev_profile eff_outdev_adr eff_indev_adr + + refresh_outdev + if {[assert_outdev blanking] <= 0} {return ""} + + if {$eff_outdev_adr == $eff_indev_adr} { + if {[assert_no_changes] <= 0} {return ""} + } + set victim "medium in" + if {[string first "stdio" $outdev_profile] == 0} { + set victim "image file" + } + if {[window_yesno \ + "Really blank the $victim [make_text_shellsafe $eff_outdev_adr] ?"] \ + != 1} { return "" } + reset_highest_cmd_sev + send_loggable_cmd "-blank as_needed" + refresh_indev + refresh_outdev +} + + +# Perform a formatting run on the output drive. +# Called when the "Format" button is hit. +# +proc burn_format {} { + global outdev_profile eff_outdev_adr eff_indev_adr + + refresh_outdev + if {[assert_outdev formatting] <= 0} {return ""} + if {$eff_outdev_adr == $eff_indev_adr} { + if {[assert_no_changes] <= 0} {return ""} + } + + if {[string first "stdio" $outdev_profile] == 0} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : Image files cannot be formatted" + return "" + } + if {[window_yesno "Really format the medium in $eff_outdev_adr ?"] \ + != 1} { return "" } + + reset_highest_cmd_sev + send_loggable_cmd "-format as_needed" + refresh_indev + refresh_outdev +} + + +# Write pending changes in the xorriso ISO model as session to the output +# drive. This will be an add-on session if the drive is output and input drive +# and if its medium is not blank. +# Else it will be a new independent ISO image. +# +proc burn_commit {} { + global outdev_adr result_list result_count outdev_medium_status + global burn_write_close burn_write_tao burn_write_defect_mgt + global indev_adr outdev_adr permission_policy + + if {[assert_outdev "writing an ISO session"] <= 0} {return ""} + if {$outdev_adr == $indev_adr} { + if {$outdev_medium_status != "blank" && \ + $outdev_medium_status != "appendable"} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : Medium in output drive is neither blank nor appendable" + return "" + } + } else { + if {$outdev_medium_status != "blank"} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : Medium in output drive is not blank" + return "" + } + } + if {[changes_are_pending] == "0"} { + window_ack "No changes are pending. Will not write ISO session." \ + "grey" "toplevel" + return "" + } + if {$outdev_adr == $indev_adr} { + if {[window_yesno "Really write ISO changes as session to $outdev_adr ?"] \ + != 1} { return "" } + } else { + if {[window_yesno "Really write a new ISO filesystem to $outdev_adr ?"] \ + != 1} { return "" } + } + + reset_highest_cmd_sev + effectuate_permission_policy + set cmd "-close" + if {$burn_write_close == 1} { + set cmd "$cmd on" + } else { + set cmd "$cmd off" + } + set cmd "$cmd -write_type" + if {$burn_write_tao == 1} { + set cmd "$cmd tao" + } else { + set cmd "$cmd auto" + } + set cmd "$cmd -stream_recording" + if {$burn_write_defect_mgt == 1} { + set cmd "$cmd off" + } else { + set cmd "$cmd data" + } + set cmd "$cmd -commit" + send_loggable_cmd $cmd + refresh_indev + refresh_outdev +} + + +# Verify the MD5 checksums of the data files in the tree underneath the +# current ISO directory. +# Called when the "Verify" in the "ISO directory:" line is hit. +# +proc isodir_verify {} { + global isodir_adr + + reset_highest_cmd_sev + send_loggable_cmd "-check_md5_r sorry [make_text_shellsafe $isodir_adr] --" + + # >>> select mismatching files or directories with mismatching files + +} + + +# Verify the MD5 checksums of the data files orch are selected or which +# sit in the trees underneath the selected items in the isolist box. +# Called when the "Verify" in the "Selection:" line is hit. +# +proc isomanip_verify {} { + global .isolist + global isomanip_move_target isolist_names isodir_is_pwd isodir_adr + + set selected [.isolist curselection] + if {[llength $selected] < 1} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : First you must select one or more ISO files" + return "" + } + reset_highest_cmd_sev + foreach i $selected { + set name [combine_dir_and_name $isodir_adr \ + [lindex $isolist_names $i]] + send_loggable_cmd "-check_md5_r sorry [make_text_shellsafe $name] --" + } + + # >>> select mismatching files or directories with mismatching files + +} + + +# Slow down the spinning of the acquired optical drives. +# Called when button "Calm drives" is hit. +# +proc calm_drives {} { + reset_highest_cmd_sev + send_loggable_cmd "-calm_drive all" +} + + +# Burn a data file from disk as session to the output drive. +# Called when the "Burn image file:" button is hit. +# +proc burn_write_image {} { + global burn_write_image_adr burn_write_close outdev_adr outdev_medium_status + global outdev_profile burn_write_tao burn_write_defect_mgt indev_adr + + update_dev_var + if {$indev_adr != ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You may not have an input drive open when writing an image file" + return "" + } + + if {[assert_outdev "writing an image file"] <= 0} {return ""} + if {$burn_write_image_adr == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You have to set an image file address in the hard disk filesystem first" + return "" + } + + if {$outdev_medium_status != "blank"} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You must have a blank medium in the output drive for burning an image data file" + return "" + } + if {[file readable $burn_write_image_adr] == 0 || \ + [file isfile $burn_write_image_adr] == 0 || + [file exists $burn_write_image_adr] == 0} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : Image file '$burn_write_image_adr' is not a readable data file" + return "" + } + if {[window_yesno "Really write '$burn_write_image_adr' as image to $outdev_adr ?"] \ + != 1} { return "" } + + set cmd "-as cdrecord -v" + if {[regexp "^CD" $outdev_profile] == 1 && \ + ( $outdev_medium_status == "appendable" || $burn_write_tao == 1 )} { + set cmd "$cmd padsize=150s" + } + set cmd "$cmd dev=[make_text_shellsafe $outdev_adr]" + set cmd "$cmd [make_text_shellsafe $burn_write_image_adr]" + if {$burn_write_tao == 1} { + set cmd "$cmd -tao" + } + if {$burn_write_close != 1} { + set cmd "$cmd -multi" + } + if {$burn_write_defect_mgt == 1} { + set cmd "$cmd stream_recording=off" + } else { + set cmd "$cmd stream_recording=32s" + } + reset_highest_cmd_sev + send_loggable_cmd $cmd + refresh_state +} + + +# Discard all image modifications and reload ISO image model from input drive. +# Called when the "Rollback" button is hit. +# +proc iso_rollback {} { + if {[window_yesno \ + "Really discard all pending changes and reload from input drive ?"] \ + != 1} { return "" } + reset_highest_cmd_sev + send_loggable_cmd "-rollback" + .avail_label configure -text "" + isodir_return "iso_rollback" +} + + +# Inquire an accurate prediction of free space after writing a session with +# the pending changes of the ISO image. +# Called when button "Refresh avail:" is hit. +# +proc refresh_avail {} { + global result_list highest_cmd_sev + global sieve_ret + + if {[assert_outdev "refreshing available space prediction"] <= 0} {return ""} + + set line "n.a." + reset_highest_cmd_sev + clear_sieve + send_loggable_cmd "-tell_media_space" + if {[compare_sev $highest_cmd_sev "FAILURE"] < 0} { + set ac "" + read_sieve "After commit :" + if {$sieve_ret > 0} { + set ac [lindex $result_list 0] + set ac [string range $ac 0 [expr [string length $ac] - 2]] + set line "[format "%7dm" [expr "$ac / 512"]]" + } + } + .avail_label configure -text $line +} + + +# Warn and prompt the user for confirmation if there is the risk to overwrite +# existing files on hard disk or in the ISO image model. +# Called from several procedures which cause side effects on directory trees. +# +proc handle_overwriting {target_fs target target_ftype + source_fs source source_ftype multi_source + selected_adr selected_ftype dir_action} { + global overwrite_iso_files overwrite_iso_dirs overwrite_disk_files + + if {$target_fs == "localfs"} { + set to_fs "hard disk" + set overwrite_fs "disk" + set overwrite_dirs 0 + set overwrite_files $overwrite_disk_files + } else { + set to_fs "ISO" + set overwrite_fs "ISO" + set overwrite_dirs $overwrite_iso_dirs + set overwrite_files $overwrite_iso_files + } + if {$source_fs == "localfs"} { + set from_fs "hard disk" + } else { + set from_fs "ISO" + } + if {$multi_source == 1} { + set what_window window_yesno_ever + } else { + set what_window window_yesno + } + + # >>> Nicer would be: + # >>> Check if any file will get overwritten. Not only the direct target. + # >>> Then silently allow directories to be merged + + if {$target_ftype != ""} { + if {$target_ftype == "d"} { + if {$source_ftype == "d"} { + if {$dir_action == "replace"} { + if {$overwrite_iso_dirs != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You would have to enable \"Overwrite $overwrite_fs dirs\" for\n[make_text_shellsafe $target]" + return "0" + } + if {[$what_window \ + "Really replace existing $to_fs directory\n\n[make_text_shellsafe $target]\n\nby $from_fs directory\n[make_text_shellsafe $source]\n?"] \ + != 1} { return "0" } + return "1" + } + if {[$what_window \ + "Really merge existing $to_fs directory\n\n[make_text_shellsafe $target]\n\nwith $from_fs directory\n[make_text_shellsafe $source]\n?"] \ + != 1} { return "0" } + } else { + if {$target_fs != "isofs"} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : Will not replace directory on hard disk by file of other type\n[make_text_shellsafe $target]" + return "0" + } + if {$overwrite_dirs == 1} { + if {[$what_window \ + "Really overwrite $to_fs directory\n\n[make_text_shellsafe $target]\n\nby $from_fs file\n[make_text_shellsafe $source]\n?"] \ + != 1} { return "0" } + } else { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You would have to enable \"Overwrite $overwrite_fs dirs\" for\n[make_text_shellsafe $target]" + return "0" + } + } + } else { + if {$overwrite_files == 1} { + if {[$what_window \ + "Really overwrite $to_fs file\n\n[make_text_shellsafe $target]\n\nby $from_fs file\n[make_text_shellsafe $source]\n?"] != 1} { + return "0" + } + } else { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You would have to enable \"Overwrite $overwrite_fs files\" for\n[make_text_shellsafe $target]" + return "0" + } + } + } + if {$selected_adr != $target && $selected_adr != "" && \ + $selected_ftype != "d" && $selected_ftype != ""} { + if {[$what_window \ + "Really replace existing $to_fs file\n\n[make_text_shellsafe $target]\n\nby $from_fs directory\n[make_text_shellsafe $source]\n?"] != 1} { + return "0" + } + } + return "1" +} + + +# Insert a file or directory tree into the ISO model tree and schedule it +# for being copied when "Write ISO session" is hit. +# Called when button "Insert from disk:" is hit. +# +proc insert_from {} { + global insert_from_adr isodir_adr isolist_names isodir_return_name + global insert_at_selected insert_underneath + + if {[assert_iso_image 1] == 0} {return ""} + if {$insert_from_adr == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You have to set a source address in the hard disk filesystem first" + return "" + } + set selected_ftype "" + set selected_adr "" + if {$insert_at_selected == 1} { + set selected [.isolist curselection] + if {[llength $selected] != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select exactly one ISO file as insertion target" + return "" + } + set target "[lindex $isolist_names [lindex $selected 0]]" + set selected_ftype [isofs_filetype $target] + set selected_adr $target + } else { + set target $isodir_adr + } + set source_ftype [localfs_filetype $insert_from_adr] + set name [file tail $insert_from_adr] + if {$insert_underneath == 1 || $source_ftype == "d"} { + set target [combine_dir_and_name $target $name] + } + set target_ftype [isofs_filetype $target] + + reset_yesno_to_all + if {[handle_overwriting "isofs" $target $target_ftype \ + "localfs" $insert_from_adr $source_ftype 0 \ + $selected_adr $selected_ftype "merge"] == "0"} { + return "" + } + + set preserve_selection 0 + if {$insert_underneath + $insert_at_selected == 1} { + set isodir_return_name $name + } else { + set preserve_selection 1 + } + reset_highest_cmd_sev + enforce_overwrite_settings "isofs" + send_loggable_cmd "-map [make_text_shellsafe $insert_from_adr] [make_text_shellsafe $target]" + + if {$preserve_selection == 1} { + memorize_isolist_selection + } + isodir_return "insert_from" + if {$preserve_selection == 1} { + restore_isolist_selection + } + browse_iso_refresh +} + + +# Copy a file out of the ISO image model to the hard disk filesystem. +# The meta data stem from the ISO model tree. The content data are usually +# read from the input drive. +# Called when button "Extract to disk:" is hit. +# +proc extract_to {} { + global extract_to_adr extract_from_selected extract_underneath + global extract_auto_chmod osirrox_allowed + global isodir_adr isolist_names + + if {$osirrox_allowed != 1} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : Extraction from ISO to hard disk is already irrevocably banned." + return "" + } + + if {[assert_iso_image 1] == 0} {return ""} + if {$extract_to_adr == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You have to set a target address in the hard disk filesystem first" + return "" + } + set sources "" + set selected_ftype "" + set selected_adr "" + if {$extract_from_selected == 1} { + set selected [.isolist curselection] + if {[llength $selected] < 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select at least one ISO file as extraction source" + return "" + } + foreach i $selected { + set path [combine_dir_and_name $isodir_adr \ + [lindex $isolist_names $i]] + lappend sources $path + } + } else { + set sources [list $isodir_adr] + } + + reset_highest_cmd_sev + reset_yesno_to_all + enforce_overwrite_settings "localfs" + set disp_en_mem [set_display_msg 0] + if {$extract_auto_chmod == 1} { + send_loggable_cmd "-osirrox on:sort_lba_on:auto_chmod_on" + } else { + send_loggable_cmd "-osirrox on:sort_lba_off:auto_chmod_off" + } + set_display_msg $disp_en_mem + set multi_source 0 + if {[llength $sources] != 1} {set multi_source 1} + foreach i $sources { + if {$extract_underneath == 1} { + set name [file tail $i] + set target [combine_dir_and_name $extract_to_adr $name] + } else { + if {[llength $sources] != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select exactly one ISO file as extraction source" + return "" + } + set target $extract_to_adr + } + if {$i == ""} { + set i "/" + } + set target_ftype [localfs_filetype $target] + set from_is_dir 0 + set source_ftype [isofs_filetype $i] + if {[handle_overwriting "localfs" $target $target_ftype \ + "isofs" $i $source_ftype $multi_source \ + "" "" "merge"] == 0} { + continue + } + send_loggable_cmd \ + "-extract [make_text_shellsafe $i] [make_text_shellsafe $target]" + } + browse_tree_populate "localfs" +} + + +# Send the currently chosen -overwrite settings of the checkbuttons +# "Overwrite ISO files", "Overwrite ISO dirs", "Overwrite hard disk files". +# Called before operations which could overwrite files in ISO model +# or in the hard disk filesystem. +# I.e. any -overwrite command sent via the "Command:" text field will not +# be able to override the checkbuttons. +# +proc enforce_overwrite_settings {which_fs} { + global overwrite_iso_files overwrite_iso_dirs overwrite_disk_files + + if {$which_fs == "isofs"} { + if {$overwrite_iso_files == 0} { + set mode "off" + } else { + if {$overwrite_iso_dirs == 0} { + set mode "nondir" + } else { + set mode "on" + } + } + } else { + if {$overwrite_disk_files == 1} { + set mode "on" + } else { + set mode "off" + } + } + set disp_en_mem [set_display_msg 0] + send_loggable_cmd "-overwrite $mode" + set_display_msg $disp_en_mem +} + + +# Send xorriso an appropriate end command and wait for the pipes to break. +# Called when button "End" is hit. +# +proc end_xorriso {} { + global expect_broken_pipes + + if {[window_yesno "Really end this program and its xorriso backend ?"] \ + != 1} { return "" } + if {[changes_are_pending] == 1} { + if {[window_yesno \ + "Changes of the ISO image are pending.\nReally discard them ?"] \ + != 1} { return "" } + set expect_broken_pipes "1" + send_loggable_cmd "-rollback_end" + } else { + set expect_broken_pipes "1" + send_loggable_cmd "-end" + } + central_exit 0 +} + + +# Check whether an output drive is acquired. Propose refusal if not. +# Called by procedures which are about to use the output drive. +# +proc assert_outdev {purpose} { + global eff_outdev_adr + + inquire_dev + if {$eff_outdev_adr == ""} { + xorriso_tcltk_errmsg \ + "xorriso-tcltk : SORRY : You must choose an output drive before $purpose" + return "0" + } + return "1" +} + + +# Check whether changes to the ISO model are pending. If so, propose refusal. +# Called by procedures which are about to discard the ISO model. +# +proc assert_no_changes {} { + if {[changes_are_pending] == 1} { + window_ack "ISO image changes are pending. You have to do \"Write ISO session\" or \"Rollback\"." "grey" "toplevel" + return "0" + } + return "1" +} + + +# Set the text of the "Permissions:" menubutton +# Called by the radiobuttons in the menu. +# +proc show_permission_policy {} { + global permission_policy + + set text $permission_policy + if {$permission_policy == "as_is"} { + set text "as is" + } + if {$permission_policy == "mkisofs_r"} { + set text "mkisofs -r" + } + .perm_policy configure -text "Permissions: $text" +} + + +# Set the target address of command logging. +# Called by the "Script/Log" menu. +# +proc set_log_script_address {} { + browse_tree cmd_log_target "localfs" + set w .browse_disk_window + tkwait window $w + effectuate_command_logging 0 +} + + +# Bring into effect the settings for command script logging. +# Called by the "Accept" button or the Return key of the +# "Set log script address" file browser. +# +proc effectuate_command_logging {close_window} { + global cmd_log_target cmd_logging_mode browse_disk_window_is_active + + if {$close_window == 1 && $browse_disk_window_is_active == 1} { + destroy_browse_disk .browse_disk_window + } + if {$close_window == 1 || $cmd_logging_mode > 0} { + start_command_logging $cmd_log_target $cmd_logging_mode + } +} + + +# Set the target address of communication pipe logging. +# Called by the "Script/Log" menu. +# +proc set_debug_log_address {} { + browse_tree debug_log_file "localfs" + set w .browse_disk_window + tkwait window $w + effectuate_debug_logging 0 +} + + +# Bring into effect the settings for communication pipe logging. +# Called by the "Accept" button or the Return key of the +# "Set pipe log address" file browser. +# +proc effectuate_debug_logging {close_window} { + global debug_log_file debug_logging browse_disk_window_is_active + + if {$close_window == 1 && $browse_disk_window_is_active == 1} { + destroy_browse_disk .browse_disk_window + } + if {$close_window == 1 || $debug_logging > 0} { + start_debug_logging $debug_log_file $debug_logging + } +} + + +# Trigger execution of a script of xorriso commands. +# Called by the "Script/Log" menu. +# +proc start_script_execution {} { + browse_tree execute_script_adr "localfs" + # actual script start is done by browse_tree_accept -> execute_script +} + + +# Permanently ban any extraction from ISO to hard disk +# +proc osirrox_banned {} { + global osirrox_allowed + + reset_yesno_to_all + if {[window_yesno \ + "Really irrevocably ban any extraction from ISO to hard disk ?"] \ + != 1} { return "" } + + send_loggable_cmd "-osirrox banned" + set osirrox_allowed 0 + + set m ".script_log.menu" + $m entryconfigure "Allow extract to disk" -state "disabled" + $m entryconfigure "Permanently ban extraction" -state "disabled" + + .extract_button configure -state "disabled" + +} + + +# ------ A primitive file tree browser for hard disk filesystem and ISO model + +# Write a directory content list into a Tree widget +# +proc browse_tree_fill_dir {tr parent children} { + + if {$parent == "/"} { + set parent_name root + set parent_dir / + } else { + set parent_name [escape_to_tree $parent] + set parent_dir $parent_name + } + if {[$tr exists $parent_name] == 0} {return ""} + + $tr delete [$tr nodes $parent_name] + + foreach i $children { + set name [string range $i 2 end] + set escpd [escape_to_tree $name] + set adr [combine_dir_and_name $parent_dir $escpd] + $tr insert end $parent_name $adr -text $name + if {[string range $i 0 0] == "d"} { + set dir_dummy [combine_dir_and_name $adr "_"] + $tr insert end $adr $dir_dummy -text " " + } + } +} + + +# The command to be executed when the user double-clicks a node. +# +proc browse_tree_accept {adr_var_name do_return tr value} { + global have_bwidget + global extract_to_adr insert_from_adr burn_write_image_adr isodir_adr + global isomanip_move_target indev_adr outdev_adr cmd_log_target + global debug_log_file execute_script_adr + + # Caution: Before using $tr, check for $have_bwidget + + if {$adr_var_name == "burn_write_image_adr"} { + set burn_write_image_adr $value + if {$do_return == 1} {burn_write_image} + } + if {$adr_var_name == "extract_to_adr"} { + set extract_to_adr $value + if {$do_return == 1} {extract_to} + } + if {$adr_var_name == "insert_from_adr"} { + set insert_from_adr $value + if {$do_return == 1} {insert_from} + } + if {$adr_var_name == "isodir_adr"} { + set isodir_adr $value + if {$do_return == 1} {isodir_return "browse_tree_accept"} + } + if {$adr_var_name == "isomanip_move_target"} { + set isomanip_move_target $value + if {$do_return == 1} {isomanip_mv} + } + if {$adr_var_name == "indev_adr"} { + set indev_adr $value + if {$do_return == 1} {indev_return} + } + if {$adr_var_name == "outdev_adr"} { + set outdev_adr $value + if {$do_return == 1} {outdev_return} + } + if {$adr_var_name == "cmd_log_target"} { + set cmd_log_target $value + if {$do_return == 1} {effectuate_command_logging 1} + } + if {$adr_var_name == "debug_log_file"} { + set debug_log_file $value + if {$do_return == 1} {effectuate_debug_logging 1} + } + if {$adr_var_name == "execute_script_adr"} { + set execute_script_adr $value + if {$do_return == 1} {execute_script 1} + } +} + + +# Translate a browser tree variable in a human readable topic text +# +proc browse_tree_topic {adr_var_name} { + if {$adr_var_name == "burn_write_image_adr"} { + return "Burn image file:" + } + if {$adr_var_name == "extract_to_adr"} { + return "Extract to disk:" + } + if {$adr_var_name == "insert_from_adr"} { + return "Insert from disk:" + } + if {$adr_var_name == "isodir_adr"} { + return "ISO directory:" + } + if {$adr_var_name == "isomanip_move_target"} { + return "Move to:" + } + if {$adr_var_name == "indev_adr"} { + return "Input drive/image" + } + if {$adr_var_name == "outdev_adr"} { + return "Output drive/image" + } + if {$adr_var_name == "cmd_log_target"} { + return "Set log script address" + } + if {$adr_var_name == "debug_log_file"} { + return "Set pipe log address" + } + if {$adr_var_name == "execute_script_adr"} { + return "Execute command script" + } + return $adr_var_name +} + + +# Unescape &|^! from Bwidget tree browser +# +proc unescape_from_tree {text} { + return [string map [list "\{\{\}" "\{" "\{+\}" "&" "\{I\}" "|" \ + "\{A\}" "^" "\{.\}" "!"] \ + $text] + + # <<< alternative encoding + # set escpd [string map [list "\\\\" "\\" "\\+" "&" "\\I" "|" \ + # "\\A" "^" "\\." "!"] \ +} + + +# Escape &|^! which are special to BWidget Tree +# +proc escape_to_tree {text} { + return [string map [list "\{" "\{\{\}" "&" "\{+\}" "|" "\{I\}" \ + "^" "\{A\}" "!" "\{.\}"] \ + $text] +} + + + +# Accept the single selected item of the tree browser +# Called by the \"Accept\" button in the browser window. +# +proc browse_tree_accept_sel {adr_var_name do_return tr} { + set selected [$tr selection get] + + if {[llength $selected] != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select a single tree item before clicking the \"Accept\" button." + return "" + } + browse_tree_accept $adr_var_name $do_return $tr \ + [unescape_from_tree [lindex $selected 0]] +} + + +# Hit the Return key on the text entry of the browser +# +proc browse_tree_accept_entry {adr_var_name do_return tr} { + global extract_to_adr insert_from_adr burn_write_image_adr isodir_adr + global isomanip_move_target indev_adr outdev_adr cmd_log_target + global debug_log_file execute_script_adr + + eval set text $$adr_var_name + browse_tree_accept $adr_var_name $do_return $tr $text +} + + +# Submit a Tree-escaped path to browse_tree_accept. +# Called by Double-click in browser. +# +proc browse_tree_accept_escd {adr_var_name do_return tr escd_path} { + browse_tree_accept $adr_var_name $do_return $tr \ + [unescape_from_tree $escd_path] +} + + +# Move up one directory level of the file browser selection +# +proc browse_tree_up {adr_var_name tr which_fs} { + global extract_to_adr insert_from_adr burn_write_image_adr isodir_adr + global isomanip_move_target indev_adr outdev_adr + + set selected [$tr selection get] + if {[llength $selected] != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select a single tree item before clicking the \"Up\" button." + return "" + } + set old_adr [lindex $selected 0] + set adr [file dirname $old_adr] + catch { + $tr see $adr + if {[$tr nodes $old_adr 0] != ""} { + $tr closetree $old_adr + } + } + if {$adr != "/" && $adr != ""} { + $tr selection clear + $tr selection set $adr + } +} + + +# Move down one directory level of the file browser selection +# +proc browse_tree_down {adr_var_name tr which_fs} { + global extract_to_adr insert_from_adr burn_write_image_adr isodir_adr + global isomanip_move_target indev_adr outdev_adr + + set selected [$tr selection get] + if {[llength $selected] != 1} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You must select a single tree item before clicking the \"Down\" button." + return "" + } + set adr [lindex $selected 0] + if {$which_fs == "isofs"} { + browse_iso_open_dir $tr $adr + } else { + browse_disk_open_dir $tr $adr + } + catch { + $tr opentree $adr 0 + $tr see $adr + } +} + + +# The command to be executed when the user closes a directory node. +# It replaces the directory content list by a single dummy item. +# +proc browse_tree_close_dir {tr name} { + browse_tree_fill_dir $tr $name [list "? "] +} + + +# Delete the old content of the browse window and display the freshly +# obtained current state down to the current address in the field variable. +# +proc browse_tree_populate {which_fs} { + global have_bwidget + global browse_disk_window_var browse_iso_window_var + global browse_iso_window_is_active browse_disk_window_is_active + global extract_to_adr insert_from_adr burn_write_image_adr isodir_adr + global isomanip_move_target indev_adr outdev_adr cmd_log_target + global debug_log_file execute_script_adr + + if {$have_bwidget != 1} {return ""} + + if {$which_fs == "isofs"} { + if {$browse_iso_window_is_active == 0} {return ""} + set w {.browse_iso_window} + set open_dir_cmd "browse_iso_open_dir" + set adr_var $browse_iso_window_var + } else { + if {$browse_disk_window_is_active == 0} {return ""} + set w {.browse_disk_window} + set open_dir_cmd "browse_disk_open_dir" + set adr_var $browse_disk_window_var + } + + # Variable indirection + eval set adr $$adr_var + + # Install root level + $open_dir_cmd $w.tree "/" + + # Set $adr as current address + set comps [split $adr "/"] + # Install the stack of directories above current address + set path "/" + foreach i $comps { + if {$i == ""} { + continue + } + set path [combine_dir_and_name $path [escape_to_tree $i]] + $open_dir_cmd $w.tree $path + catch { + $w.tree opentree $path 0 + $w.tree see $path + } + } +} + + +# The procedure to be run by mouse button 3 in the file browser. +# It has to strip off the surplus parameter added by the Tree widget. +# +proc browse_tree_help {about_what button_color from_item} { + window_help $about_what $button_color +} + + +# Destroy the hard disk browser pop-up window. +# +proc destroy_browse_disk {w} { + global browse_disk_window_is_active browse_disk_window_geometry + global browse_disk_window_is_grabbed + + if {$w != "" && $browse_disk_window_is_active == 1} { + if {$browse_disk_window_is_grabbed == 1} { + grab release $w + } + set browse_disk_window_is_grabbed 0 + set browse_disk_window_geometry [wm geometry $w] + destroy $w + } + set browse_disk_window_is_active 0 +} + + +# The command to be executed when the user opens a directory node in +# the hard disk filesystem. +# +proc browse_disk_open_dir {tr name} { + set escpd [unescape_from_tree $name] + if {[localfs_filetype $escpd] != "d"} {return ""} + set lslist [localfs_ls $escpd] + browse_tree_fill_dir $tr $escpd $lslist +} + + +# Refresh the content of a possibly displayed tree browser for hard disk +# +proc browse_disk_refresh {} { + browse_tree_populate "localfs" +} + + +# The command to be executed when the user opens a directory node in +# the ISO model. +# +proc browse_iso_open_dir {tr name} { + set escpd [unescape_from_tree $name] + if {[isofs_filetype $escpd] != "d"} {return ""} + set lslist [isofs_ls $escpd] + browse_tree_fill_dir $tr $escpd $lslist +} + + +# Destroy the ISO browser pop-up window. +# +proc destroy_browse_iso {w} { + global browse_iso_window_is_active browse_iso_window_geometry + global browse_iso_window_is_grabbed + + if {$w != "" && $browse_iso_window_is_active == 1} { + set browse_iso_window_geometry [wm geometry $w] + if {$browse_iso_window_is_grabbed == 1} { + grab release $w + } + set browse_iso_window_is_grabbed 0 + destroy $w + } + set browse_iso_window_is_active 0 +} + + +# Refresh the content of a possibly displayed tree browser for ISO model +# +proc browse_iso_refresh {} { + browse_tree_populate "isofs" +} + + +# Multiplexer for updating both vertical scrollbars +# +proc browse_tree_yscrollcommand {w arg1 arg2} { + $w.treescroll_y_l set $arg1 $arg2 + $w.treescroll_y_r set $arg1 $arg2 +} + + +# Open a file browser window for hard disk filesystem or ISO model +# +proc browse_tree {adr_var which_fs} { + upvar $adr_var adr + global have_bwidget browse_disk_window_is_active browse_iso_window_is_active + global browse_disk_window_var browse_iso_window_var + global tree_window_lines tree_window_width tree_window_button_width + global browse_disk_window_geometry browse_iso_window_geometry + + set button_color "grey" + + if {$which_fs == "isofs"} { + set w {.browse_iso_window} + set window_is_active $browse_iso_window_is_active + set title_name "xorriso-tcltk ISO model browser" + set open_dir_cmd "browse_iso_open_dir" + set destroy_cmd "destroy_browse_iso" + if {$browse_iso_window_var != $adr_var && $window_is_active == 1} { + destroy_browse_iso $w + set window_is_active 0 + } + set browse_iso_window_var $adr_var + set old_geometry $browse_iso_window_geometry + set browse_iso_window_is_active 1 + } else { + set w {.browse_disk_window} + set window_is_active $browse_disk_window_is_active + set title_name "xorriso-tcltk hard disk filesystem browser" + set open_dir_cmd "browse_disk_open_dir" + set destroy_cmd "destroy_browse_disk" + if {$browse_disk_window_var != $adr_var && $window_is_active == 1} { + destroy_browse_disk $w + set window_is_active 0 + } + set browse_disk_window_var $adr_var + set old_geometry $browse_disk_window_geometry + set browse_disk_window_is_active 1 + } + set re_use_widgets 0 + if {$window_is_active == 0} { + toplevel $w -borderwidth 10 -class Browser + wm title $w $title_name + set_window_position $w $old_geometry + } else { + set re_use_widgets 1 + } + if {$re_use_widgets == 0} { + + if {$have_bwidget == 1} { + # BWidget Tree + frame $w.tree_frame + frame $w.tree_frame_x + Tree $w.tree -width $tree_window_width -height $tree_window_lines \ + -opencmd "$open_dir_cmd $w.tree" \ + -closecmd "browse_tree_close_dir $w.tree" \ + -selectfill 1 \ + -yscrollcommand "browse_tree_yscrollcommand $w" \ + -xscrollcommand "$w.treescroll_x set" + + # ??? why doesn't work ? + # $w.tree bindText \ + # "browse_tree_accept_bindtext $adr_var 1 $w.tree" + + # At least double-click does work + $w.tree bindText \ + "browse_tree_accept_escd $adr_var 1 $w.tree" + + $w.tree bindText {browse_tree_help "Browse tree" grey} + + scrollbar $w.treescroll_y_l -command "$w.tree yview" + scrollbar $w.treescroll_y_r -command "$w.tree yview" + scrollbar $w.treescroll_x -orient horizontal -command "$w.tree xview " + pack $w.tree -in $w.tree_frame_x -side top -expand 1 -fill both + pack $w.treescroll_x -in $w.tree_frame_x -side top -expand 1 -fill x + pack $w.treescroll_y_l -in $w.tree_frame -side left -expand 1 -fill y + pack $w.tree_frame_x -in $w.tree_frame -side left -expand 1 -fill both + pack $w.treescroll_y_r -in $w.tree_frame -side left -expand 1 -fill y + + frame $w.button_line + button $w.accept -text "Accept" -width $tree_window_button_width \ + -command "browse_tree_accept_sel $adr_var 1 $w.tree" + bind_help $w.accept "Accept (browse tree)" + button $w.to_field -text "Edit" -width $tree_window_button_width \ + -command "browse_tree_accept_sel $adr_var 0 $w.tree" + bind_help $w.to_field "Edit (browse tree)" + button $w.up -text "Up" -width $tree_window_button_width \ + -command "browse_tree_up $adr_var $w.tree $which_fs" + bind_help $w.up "Up (browse tree)" + button $w.down -text "Down" -width $tree_window_button_width \ + -command "browse_tree_down $adr_var $w.tree $which_fs" + bind_help $w.down "Down (browse tree)" + pack $w.up $w.down $w.accept $w.to_field \ + -in $w.button_line -side left -expand 0 + + pack $w.tree_frame -side top -anchor w -expand 1 -fill both + } else { + frame $w.button_line + button $w.accept -text "Accept" -width $tree_window_button_width \ + -command "browse_tree_accept_entry $adr_var 1 $w.tree" + bind_help $w.accept "Accept (browse tree)" + pack $w.accept -in $w.button_line -side left -expand 0 + } + button $w.help -text "Help" -width $tree_window_button_width \ + -command {window_help "Browse tree" grey} + bind_help $w.help "Browse tree" + button $w.close -text "Close" -width $tree_window_button_width \ + -command "$destroy_cmd $w" \ + -background $button_color + bind_help $w.close "Close (browse tree)" + pack $w.help $w.close \ + -in $w.button_line -side left -expand 0 + + pack $w.button_line -side top -anchor center + + frame $w.text_frame + label $w.topic -text "[browse_tree_topic $adr_var]" + bind_help $w.topic "Browse tree" + entry $w.text_entry -relief sunken -bd 1 -width 40 \ + -textvariable $adr_var + bind_entry_keys $w.text_entry \ + "browse_tree_accept_entry $adr_var 1 $w.tree" + bind_help $w.text_entry "Browse tree" + pack $w.topic -in $w.text_frame -side left + pack $w.text_entry -in $w.text_frame -side left -expand 1 -fill both + pack $w.text_frame -side top -expand 1 -fill both + } + raise $w + if {$have_bwidget == 1} { + browse_tree_populate $which_fs + focus $w.tree + } + update idletasks +} + + +# ------ GUI display procedures ---- + + +# Display a message of xorriso or of this frontend in the .msglist box +# +proc display_msg {msg} { + global .msglist + global msglist_max_fill msglist_running pre_msglist display_msg_enabled + + if {$display_msg_enabled == 0} {return ""} + if {$msg == "============================" || \ + $msg == "==============================================================" || \ + $msg == "enter option and arguments :"} {return ""} + + if {$msglist_running == 0} { + lappend pre_msglist $msg + } else { + if {[.msglist index end] > $msglist_max_fill} { + .msglist delete 0 0 + } + .msglist insert end [escape_newline $msg 0] + .msglist see [expr "[.msglist index end]-1"] + update idletasks + } +} + + +# Set whether messages submitted to proc display_message shall really show up +# This is used by callback procedures to hide auxiliary commands and lengthy +# reply messages from the user display. +# +proc set_display_msg {mode} { + global display_msg_enabled + + set old $display_msg_enabled + if {$mode == "0"} { + set display_msg_enabled 0 + } else { + set display_msg_enabled "1" + } + return $old +} + + +# Display a frontend error message in the .msglist box and by a pop-up window. +# +proc xorriso_tcltk_errmsg {msg} { + global highest_cmd_sev_msg + + set highest_cmd_sev_msg [escape_newline $msg 0] + display_msg $msg + window_ack $msg "grey" "toplevel" + update idletasks +} + + +# Memorize the current selection in the .isolist box. +# +proc memorize_isolist_selection {} { + global memorized_isolist_selection isolist_names + global .isolist + + set memorized_isolist_selection "" + set selected [.isolist curselection] + foreach i $selected { + lappend memorized_isolist_selection [lindex $isolist_names $i] + } +} + + +# Restore the memorized selection in the .isolist box as far as the +# names have survived in the meantime. +# +proc restore_isolist_selection {} { + global memorized_isolist_selection isolist_names + global .isolist + + .isolist selection clear 0 end + foreach i $memorized_isolist_selection { + set idx [lsearch -exact $isolist_names $i] + if {$idx > -1} { + .isolist selection set $idx $idx + } + } + set memorized_isolist_selection "" +} + + +# Receive the answer of the yes/no window and destroy it. +# +proc destroy_yesno {w answer} { + global yesno_window_is_active answer_of_yesno yesno_window_geometry + global yesno_to_all + + if {$w != ""} { + set yesno_window_geometry [wm geometry $w] + grab release $w + destroy $w + update idletasks + } + set yesno_window_is_active 0 + set answer_of_yesno $answer + if {$answer == 2} { + set yesno_to_all 1 + set answer_of_yesno 1 + } + if {$answer == -1} { + set yesno_to_all -1 + set answer_of_yesno 0 + } +} + + +# Pop-up a window which asks for yes or no. Return 1 if answer is yes. +# +proc window_yesno {question} { + global answer_of_yesno yesno_window_is_active yesno_window_geometry + + set w {.yesno_window} + if {$yesno_window_is_active == 1} { + set yesno_window_is_active [window_exists $w] + } + if {$yesno_window_is_active == 1} { + raise $w + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You still need to answer an older yes/no question" + return "0" + } + set yesno_window_is_active 1 + set answer_of_yesno "" + toplevel $w -borderwidth 20 -class Dialog + wm title $w "xorriso-tcltk yes/no" + set_window_position $w $yesno_window_geometry + label $w.question -text $question + button $w.yes -text "yes" -command "destroy_yesno $w 1" \ + -borderwidth 4 -padx 20 -pady 20 + bind_help $w.yes "yes/no" + button $w.no -text "no" -command "destroy_yesno $w 0" \ + -borderwidth 4 -padx 20 -pady 20 + bind_help $w.no "yes/no" + pack $w.yes $w.question $w.no -side left + update idletasks + + grab set $w + tkwait variable answer_of_yesno + return $answer_of_yesno +} + + +# Pop-up a window which asks for yes, yes-to-all, no, or no-to-all. +# Return 1 if answer is yes. +# +proc window_yesno_ever {question} { + global answer_of_yesno yesno_window_is_active yesno_window_geometry + global yesno_to_all + + set w {.yesno_window} + if {$yesno_window_is_active == 1} { + set yesno_window_is_active [window_exists $w] + } + if {$yesno_window_is_active == 1} { + raise $w + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You still need to answer an older yes/no question" + return "0" + } + if {$yesno_to_all == 1} { + return "1" + } + if {$yesno_to_all == -1} { + return "0" + } + set yesno_window_is_active 1 + set answer_of_yesno "" + toplevel $w -borderwidth 20 -class Dialog + wm title $w "xorriso-tcltk yes/no" + set_window_position $w $yesno_window_geometry + + frame $w.yes_frame + frame $w.no_frame + label $w.question -text $question + button $w.yes -text "yes" -command "destroy_yesno $w 1" \ + -borderwidth 4 -padx 20 -pady 20 -relief raised + button $w.no -text "no" -command "destroy_yesno $w 0" \ + -borderwidth 4 -padx 20 -pady 20 -relief raised + button $w.yes_to_all -text "yes to all" -command "destroy_yesno $w 2" + bind_help $w.yes_to_all "yes to all" + button $w.no_to_all -text "no to all" -command "destroy_yesno $w -1" + bind_help $w.no_to_all "no to all" + pack $w.yes $w.yes_to_all -in $w.yes_frame -side top -expand 1 -fill both + pack $w.no $w.no_to_all -in $w.no_frame -side top -expand 1 -fill both + pack $w.yes_frame $w.question $w.no_frame \ + -in $w -side left -expand 1 -fill both + + raise $w + update idletasks + + grab set $w + tkwait variable answer_of_yesno + return $answer_of_yesno +} + + +proc reset_yesno_to_all {} { + global yesno_to_all + + set yesno_to_all 0 +} + + +# Destroy the notification pop-up window. +# +proc destroy_ack {w had_focus} { + global ack_window_is_active ack_window_geometry + + if {$w != ""} { + set ack_window_geometry [wm geometry $w] + grab release $w + if {$had_focus != "-"} { + focus $had_focus + } + destroy $w + update idletasks + } + set ack_window_is_active 0 +} + + +# Pop-up a window which notifies of a problem and asks for a button click. +# +proc window_ack {question button_color where} { + global answer_of_yesno ack_window_is_active ack_window_geometry + global continue_from_ack + + set had_focus [focus] + if {$had_focus == ""} {set had_focus "-"} + set re_use_widgets 0 + if {$where == "embedded"} { + set w "" + set destroy_cmd "" + } else { + set w {.ack_window} + if {$ack_window_is_active == 1} { + set ack_window_is_active [window_exists $w] + } + if {$ack_window_is_active == 0} { + toplevel $w -borderwidth 20 -class Dialog + wm title $w "xorriso-tcltk acknowledge" + set ack_window_is_active 1 + } else { + set re_use_widgets 1 + } + set_window_position $w $ack_window_geometry + set destroy_cmd "destroy_ack $w $had_focus" + } + if {$re_use_widgets == 1} { + $w.question configure -text $question + } else { + label $w.question -text $question + button $w.ok -text "Continue" -command $destroy_cmd \ + -background $button_color + bind $w.ok $destroy_cmd + bind_help $w.ok "Continue" + pack $w.question -side top -expand 1 -fill both + pack $w.ok -side top + } + + raise $w + update idletasks + focus $w.ok + grab set $w + tkwait variable ack_window_is_active +} + + +# Destroy the help pop-up window. +# +proc destroy_help {w help_main} { + global help_window_is_active help_window_has_scroll help_window_geometry + global main_help_window_is_active main_help_window_geometry + + if {$w != ""} { + if {$help_main == 1} { + set main_help_window_geometry [wm geometry $w] + } else { + set help_window_geometry [wm geometry $w] + } + destroy $w + } + if {$help_main == 1} { + set main_help_window_is_active 0 + } else { + set help_window_is_active 0 + set help_window_has_scroll 0 + } +} + + +proc surround_text {text} { + return "\n\n [string map {\n "\n "} $text]\n" +} + + +# Pop-up a window which shows a help text and a Close button. +# +proc window_help {about_what button_color} { + global help_window_is_active help_window_lines help_window_has_scroll + global help_window_border_width help_window_geometry + global main_help_window_is_active + global main_help_window_lines main_help_window_geometry + global .help_window .main_help_window + + # The main help window is independent of the GUI element help window + if {$about_what == "Help"} { + set help_main 1 + set w {.main_help_window} + set window_is_active $main_help_window_is_active + set window_has_scroll 1 + set old_geometry $main_help_window_geometry + set window_lines $main_help_window_lines + } else { + set help_main 0 + set w {.help_window} + set window_is_active $help_window_is_active + set window_has_scroll $help_window_has_scroll + set old_geometry $help_window_geometry + set window_lines $help_window_lines + } + if {$window_is_active == 1} { + set window_is_active [window_exists $w] + } + + # Giving the help text some distance from the border decorations + set line_width 82 + set helptext "\n\n [string map {\n "\n "} [tell_helptext $about_what]]\n" + + if {[count_newlines $helptext] >= $window_lines} { + if {$window_is_active == 1 && $window_has_scroll == 0} { + destroy_help $w $help_main + set window_is_active 0 + } + if {$help_main == 1} { + set old_geometry $main_help_window_geometry + } else { + set help_window_has_scroll 1 + set window_has_scroll 1 + set old_geometry $help_window_geometry + } + } + # Dealing with initiating windows that are grabbed + set grabbed [grab current] + if {$grabbed == ""} {set grabbed "-"} + if {$grabbed != "-" && $window_is_active == 1} { + destroy_help $w $help_main + set window_is_active 0 + } + if {$grabbed != "-"} { + # Set old_geometry to position underneath grabbed window + set value [wm geometry $grabbed] + set idx [string first "+" $value] + set height_idx [string first "x" $value] + if {$idx != -1 && $height_idx != -1 && $idx > $height_idx} { + set width [string range $value 0 [expr $height_idx-1]] + set height [string range $value [expr $height_idx+1] [expr $idx-1]] + set x [string range $value [expr $idx+1] end] + set idx [string first "+" $x] + if {$idx != -1} { + set y [string range $x [expr $idx+1] end] + set x [string range $x 0 [expr $idx-1]] + set y [expr $y+$height] + set old_geometry "${width}x${height}+${x}+${y}" + } + } + } + + set re_use_widgets 0 + if {$window_is_active == 0} { + toplevel $w -borderwidth $help_window_border_width -class Help + set_window_position $w $old_geometry + if {$help_main == 1} { + wm title $w "xorriso-tcltk main help text" + set main_help_window_is_active 1 + reset_to_normal_background .help + update idletasks + } else { + wm title $w "xorriso-tcltk GUI element help text" + set help_window_is_active 1 + } + } else { + set re_use_widgets 1 + } + + if {$re_use_widgets == 1} { + $w.text configure -state normal + $w.text delete 1.0 end + $w.text insert end $helptext + raise $w + } else { + set destroy_cmd "destroy_help $w $help_main" + + frame $w.text_frame + text $w.text -width $line_width -height $window_lines \ + -relief flat -borderwidth 0 + $w.text insert end $helptext + pack $w.text -in $w.text_frame -side left -expand 1 -fill both + if {$window_has_scroll == 1} { + scrollbar $w.scroll_y -command "$w.text yview" + $w.text configure -yscrollcommand "$w.scroll_y set" + bind_listbox_keys $w.text $window_lines "text" + pack $w.scroll_y -in $w.text_frame -side left -fill y + } + + button $w.close -text "Close" -command $destroy_cmd \ + -background $button_color + pack $w.text_frame -side top -expand 1 -fill both + frame $w.middle_spacer -height 6 + frame $w.bottom_spacer -height 6 + pack $w.middle_spacer $w.close $w.bottom_spacer -side top + } + $w.text configure -state disabled +} + + +# Display the busy/ready state of xorriso. +# Called with 1 by sender of commands and with 0 by receivers of replies . +# +proc display_busy {state} { + global busy_text_exists + global .busy_text + + if {$busy_text_exists == 0} {return ""} + + if {$state == 0} { + .busy_text configure -text "ready" + .busy_text configure -background "#D0D0D0" + } else { + .busy_text configure -text "busy" + .busy_text configure -background "#808080" + } + update idletasks +} + + +# Tries to make use of the BWidget package for getting its Tree widget +# +proc check_for_bwidget {} { + global have_bwidget bwidget_version + + if {$have_bwidget == 0} { + catch { + set bwidget_version [package require BWidget] + set have_bwidget 1 + } + } +} + + +# A window to display if no file browser is available +# +proc browser_dummy {} { + window_ack \ + "The file browser cannot be used because Tcl/Tk package \"BWidget\" is not loaded" "grey" "toplevel" +} + + +# Obtain the geometry string of a window +# +proc get_window_geometry {w} { + wm geometry $w +} + + +# Set the position of a window from a geometry string +# +proc set_window_position {w geometry} { + set value $geometry + set idx [string first "+" $value] + if {$idx == -1} { + set value [wm geometry .] + set idx [string first "+" $value] + } + if {$idx == -1} { return "" } + set pos [string range $value $idx end] + wm geometry $w $pos +} + + +# Reset button appearance from startup color to normal color +# +proc reset_to_normal_background {w} { + set normal_color [.drive_drop_both cget -background] + $w configure -background $normal_color +} + + +# Checks whether a window is really there +# +proc window_exists {w} { + set window_exists 0 + catch { + $w cget -background + set window_exists 1 + } + return $window_exists +} + + +# ------ Building GUI components ------ + +# ------ GUI layout parameters ------ + +# The default position of the main window +set main_window_geometry "" + +# How to mark the borders of the main grouping frames +set main_framerelief ridge +set main_borderwidth 4 + +# How to mark the borders of the second level grouping frames +set borderwidth 1 + +# Number of lines in msglist display +set msglist_lines 8 +set msglist_max_fill 1000 +set msglist_running 0 + +# Number of lines in drivelist display +set drivelist_lines 2 + +# Number of lines in ISO directory content display +set isolist_lines 8 + +# Whether the message box shall export its selection to the whole X display +set export_msg_selection true + +# Wether the item lists shall export their selection +set export_selection false + +# The number of lines in the display of the help texts +set main_help_window_lines 24 +set help_window_lines 16 + +# The distance of the help text from the help window border +set help_window_border_width 0 + +# The number of items to display in a tree browser window +set tree_window_lines 12 +# The number of visible characters in a tree browser line +set tree_window_width 50 +# The width in characters of the six buttons under the tree browser +set tree_window_button_width 6 + + +# -------- GUI definition procedures + + +# Overall definition of the GUI +# +proc init_gui {} { + global .input .cmdline_entry .msgbox .errmsg .dev .drivebox + global .isobox .localfs + global main_framerelief main_borderwidth click_to_focus + + check_for_bwidget + + # Main grouping frames + frame .connection_block \ + -relief $main_framerelief -borderwidth $main_borderwidth + frame .drive_block \ + -relief $main_framerelief -borderwidth $main_borderwidth + frame .iso_block \ + -relief $main_framerelief -borderwidth $main_borderwidth + + init_input + init_msgbox + init_errmsg + init_dev + init_drivebox + init_isobox + init_isomanip + init_burn + init_localfs + + pack .input .msgbox .errmsg -in .connection_block \ + -side top -expand 1 -fill both + pack .drivebox .dev .burn -in .drive_block \ + -side top -expand 1 -fill both + pack .localfs .isobox .isomanip -in .iso_block \ + -side top -expand 1 -fill both + + pack .connection_block .drive_block .iso_block \ + -side top -expand 1 -fill both + + if {$click_to_focus == 1} { + focus .msglist + } +} + + +# The xorriso headline with End button, xorriso version, busy/ready indicator, +# command line, and "Refresh disp" button. +# +proc init_input {} { + global borderwidth busy_text_exists xorriso_version debug_logging + global cmd_logging_mode cmd_log_target osirrox_allowed cmd_logging_all + global .input .input_line1 .xorriso_version .busy .busy_text + global .refresh_state .end_button .cmdline .log_pipes_switch + + set extract_state "normal" + if {$osirrox_allowed == 0} {set extract_state "disabled"} + + frame .input -borderwidth $borderwidth + frame .input_line1 -borderwidth 0 + pack .input_line1 -in .input \ + -side top -anchor w -expand 1 -fill both + + button .end_button -text "End" -command "end_xorriso" + bind_help .end_button "End" + + if {[string length $xorriso_version] > 10} { + set xorriso_version [string range $xorriso_version 0 9] + } + label .xorriso_version -text "xorriso-$xorriso_version" + bind_help .xorriso_version "version" + frame .busy -relief ridge -borderwidth 2 + label .busy_text -width 5 -text "busy" + bind_help .busy_text "ready/busy" + set busy_text_exists 1 + pack .busy_text -in .busy + + button .refresh_state -text "Refresh disp" \ + -command "refresh_state" + bind_help .refresh_state "Refresh disp" + + menubutton .script_log -text "Script/Log" -anchor w \ + -direction below -relief ridge -indicatoron 1 \ + -menu .script_log.menu + bind_help .script_log "Script/Log" + set m ".script_log.menu" + menu $m + $m add checkbutton -label "Log command script" \ + -indicatoron 1 -selectcolor "" \ + -command "effectuate_command_logging 0" \ + -variable cmd_logging_mode \ + -onvalue 1 -offvalue 0 + $m add checkbutton -label "Log non-essential commands" \ + -indicatoron 1 -selectcolor "" \ + -variable cmd_logging_all \ + -onvalue 1 -offvalue 0 + $m add command -label "Set log script address" \ + -command "set_log_script_address" + $m add separator + $m add checkbutton -label "Log pipes" \ + -indicatoron 1 -selectcolor "" \ + -variable debug_logging \ + -onvalue 1 -offvalue 0 + $m add command -label "Set pipe log address" \ + -command "set_debug_log_address" + $m add separator + $m add separator + $m add command -label "Execute command script" \ + -command "start_script_execution" + $m add checkbutton -label "Allow extract to disk" \ + -state $extract_state \ + -indicatoron 1 -selectcolor "" \ + -variable script_with_osirrox \ + -onvalue 1 -offvalue 0 + $m add separator + $m add command -label "Permanently ban extraction" \ + -state $extract_state \ + -command "osirrox_banned" + + button .help -text "Help" -command {window_help "Help" "grey"} \ + -background "grey" + bind_help .help "Help" + + init_cmdline + + pack .end_button .xorriso_version .busy -in .input_line1 -side left + pack .cmdline \ + -in .input_line1 -side left -expand 1 -fill both + pack .refresh_state .script_log .help -in .input_line1 -side left +} + + +# The combination of "Command:" label and command line +# +proc init_cmdline {} { + global cmdline borderwidth + global .cmdline .cmdline_text .cmdline_entry + + frame .cmdline -borderwidth 0 + + label .cmdline_text -width 10 -text "Command:" + bind_help .cmdline_text "Command:" + entry .cmdline_entry -width 56 -relief sunken -bd 1 \ + -textvariable cmdline + bind_entry_keys .cmdline_entry {cmdline_return} + bind_help .cmdline_entry "Command:" + + # >>> is there a chance to get a history on an entry ? + + pack .cmdline_text -in .cmdline -side left + pack .cmdline_entry -in .cmdline -side left -expand 1 -fill both +} + + +# The listbox where to display commands and reply messages unless this is +# disabled for auxiliary commands which shall not clutter the display. +# +proc init_msgbox {} { + global borderwidth + global msglist_lines export_msg_selection msglist_running pre_msglist + global .msgbox .msglist .msgscroll + + frame .msgbox -borderwidth $borderwidth + + listbox .msglist -height $msglist_lines -selectmode extended \ + -yscrollcommand ".msgscroll set" \ + -exportselection $export_msg_selection + bind_listbox_keys ".msglist" $msglist_lines "listbox" + bind_help .msglist "message box" + set msglist_running 1 + foreach i $pre_msglist { + display_msg [escape_newline $i 0] + } + scrollbar .msgscroll -command ".msglist yview" + pack .msglist -in .msgbox -side left -expand 1 -fill both + pack .msgscroll -in .msgbox -side right -fill y + set pre_msglist "" +} + + +# Two display lines for most severe event messages. One gets reset with +# each important command. The other one stays until the user clears it. +# +proc init_errmsg {} { + global borderwidth + global .errmsg .total_errmsg .cmd_errmsg + + frame .errmsg -borderwidth $borderwidth + + init_total_errmsg + init_cmd_errmsg + + pack .cmd_errmsg .total_errmsg -in .errmsg \ + -side top -anchor w -expand 1 -fill both + +} + + +# The most severe message display which gets reset automatically. +# +proc init_cmd_errmsg {} { + global borderwidth + global .cmd_errmsg .cmd_errmsg_label .cmd_errmsg_msg + + frame .cmd_errmsg -borderwidth $borderwidth + + label .cmd_errmsg_label -width 14 -text "Recent problem:" -anchor w + bind_help .cmd_errmsg_label "Recent problem:" + label .cmd_errmsg_msg -width 80 -relief ridge -bd 2 \ + -anchor w \ + -textvariable highest_cmd_sev_msg + # (no keys, no focus) + bind_help .cmd_errmsg_msg "Recent problem:" + pack .cmd_errmsg_label -in .cmd_errmsg -side left + pack .cmd_errmsg_msg -in .cmd_errmsg -side left -expand 1 -fill both +} + + +# The persistent most severe message display that is to be reset by the user. +# +proc init_total_errmsg {} { + global borderwidth + global .total_errmsg .total_errmsg_label .total_errmsg_msg + global .total_errmsg_clear + + frame .total_errmsg -borderwidth $borderwidth + + label .total_errmsg_label -text "Worst problem:" -width 14 -anchor w + bind_help .total_errmsg_label "Worst problem:" + button .total_errmsg_clear -text "Clear" \ + -width 5 \ + -command "clear_total_errmsg" + bind_help .total_errmsg_clear "Clear" + label .total_errmsg_msg -width 80 -relief ridge -bd 2 \ + -anchor w \ + -textvariable highest_total_sev_msg + # (no keys, no focus) + bind_help .total_errmsg_msg "Worst problem:" + pack .total_errmsg_label -in .total_errmsg -side left + pack .total_errmsg_msg -in .total_errmsg -side left -expand 1 -fill both + pack .total_errmsg_clear -in .total_errmsg -side left +} + + +# The list of drives which were found by scanning, the Scan button, and +# buttons for picking a drive from the list, for giving them up, for +# calming them down, and for reloading the ISO image from the input drive. +# +proc init_drivebox {} { + global borderwidth drivelist_lines export_selection + global .drivebox .drivelistbox .drivelist .drivescroll .drive_scan + global .drive_picker .drive_scan .drive_pick_in .drive_pick_out + global .drive_pick_both .drive_drop_both .drive_calm .iso_rollback_button + + + frame .drivebox -borderwidth $borderwidth + frame .drivelistbox -borderwidth $borderwidth + listbox .drivelist -height $drivelist_lines -selectmode extended \ + -yscrollcommand ".drivescroll set" \ + -exportselection $export_selection + bind_listbox_keys ".drivelist" $drivelist_lines "listbox" + bind_help .drivelist "drivelist" + scrollbar .drivescroll -command ".drivelist yview" + + pack .drivelist -in .drivelistbox -side left -expand 1 -fill both + pack .drivescroll -in .drivelistbox -side right -fill y + + frame .drive_picker -borderwidth $borderwidth + frame .drive_picker_line_1 -borderwidth 0 + frame .drive_picker_line_2 -borderwidth 0 + frame .drive_aux_buttons_line_1 -borderwidth 0 + frame .drive_aux_buttons_line_2 -borderwidth 0 + frame .drive_aux_buttons -borderwidth 0 + + button .drive_scan -text "Scan for drives" \ + -background "grey" \ + -command "scan_for_drives" + bind_help .drive_scan "Scan for drives" + button .drive_pick_in -text "Pick input drive" \ + -command "pick_indev" + bind_help .drive_pick_in "Pick input drive" + button .drive_pick_out -text "Pick output drive" \ + -command "pick_outdev" + bind_help .drive_pick_out "Pick output drive" + button .drive_pick_both -text "Pick drive for both roles" \ + -command "pick_dev" + bind_help .drive_pick_both "Pick drive for both roles" + button .drive_drop_both -text "Give up drives" \ + -command "give_up_dev" + bind_help .drive_drop_both "Give up drives" + button .drive_calm -text "Calm drives" \ + -command "calm_drives" + bind_help .drive_calm "Calm drives" + button .iso_rollback_button -text "Rollback" -width 9 \ + -command {iso_rollback} + bind_help .iso_rollback_button "Rollback" + + # One button block left, one right + pack .drive_pick_in .drive_pick_out \ + -in .drive_picker_line_1 -side left -expand 1 -fill none + pack .drive_pick_both \ + -in .drive_picker_line_2 -side left -expand 1 -fill x + pack .drive_picker_line_1 .drive_picker_line_2 \ + -in .drive_picker -side top -expand 1 -fill x -anchor w + pack .drive_scan .drive_calm \ + -in .drive_aux_buttons_line_1 -side left -expand 1 -fill none + pack .drive_drop_both .iso_rollback_button \ + -in .drive_aux_buttons_line_2 -side left -expand 1 -fill x + pack .drive_aux_buttons_line_1 .drive_aux_buttons_line_2 \ + -in .drive_aux_buttons -side top -expand 1 -fill x -anchor w + pack .drive_picker -in .drivebox -side left -expand 0 -fill none + pack .drivelistbox -in .drivebox -side left -expand 1 -fill both + pack .drive_aux_buttons -in .drivebox -side left -expand 0 -fill none + + bind .drivelist { + pick_dev + } +} + + +# The text fields for setting and display of the current input and output +# drives. With Eject button and a short text description of the medium status. +# +proc init_dev {} { + global borderwidth + global .dev .indev .outdev + + frame .dev -borderwidth $borderwidth + + init_indev + init_outdev + + pack .indev .outdev -in .dev \ + -side top -anchor w -expand 1 -fill both +} + + +# Set and display the current input drive. +# +proc init_indev {} { + global borderwidth indev_adr + global .indev .indev_eject .indev_label .indev_entry .indev_summary + + frame .indev -borderwidth $borderwidth + + button .indev_eject -text "Eject" -command {eject_indev} + bind_help .indev_eject "Eject (indev)" + + button .indev_label -width 16 -text "Input drive/image " \ + -command {indev_return} + + bind_help .indev_label "Input drive/image" + entry .indev_entry -width 34 -relief sunken -bd 1 \ + -textvariable indev_adr + + bind_entry_keys .indev_entry {indev_return} + bind_help .indev_entry "Input drive/image" + label .indev_summary -width 60 -text "" -relief ridge -borderwidth 2 + bind_help .indev_summary "input drive info" + create_browser_button .indev_browse_button \ + "indev_adr" "localfs" "Browse disk (indev)" + + pack .indev_eject .indev_label .indev_entry \ + -in .indev -side left -expand 1 -fill both + pack .indev_browse_button -in .indev -side left + pack .indev_summary \ + -in .indev -side left -expand 1 -fill both +} + + +# Set and display the current output drive. +# +proc init_outdev {} { + global .outdev .outdev_eject .outdev_label .outdev_entry .outdev_summary + global borderwidth outdev_adr + + frame .outdev -borderwidth $borderwidth + + button .outdev_eject -text "Eject" -command {eject_outdev} + bind_help .outdev_eject "Eject (outdev)" + + button .outdev_label -width 16 -text "Output drive/image" \ + -command {outdev_return} + + bind_help .outdev_label "Output drive/image" + entry .outdev_entry -width 34 -relief sunken -bd 1 \ + -textvariable outdev_adr + bind_entry_keys .outdev_entry {outdev_return} + bind_help .outdev_entry "Output drive/image" + create_browser_button .outdev_browse_button \ + "outdev_adr" "localfs" "Browse disk (outdev)" + label .outdev_summary -width 60 -text "" -relief ridge -borderwidth 2 + bind_help .outdev_summary "output drive info" + pack .outdev_eject .outdev_label .outdev_entry \ + -in .outdev -side left -expand 1 -fill both + pack .outdev_browse_button -in .outdev -side left + pack .outdev_summary \ + -in .outdev -side left -expand 1 -fill both +} + + +# The button panel for blanking, formatting, and writing to the output drive. +# +proc init_burn {} { + global borderwidth burn_write_image_adr burn_write_close burn_write_tao + global burn_write_defect_mgt + global .burn .burn_blank_button .burn_format_button .burn_commit_button + global .burn_write_image .burn_write_image_entry .burn_write_close + global .burn_write_tao .burn_write_defect_mgt + + frame .burn -borderwidth $borderwidth + + button .burn_blank_button -text "Blank" \ + -command {burn_blank} + bind_help .burn_blank_button "Blank" + button .burn_format_button -text "Format" \ + -command {burn_format} + bind_help .burn_format_button "Format" + button .burn_commit_button -text "Write ISO session" \ + -command {burn_commit} + bind_help .burn_commit_button "Write ISO session" + button .burn_write_image -text "Burn image file:" \ + -command {burn_write_image} + bind_help .burn_write_image "Burn image file:" + entry .burn_write_image_entry -width 40 -relief sunken -bd 1 \ + -textvariable burn_write_image_adr + bind_entry_keys .burn_write_image_entry {burn_write_image} + bind_help .burn_write_image_entry "Burn image file:" + create_browser_button .burn_image_browse_button \ + "burn_write_image_adr" "localfs" "Browse disk (burn image)" + checkbutton .burn_write_close -text "Close" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable burn_write_close \ + -onvalue 1 -offvalue 0 + bind_help .burn_write_close "Close" + checkbutton .burn_write_tao -text "TAO" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable burn_write_tao \ + -onvalue 1 -offvalue 0 + bind_help .burn_write_tao "TAO" + checkbutton .burn_write_defect_mgt -text "Defect Mgt" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable burn_write_defect_mgt \ + -onvalue 1 -offvalue 0 + bind_help .burn_write_defect_mgt "Defect Mgt" + pack .burn_blank_button .burn_format_button \ + .burn_commit_button .burn_write_close .burn_write_tao \ + .burn_write_defect_mgt \ + .burn_write_image .burn_write_image_entry \ + -in .burn -side left -expand 1 -fill both + pack .burn_image_browse_button -in .burn -side left +} + + +# Set and display the current ISO directory and its content. +# +proc init_isobox {} { + global borderwidth isolist_lines export_selection + global .isobox .isodir .isolist .isodir_entry .isodir_up .isodir_up2 + global .isodir_label .isodir_verify .isolistbox .isoscroll_y .isoscroll_x + + frame .isobox -borderwidth $borderwidth + frame .isodir -borderwidth 0 + + label .isodir_label -text "ISO directory:" \ + -width 14 + bind_help .isodir_label "ISO directory:" + entry .isodir_entry -width 60 -relief sunken -bd 1 \ + -textvariable isodir_adr + bind_entry_keys .isodir_entry {isodir_return "isodir_entry"} + bind_help .isodir_entry "ISO directory:" + create_browser_button .isodir_browse_button \ + "isodir_adr" "isofs" "Browse ISO (isodir)" + button .isodir_verify -text "Verify" -command {isodir_verify} + bind_help .isodir_verify "Verify" + button .isodir_up -text "Up" -command {isodir_up} + bind_help .isodir_up "Up" + button .isodir_up2 -text "Up" -command {isodir_up} + bind_help .isodir_up2 "Up" + pack .isodir_label .isodir_up \ + -in .isodir -side left + pack .isodir_entry \ + -in .isodir -side left -expand 1 -fill both + pack .isodir_browse_button .isodir_up2 .isodir_verify \ + -in .isodir -side left + + frame .isolistbox -borderwidth 0 + listbox .isolist -height $isolist_lines -selectmode extended \ + -yscrollcommand ".isoscroll_y set" \ + -xscrollcommand ".isoscroll_x set" \ + -exportselection $export_selection + bind_listbox_keys ".isolist" $isolist_lines "listbox" + bind_help .isolist "isolist" + scrollbar .isoscroll_y -command ".isolist yview" + scrollbar .isoscroll_x -orient horizontal -command ".isolist xview" + pack .isolist -in .isolistbox -side left -expand 1 -fill both + bind .isolist { pick_isodir } + pack .isoscroll_y -in .isolistbox -side right -fill y + + pack .isodir .isolistbox .isoscroll_x \ + -in .isobox -side top -expand 1 -fill both +} + + +# The ISO-internal manipulation buttons for the ISO directory or its content. +# Plus a text field where to set an ISO path as target for renaming or +# directory making. +# +proc init_isomanip {} { + global borderwidth isomanip_move_target + global .isomanip .isomanip_move .isomanip_prefix .isomanip_verify_button + global .isomanip_move_target .isomanip_rm_r_button .isomanip_move_button + global .isomanip_mkdir_button .isomanip_move_target + global .avail_label .avail_label_frame .avail_button + + frame .isomanip -borderwidth $borderwidth + frame .isomanip_move -borderwidth 0 + + label .isomanip_prefix -text "Selection:" + bind_help .isomanip_prefix "Selection:" + + button .isomanip_verify_button -text "Verify" \ + -command {isomanip_verify} + bind_help .isomanip_verify_button "Verify (selection)" + button .isomanip_rm_r_button -text "Delete" \ + -command {isomanip_rm_r} + bind_help .isomanip_rm_r_button "Delete" + button .isomanip_move_button -text "Move to:" \ + -command {isomanip_mv} + bind_help .isomanip_move_button "Move to:" + button .isomanip_mkdir_button -text "Make dir" \ + -command {isomanip_mkdir} + bind_help .isomanip_mkdir_button "Make dir" + entry .isomanip_move_target -width 60 -relief sunken -bd 1 \ + -textvariable isomanip_move_target + bind_entry_keys .isomanip_move_target {isomanip_mv} + bind_help .isomanip_move_target "rename and mkdir target" + create_browser_button .isomanip_move_target_button \ + "isomanip_move_target" "isofs" "Browse ISO (move target)" + + pack .isomanip_prefix .isomanip_verify_button .isomanip_rm_r_button \ + .isomanip_move_button \ + -in .isomanip_move -side left + pack .isomanip_move_target \ + -in .isomanip_move -side left -expand 1 -fill both + pack .isomanip_move_target_button -in .isomanip_move -side left + pack .isomanip_mkdir_button \ + -in .isomanip_move -side left -expand 1 -fill both + pack .isomanip_move \ + -in .isomanip -side top -expand 1 -fill both +} + + +# The means for interaction of ISO image and hard disk filesystem. +# +proc init_localfs {} { + global borderwidth + global .localfs .extract_frame .aux_control_frame .insert_frame + + frame .localfs -borderwidth $borderwidth + + init_extract + init_aux_control + init_insert + + pack .extract_frame .aux_control_frame .insert_frame \ + -in .localfs -side top -expand 1 -fill both +} + + +# The means for extracting files from ISO image to disk +# +proc init_extract {} { + global borderwidth extract_to_adr extract_from_selected extract_underneath + global osirrox_allowed + global .extract_button .extract_frame .extract_entry .extract_from_selected + global .extract_underneath + + set extract_state "normal" + if {$osirrox_allowed == 0} {set extract_state "disabled"} + + frame .extract_frame -borderwidth 0 + button .extract_button -text "Extract to disk:" \ + -state $extract_state \ + -width 17 \ + -command {extract_to} + bind_help .extract_button "Extract to disk:" + entry .extract_entry -width 40 -relief sunken -bd 1 \ + -textvariable "extract_to_adr" + bind_entry_keys .extract_entry {extract_to} + bind_help .extract_entry "Extract to disk:" + create_browser_button .extract_browse_button \ + "extract_to_adr" "localfs" "Browse disk (extract)" + checkbutton .extract_underneath -text "Underneath" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable extract_underneath \ + -onvalue 1 -offvalue 0 + bind_help .extract_underneath "Underneath (extract)" + checkbutton .extract_from_selected -text "Selected" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable extract_from_selected \ + -onvalue 1 -offvalue 0 + bind_help .extract_from_selected "Selected (extract)" + pack .extract_button -in .extract_frame -side left + pack .extract_entry \ + -in .extract_frame -side left -expand 1 -fill both + pack .extract_from_selected .extract_underneath \ + -in .extract_frame -side right + pack .extract_browse_button -in .extract_frame -side right +} + + +# Some controls which apply to insertion, extraction, or both. +# +proc init_aux_control {} { + global borderwidth have_bwidget permission_policy + global .aux_control_frame + global .overwrite_iso_files_button .overwrite_dir_button .extract_auto_chmod + + frame .aux_control_frame -borderwidth 0 + + menubutton .overwriting -text "Overwriting:" -width 16 -anchor w \ + -direction above -relief ridge -indicatoron 1 \ + -menu .overwriting.menu + bind_help .overwriting "Overwriting:" + set_overwriting_label + set m ".overwriting.menu" + menu $m + $m add checkbutton -label "Overwrite ISO files" \ + -indicatoron 1 -selectcolor "" \ + -command set_overwriting_label \ + -variable overwrite_iso_files \ + -onvalue 1 -offvalue 0 + $m add checkbutton -label "Overwrite ISO dirs" \ + -indicatoron 1 -selectcolor "" \ + -command set_overwriting_label \ + -variable overwrite_iso_dirs \ + -onvalue 1 -offvalue 0 + $m add checkbutton -label "Overwrite hard disk files" \ + -indicatoron 1 -selectcolor "" \ + -command set_overwriting_label \ + -variable overwrite_disk_files \ + -onvalue 1 -offvalue 0 + $m add checkbutton -label "Enforce disk dir write access" \ + -indicatoron 1 -selectcolor "" \ + -command set_overwriting_label \ + -variable extract_auto_chmod \ + -onvalue 1 -offvalue 0 + + pack .overwriting -in .aux_control_frame -side left + + menubutton .perm_policy -text "Permissions: as is" -width 22 -anchor w \ + -direction above -relief ridge -indicatoron 1 \ + -menu .perm_policy.menu + set m ".perm_policy.menu" + menu $m -tearoff 0 + $m add radiobutton -label "as is" -value "as_is" \ + -variable permission_policy -command show_permission_policy + $m add radiobutton -label "readable" -value "readable" \ + -variable permission_policy -command show_permission_policy + $m add radiobutton -label "readonly" -value "readonly" \ + -variable permission_policy -command show_permission_policy + $m add radiobutton -label "mkisofs -r" -value "mkisofs_r" \ + -variable permission_policy -command show_permission_policy + show_permission_policy + bind_help .perm_policy "Permissions:" + + button .avail_button -text "Refresh avail:" \ + -command {refresh_avail} + bind_help .avail_button "Refresh avail:" + frame .avail_label_frame -relief ridge -borderwidth 2 + label .avail_label -width 12 -text "" + bind_help .avail_label "Refresh avail:" + pack .avail_label -in .avail_label_frame + + pack .avail_label_frame .avail_button .perm_policy \ + -in .aux_control_frame -side right +} + + +# The means for inserting files from disk into the ISO image +# +proc init_insert {} { + global borderwidth insert_from_adr insert_at_selected insert_underneath + global .insert_button .insert_from_frame .insert_entry .insert_at_selected + global .insert_underneath .insert_frame + + frame .insert_frame -borderwidth 0 + frame .insert_from_frame -borderwidth 0 + button .insert_button -text "Insert from disk:" \ + -width 17 \ + -command {insert_from} + bind_help .insert_button "Insert from disk:" + entry .insert_entry -width 40 -relief sunken -bd 1 \ + -textvariable "insert_from_adr" + bind_entry_keys .insert_entry {insert_from} + bind_help .insert_entry "Insert from disk:" + create_browser_button .insert_browse_button \ + "insert_from_adr" "localfs" "Browse disk (insert)" + checkbutton .insert_underneath -text "Underneath" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable insert_underneath \ + -onvalue 1 -offvalue 0 + bind_help .insert_underneath "Underneath (insert)" + checkbutton .insert_at_selected -text "Selected" \ + -indicatoron 1 -selectcolor "" \ + -relief ridge -borderwidth 2 \ + -variable insert_at_selected \ + -onvalue 1 -offvalue 0 + bind_help .insert_at_selected "Selected (insert)" + pack .insert_button -in .insert_from_frame -side left + pack .insert_entry \ + -in .insert_from_frame -side left -expand 1 -fill both + pack .insert_browse_button -in .insert_from_frame -side left + pack .insert_at_selected .insert_underneath \ + -in .insert_from_frame -side right + pack .insert_from_frame -in .insert_frame -side left -expand 1 -fill both +} + + +# Set common behavior of listboxes in respect to focus and navigation keys. +# +proc bind_listbox_keys {box height what_widget} { + global click_to_focus + + if {$click_to_focus == 1} { + bind $box <1> "focus \"$box\"" + bind $box <2> "focus \"$box\"" + bind $box <3> "focus \"$box\"" + } else { + bind $box "focus \"$box\"" + } + + # No underlining + if {$what_widget == "listbox"} { + $box configure -activestyle "none" + } + + # Need to evaluate all $box and $height at bind-time. Thus "-quotes. + bind $box " + if {\"%K\" == \"Up\"} { + $box yview scroll \"-1\" units + } + if {\"%K\" == \"Down\"} { + $box yview scroll 1 units + } + if {\"%K\" == \"Prior\"} { + $box yview scroll -[expr \"$height\" - 1] units +# $box yview scroll -1 pages + } + if {\"%K\" == \"Next\"} { + $box yview scroll [expr \"$height\" - 1] units +# $box yview scroll 1 pages + } + if {\"%K\" == \"Home\"} { + $box yview 0 + } + if {\"%K\" == \"End\"} { + $box yview end + } + + # >>> Do i need this ? + # >>> For now: yes. It prevents double scrolling by PgUp PgDown + # Prevent other bindings from being performed + break + " +} + + +# Set common behavior of entries in respect to focus and Return key. +# +proc bind_entry_keys {entry return_cmd} { + global click_to_focus + + if {$click_to_focus != 1} { + bind $entry "focus \"$entry\"" + } + if {$return_cmd != ""} { + bind $entry $return_cmd + } +} + + +# Bind a help text to a widget. +# +proc bind_help {to_what help_name} { + bind $to_what "window_help \"$help_name\" grey" +} + + +# Create a "/" button and wire it with variable, fileystem type, and help text. +# +proc create_browser_button {button_name var_name which_fs help_name} { + global have_bwidget + + button $button_name -text "/" -command "browse_tree $var_name $which_fs" + bind_help $button_name $help_name +} + + +proc set_overwriting_label {} { + global overwrite_iso_files overwrite_iso_dirs overwrite_disk_files + global extract_auto_chmod + global .overwriting + + # Determine text suffix for menubutton from overwrite variables + set oif "-" + if {$overwrite_iso_files == 1} {set oif "f"} + set oid "-" + if {$overwrite_iso_dirs == 1} {set oid "d"} + set ohf "-" + if {$overwrite_disk_files == 1} {set ohf "h"} + set fdw "-" + if {$extract_auto_chmod == 1} {set fdw "w"} + set otext "Overwriting: ${oif}${oid}${ohf}${fdw}" + .overwriting configure -text $otext +} + + +# The central storage for help texts. +# +proc tell_helptext {what} { + global own_version argv0 bwidget_version use_command_move + + if {$what == "Help"} { + return \ +"For getting particular help texts: + + Click the rightmost mouse button on any button, list box, or text field. + +For a help text about startup options of this frontend, execute in a shell: + + $argv0 --help + +For background info about xorriso and its commands, execute in a shell: + + man xorriso + +----------------------------------------------------------------------------- + +The GUI window is separated into three main areas: + +- The area for connection to xorriso + - shows xorriso messages, + - offers some general activities, + - displays the \"ready/busy\" state of the connection, + - and allows to toggle xorriso commands into the \"Command:\" field. + +- The area for management of drives and ISO image data files + - allows to scan for optical drives, + - to acquire them and load their ISO directory tree, + - to acquire ISO image files from hard disk as pseudo drives like DVD+RW, + - to blank CD-RW, DVD-RW DVD+RW, BD-RE and format DVD-RW, BD-R, + - to trigger writing of ISO sessions (which get defined in the third area), + - and to burn image data files from hard disk to optical media. + +- The area for inspection, manipulation, and exploitation of the ISO model + - allows to insert directories and files from hard disk into the ISO model, + - to delete and rename file objects in the ISO model, + - to verify data files of loaded ISO directory trees by MD5, + - to extract directories and files from ISO filesystem to hard disk. + +----------------------------------------------------------------------------- + Some Use Cases +----------------------------------------------------------------------------- + +- Burn a directory as only content onto a CD, DVD or BD +- Write a directory as only content to an ISO image data file on hard disk +- Burn an image data file from hard disk onto CD, DVD or BD +- Add more data to an appendable medium or to an ISO image data file +- Extract a directory tree from an ISO filesystem to hard disk + +----------------------------------------------------------------------------- + + Burn a directory as only content onto a CD, DVD or BD + +- Click the \"Scan for drives\" button in the middle area. +- Select a drive and click the \"Pick output drive\" button. +- If the information field in the \"Output drive/image\" line begins by + \"appendable\" or \"closed\" and if the medium is CD-RW, DVD-RW, DVD+RW, or + BD-RE then click the \"Blank\" button to erase the old data. + (Blanking of \"DVD-RW sequential recording\" will last very long.) +- Go to the \"Insert from disk:\" line in the lower area. + Either toggle in the address of the hard disk directory, + or click on the \"/\" button to the right of the text field to get + a file browser. +- Hit the Return key in the text field or double click on a name in the + browser to schedule the disk directory for writing to the medium. + You may of course insert several directories or files that way. +- Close the browser and click the \"Write ISO session\" button in the + middle area. Confirm in the \"yes/no\" window that pops up. + Burning will begin (or refuse on unsuitable medium status). +- When the \"busy\" field displays \"ready\" again, you may click \"Eject\". + Desktop drives should then put out the tray with the medium. + +----------------------------------------------------------------------------- + + Write a directory as only content to an ISO image data file on hard disk + +- Go to the text field beside the \"Output drive/image\" button and toggle + the address of the image file. Click the button or hit the Return key + when the address is complete. + Or click on the \"/\" button to the right of the field to get a file browser. +- You may click on a name in the browser and bring it into the text field + by button \"Edit\". +- When the intended file address is composed, hit the Return key in the + text field or click the \"Output drive/image\" button. +- If the information field in the \"Output drive/image\" line begins by + \"appendable\" or \"closed\" then you addressed an existing data file. + Warning: Applying the \"Blank\" button to it would damage its content ! + You probably do not want this in this special use case. +- Go to the \"Insert from disk:\" line in the lower area. + Continue like in the above description for CD, DVD, and BD media. + +----------------------------------------------------------------------------- + + Burn an image data file from hard disk onto CD, DVD or BD + +- Click the \"Scan for drives\" button in the middle area. +- Select a drive and click the \"Pick output drive\" button. +- If the information field in the \"Output drive/image\" line begins by + \"appendable\" or \"closed\" and if the medium is CD-RW, DVD-RW, DVD+RW, or + BD-RE then click the \"Blank\" button to erase the old data. + (Blanking of \"DVD-RW sequential recording\" will last very long.) +- Go to the text field beside the \"Burn image file:\" button and toggle + the address of the image file. Or click on the \"/\" button to the right + of the field to get a file browser. +- Hit the Return key in the text field or double click on a name in the + browser to initiate the burn run. + Confirm in the \"yes/no\" window that pops up. +- When the \"busy\" field displays \"ready\" again, you may click \"Eject\". + Desktop drives should then put out the tray with the medium. + +----------------------------------------------------------------------------- + + Add more data to an appendable medium or to an ISO image data file + +- Like above, \"Scan for drives\" but click button \"Pick drive for both roles\" + in order to load the directory tree of the existing ISO filesystem. + For an ISO image data file, bring its name into the input fields of both + lines \"Input drive/image\" and \"Output drive/image\" and activate it + by clicking both buttons or hitting the Return key in both fields. + You should now see in both info fields texts which begin by \"appendable\". +- Go to the \"Insert from disk:\" line in the lower area. + Use the means described in the first use case to add more directories or + data files. +- If you are interested in \"Delete\" or \"Move to:\" buttons in the + bottom line of the GUI: Click them by the rightmost mouse button to see + their help texts. +- When all intended changes are done: Click \"Write ISO session\" and + confirm in the \"yes/no\" window. + +----------------------------------------------------------------------------- + + Extract a directory tree from an ISO filesystem to hard disk + +- Like above, \"Scan for drives\" but click button \"Pick input drive\" + in order to load the directory tree of the existing ISO filesystem. + For an ISO image data file, bring its name into the input field of the + line \"Input drive/image\". You should now see in its info field a text + which begins by \"appendable\" or \"closed\". +- Go to the \"ISO directory:\" line and list box in the lower area and + select the directory or file you want to copy to hard disk. +- To get to see the desired file items, either toggle the address of their + parent directory into the text field and hit Return, or double click items + to open them as directories, or click the \"/\" button to get a file browser. + Select the item in the list box of the main window by a single click. +- Go to the \"Extract to disk:\" line and choose the target address on disk. + Either toggle in the address of the hard disk directory, or click on the + \"/\" button to the right of the text field to get a file browser. +- Hit the Return key in the text field or double click on a name in the + browser to initiate the extraction run. + If a \"yes/no\" window pops up, consider well whether you are up to + shooting your own foot right now. + Enable the \"Overwrite hard disk files\" switch only if you are really + sure that the files from ISO are better than the ones on hard disk. + +----------------------------------------------------------------------------- + +xorriso-tcltk is mainly a proof of concept for a frontend that operates +xorriso in dialog mode. + +It demonstrates some of xorriso's multi-session features with ISO 9660 +filesystems on optical media (CD, DVD, BD) or in disk files. + +Dependencies: + xorriso, Tcl language, Tk GUI toolkit, optionally Tcl/Tk package BWidget + +Copyright (C) 2012 - 2016 +Thomas Schmitt , libburnia-project.org +Provided under BSD license: Use, modify, and distribute as you like." + } + if {$what == "End"} { + return \ +"The \"End\" button leads to the end of frontend and xorriso process." + } + if {$what == "version"} { + return \ +"The field between \"End\" button and ready/busy field displays the +version of the serving xorriso program. + +xorriso is a program which copies file objects from POSIX compliant +filesystems into Rock Ridge enhanced ISO 9660 filesystems and allows +session-wise manipulation of such filesystems. It can load the management +information of existing ISO images and it writes the session results to +optical media or to filesystem objects. +Vice versa xorriso is able to restore file objects from ISO 9660 filesystems. + +xorriso-tcltk-$own_version is mainly a proof of concept for a frontend +that operates xorriso in dialog mode. + +It exercises several fundamental gestures of communication: +- connecting via two pipes +- sending commands +- receiving replies +- inquiring the xorriso message sieve +- using the xorriso parsing service + +Note that any other language than Tcl/Tk could be used, if it only can +do i/o via standard input and standard output or via named pipes. +Further it has to perform integer arithmetics and string manipulations. +And, well, a graphical widget set would be nice." + } + if {$what == "Refresh disp"} { + return \ +"The \"Refresh disp\" button causes several text fields and list +boxes to update their display after manually transmitted commands may +have changed the state of drives or ISO model." + } + if {$what == "ready/busy"} { + return \ +"The ready/busy field indicates whether a xorriso command is being executed +and the frontend is still waiting for its reply messages." + } + if {$what == "Command:"} { + return \ +"The \"Command:\" field can be used to send commands to xorriso. +See the manual page of xorriso for its concepts and commands. + +Normally the other GUI elements will emit xorriso commands for you. +This input field is presented only to make accessible those features +of xorriso which are not covered by the GUI. Use the \"Refresh disp\" +button to update the display after you have manually transmitted commands." + } + if {$what == "Script/Log"} { + return \ +"The \"Script/Log\" menu controls logging of xorriso commands and replies. + +The \"Log command script\" switch controls whether the essential xorriso +commands of the GUI session shall be written to the end of a script file +on hard disk. Not written will be the commands by which the GUI inspects +the xorriso state, but only those which set up that state and those which +get sent via the \"Command:\" field. +Commands -osirrox and -extract will be logged only as comments. + +The \"Log non-essential commands\" switch controls whether all commands +shall be logged if \"Log command script\" is enabled. Commands +-msg_op \"parse\" and -msg_op \"parse_bulk\" will be logged only as comments. + +The item \"Set log script address\" pops up a file tree browser window +which asks for the target of appending to script. Address \"-\" means +standard error. Else it must not yet exist or be a writable data file. + +The \"Log pipes\" switch controls whether all xorriso commands and replies +shall be logged to standard error or to the file that has been given +with program argument --pipe_log_file. +Caution: This log is verbous. + +The item \"Set pipe log address\" pops up a file tree browser window +which asks for the target of pipe logging . Address \"-\" means +standard error. Else it must not yet exist or be a writable data file. + +The item \"Execute command script\" executes the commands in a script +file that should stem from \"Log command script\". +At least it must begin by this line: +# xorriso-tcltk command log script +Be aware that xorriso will slavishly execute those commands. Better check +in advance whether the content of the script file is what you expect. +See man xorriso for the meaning of the commands. + +The \"Allow extract to disk\" switch controls whether commands like -extract +are allowed in command scripts. If disabled, then command -osirrox is used +to temporarily block those commands (unless the script unblocks itself, which +would be nasty behavior). + +The item \"Permanently ban extraction\" disables -extract irrevocably for +scripts and GUI alike." + } + if {$what == "message box"} { + return \ +"The message box displays commands sent to xorriso and messages received +from xorriso. + +Many commands which are emitted by the GUI will hide themselves and their +replies from this display. All event messages with severity WARNING or +higher will show up, nevertheless." + } + if {$what == "Recent problem:"} { + return \ +"The \"Recent problem:\" field shows the most severe event message that occurred +during the execution of the most recent command. It also displays the most +recent problem message from the frontend program itself. + +Several commands emitted by the GUI will not clear this display. But any +manually transmitted command and the major GUI gestures will do. +" + } + if {$what == "Worst problem:"} { + return \ +"The \"Worst problem:\" field shows the most severe event message that occurred +since last time the \"Clear\" button was hit. It will not clear automatically." + } + if {$what == "Clear"} { + return \ +"The \"Clear\" button removes the message from the \"Worst problem:\" field." + } + if {$what == "Scan for drives"} { + return \ +"The \"Scan for drives\" button executes command -devices and puts the list +of found optical drives into the box beside the button. + +Scanning should be done before any ISO image manipulations because xorriso +has to give up its acquired drives in order to perform the scan run. + +To become visible and to be usable, the drives have to offer rw-permission +to the user of this program. If drives do not show up, then consider to +become superuser and to execute + xorriso -devices +Then apply + chmod a+rw +to the listed device files. (Consider to use finer means of permission +granting for a permanent solution.)" + } + if {$what == "Pick input drive"} { + return \ +"The \"Pick input drive\" button executes command -indev and obtains some +information about the medium status. This info is displayed in the +\"Input drive/image\" line. +Further it causes the display of the ISO image model to be updated. + +The medium in the input drive must be blank or contain a valid ISO 9660 +filesystem. +Choosing an input drive causes a root directory to be created in the ISO +model of xorriso. If there is a valid ISO filesystem in the input drive +then its directory tree gets loaded underneath that model root directory. + +The input drive may also be a data file on hard disk if that file contains +an ISO 9660 filesystem image. See the \"Input drive/image\" button." + } + if {$what == "Pick output drive"} { + return \ +"The \"Pick output drive\" button executes command -outdev and obtains some +information about the medium status. This info is displayed in the +\"Output drive/image\" line. + +The output drive may be empty or loaded with a medium, that may be blank, +appendable or closed. +It is usable for writing only if there is a medium inserted which is either +blank or appendable. Button \"Blank\" can bring appendable or closed media +into blank state. + +The output drive may also be a data file on hard disk. See field +\"Output drive/image\"." +It is considered appendable if it contains an ISO 9660 filesystem image. +It is considered blank if it is empty or marked as blank by button \"Blank\". +It is considered closed if it contains other data." + } + if {$what == "Pick drive for both roles"} { + return \ +"The \"Pick drive for both roles\" button executes command -dev and obtains some +information about the medium status. This info is displayed in the +\"Input drive/image\" line and in the \"Output drive/image\" line. +Further it causes the display of the ISO image model to be updated. + +The medium in the drive must be blank or contain a valid ISO 9660 filesystem. +Else the drive will only be acquired as output drive. + +This drive configuration is the most usual one with xorriso. It loads +an eventual ISO image, allows to manipulate it by insertion, deletion, +and renaming. When this is done, the changes get written to the drive +via button \"Write ISO session\". + +The drive may also be a data file on hard disk. See the fields beside +the \"Input drive/image\" and \"Output drive/image\" buttons. +A file is considered appendable if it contains an ISO 9660 filesystem image. +It is considered blank if it is empty or marked as blank by button \"Blank\". +It is considered closed if it contains other data." + } + if {$what == "Give up drives"} { + return \ +"The \"Give up drives\" button executes commands -indev \"\" -outdev \"\" +and clears both \"... drive/image\" lines, as well as the ISO model." + } + if {$what == "Calm drives"} { + return \ +"The \"Calm drives\" button executes command -calm_drives which tells the +acquired optical drives to stop spinning until the next drive activity +gets triggered." + } + if {$what == "Rollback"} { + return \ +"The \"Rollback\" button executes command -rollback which drops all pending +changes of the ISO model and reloads it from the input drive, if one is +acquired." + } + if {$what == "drivelist"} { + return \ +"The box beside the \"Scan for drives\" button shows the optical drives +which were found by the most recent scan run. + +A double-click on a drive item has the same effect as button +\"Pick drive for both roles\". +" + } + if {$what == "Input drive/image"} { + return \ +"The field beside the \"Input drive/image\" button displays the address of +the input drive. You may edit this field. +Clicking the button or pressing the Return key causes the execution of +command -indev with the field content as drive address. + +Use this to load the model from an ISO image data file on hard disk. +It is of course permissible that input image and output image are the +same file. +" + } + if {$what == "input drive info"} { + return \ +"The text beside the \"Input drive/image\" field displays the medium +status of the input drive. It tells about the writability, the medium type, +the number of ISO sessions, and the amount of readable data." + } + if {$what == "Eject (indev)"} { + return \ +"The \"Eject\" button beside the \"Input drive/image\" button executes +command -eject \"in\"." + } + if {$what == "Output drive/image"} { + return \ +"The field beside the \"Output drive/image\" button displays the address +of the output drive. You may edit this field. +Clicking the button or pressing the Return key causes the execution +of command -outdev with the field content as drive address. + +Use this to direct writing to an ISO image data file on hard disk. +It is of course permissible that input image and output image are the +same file. +" + } + if {$what == "output drive info"} { + return \ +"The text beside the \"Output drive/image\" field displays the medium +status of the output drive. It tells about the writability, the medium type, +the number of ISO sessions, and the amount of free space." + } + if {$what == "Eject (outdev)"} { + return \ +"The \"Eject\" button beside the \"Output drive/image\" button executes +command -eject \"out\"." + } + if {$what == "Blank"} { + return \ +"The \"Blank\" button executes command -blank \"as_needed\" on the output drive +in order to make a re-usable medium or an ISO image data file writable from +scratch. + +Genuine blanking applies only to CD-RW and DVD-RW. +But xorriso emulates ISO 9660 multi-session on DVD+RW, DVD-RAM, +formatted DVD-RW, BD-RE, as well as in ISO image data files on hard disk. +On those media and pseudo media, blanking will be performed by a small +write operation which invalidates their existing ISO filesystem. + +One-time writable media CD-R, DVD-R, DVD+R, and BD-R cannot be blanked." + } + if {$what == "Format"} { + return \ +"The \"Format\" button executes -format \"as_needed\". + +This only applies to real optical drives and is of interest only with DVD-RW +or BD-R media, which both can be used formatted and unformatted. Other media +types which mandatorily need formatting will be formatted by the write +commands. + +Formatted DVD-RW media have the advantage of being overwritable and thus +being quickly blankable while maintaining the capability for multi-session. + +Formatted BD-R can perform Defect Management, which is of questionable value." + } + if {$what == "Write ISO session"} { + return \ +"The \"Write ISO session\" executes command -commit, which writes a session +with all pending changes to the output drive. + +The output drive must be either blank or it must be the same as the input +drive. + +Writing the session is the last step in the course of creating a new ISO +filesystem or an add-on session that expands or changes the ISO filesystem +on the medium of the output drive. +So first choose a drive, then insert files from hard disk or do other +manipulations, and then click \"Write ISO session\" to let xorriso +write the data to medium or ISO image file. +" + } + if {$what == "Close"} { + return \ +"The \"Close\" switch controls whether command -close \"on\" is emitted with +\"Write ISO session\" or whether -as cdrecord option -multi is omitted with +\"Burn image file:\". + +Closed optical media cannot be written any more unless they get blanked, +which is not possible with CD-R, DVD-R, DVD+R, and BD-R. +" + } + if {$what == "TAO"} { + return \ +"The \"TAO\" switch controls whether an incremental MMC write type shall be +enforced with write commands. See xorriso command -write_type. + +Normally xorriso will decide by medium status and job parameters which +MMC write type to choose. Some drives at the edge of failure might work +with the one write type while already failing with the other." + } + if {$what == "Defect Mgt"} { + return \ +"The \"Defect Mgt\" switch controls whether slow and error-prone drive internal +check-reading shall be enabled when writing to formatted BD-R or BD-RE. +See xorriso command -stream_recording." + } + if {$what == "Burn image file:"} { + return \ +"The \"Burn image file:\" button executes command -as \"cdrecord\" to +burn a data file from hard disk onto the output drive. +The address of the disk file is taken from the neighboring text field. + +If you do not plan to append further data to the medium, then consider +to enable the \"Close\" switch. + +No input drive may be acquired. (Delete all characters from the field +\"Input drive/image\" and hit Return to give up the input drive.) + +The medium in the drive must be blank. +(It is well possible to burn image files to appendable media. But the +image needs to be prepared for the address offset. Who can do that can +as well use one of the command line tools for burning the result. E.g. + xorriso -as cdrecord -v dev=/dev/sr0 -multi stream_recording=32s image.iso +)" + } + if {$what == "Extract to disk:"} { + return \ +"The \"Extract to disk:\" button executes command -extract with the whole +tree of the current ISO directory or with the selected items of the box +underneath \"ISO directory:\". + +This copies the selected files or directory trees from the input drive +to the address on hard disk which is given by the text field right of +the button." + } + if {$what == "Browse tree"} { + return "[tell_file_browser_help 0]" + } + if {$what == "Close (browse tree)"} { + return \ +"The \"Close\" button in the file browser closes the browser window without +performing other actions." + } + if {$what == "Up (browse tree)"} { + return \ +"The \"Up\" button in the file browser brings you to the parent directory +of the currently selected file tree item. + +The parent directory will be opened and become the selected item. +All opened directory trees underneath the parent will be closed." + } + if {$what == "Down (browse tree)"} { + return \ +"The \"Down\" button in the file browser opens the directory underneath +the currently selected file tree item. + +It has the same effect as clicking the \"+\" node of the selected item." + } + if {$what == "Accept (browse tree)"} { + return \ +"The \"Accept\" button in the file browser brings the single selected item +from the file browser tree into effect with the associated text field. +I.e. it hits the Return key of the field. + +It works as if the item had been double clicked." + } + if {$what == "Edit (browse tree)"} { + return \ +"The \"Edit\" button in the file browser brings the single selected item +from the file browser tree into the associated text field. + +It does not hit the Return key of the field, but gives you the opportunity +to edit the file address." + } + if {$what == "Browse disk (extract)"} { + return \ +"The \"/\" button in the \"Extract to disk:\" line pops up a file tree +browser to select a target address in the hard disk filesystem. + +[tell_file_browser_help 1]" + } + if {$what == "Browse disk (burn image)"} { + return \ +"The \"/\" button beside the \"Burn image file\" field pops up a file +tree browser to select a source address in the hard disk filesystem. + +[tell_file_browser_help 1]" + } + if {$what == "Browse disk (insert)"} { + return \ +"The \"/\" button beside the \"Insert from disk\" field pops up a file +tree browser to select a source address in the hard disk filesystem. + +[tell_file_browser_help 1]" + } + if {$what == "Browse disk (indev)"} { + return \ +"The \"/\" button in the \"Input drive/image\" line pops up a file tree +browser to select a source address in the hard disk filesystem. + +[tell_file_browser_help 1]" + } + if {$what == "Browse disk (outdev)"} { + return \ +"The \"/\" button in the \"Output drive/image\" line pops up a file tree +browser to select a source address in the hard disk filesystem. + +[tell_file_browser_help 1]" + } + if {$what == "Browse ISO (isodir)"} { + return \ +"The \"/\" button in the \"ISO directory\" line pops up a file tree +browser to select the current directory in the ISO filesystem model. + +[tell_file_browser_help 1]" + } + if {$what == "Browse ISO (move target)"} { + return \ +"The \"/\" button in the \"Selection:\" line pops up a file tree +browser to select the current directory in the ISO filesystem model. + +[tell_file_browser_help 1]" + } + if {$what == "Browse disk (dummy)"} { + return \ +"Normally this button would start a file browser to select a file or +directory on hard disk. + +But the browser cannot be displayed because Tcl/Tk package \"BWidget\" +is not loaded." + } + if {$what == "Browse ISO (dummy)"} { + return \ +"Normally this button would start a file browser to select a file or +directory in the ISO model. + +But the browser cannot be displayed because Tcl/Tk package \"BWidget\" +is not loaded." + } + if {$what == "Underneath (extract)"} { + return \ +"The \"Underneath\" switch controls the effective hard disk target address +of an item if the address in the \"Extract to disk:\" field points to a +directory. + +If \"Underneath\" is enabled, then the file object from the ISO filesystem +will be copied to its name underneath the hard disk directory. +If \"Underneath\" is disabled then an ISO directory tree item will be merged +with the disk directory tree at the given address. + +Example: +Selected are \"/iso_dir\" and \"/iso_file\". +Address for hard disk is \"/tmp/from_iso\". Switch \"Selected\" is enabled. +\"Underneath\" enabled causes commands: + -extract /iso_dir /tmp/from_iso/iso_dir + -extract /iso_file /tmp/from_iso/iso_file +\"Underneath\" disabled: + -extract /iso_dir /tmp/from_iso + -extract /iso_file /tmp/from_iso +The last command will fail because /tmp/from_iso already exists as directory." + } + if {$what == "Selected (extract)"} { + return \ +"The \"Selected\" switch controls whether the whole current ISO directory, +or only the selected items shall be copied to hard disk. +" + } + if {$what == "Overwriting:"} { + return \ +"The \"Overwriting\" menu bundles several switches which control whether +existing files or directories may be overwritten. + +The frontend program will only detect the most obvious name collisions, +but xorriso will reliably refuse to overwrite files if this is banned. + +---------------------------------------------------------------------------- + +The \"Overwrite ISO files\" switch controls whether existing files may be +overwritten in the ISO image. See xorriso command -overwrite \"nondir\". + +---------------------------------------------------------------------------- + +The \"Overwrite ISO dirs\" switch controls whether it is allowed to replace +an ISO directory by a another file. See xorriso command -overwrite \"on\". + +---------------------------------------------------------------------------- + +The \"Overwrite hard disk files\" switch controls whether existing files may be +overwritten by extraction to hard disk. See xorriso command -overwrite \"on\". + +This is DANGEROUS, of course, but comes in handy with restoring of backups. + +---------------------------------------------------------------------------- + +The \"Enforce disk dir write access\" switch enables the -osirrox options +\"auto_chmod_on\" and \"sort_lba_on\" which influence file extraction. + +\"auto_chmod_on\" allows xorriso to give itself temporariy w-permission to +all disk directories which are owned by the xorriso user. + +This is DANGEROUS, of course, but comes in handy with restoring of backups. + +Option \"sort_lba_on\" reduces head-moves of optical drives and thus can +speed up extraction substantially. It is bound to \"auto_chmod_on\" because +else it might get into trouble when restoring ISO directories which offer +no w-permission." + } + if {$what == "Permissions:"} { + return \ +"The \"Permissions\" menu allows to choose a global policy to adjust +the access permissions of the files when an ISO session gets written. + +The default policy \"as is\" leaves the permissions as they are. +Usually they have been imported from hard disk or from a loaded ISO image. +xorriso commands -chmod , -chmod_r, and -find ... -exec chmod -- +may be used to perform permission manipulations. + +Policy \"readable\" adds read permission to all kinds of files and +search permission to all directories. + +Policy \"readonly\" sets the permissions of all kinds of files to read-only. +Directories get added search permission. + +Policy \"mkisofs -r\" does what option -r of program mkisofs does: +User id and group id become 0, all r-permissions get granted, all w denied. +If there is any x-permission, then all three x get granted. s- and t-bits +get removed. +" + } + if {$what == "Refresh avail:"} { + return \ +"The \"Refresh avail:\" button triggers command -tell_media_space. It makes +a time consuming exact prediction of the free space on the medium in the +output drive. For this purpose, the size of an ISO session with the pending +changes is computed. + +With image files rather than real optical drives, the free space of +the hosting filesystem is displayed." + } + if {$what == "Insert from disk:"} { + return \ +"The \"Insert from disk:\" button executes command -map with the disk file +address that is given by the text field right to the button. + +This inserts files or directory trees into the ISO image model and +schedules them for being copied with the next \"Write ISO session\" run. + +The switches \"Underneath\" and \"Selected\" control what ISO address +the inserted files shall have. You may use buttons \"Delete\" and +\"Move to:\" for further adjustments. +" + } + if {$what == "Underneath (insert)"} { + return \ +"The \"Underneath\" switch controls the effective ISO target address +if the address in the \"Insert from disk:\" field points to a hard disk +directory. + +If \"Underneath\" is enabled, a directory from disk will not be unpacked +to its single files but be put underneath the target address by its own +leaf name." + +If \"Underneath\" is disabled then the directory itself will not show up in +the ISO image but only its files and sub directories will do." + } + if {$what == "Selected (insert)"} { + return \ +"If the switch \"Selected\" is enabled, then the given disk file or tree will +be inserted at or underneath the only selected item in the box underneath +\"ISO directory:\"." + } + if {$what == "ISO directory:"} { + return \ +"The current ISO directory shall be used to navigate in the ISO image model +of xorriso. By default it is the target of file insertions and the source +of file extractions. + +The text field in the \"ISO directory:\" line displays the current ISO +directory and can be used to toggle its path directly. +Hitting the Return key causes the current directory to change and the +display in the box underneath to be refreshed. + +It is possible to choose the ISO directory by double-clicking an item +in the box underneath the \"ISO directory:\" line. +" + } + if {$what == "Up"} { + return \ +"The \"Up\" buttons move the current ISO directory one directory level up." + } + if {$what == "Verify"} { + return \ +"The \"Verify\" button executes -md5_check_r \"SORRY\" with the current ISO +directory. + +This reads the content of all data files which are underneath the current ISO +directory and which have MD5 checksums in the ISO image. +ISO images bear MD5 checksums for each data file if they were produced +by xorriso with -md5 \"on\" or -for_backup. This frontend enables +this feature on startup." + } + if {$what == "isolist"} { + return \ +"The list box underneath the \"ISO directory:\" line displays the files in +the current ISO directory. One or more item can be selected and play a +role with extraction or insertion of files. + +Most of the buttons underneath the box operate on the selected items +unconditionally." + } + if {$what == "Selection:"} { + return \ +"The ISO selection consists of the items which are selected in the list box +above the \"Selection:\" line. + +If the respective \"Selected\" switches are enabled, then the ISO selection +is source of file extraction and target of file insertion. + +In any case it is the old name of the \"Move to:\" button, the victim +of the \"Delete\" button, and the subject of the \"Verify\" button." + } + if {$what == "Verify (selection)"} { + return \ +"The \"Verify\" button in the \"Selection:\" line executes command +-md5_check_r \"SORRY\" with each of the selected items. + +This reads the content of all data files which are selected or underneath +selected directories and which have MD5 checksums in the ISO image. +ISO images bear MD5 checksums for each data file if they were produced +by xorriso with -md5 \"on\" or -for_backup. This frontend enables +this feature on startup." + } + if {$what == "Delete"} { + return \ +"The \"Delete\" button executes command -rm_r with each of the selected items. + +This removes the affected files and directory trees from the ISO model. +They will not show up in the directory tree of the next session that +is written via \"Write ISO session\". Nevertheless they will stay present +in earlier sessions beginning from the session where they were inserted." + } + if {$what == "Move to:"} { + if {$use_command_move == 0} { + return \ +"The \"Move to:\" button uses command -mv to move each of the selected +items to the address that is given by the text field right to the button. + +If this address points to an existing ISO directory, then the items will +be moved underneath that directory and keep their leaf names. +Else there may be only one selected item which will be renamed to the +given address." + } else { + return \ +"The \"Move to:\" button uses command -move to rename each of the selected +items to the address that is given by the text field right to the button." + } + } + if {$what == "Make dir"} { + return \ +"The \"Make dir\" button executes command -mkdir with the address in the +text field to its left (the same as used by \"Move to:\"). + +Useful to create a target directory before moving the selection." + } + if {$what == "rename and mkdir target"} { + return \ +"The text field between the \"Move to:\" button and the \"Make dir\" button +serves both buttons by providing the target address for renaming +or directory creation, respectively. + +If you hit the Return key in this field, it will trigger \"Mode to:\"." + } + if {$what == "yes to all"} { + return \ +"The \"yes to all\" button appears in the yes/no window if a GUI action is +about to overwrite a file object and more such overwrite situations are +to be expected. + +If the button is clicked, then all further yes/no questions of that GUI +action will be answered automatically with yes. + +[about_help_for_yesno]" + } + if {$what == "no to all"} { + return \ +"The \"no to all\" button appears in the yes/no window if a GUI action is +about to overwrite a file object and more such overwrite situations are +to be expected. + +If the button is clicked, then all further yes/no questions of that GUI +action will be answered automatically with no. + +[about_help_for_yesno]" + } + if {$what == "Continue"} { + return \ +"The \"Continue\" button appears in the notification windows which tell +about a failed or rejected GUI action. + +--------------------------------------------------------------------------- + +It is impossible to trigger any further GUI action while the notification +window is displayed. You either have to click the \"Continue\" button +or hit the Return key. + +You cannot even close this help window before you did that." + } + if {$what == "yes/no"} { + return \ +"The \"yes\" and \"no\" buttons appear in the confirmation window which tells +about a potentially dangerous GUI action and demands a user decision whether +to really perform this action. + +[about_help_for_yesno]" + } + + return "--- No help text found for topic '$what'" +} + + +# Tell the general help text of the file browser. +# +proc tell_file_browser_help {with_separator} { + global have_bwidget + + set text "" + if {$with_separator == 1} { + set text \ +"-------------------------------------------------------------------------\n\n" + } + if {$have_bwidget == 1} { + + set text \ +"${text}The file tree browser presents to you a directory tree and +lets you bring into effect one of the file addresses in that tree.\n" + + } else { + + set text \ +"${text}Normally the file tree browser would present to you a directory tree +and let you bring into effect one of the file addresses in that tree. + +But the tree view cannot be displayed because Tcl/Tk package \"BWidget\" +is not loaded. + +-------------------------------------------------------------------------\n" + + } + + set text "${text} +The bottom line of the browser window tells the associated text field +in the GUI. E.g. \"ISO directory:\". +Left of this label is a copy of that associated text field. You may edit +its content and bring it into effect by hitting the Return key.\n" + + if {$have_bwidget == 1} { + + set text "${text} +In the tree display click on the \"+\" or \"-\" nodes to open or +close directories, respectively. + +Double click on an item to bring it into effect with the associated +text field. I.e. double clicking also hits the Return key in that field.\n" + + } + + set text "${text} +The \"Accept\" button does the same with the selected item.\n" + + if {$have_bwidget == 1} { + + set text "${text} +The \"Edit\" button brings the selected item into the text field +without hitting the Return key. So you may edit the name before hitting +Return yourself. + +The \"Up\" button brings you to the parent directory of the selected item. + +The \"Down\" button works like clicking the \"+\" node of the selected item.\n" + + } + + set text "${text} +The \"Help\" button displays this help text window. + +The \"Close\" button closes the browser window.\n" +} + + +# Tell about pecliarity of help window triggered by yes/no window +proc about_help_for_yesno {} { + return \ +"--------------------------------------------------------------------------- + +It is impossible to trigger any further GUI action while the confirmation +window is displayed. You have to click one of the buttons in that window. + +You cannot even close this help window before you clicked one of the buttons." +} + + +# ------- Misc helper procedures ------- + + +# Equip a text with quotation marks so that xorriso will consider it as +# a single word. +# +proc make_text_shellsafe {text} { + set result "'" + set rest $text + while {[string length $rest]} { + set idx [string first "'" $rest] + if {$idx == -1} { + set result "$result$rest" + break + } else { + if {$idx > 0} { + set result "$result[string range $rest 0 [expr $idx - 1]]" + } + set result "$result'\"'\"'" + if {$idx == [expr [string length $rest] - 1]} { + break + } + set rest [string range $rest [expr $idx + 1] end] + } + } + set result "$result'" +} + + +# Count the number of newline chracters in text. +# +proc count_newlines {text} { + set rest $text + set count 0 + while {[string length $rest]} { + set idx [string first "\n" $rest] + if {$idx == -1} { + break + } else { + set count [expr $count + 1] + if {$idx == [expr [string length $rest] - 1]} { + break + } + set rest [string range $rest [expr $idx + 1] end] + } + } + return $count +} + + +# Append name to dir so that the result is a path to name under dir. +# +proc combine_dir_and_name {dir name} { + set has_slash 0 + if {$name == ""} { + return $dir + } + if {[string range $name 0 0] == "/"} { + incr has_slash + } + if {[string last "/" $dir] == [expr [string length $dir] - 1] && + $dir != ""} { + incr has_slash 1 + } + if {$has_slash == 2} { + return "$dir[string range $name" 1 end]" + } + if {$has_slash == 1} { + return "$dir$name" + } + return "$dir/$name" +} + + +# Force the content of variable isodir_adr to be an absolute address +# +proc normalize_isodir_adr {} { + global isodir_adr + + if {$isodir_adr == ""} { + set isodir_adr "/" + } + if {[string range $isodir_adr 0 0] != "/"} { + set isodir_adr "/$isodir_adr" + } +} + + +# Inspect path whether one of its components is in isodir_adr +# +proc path_touches_isodir {path} { + global isodir_adr + + normalize_isodir_adr + set cmp_start 0 + if {$isodir_adr == "/"} { + set cmp_start 1 + } + if {[string range $path 0 0] != "/"} { + if {[string first "/" $path] == -1} { + return $path + } else { + return [file dirname $path] + } + } + set l [expr {[string length $isodir_adr] - $cmp_start}] + if {[string length $path] < [expr {$l + 2}]} { + return "" + } + if {$l > 0} { + if {[string range $path $cmp_start [expr {$l - 1}]] != \ + [string range $isodir_adr $cmp_start end]} { + return "" + } + } + if {[string range $path $l $l] != "/"} { + return "" + } + set subpath [string range $path [expr {$l + 1}] end] + set slash [string first "/" $subpath] + if {$slash == -1} { + return $subpath + } + if {$slash == 0} { + return "" + } + return [string range $subpath 0 [expr {$slash - 1}]] +} + + +# Compare two severity names by help of the severity list that was obtained +# from xorriso via proc inquire_severity_list. +# +proc compare_sev {sev1 sev2} { + global xorriso_severity_list + + set idx1 [lsearch -exact $xorriso_severity_list $sev1] + set idx2 [lsearch -exact $xorriso_severity_list $sev2] + if {$idx1 < $idx2} {return -1} + if {$idx1 > $idx2} {return 1} + return 0 +} + + +# Write a text to the pipe log +# +proc debug_log_puts {text} { + global debug_logging debug_log_conn + + if {$debug_logging == 1} { + puts $debug_log_conn $text + flush $debug_log_conn + } +} + + +# End program and return the given exit value. +# +proc central_exit {value} { + exit $value +} + + +# Start a xorriso process which will in return launch another frontend +# process. This is necessary until i learned how to create a pair of pipes +# and to fork in Tcl. +# +proc start_xorriso {} { + global argv0 argv + + set self "" + if {[string first "/" $argv0] != -1} { + set self $argv0 + } + if {$self == ""} { + set self "/usr/bin/xorriso-tcltk" + if {[file executable $self] == 0} {set self ""} + } + if {$self == ""} { + set self "/usr/local/bin/xorriso-tcltk" + if {[file executable $self] == 0} {set self ""} + } + if {$self == ""} { + catch { + set conn [open "|which xorriso-tcltk" r] + set self [gets $conn] + close $conn + } + } + if {$self == ""} { + catch { + set conn [open "|sh -c \"type -p xorriso-tcltk\"" r] + set self [gets $conn] + close $conn + } + } + if {$self == ""} { + puts stderr "$argv0 :\n Cannot locate address of script xorriso-tcltk in filesystem.\n" + puts stderr "You will have to use --stdio or --named_pipes." + puts stderr "See $argv0 --help\n" + central_exit 1 + } + + # eval is used to split $argv into single words + eval exec xorriso -launch_frontend "\"$self\"" --silent_start --stdio $argv -- 2>@stderr + + central_exit 0 +} + + +# Print a startup message to stderr if not the first argument is --silent_start +# +proc yell_xorriso_tcltk {} { + global argv own_version + + if {[llength $argv] > 0} { + if {[lindex $argv 0] == "--silent_start"} {return ""} + } + puts stderr "xorriso-tcltk $own_version : Proof of concept for GUI frontends of xorriso\n" +} + + +# Log a command (if enabled) +# +proc log_command {cmd essential} { + global cmd_log_conn cmd_logging_mode cmd_logging_all recent_cd_path + + if {$cmd_logging_mode < 1} {return ""} + if {$essential <= 0} { + if {$cmd_logging_all <= 0} {return ""} + } else { + # Leave logging to non-essential call which will come soon after + if {$cmd_logging_all > 0} {return ""} + } + + if {[string first "-cd " $cmd] == 0} { + set path [string range $cmd 4 end] + if {$path == $recent_cd_path && $cmd_logging_all <= 0} {return ""} + set recent_cd_path $path + } + + if {$cmd_log_conn == ""} { + effectuate_command_logging 0 + if {$cmd_logging_mode < 1} {return ""} + } + set prefix "" + if {$cmd_logging_mode == 1} { + if {[string first "-osirrox" $cmd] != -1 || \ + [string first "-extract" $cmd] != -1} { + set prefix "# " + } + } + if {[string first "-msg_op parse" $cmd] != -1} { + set prefix "# " + } + puts $cmd_log_conn $prefix$cmd + flush $cmd_log_conn +} + + +# Start command logging +# Called by setup_by_args and by the "Script/Log" menu. +# (target == "." and mode == -1 preserve the current state.) +# +proc start_command_logging {target mode} { + global cmd_log_conn cmd_logging_mode msglist_running cmd_log_target + + set is_stderr 0 + if {$cmd_log_target == "" || $cmd_log_target == "-" || \ + $cmd_log_conn == "stderr"} {set is_stderr 1} + set errmsg "" + if {$target != "." && $cmd_log_conn != "" && $target != $cmd_log_target && \ + $is_stderr == 0} { + catch "close $cmd_log_conn" + set cmd_log_conn "" + } + set ret 0 + if {$cmd_log_conn == "" || $is_stderr == 1} { + if {$target == "-" || $target == "" || $target == "."} { + set cmd_log_conn stderr + } else { + set ret [catch {set cmd_log_conn [open $target a]} errmsg] + } + if {$target != "."} { + set cmd_log_target $target + } + } + if {$ret == 0 && $mode >= 0} { + set cmd_logging_mode $mode + } + if {$ret == 1} { + set msg "xorriso-tcltk : SORRY : Failed to open command log script [make_text_shellsafe $target] :\n$errmsg" + if {$msglist_running == 1} { + xorriso_tcltk_errmsg $msg + } else { + puts stderr $msg + } + set cmd_logging_mode 0 + return 0 + } + if {$mode > 0} { + puts $cmd_log_conn "# xorriso-tcltk command log script" + puts $cmd_log_conn [xorriso_loggable_init_cmds] + flush $cmd_log_conn + } + return 1 +} + + +# Start communications pipe logging +# Called by setup_by_args and by the "Script/Log" menu. +# (target == "." and mode == -1 preserve the current state.) +# +proc start_debug_logging {target mode} { + global debug_log_conn debug_log_file debug_logging msglist_running + + set is_stderr 0 + if {$debug_log_file == "" || $debug_log_file == "-" || \ + $debug_log_conn == "stderr"} {set is_stderr 1} + set errmsg "" + if {$target != "." && $debug_log_conn != "" && \ + $target != $debug_log_file && $is_stderr == 0} { + catch "close $debug_log_conn" + set debug_log_conn "" + } + set ret 0 + if {$debug_log_conn == "" || $is_stderr == 1} { + if {$target == "-" || $target == "" || $target == "."} { + set debug_log_conn stderr + } else { + set ret [catch {set debug_log_conn [open $target a]} errmsg] + } + if {$target != "."} { + set debug_log_file $target + } + } + if {$ret == 0 && $mode >= 0} { + set debug_logging $mode + } + if {$ret == 1} { + set msg "xorriso-tcltk : SORRY : Failed to open pipe log [make_text_shellsafe $target] :\n$errmsg" + if {$msglist_running == 1} { + xorriso_tcltk_errmsg $msg + } else { + puts stderr $msg + } + return 0 + } + return 1 +} + + +proc execute_script {close_window} { + global execute_script_conn execute_script_adr browse_disk_window_is_active + global osirrox_allowed script_with_osirrox cmd_logging_mode cmd_log_target + global highest_cmd_sev + + if {$close_window == 1 && $browse_disk_window_is_active == 1} { + destroy_browse_disk .browse_disk_window + } + + set n1 [file normalize $execute_script_adr] + set n2 [file normalize $cmd_log_target] + if {$n1 == $n2 && $cmd_logging_mode > 0} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : You first have to disable command script logging before using the log script" + return "" + } + + set errmsg "" + set ret [catch {set execute_script_conn [open $execute_script_adr r]} errmsg] + if {$ret != 0} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : Failed to open command script [make_text_shellsafe $execute_script_adr] :\n$errmsg" + return "" + } + set line "" + set ret [gets $execute_script_conn line] + if {$ret < 0 || $line != "# xorriso-tcltk command log script"} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : Given file does not look like a xorriso command log script" + close $execute_script_conn + return "" + } + + # >>> ??? Show script + + if {[window_yesno "Really perform the xorriso commands in file\n\n[make_text_shellsafe $execute_script_adr]\n\n?"] != 1} { + close $execute_script_conn + return "" + } + if {$script_with_osirrox != 1} { + send_silent_cmd "-osirrox blocked" + } + while {1} { + set ret [gets $execute_script_conn line] + if {$ret < 0} { + break + } + if {$line == "" || [string first "#" $line] == 0} { + continue + } + reset_highest_cmd_sev + send_loggable_cmd $line + if {[compare_sev $highest_cmd_sev "FAILURE"] >= 0} { + xorriso_tcltk_errmsg "xorriso-tcltk : SORRY : Encountered problem event of severity '$highest_cmd_sev'.\nScript execution aborted." + break + } + } + close $execute_script_conn + if {$script_with_osirrox != 1} { + send_silent_cmd "-osirrox unblock" + } +} + + +# Convert newline into \n +# +proc escape_newline {text backslash_too} { + if {$backslash_too == 0} { + return [string map [list "\n" "\\n"] $text] + } + return [string map [list "\n" "\\n" "\\" "\\\\"] $text] +} + + +# -------- start living + + +proc setup_by_args {argv0 argv} { + global cmd_pipe_adr reply_pipe_adr main_window_geometry click_to_focus + global have_bwidget cmd_conn reply_conn geometry stdout stdin + global osirrox_allowed cmd_logging_all use_command_move + + # wish normally eats the -geometry option and puts the result into $geometry + catch {set main_window_geometry $geometry} + + set connection_defined 0 + set pipe_logging 0 + set script_logging 0 + + set loop_limit [llength $argv] + for {set i 0} {$i < $loop_limit} {incr i} { + set ok "0" + set opt [lrange $argv $i $i] + if {$opt == "--help"} { + set ok "1" + print_usage $argv0 + central_exit 0 + } + if {$opt == "--silent_start"} { + set ok "1" + } + if {$opt == "--stdio"} { + set ok "1" + set connection_defined 1 + } + if {$opt == "--named_pipes"} { + set ok "1" + incr i + set cmd_pipe_adr [lrange $argv $i $i] + incr i + set reply_pipe_adr [lrange $argv $i $i] + if {$cmd_pipe_adr != "" && $reply_pipe_adr != "" && + $cmd_pipe_adr != "-" && $reply_pipe_adr != "-"} { + init_frontend_named_pipes $cmd_pipe_adr $reply_pipe_adr + } + set connection_defined 1 + } + if {$opt == "--geometry" || $opt == "-geometry"} { + set ok "1" + # Just in case -geometry does not get eaten by wish + incr i + set main_window_geometry [lrange $argv $i $i] + set give_geometry [lrange $argv $i $i] + } + if {$opt == "--click_to_focus"} { + set ok "1" + set click_to_focus "1" + } + if {$opt == "--auto_focus"} { + set ok "1" + set click_to_focus "0" + } + if {$opt == "--pipe_log_file"} { + set ok "1" + incr i + set pipe_log_name [lrange $argv $i $i] + # postpone actual log start until start_xorriso has been passed + set pipe_logging 1 + } + if {$opt == "--script_log_file"} { + set ok "1" + incr i + set script_log_name [lrange $argv $i $i] + # postpone actual log start until start_xorriso has been passed + set script_logging 1 + } + if {$opt == "--script_log_all_commands"} { + set ok "1" + set cmd_logging_all 1 + } + if {$opt == "--no_extract"} { + set ok "1" + set osirrox_allowed 0 + } + if {$opt == "--no_bwidget"} { + set ok "1" + set have_bwidget "-1" + } + if {$opt == "--use_command_move"} { + set ok "1" + set use_command_move 1 + } + if {$opt == "--use_command_mv"} { + set ok "1" + set use_command_move 0 + } + if {$ok == 0} { + puts stderr "$argv0 : Unknown option '$opt'" + print_usage $argv0 + central_exit 1 + } + } + + if {$connection_defined == 0} { + start_xorriso + } + + if {$cmd_pipe_adr == "" || $reply_pipe_adr == "" || + $cmd_pipe_adr == "-" || $reply_pipe_adr == "-"} { + set cmd_conn stdout + set reply_conn stdin + } + if {$pipe_logging == 1} { + set ret [start_debug_logging $pipe_log_name 1] + if {$ret <= 0} { + puts stderr \ + "$argv0 : Cannot open --pipe_log_file '$pipe_log_name' for writing" + central_exit 2 + } + } + if {$script_logging == 1} { + set ret [start_command_logging $script_log_name 1] + if {$ret <= 0} { + puts stderr \ + "$argv0 : Cannot open --script_log_file '$script_log_name' for writing" + central_exit 2 + } + } + + if {$main_window_geometry != ""} { + wm geometry . $main_window_geometry + } +} + +yell_xorriso_tcltk + +setup_by_args $argv0 $argv +check_xorriso_version +setup_xorriso + +init_gui + +display_busy 0 +refresh_state + diff --git a/libisoburn/branches/1.4.6/frontend/xorriso_broker.sh b/libisoburn/branches/1.4.6/frontend/xorriso_broker.sh new file mode 100755 index 00000000..3f8a9e28 --- /dev/null +++ b/libisoburn/branches/1.4.6/frontend/xorriso_broker.sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# Copyright (C) 2015 +# Thomas Schmitt , libburnia-project.org +# Provided under BSD license: Use, modify, and distribute as you like. + +# set -x + +# ---------------------------- functions --------------------------- + +usage() { + echo >&2 + echo "usage: $0 "'\' >&2 + echo " [-xorriso path] id_string [-dev] iso_adr [xorriso_arguments ...]" >&2 + echo >&2 + echo " This script looks for named pipe" >&2 + echo ' /tmp/xorriso_stdin_pipe_${id_string}' >&2 + echo " which is supposed to be connected to a xorriso process." >&2 + echo " If not found, the stdin pipe and a stdout pipe get created" >&2 + echo " and a xorriso dialog process gets started and connected." >&2 + echo " Each character in id_string must match [-+:.,=@0-9A-Za-z]." >&2 + echo " If iso_adr differs from the previous run with the same id_string," >&2 + echo " then any changes on the previous ISO are committed as session" >&2 + echo " before command -dev is performed to load the meta data of" >&2 + echo " the newly addressed ISO." >&2 + echo " After this is done, the optionally given xorriso_arguments" >&2 + echo " are written into the stdin pipe from where xorriso will read" >&2 + echo " them as commands and their parameters." >&2 + echo >&2 +} + + +# Make filenames safe for transport by wrapping them in quotes and +# escaping quotes in their text +xorriso_esc() { + echo -n "'" + echo -n "$1" | sed -e "s/'/'"'"'"'"'"'"'/g" + echo -n "'" +} + + +# Send one or more command lines to xorriso +xorriso_send_cmd() { + # $1 : the lines to send + + # >>> is it possible to have a timeout on echo ? + + if test -p "$cmd_pipe" + then + echo " $1" >"$cmd_pipe" + else + xorriso_is_running=0 + return 1 + fi +} + + +# Send command and wait for answer +xorriso_cmd_and_result() { + # $1: command line for xorriso + # $2: if not empty, grep expression for stdout + if test "$xorriso_is_running" = 0 + then + return 1 + fi + xorriso_send_cmd "$1" || return 1 + if test -n "$2" + then + cat "$result_pipe" + else + grep "$2" <"$result_pipe" + fi + return 0 +} + + +# ------------------------------- main ----------------------------- + +# Argument interpreter + +if test "$#" -lt 2 +then + usage "$0" + exit 1 +fi + +xorriso=xorriso +if test o"$1" = o"-xorriso" +then + xorriso="$2" + shift 2 +fi +export xorriso_is_running=0 + +if test "$#" -lt 2 +then + usage "$0" + exit 1 +fi + +id_string=$(echo "$1" | sed -e 's/[^-+:.,=@0-9A-Za-z]/_/g' ) +shift 1 + +# Ignore second argument -dev +if test o"$1" = o"-dev" +then + shift 1 + if test "$#" -lt 1 + then + usage "$0" + exit 1 + fi +fi +device="$1" +shift 1 + +# Perform the action + +export cmd_pipe=/tmp/xorriso_stdin_pipe_$id_string +export result_pipe=/tmp/xorriso_stdout_pipe_$id_string + +if test -p "$cmd_pipe" +then + xorriso_is_running=1 +else + xorriso_is_running=0 +fi +if test "$xorriso_is_running" = "0" +then + # xorriso is not started yet + + # Check for xorriso version which knows command -named_pipe_loop + echo "Checking xorriso version ..." >&2 + xorriso_version_req="1.3.2" + version=$("$xorriso" -version | grep '^xorriso version' | + sed -e 's/^xorriso version : //') + smallest=$( (echo "$xorriso_version_req" ; echo "$version" ) | \ + sort | head -1) + if test "$smallest" = "$xorriso_version_req" + then + dummy=dummy + else + echo "$0 : FATAL : Need xorriso version >= $xorriso_version_req" >&2 + echo "Found version: $version" >&2 + exit 2 + fi + + if mknod "$cmd_pipe" p + then + echo "Created named pipe for xorriso commands: $cmd_pipe" >&2 + else + echo "Failed to create named pipe for xorriso commands: $cmd_pipe" >&2 + exit 3 + fi + if mknod "$result_pipe" p + then + echo "Created named pipe for xorriso result channel: $result_pipe" >&2 + else + echo \ + "Failed to create named pipe for xorriso result channel: $result_pipe" >&2 + if rm "$cmd_pipe" + then + echo "Removed named pipe for xorriso commands: $cmd_pipe" >&2 + fi + exit 3 + fi + echo "Starting xorriso process ..." >&2 + "$xorriso" -abort_on NEVER -for_backup \ + -named_pipe_loop cleanup:buffered "$cmd_pipe" "$result_pipe" "-" \ + >&2 & + # (stdout is redirected to stderr, in order not to keep a pipe waiting for + # input from the still open stdout copy of the background process. + # -named_pipe_loop will disconnect xorriso result channel from stdout.) + xorriso_is_running=1 +fi + +# Inquire current xorriso -dev +xorriso_device=$(xorriso_cmd_and_result "-status -dev" "^-dev" | \ + sed -e 's/^-dev //') +if echo " $device" | grep "^ '" >/dev/null +then + quoted="$device" +else + quoted=$(xorriso_esc "$device") +fi +if test "$xorriso_device" = "$quoted" +then + dummy=dummy +else + # Inquire the need for a -commit command + pending=$(xorriso_cmd_and_result "-changes_pending show_status" \ + "^-changes_pending" \ + | sed -e 's/^-changes_pending //') + if test "$pending" = "yes" + then + if xorriso_cmd_and_result "-commit" + then + dummy=dummy + else + exit 1 + fi + fi + # Now change ISO filesystem + if xorriso_cmd_and_result "-dev $device" + then + xorriso_device="$device" + else + exit 1 + fi +fi + +test "$*" = "" && exit 0 + +if xorriso_cmd_and_result "$*" +then + dummy=dummy +else + exit 1 +fi + +exit 0 + diff --git a/libisoburn/branches/1.4.6/libisoburn-1.pc.in b/libisoburn/branches/1.4.6/libisoburn-1.pc.in new file mode 100644 index 00000000..7fae3f90 --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn-1.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libisoburn +Description: Multi-session filesystem extension to libisofs, libburn. +Version: @VERSION@ +Requires: +Libs: -L${libdir} -lisoburn +Cflags: -I${includedir}/libisoburn + diff --git a/libisoburn/branches/1.4.6/libisoburn/burn_wrap.c b/libisoburn/branches/1.4.6/libisoburn/burn_wrap.c new file mode 100644 index 00000000..2f0d0969 --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/burn_wrap.c @@ -0,0 +1,2155 @@ + +/* + cc -g -c \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \ + burn_wrap.c +*/ +/* libburn wrappers for libisoburn + + Copyright 2007 - 2016 Thomas Schmitt, + Provided under GPL version 2 or later. +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo +#define Hardcoded_cd_rW 1 +#define Hardcoded_cd_rw_c1 12999 +#define Hardcoded_cd_rw_nwA 152660 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef Xorriso_standalonE + +#include +#include +#ifdef Xorriso_with_libjtE +#include +#endif + +#else /* ! Xorriso_standalonE */ + +#include "../libisofs/libisofs.h" +#include "../libburn/libburn.h" +#ifdef Xorriso_with_libjtE +#include "../libjte/libjte.h" +#endif + +#endif /* Xorriso_standalonE */ + + +#include "libisoburn.h" +#include "isoburn.h" + + +/* The global list of isoburn objects. Usually there is only one. */ +extern struct isoburn *isoburn_list_start; /* in isoburn.c */ + +/* Default values for application provided msgs_submit methods. + To be attached to newly acquired drives. + Storage location is isoburn.c +*/ +extern int (*libisoburn_default_msgs_submit) + (void *handle, int error_code, char msg_text[], + int os_errno, char severity[], int flag); +extern void *libisoburn_default_msgs_submit_handle; +extern int libisoburn_default_msgs_submit_flag; + + +static int isoburn_emulate_toc(struct burn_drive *d, int flag); + + +int isoburn_initialize(char msg[1024], int flag) +{ + int major, minor, micro, bad_match= 0, no_iso_init= 0; + + +/* First the ugly compile time checks for header version compatibility. + If everything matches, then they produce no C code. In case of mismatch, + intentionally faulty C code will be inserted. +*/ + +#ifdef iso_lib_header_version_major +/* The minimum requirement of libisoburn towards the libisofs header + at compile time is defined in libisoburn/libisoburn.h : + isoburn_libisofs_req_major + isoburn_libisofs_req_minor + isoburn_libisofs_req_micro + It gets compared against the version macros in libisofs/libisofs.h : + iso_lib_header_version_major + iso_lib_header_version_minor + iso_lib_header_version_micro + If the header is too old then the following code shall cause failure of + libisoburn compilation rather than to allow production of a program with + unpredictable bugs or memory corruption. + The compiler messages supposed to appear in this case are: + error: 'LIBISOFS_MISCONFIGURATION' undeclared (first use in this function) + error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_AND_burn_wrap_dot_h' undeclared (first use in this function) + error: 'LIBISOFS_MISCONFIGURATION_' undeclared (first use in this function) +*/ +/* The indendation is an advise of man gcc to help old compilers ignoring */ + #if isoburn_libisofs_req_major > iso_lib_header_version_major + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + #if isoburn_libisofs_req_major == iso_lib_header_version_major && isoburn_libisofs_req_minor > iso_lib_header_version_minor + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + #if isoburn_libisofs_req_minor == iso_lib_header_version_minor && isoburn_libisofs_req_micro > iso_lib_header_version_micro + #define Isoburn_libisofs_dot_h_too_olD 1 + #endif + +#ifdef Isoburn_libisofs_dot_h_too_olD +LIBISOFS_MISCONFIGURATION = 0; +INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_AND_burn_wrap_dot_c = 0; +LIBISOFS_MISCONFIGURATION_ = 0; +#endif + +#endif /* iso_lib_header_version_major */ + +/* The minimum requirement of libisoburn towards the libburn header + at compile time is defined in libisoburn/libisoburn.h : + isoburn_libburn_req_major + isoburn_libburn_req_minor + isoburn_libburn_req_micro + It gets compared against the version macros in libburn/libburn.h : + burn_header_version_major + burn_header_version_minor + burn_header_version_micro + If the header is too old then the following code shall cause failure of + cdrskin compilation rather than to allow production of a program with + unpredictable bugs or memory corruption. + The compiler messages supposed to appear in this case are: + error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function) + error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function) + error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function) +*/ + +/* The indendation is an advise of man gcc to help old compilers ignoring */ + #if isoburn_libburn_req_major > burn_header_version_major + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + #if isoburn_libburn_req_major == burn_header_version_major && isoburn_libburn_req_minor > burn_header_version_minor + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + #if isoburn_libburn_req_minor == burn_header_version_minor && isoburn_libburn_req_micro > burn_header_version_micro + #define Isoburn_libburn_dot_h_too_olD 1 + #endif + +#ifdef Isoburn_libburn_dot_h_too_olD +LIBBURN_MISCONFIGURATION = 0; +INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; +LIBBURN_MISCONFIGURATION_ = 0; +#endif + + +#ifdef Xorriso_with_libjtE + +/* The minimum requirement of libisoburn towards the libjte header + at compile time is the same as the one of a usable libisofs towards libjte. + So the requirement is defined in libisofs/libisofs.h : + iso_libjte_req_major , iso_libjte_req_minor , iso_libjte_req_micro +*/ + /* The indendation is an advise of man gcc to help old compilers ignoring */ + #if iso_libjte_req_major > LIBJTE_VERSION_MAJOR + #define Libisofs_libjte_dot_h_too_olD 1 + #endif + #if iso_libjte_req_major == LIBJTE_VERSION_MAJOR && iso_libjte_req_minor > LIBJTE_VERSION_MINOR + #define Libisofs_libjte_dot_h_too_olD 1 + #endif + #if iso_libjte_req_minor == LIBJTE_VERSION_MINOR && iso_libjte_req_micro > LIBJTE_VERSION_MICRO + #define Libisofs_libjte_dot_h_too_olD 1 + #endif + +#ifdef Libisofs_libjte_dot_h_too_olD +LIBJTE_MISCONFIGURATION = 0; +INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libjte_dot_h_TOO_OLD__SEE_libisofs_dot_h_AND_burn_wrap.c_c = 0; +LIBJTE_MISCONFIGURATION_ = 0; +#endif + +#endif /* Xorriso_with_libjtE */ + + +/* End of ugly compile time tests (scroll up for explanation) */ + + + msg[0]= 0; + +#ifdef Xorriso_with_libjtE + + libjte__version(&major, &minor, µ); + sprintf(msg + strlen(msg), "libjte-%d.%d.%d ", major, minor, micro); + if (libjte__is_compatible(LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, + LIBJTE_VERSION_MICRO, 0)) { + sprintf(msg+strlen(msg), "ok, "); + } else { + sprintf(msg + strlen(msg), + "- TOO OLD -, need at least libjte-%d.%d.%d ,\n", + LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, + LIBJTE_VERSION_MICRO); + bad_match= 1; + no_iso_init= 1; /* iso_init() will fail anyway */ + } + +#endif /* Xorriso_with_libjtE */ + + if(!no_iso_init) { + if(iso_init()<0) { + sprintf(msg+strlen(msg), "Cannot initialize libisofs\n"); + return(0); + } + } + iso_lib_version(&major, &minor, µ); + sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro); +#ifdef iso_lib_header_version_major + if(iso_lib_is_compatible(iso_lib_header_version_major, + iso_lib_header_version_minor, + iso_lib_header_version_micro)) { + sprintf(msg+strlen(msg), "ok, "); + } else { + sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", + iso_lib_header_version_major, iso_lib_header_version_minor, + iso_lib_header_version_micro); + bad_match= 1; + } +#else + if(iso_lib_is_compatible(isoburn_libisofs_req_major, + isoburn_libisofs_req_minor, + isoburn_libisofs_req_micro)) { + sprintf(msg+strlen(msg), "suspicious, "); + } else { + sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", + isoburn_libisofs_req_major, isoburn_libisofs_req_minor, + isoburn_libisofs_req_micro); + bad_match= 1; + } +#endif /* ! iso_lib_header_version_major */ + + if(!burn_initialize()) { + sprintf(msg+strlen(msg), "Cannot initialize libburn\n"); + return(0); + } + + burn_version(&major, &minor, µ); + sprintf(msg+strlen(msg), "libburn-%d.%d.%d ", major, minor, micro); + if(major > burn_header_version_major + || (major == burn_header_version_major + && (minor > burn_header_version_minor + || (minor == burn_header_version_minor + && micro >= burn_header_version_micro)))) { + sprintf(msg+strlen(msg), "ok, "); + } else { + sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n", + burn_header_version_major, burn_header_version_minor, + burn_header_version_micro); + bad_match= 1; + } + + isoburn_version(&major, &minor, µ); + sprintf(msg+strlen(msg), "for libisoburn-%d.%d.%d", major, minor, micro); + if(bad_match) + return(0); + + isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ + return(1); +} + + +/* API @since 0.1.0 */ +int isoburn_libisofs_req(int *major, int *minor, int *micro) +{ + *major= iso_lib_header_version_major; + *minor= iso_lib_header_version_minor; + *micro= iso_lib_header_version_micro; + return(1); +} + + +/* API @since 0.1.0 */ +int isoburn_libburn_req(int *major, int *minor, int *micro) +{ + *major= burn_header_version_major; + *minor= burn_header_version_minor; + *micro= burn_header_version_micro; + return(1); +} + + +/* API @since 0.6.4 */ +int isoburn_libjte_req(int *major, int *minor, int *micro) +{ +#ifdef Xorriso_with_libjtE + *major= LIBJTE_VERSION_MAJOR; + *minor= LIBJTE_VERSION_MINOR; + *micro= LIBJTE_VERSION_MICRO; +#else + *major= *minor= *micro= 0; +#endif /* ! Xorriso_with_libjtE */ + return(1); +} + + +int isoburn_set_msgs_submit(int (*msgs_submit)(void *handle, int error_code, + char msg_text[], int os_errno, + char severity[], int flag), + void *submit_handle, int submit_flag, int flag) +{ + libisoburn_default_msgs_submit= msgs_submit; + libisoburn_default_msgs_submit_handle= submit_handle; + libisoburn_default_msgs_submit_flag= submit_flag; + return(1); +} + + +int isoburn_is_intermediate_dvd_rw(struct burn_drive *d, int flag) +{ + int profile, ret= 0, format_status, num_formats; + char profile_name[80]; + enum burn_disc_status s; + off_t format_size= -1; + unsigned bl_sas; + + s= isoburn_disc_get_status(d); + ret= burn_disc_get_profile(d, &profile, profile_name); + if(ret>0 && profile==0x13) + ret= burn_disc_get_formats(d, &format_status, &format_size, + &bl_sas, &num_formats); + if(ret>0 && profile==0x13 && s==BURN_DISC_BLANK && + format_status==BURN_FORMAT_IS_UNKNOWN) + return(1); + return(0); +} + + +/** Examines the medium and sets appropriate emulation if needed. + @param flag bit0= pretent blank on overwriteable media + bit3= if the drive reports a -ROM profile then try to read + table of content by scanning for ISO image headers. + bit4= do not emulate TOC on overwriteable media + bit5= ignore ACL from external filesystems + bit6= ignore POSIX Extended Attributes from external filesystems + bit7= pretend -ROM and scan for table of content + bit9= when scanning for ISO 9660 sessions on overwritable + media: Do not demand a valid superblock at LBA 0 + and scan until end of medium. +*/ +static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d, + int flag) +{ + int ret, profile, readonly= 0, role, random_access; + int emulation_started= 0; + struct burn_multi_caps *caps= NULL; + struct isoburn_toc_entry *t; + char profile_name[80]; + struct isoburn_toc_disc *disc= NULL; + struct isoburn_toc_session **sessions; + struct isoburn_toc_track **tracks; + int num_sessions= 0, num_tracks= 0, track_count= 0, session_no= 0; + char msg[80]; + enum burn_disc_status s; + +#ifndef Hardcoded_cd_rW + int lba, nwa; +#endif + + s= burn_disc_get_status(d); + profile_name[0]= 0; + ret= burn_disc_get_profile(d, &profile, profile_name); + if(ret<=0) + profile= 0x00; + ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0); + if(ret<0) /*== 0 is read-only medium, but it is too early to reject it here */ + goto ex; + if(ret==0 || (flag & 128)) + readonly= 1; + if(flag & 128) + flag = (flag & ~ 16) | 8; + + ret= isoburn_find_emulator(o, d, 0); + if(ret >= 0 && *o != NULL) + isoburn_destroy(o, 0); + ret= isoburn_new(o, 0); + if(ret<=0) + goto ex; + (*o)->drive= d; + (*o)->msgs_submit= libisoburn_default_msgs_submit; + (*o)->msgs_submit_handle= libisoburn_default_msgs_submit_handle; + (*o)->msgs_submit_flag= libisoburn_default_msgs_submit_flag; + iso_image_set_ignore_aclea((*o)->image, (flag >> 5 ) & 3); + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + caps->start_adr= 0; + (*o)->fabricated_disc_status= BURN_DISC_APPENDABLE; +#endif + + role= burn_drive_get_drive_role(d); + random_access= caps->start_adr || role == 4; + if(random_access) + (*o)->emulation_mode= 1; + if(random_access && !readonly) { /* set emulation to overwriteable */ + ret= isoburn_is_intermediate_dvd_rw(d, 0); + if(ret>0) { + (*o)->min_start_byte= 0; + (*o)->nwa= 0; + (*o)->zero_nwa= 0; + } + if((flag & 1) && role != 4 && role != 5) { + (*o)->nwa= (*o)->zero_nwa; + (*o)->fabricated_disc_status= BURN_DISC_BLANK; + } else { + ret= isoburn_start_emulation(*o, 0); + if(ret<=0) { + (*o)->emulation_mode= -1; + goto ex; + } + emulation_started= 1; + /* try to read emulated toc */ + ret= isoburn_emulate_toc(d, (flag & 16) | ((!!(flag & 512)) << 1)); + if(ret<0) { + (*o)->emulation_mode= -1; + goto ex; + } + } + } else { + + /* >>> recognize unsuitable media (but allow read-only media) */; + + if(readonly && s != BURN_DISC_EMPTY) { + + /* >>> ts B10712: This maps BURN_DISC_UNSUITABLE to BURN_DISC_FULL + which can hardly be correct in general. + ??? What reason does this have ? + */ + (*o)->fabricated_disc_status= BURN_DISC_FULL; + + /* This might be an overwriteable medium in a -ROM drive. + Pitfall: + Multi-session media which bear a xorriso image for overwriteables + in their first session would get a TOC of that first image rather + than of the medium. + It is not possible to distinguish a BD-RE from a single session + BD-R with an image for overwriteables. But as soon as the medium + bears 2 logical tracks it cannot be overwriteable. + So count the number of tracks first. + */ + disc= isoburn_toc_drive_get_disc(d); + if(disc != NULL) { + sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); + for(session_no= 0; session_no < num_sessions; session_no++) { + tracks= isoburn_toc_session_get_tracks(sessions[session_no], + &num_tracks); + if(tracks != NULL) + track_count+= num_tracks; + } + isoburn_toc_disc_free(disc); + } + + sprintf(msg, "ROM medium has libburn track count = %d", track_count); + isoburn_msgs_submit(*o, 0x00060000, msg, 0, "DEBUG", 0); + + if((flag & 16) || track_count >= 2) { + ret= 0; /* toc emulation off, or not overwriteable */ + } else { + ret= isoburn_start_emulation(*o, 1); + if(ret<=0) { + (*o)->emulation_mode= -1; + goto ex; + } + emulation_started= 1; + ret= isoburn_emulate_toc(d, 1 | ((!!(flag & 512)) << 1)); + if(ret<0) + goto ex; + else if(ret > 0) + (*o)->emulation_mode= 1; + } + if(ret == 0 && (profile != 0x08 || (flag & 128)) && (flag & 8)) { + /* This might also be multi-session media which do not + get shown with a decent TOC. + CD-R TOC (profile 0x08) can be trusted. Others not. + Do a scan search of ISO headers. + */ + if(!emulation_started) { + ret= isoburn_start_emulation(*o, 1); + if(ret<=0) { + (*o)->emulation_mode= -1; + goto ex; + } + } + ret= isoburn_emulate_toc(d, 1 | 2); + if(ret<0) + goto ex; + if(ret>0) { /* point msc1 to last session */ + if((*o)->toc!=NULL) { + for(t= (*o)->toc; t->next!=NULL; t= t->next) + ; /* clang wants newline in empty loops */ + (*o)->fabricated_msc1= t->start_lba; + } + } + } + } +#ifdef Hardcoded_cd_rW + (*o)->nwa= Hardcoded_cd_rw_nwA; +#else + ret= burn_disc_track_lba_nwa(d, NULL, 0, &lba, &nwa); + if(ret>0) + (*o)->nwa= nwa; + if((*o)->nwa < (*o)->zero_nwa) + (*o)->zero_nwa= 0; +#endif + + } + + ret= 1; +ex: + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + return(ret); +} + + +/** + @param flag bit0= load + bit1= regard overwriteable media as blank + bit2= if the drive is a regular disk file: truncate it to + the write start address + bit3= if the drive reports a -ROM profile then try to read + table of content by scanning for ISO image headers. + (depending on media type and drive state this might + help or it might make the resulting toc even worse) + bit4= do not emulate TOC on overwriteable media + bit5= ignore ACL from external filesystems + bit6= ignore POSIX Extended Attributes from external filesystems + bit7= pretend -ROM profile and scan for table of content + bit8= re-assess (*drive_infos)[0] rather than acquiring adr + bit9= when scanning for ISO 9660 sessions on overwritable + media: Do not demand a valid superblock at LBA 0 + and scan until end of medium. +*/ +int isoburn_drive_aquire(struct burn_drive_info *drive_infos[], + char *adr, int flag) +{ + int ret, drive_grabbed= 0; + struct isoburn *o= NULL; + int conv_ret; + char *libburn_drive_adr= NULL; + + /* Should be obsolete by new drive addressing of libburn-0.5.2 */ + /* but helps with kernel 2.4 to use /dev/sr */ + libburn_drive_adr= calloc(1, BURN_DRIVE_ADR_LEN); + if(libburn_drive_adr == NULL) + {ret= -1; goto ex;} + conv_ret= burn_drive_convert_fs_adr(adr, libburn_drive_adr); + if(conv_ret<=0) + strcpy(libburn_drive_adr, adr); + + if(flag & 256) + ret= burn_drive_re_assess((*drive_infos)[0].drive, 0); + else + ret= burn_drive_scan_and_grab(drive_infos, libburn_drive_adr, flag&1); + if(ret<=0) + goto ex; + drive_grabbed= 1; + ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, + (flag & (8 | 16 | 32 | 64 | 128 | 512)) | !!(flag&2)); + if(ret<=0) + goto ex; + + if(flag&4) { + ret= isoburn_find_emulator(&o, (*drive_infos)[0].drive, 0); + if(ret>0 && o!=NULL) + o->truncate= 1; + } + + ret= 1; +ex: + if(ret<=0) { + if(drive_grabbed) + burn_drive_release((*drive_infos)[0].drive, 0); + isoburn_destroy(&o, 0); + } + if(libburn_drive_adr != NULL) + free(libburn_drive_adr); + return(ret); +} + + +int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], + char *adr, int load) +{ + int ret; + + ret= isoburn_drive_aquire(drive_infos, adr, !!load); + return(ret); +} + + +int isoburn_drive_grab(struct burn_drive *drive, int load) +{ + int ret; + struct isoburn *o= NULL; + + ret= burn_drive_grab(drive, load); + if(ret<=0) + goto ex; + ret= isoburn_welcome_media(&o, drive, 0); + if(ret<=0) + goto ex; + + ret= 1; +ex: + if(ret<=0) + isoburn_destroy(&o,0); + return(ret); +} + + +/** Retrieve medium emulation and eventual isoburn emulator of drive. + @return -1 unsuitable medium, 0 generic medium, 1 emulated medium. +*/ +int isoburn_find_emulator(struct isoburn **pt, + struct burn_drive *drive, int flag) +{ + int ret; + + ret= isoburn_find_by_drive(pt, drive, 0); + if(ret<=0) + return(0); + if((*pt)->emulation_mode==-1) { + isoburn_msgs_submit(*pt, 0x00060000, + "Unsuitable drive and medium state", 0, "FAILURE", 0); + return(-1); + } + if((*pt)->emulation_mode==0) + return(0); + return(1); +} + + +enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return(BURN_DISC_UNSUITABLE); + if(o!=NULL) + if(o->fabricated_disc_status!=BURN_DISC_UNREADY) + return(o->fabricated_disc_status); + if(ret==0) + return(burn_disc_get_status(drive)); + + /* emulated status */ + if(o->emulation_mode==-1) + return(BURN_DISC_UNSUITABLE); + if(o->nwa>o->zero_nwa) + return(BURN_DISC_APPENDABLE); + return(BURN_DISC_BLANK); +} + + +int isoburn_disc_pretend_full_uncond(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret > 0 && o != NULL) + o->fabricated_disc_status= BURN_DISC_FULL; + ret= burn_disc_pretend_full_uncond(drive); + return(ret); +} + + +int isoburn_disc_erasable(struct burn_drive *d) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret>0) + if(o->emulation_mode==1) + return(1); + return burn_disc_erasable(d); +} + + +static int isoburn_is_overwritable(struct burn_drive *drive, int flag) +{ + char name[80]; + int profile, ret; + + ret= burn_disc_get_profile(drive, &profile, name); + if(ret <= 0) + return(0); + if(profile == 0x12 || profile == 0x13 || profile == 0x1a || profile == 0x43) + return(1); + return(0); + +} + + +void isoburn_disc_erase(struct burn_drive *drive, int fast) +{ + int ret, do_pseudo_blank= 0, role; + struct isoburn *o; + enum burn_disc_status s; + char *zero_buffer= NULL; + struct burn_multi_caps *caps= NULL; + + zero_buffer= calloc(1, Libisoburn_target_head_sizE); + if(zero_buffer == NULL) { + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + goto ex; + } + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret>0) { + if(o->emulation_mode==-1) { + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + goto ex; + } + role = burn_drive_get_drive_role(drive); + if (role == 5) { + /* libburn will truncate the random-access write-only file + to zero size and change its state */ + burn_disc_erase(drive, fast); + o->fabricated_disc_status= burn_disc_get_status(drive); + o->nwa= o->zero_nwa= 0; + goto ex; + } + if(o->emulation_mode > 0) { /* might be readonly with emulated sessions */ + ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); + if(ret <= 0) /* Maybe because of burn_disc_pretend_full() */ + do_pseudo_blank= isoburn_is_overwritable(drive, 0); /* known profiles */ + else if(caps->start_adr) + do_pseudo_blank= 1; + } + if(do_pseudo_blank) { + s= isoburn_disc_get_status(drive); + if(s==BURN_DISC_FULL) { /* unknown data format in first 64 kB */ + memset(zero_buffer, 0, Libisoburn_target_head_sizE); + ret= burn_random_access_write(drive, (off_t) 0, zero_buffer, + (off_t) Libisoburn_target_head_sizE, 1); + } else { + ret= isoburn_invalidate_iso(o, 0); + } + if(ret<=0) + burn_drive_cancel(drive); /* mark run as failure */ + goto ex; + } + } + burn_disc_erase(drive, fast); +ex:; + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + if(zero_buffer != NULL) + free(zero_buffer); +} + + +off_t isoburn_disc_available_space(struct burn_drive *d, + struct burn_write_opts *opts) +{ + int ret; + struct isoburn *o; + struct burn_write_opts *eff_opts= NULL, *local_opts= NULL; + enum burn_disc_status s; + off_t avail; + + eff_opts= opts; + ret= isoburn_find_emulator(&o, d, 0); + if(ret>0 && o!=NULL) + if(o->emulation_mode!=0) { + s= isoburn_disc_get_status(d); + if(s==BURN_DISC_FULL) /* unknown data format in first 64 kB */ + return((off_t) 0); + local_opts= burn_write_opts_new(d); + eff_opts= local_opts; + burn_write_opts_set_start_byte(eff_opts, ((off_t) o->nwa) * (off_t) 2048); + } + avail= burn_disc_available_space(d, eff_opts); + if(local_opts!=NULL) + burn_write_opts_free(local_opts); + local_opts= NULL; + return(avail); +} + + +int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba) +{ + int ret; + struct isoburn *o; + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + *start_lba= Hardcoded_cd_rw_c1; + return(1); +#endif + + if(isoburn_disc_get_status(d)!=BURN_DISC_APPENDABLE && + isoburn_disc_get_status(d)!=BURN_DISC_FULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Medium contains no recognizable data", 0, "SORRY", 0); + return(0); + } + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(o->fabricated_msc1>=0) { + *start_lba= o->fabricated_msc1; + return(1); + } + if(ret>0) if(o->emulation_mode>0) { + *start_lba= 0; + return(1); + } + return(burn_disc_get_msc1(d, start_lba)); +} + + +int isoburn_disc_track_lba_nwa(struct burn_drive *d, + struct burn_write_opts *opts, + int trackno, int *lba, int *nwa) +{ + int ret; + struct isoburn *o; + enum burn_disc_status s; + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + *lba= Hardcoded_cd_rw_c1; + *nwa= Hardcoded_cd_rw_nwA; + return(1); +#endif + + *nwa= *lba= 0; + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(ret>0) if(o->emulation_mode>0) { + *lba= 0; + *nwa= o->nwa; + return(1); + } + if(burn_drive_get_drive_role(d) != 1) + return(1); + + s= isoburn_disc_get_status(d); + if(s == BURN_DISC_BLANK) /* We do not believe in anything but nwa = lba = 0 */ + return(1); + return(burn_disc_track_lba_nwa(d, opts, trackno, lba, nwa)); +} + + +int isoburn_get_msc2(struct isoburn *o, + struct burn_write_opts *opts, int *msc2, int flag) +{ + int ret, lba, nwa; + + if(o->fabricated_msc2>=0) + *msc2= o->fabricated_msc2; + else { + ret= isoburn_disc_track_lba_nwa(o->drive, opts, 0, &lba, &nwa); + if(ret<=0) + return(ret); + *msc2= nwa; + } + return(1); +} + +/* @param flag bit0= truncate (else do not truncate) + bit1= do not warn if call is inappropriate to drive + bit2= only set if truncation is currently enabled +*/ +int isoburn_set_truncate(struct burn_drive *drive, int flag) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret < 0) + return ret; + if(o == NULL) { + if(!(flag & (2 | 4))) + isoburn_msgs_submit(o, 0x00060000, + "Drive type or role is inappropriate for truncation", 0, "WARNING", 0); + return(0); + } + if(o->truncate || !(flag & 4)) + o->truncate= flag & 1; + return(1); +} + + +void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) +{ + int ret; + off_t nwa= 0; + struct isoburn *o; + struct burn_drive *drive; + char *reasons= NULL, *msg= NULL, *adr= NULL; + struct stat stbuf; + enum burn_write_types write_type; + + drive= burn_write_opts_get_drive(opts); + + reasons= calloc(1, BURN_REASONS_LEN); + msg= calloc(1, 160+BURN_REASONS_LEN); + adr= calloc(1, BURN_DRIVE_ADR_LEN); + if(reasons == NULL || msg == NULL || adr == NULL) { + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + goto ex; + } + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + goto ex; + if(o == NULL) { + sprintf(msg, + "Program error: Cannot find isoburn object associated to the drive"); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); + burn_drive_cancel(drive); + goto ex; + } + o->wrote_well= -1; + if(o->emulation_mode!=0) { + burn_write_opts_set_multi(opts, 0); + if(o->emulation_mode>0 && o->nwa >= 0) { + nwa= o->nwa; + + /* This caters for unwritten formatted DVD-RW. They need to be written + sequentially on the first use. Only written areas are random access. + If the first session is not written to LBA 0, then re-opening of + formatting and padding is needed. + This can be done. But when the track gets closed after padding, + this lasts a long time. There is a high risk that an app will not + poll the message queue while waiting for isoburn_disc_write() to + return. The pacifier loop usually happens only afterwards. + So automatic formatting might cause a nervous clueless user. + */ + ret= isoburn_is_intermediate_dvd_rw(drive, 0); + if(ret>0 && nwa>0 && nwa <= o->zero_nwa) { + /* actually this should not happen since such media get recognized + by isoburn_welcome_media and o->zero_nwa gets set to 0 + */ + sprintf(msg, + "DVD-RW insufficiently formatted. (Intermediate State, size unknown)"); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); + sprintf(msg, + "It might help to first deformat it and then format it again"); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "HINT", 0); + burn_drive_cancel(drive); /* mark run as failure */ + goto ex; + } + /* end of DVD-RW oriented check */ + burn_write_opts_set_start_byte(opts, nwa * (off_t) 2048); + } + } + + if(o->do_tao) { + if (o->do_tao > 0) + burn_write_opts_set_write_type(opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1); + else + burn_write_opts_set_write_type(opts, BURN_WRITE_SAO, BURN_BLOCK_SAO); + + ret = burn_precheck_write(opts, disc, reasons, 0); + if(ret <= 0) { + sprintf(msg, "Cannot set write type %s for this medium.", + o->do_tao > 0 ? "TAO" : "SAO"); + sprintf(msg + strlen(msg), "Reasons given:\n %s", reasons); + goto no_write_type; + } + sprintf(msg, "Explicitly chosen write type: %s", + o->do_tao > 0 ? "TAO" : "SAO"); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "NOTE", 0); + } else { + write_type= burn_write_opts_auto_write_type(opts, disc, reasons, 0); + if (write_type == BURN_WRITE_NONE) { + sprintf(msg, "Failed to find a suitable write type:\n%s", reasons); +no_write_type:; + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); + if(o!=NULL) + o->wrote_well= 0; + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + goto ex; + } + + sprintf(reasons, "%d", (int) write_type); + sprintf(msg, "Write_type = %s\n", + (write_type == BURN_WRITE_SAO ? "SAO" : + (write_type == BURN_WRITE_TAO ? "TAO" : reasons))); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "DEBUG", 0); + } + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + fprintf(stderr, "Setting write address to LBA %d\n", Hardcoded_cd_rw_nwA); + burn_write_opts_set_start_byte(opts, + ((off_t) Hardcoded_cd_rw_nwA) * (off_t) 2048); +#endif + + if(o->truncate) { + ret= burn_drive_get_drive_role(drive); + if(ret == 2 || ret == 5) { + ret= burn_drive_d_get_adr(drive, adr); + if(ret>0) { + ret= lstat(adr, &stbuf); + if(ret!=-1) + if(S_ISREG(stbuf.st_mode)) + ret= truncate(adr, nwa * (off_t) 2048); + /* (result of truncate intentionally ignored) */ + } + } + } + + burn_disc_write(opts, disc); +ex:; + if(reasons != NULL) + free(reasons); + if(msg != NULL) + free(msg); + if(adr != NULL) + free(adr); +} + + +void isoburn_drive_release(struct burn_drive *drive, int eject) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return; + if(o!=NULL) { + isoburn_destroy(&o, 0); + } + burn_drive_release(drive, eject); +} + + +void isoburn_finish(void) +{ + isoburn_destroy_all(&isoburn_list_start, 0); + burn_finish(); + iso_finish(); +} + + +int isoburn_needs_emulation(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + enum burn_disc_status s; + + s= isoburn_disc_get_status(drive); + if(s!=BURN_DISC_BLANK && s!=BURN_DISC_APPENDABLE) + return(-1); + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return(-1); + if(ret>0) + if(o->emulation_mode>0) + return(1); + return(0); +} + + +int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag) +{ + int ret; + struct burn_drive *drive = o->drive; + struct burn_multi_caps *caps= NULL; + + ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); + if(ret<=0) + goto ex; + if(!caps->start_adr) { + isoburn_msgs_submit(o, 0x00060000, + "Cannot set start byte address with this type of media", + 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + o->min_start_byte= value; + if(value % caps->start_alignment) + value+= caps->start_alignment - (value % caps->start_alignment); + o->nwa= value/2048; + if(o->nwa < o->zero_nwa) + o->zero_nwa= 0; + /* If suitable for media alignment, round up to Libisoburn_nwa_alignemenT */ + if((o->nwa % Libisoburn_nwa_alignemenT) && + ((Libisoburn_nwa_alignemenT*2048) % caps->start_alignment)==0 ) + o->nwa+= Libisoburn_nwa_alignemenT - (o->nwa % Libisoburn_nwa_alignemenT); + ret= 1; +ex: + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + return(ret); +} + + +int isoburn_get_min_start_byte(struct burn_drive *d, off_t *start_byte, + int flag) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(ret==0) + return(0); + *start_byte= o->min_start_byte; + if(o->min_start_byte<=0) + return(0); + return(1); +} + + +int isoburn_drive_wrote_well(struct burn_drive *d) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(o!=NULL) + if(o->wrote_well>=0) + return(o->wrote_well); + ret= burn_drive_wrote_well(d); + return ret; +} + + +int isoburn_get_fifo_status(struct burn_drive *d, int *size, int *free_bytes, + char **status_text) +{ + int ret; + struct isoburn *o; + size_t hsize= 0, hfree_bytes= 0; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + + if(o==NULL) + return(-1); + if(o->iso_source==NULL) + return(-1); + ret= iso_ring_buffer_get_status(o->iso_source, &hsize, &hfree_bytes); + if(hsize > 1024*1024*1024) + *size= 1024*1024*1024; + else + *size= hsize; + if(hfree_bytes > 1024*1024*1024) + *free_bytes= 1024*1024*1024; + else + *free_bytes= hfree_bytes; + *status_text= ""; + if(ret==0) + *status_text= "standby"; + else if(ret==1) + *status_text= "active"; + else if(ret==2) + *status_text= "ending"; + else if(ret==3) + *status_text= "failing"; + else if(ret==4) + *status_text= "unused"; + else if(ret==5) + *status_text= "abandoned"; + else if(ret==6) + *status_text= "ended"; + else if(ret==7) + *status_text= "aborted"; + return(ret); +} + + +/* @param flag bit0= -reserved- + bit1= this is a libburn severity +*/ +int isoburn__sev_to_text(int severity, char **severity_name, + int flag) +{ + int ret; + + ret= iso_sev_to_text(severity, severity_name); + if(ret>0) + return(ret); + ret= burn_sev_to_text(severity, severity_name, 0); + return(ret); +} + + +int isoburn__text_to_sev(char *severity_name, int *severity_number, int flag) +{ + int ret= 1; + + ret= iso_text_to_sev(severity_name, severity_number); + if(ret>0) + return(ret); + ret= burn_text_to_sev(severity_name, severity_number, 0); + return(ret); +} + + +int isoburn_report_iso_error(int iso_error_code, char msg_text[], int os_errno, + char min_severity[], int flag) +{ + int error_code, iso_sev, min_sev, ret; + char *sev_text_pt, *msg_text_pt= NULL; + + error_code= iso_error_get_code(iso_error_code); + if(error_code < 0x00030000 || error_code >= 0x00040000) + error_code= (error_code & 0xffff) | 0x00050000; + + if(iso_error_code<0) + msg_text_pt= (char *) iso_error_to_msg(iso_error_code); + if(msg_text_pt==NULL) + msg_text_pt= msg_text; + iso_sev= iso_error_get_severity(iso_error_code); + sev_text_pt= min_severity; + isoburn__text_to_sev(min_severity, &min_sev, 0); + if(min_sev < iso_sev) + isoburn__sev_to_text(iso_sev, &sev_text_pt, 0); + ret= iso_msgs_submit(error_code, msg_text_pt, os_errno, sev_text_pt, 0); + return(ret); +} + + +/* @param flag bit0-7: info return mode + 0= do not return anything in info (do not even touch it) + 1= copy volume id to info (info needs 33 bytes) + 2= do not touch info (caller will copy 64 kB header to it) + bit14= -reserved - + bit15= -reserved- + @return 1 seems to be a valid ISO image , 0 format not recognized, <0 error +*/ +int isoburn_read_iso_head_parse(unsigned char *data, + int *image_blocks, char *info, int flag) +{ + int i, info_mode; + + /* is this an ISO image ? */ + if(data[0]!=1) + return(0); + if(strncmp((char *) (data+1),"CD001",5)!=0) + return(0); + /* believe so */ + + *image_blocks= data[80] | (data[81]<<8) | (data[82]<<16) | (data[83]<<24); + info_mode= flag&255; + if(info_mode==0) { + ; + } else if(info_mode==1) { + strncpy(info, (char *) (data+40), 32); + info[32]= 0; + for(i= strlen(info)-1; i>=0; i--) + if(info[i]!=' ') + break; + else + info[i]= 0; + } else if(info_mode==2) { + ; + } else { + isoburn_msgs_submit(NULL, 0x00060000, + "Program error: Unknown info mode with isoburn_read_iso_head()", + 0, "FATAL", 0); + return(-1); + } + return(1); +} + + +/* API + @param flag bit0-7: info return mode + 0= do not return anything in info (do not even touch it) + 1= copy volume id to info (info needs 33 bytes) + 2= copy 64 kB header to info (needs 65536 bytes) + bit13= do not read head from media but use first 64 kB from info + bit14= check both half buffers (not only second) + return 2 if found in first block + bit15= return-1 on read error + @return 1 seems to be a valid ISO image , 2 found in first half buffer, + 0 format not recognized, <0 error +*/ +int isoburn_read_iso_head(struct burn_drive *d, int lba, + int *image_blocks, char *info, int flag) +{ + unsigned char *buffer= NULL; + int ret, info_mode, capacity, role; + off_t data_count, to_read; + struct isoburn *o; + + buffer= calloc(1, 64 * 1024); + if(buffer == NULL) + {ret= -1; goto ex;} + + info_mode= flag&255; + *image_blocks= 0; + if(flag&(1<<13)) { + memcpy(buffer, info, 64*1024); + } else { + memset(buffer, 0, 64 * 1024); + role = burn_drive_get_drive_role(d); + if (role == 3 || role == 5) + + /* >>> ??? return always 0 ? */ + {ret= (-1*!!(flag&(1<<15))); goto ex;} + + ret = burn_get_read_capacity(d, &capacity, 0); + if (ret <= 0 && (role == 2 || role == 4)) { + /* Might be a block device on a system where libburn cannot determine its + size. Try to read anyway. */ + capacity = 0x7ffffff0; + ret = 1; + } + to_read= (off_t) capacity * ((off_t) 2048); + if(ret > 0 && to_read >= (off_t) (36 * 1024)) { + ret= isoburn_find_emulator(&o, d, 0); + if(ret > 0) + if(o->media_read_error) + {ret= (-1 * !!(flag & (1 << 15))); goto ex;} + if(to_read >= (off_t) (64 * 1024)) + to_read= 64 * 1024; + ret = burn_read_data(d, ((off_t) lba) * (off_t) 2048, (char *) buffer, + to_read, &data_count, 32); /* error messages as DEBUG */ + } else + ret= 0; + if(ret<=0) + {ret= (-1*!!(flag&(1<<15))); goto ex;} + if(info_mode==2) + memcpy(info, buffer, 64*1024); + } + + if(flag&(1<<14)) { + ret= isoburn_read_iso_head_parse(buffer, image_blocks, info, info_mode); + if(ret<0) + goto ex; + if(ret>0) + {ret= 2; goto ex;} + } + ret= isoburn_read_iso_head_parse(buffer+32*1024, image_blocks, info, + info_mode); + if(ret<=0) + goto ex; + ret= 1; +ex:; + if(buffer != NULL) + free(buffer); + return(ret); +} + + +int isoburn_make_toc_entry(struct isoburn *o, int *session_count, int lba, + int track_blocks, char *volid, int flag) +{ + int ret; + struct isoburn_toc_entry *item; + + ret= isoburn_toc_entry_new(&item, o->toc, 0); + if(ret<=0) { +no_memory:; + isoburn_msgs_submit(o, 0x00060000, + "Not enough memory for emulated TOC entry object", + 0, "FATAL", 0); + return(-1); + } + if(o->toc==NULL) + o->toc= item; + (*session_count)++; + item->session= *session_count; + item->track_no= *session_count; + item->start_lba= lba; + item->track_blocks= track_blocks; + if(volid != NULL) { + item->volid= strdup(volid); + if(item->volid == NULL) + goto no_memory; + } + return(1); +} + + +/* @param flag bit0= allow unemulated media + bit1= free scanning without enclosing LBA-0-header + bit4= represent emulated media as one single session + (not with bit1) + @return -1 severe error, 0= no neat header chain, 1= credible chain read +*/ +int isoburn_emulate_toc(struct burn_drive *d, int flag) +{ + int ret, image_size= 0, lba, track_blocks, session_count= 0, read_flag= 0; + int scan_start= 0, scan_count= 0, probe_minus_16= 0, growisofs_nwa, role; + int with_enclosure= 0, readable_blocks= -1; + struct isoburn *o; + char *msg= NULL, *size_text= NULL, *sev, volid[33], *volid_pt= NULL; + time_t start_time, last_pacifier, now; + + msg= calloc(1, 160); + size_text= calloc(1, 80); + if(msg == NULL || size_text == NULL) + {ret= -1; goto ex;} + + /* is the medium emulated multi-session ? */ + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + {ret= -1; goto ex;} + if(o==NULL) + {ret= -1; goto ex;} + if(o->emulation_mode<=0 && !(flag&1)) + {ret= 0; goto ex;} + + ret= burn_get_read_capacity(d, &readable_blocks, 0); + if(ret <= 0) { + role = burn_drive_get_drive_role(d); + if (role == 2 || role == 4) + /* Might be a block device on a system where libburn cannot determine its + size. Try to read anyway. */ + readable_blocks= 0x7ffffff0; /* try to read anyway */ + else + readable_blocks= -1; + } + if(o->fabricated_disc_status == BURN_DISC_BLANK) + {ret= 0; goto failure;} + + start_time= last_pacifier= time(NULL); + lba= 0; + if(flag & 2) { + /* If there is a PVD at LBA 32 then this is an image with emulated TOC */ + ret= isoburn_read_iso_head(d, 32, &image_size, NULL, 0); + if(ret > 0) + lba= 32; + } else { + ret= isoburn_read_iso_head(d, lba, &image_size, NULL, 0); + if(ret<=0) + {ret= 0; goto failure;} + lba= o->target_iso_head_size / 2048; + with_enclosure= 1; + if((flag & 16) && o->emulation_mode == 1) { + ret= 1; + goto failure; /* This will represent the medium as single session */ + } + } + while(lba= 5) { + last_pacifier= now; + if(scan_count>=10*512) + sprintf(size_text, "%.f MB", ((double) scan_count) / 512.0); + else + sprintf(size_text, "%.f kB", 2 * (double) scan_count); + sprintf(msg, "Found %d ISO sessions by scanning %s in %.f seconds", + session_count, size_text, (double) (now - start_time)); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); + } + read_flag= 1; + if(flag&2) + read_flag|= (1<<15)|((session_count>0)<<14); + else { + + /* growisofs aligns to 16 rather than 32. Overwriteable TOC emulation + relies on not accidentially seeing inter-session trash data. + But one can safely access 16 blocks earlier because a xorriso header + would have been overwritten with the unused 16 blocks at its start. + If libisoburn alignment would increase, then this would not be + possible any more. + */ + + if(probe_minus_16) + read_flag|= (1<<14); + probe_minus_16= 0; + } + + ret= isoburn_read_iso_head(d, lba, &track_blocks, volid, read_flag); + if(ret > 0) { + volid_pt= volid; + } else { + volid_pt= NULL; + if(session_count>0) { + if(flag&2) { + if(ret==0) { + /* try at next 64 k block (check both 32 k halves) */ + lba+= 32; + scan_count+= 32; + if(lba-scan_start <= Libisoburn_toc_scan_max_gaP) + continue; + } + break; + } + sprintf(msg, + "Chain of ISO session headers broken at #%d, LBA %ds", + session_count+1, lba); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); + + if(with_enclosure) { + ret= isoburn_make_toc_entry(o, &session_count, 0, image_size, NULL,0); + if(ret<=0) + goto failure; + } + break; /* do not return failure */ + + } + {ret= 0; goto failure;} + } + if(ret==2) /* ISO header was found in first half block */ + lba-= 16; + + if(readable_blocks >= 0 && lba + track_blocks > readable_blocks) { + sprintf(msg, "ISO image size %ds larger than readable size %ds", + lba + track_blocks, readable_blocks); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); + track_blocks= readable_blocks - lba; + } + ret= isoburn_make_toc_entry(o, &session_count, lba, track_blocks, volid_pt, + 0); + if(ret<=0) + goto failure; + lba+= track_blocks; + scan_count+= 32; + + /* growisofs aligns to 16 rather than 32 */ + growisofs_nwa= lba; + if(growisofs_nwa % 16) + growisofs_nwa+= 16 - (growisofs_nwa % 16); + if(lba % Libisoburn_nwa_alignemenT) + lba+= Libisoburn_nwa_alignemenT - (lba % Libisoburn_nwa_alignemenT); + scan_start= lba; + if(lba - growisofs_nwa == 16) + probe_minus_16= 1; + } + if(last_pacifier != start_time) + sev= "UPDATE"; + else + sev= "DEBUG"; + now= time(NULL); + if(scan_count>=10*512) + sprintf(size_text, "%.f MB", ((double) scan_count) / 512.0); + else + sprintf(size_text, "%.f kB", 2 * (double) scan_count); + sprintf(msg, "Found %d ISO sessions by scanning %s in %.f seconds", + session_count, size_text, (double) (now - start_time)); + isoburn_msgs_submit(o, 0x00060000, msg, 0, sev, 0); + {ret= 1; goto ex;} +failure:; + isoburn_toc_entry_destroy(&(o->toc), 1); + if(with_enclosure && o->emulation_mode == 1) { + if(readable_blocks >= 0 && image_size > readable_blocks) { + sprintf(msg, "ISO image size %ds larger than readable size %ds", + image_size, readable_blocks); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); + image_size= readable_blocks; + } + session_count= 0; + ret= isoburn_make_toc_entry(o, &session_count, 0, image_size, NULL, 0); + } +ex:; + if(msg != NULL) + free(msg); + if(size_text != NULL) + free(size_text); + return(ret); +} + + +int isoburn_toc_new_arrays(struct isoburn_toc_disc *o, + int session_count, int track_count, int flag) +{ + int i; + int isoburn_toc_destroy_arrays(struct isoburn_toc_disc *o, int flag); + + o->sessions= calloc(session_count, sizeof(struct isoburn_toc_session)); + o->session_pointers= + calloc(session_count, sizeof(struct isoburn_toc_session *)); + o->tracks= calloc(track_count, sizeof(struct isoburn_toc_track)); + o->track_pointers= calloc(track_count, sizeof(struct isoburn_toc_track *)); + if(o->sessions!=NULL && o->session_pointers!=NULL && + o->tracks!=NULL && o->track_pointers!=NULL) { + for(i= 0; isessions[i].session= NULL; + o->sessions[i].track_pointers= NULL; + o->sessions[i].track_count= 0; + o->sessions[i].toc_entry= NULL; + o->session_pointers[i]= NULL; + } + for(i= 0; itracks[i].track= NULL; + o->tracks[i].toc_entry= NULL; + o->track_pointers[i]= NULL; + } + return(1); + } + /* failed */ + isoburn_toc_destroy_arrays(o, 0); + return(-1); +} + + +int isoburn_toc_destroy_arrays(struct isoburn_toc_disc *o, int flag) +{ + if(o->sessions!=NULL) + free((char *) o->sessions); + o->sessions= NULL; + if(o->session_pointers!=NULL) + free((char *) o->session_pointers); + o->session_pointers= NULL; + if(o->tracks!=NULL) + free((char *) o->tracks); + o->tracks= NULL; + if(o->track_pointers!=NULL) + free((char *) o->track_pointers); + o->track_pointers= NULL; + return(1); +} + + +struct isoburn_toc_disc *isoburn_toc_drive_get_disc(struct burn_drive *d) +{ + int ret, session_count= 0, track_count= 0, num_tracks= 0, i, j; + int open_sessions= 0; + struct isoburn *o; + struct isoburn_toc_entry *t; + struct isoburn_toc_disc *toc_disc= NULL; + struct burn_session **s; + struct burn_track **tracks; + + toc_disc= calloc(1, sizeof(struct isoburn_toc_disc)); + if(toc_disc==NULL) + return(NULL); + toc_disc->disc= NULL; + toc_disc->sessions= NULL; + toc_disc->session_pointers= NULL; + toc_disc->tracks= NULL; + toc_disc->track_pointers= NULL; + toc_disc->session_count= 0; + toc_disc->incomplete_session_count= 0; + toc_disc->track_count= 0; + toc_disc->toc= NULL; + + /* is the medium emulated multi-session ? */ + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + goto libburn; + if(o->toc==NULL) + goto libburn; + + /* This is an emulated TOC */ + toc_disc->toc= o->toc; + for(t= toc_disc->toc; t!=NULL; t= t->next) + session_count++; + ret= isoburn_toc_new_arrays(toc_disc, session_count, session_count, 0); + if(ret<=0) + goto failure; + t= toc_disc->toc; + for(i= 0; isessions[i].track_pointers= toc_disc->track_pointers+i; + toc_disc->sessions[i].track_count= 1; + toc_disc->sessions[i].toc_entry= t; + toc_disc->session_pointers[i]= toc_disc->sessions+i; + toc_disc->tracks[i].toc_entry= t; + toc_disc->track_pointers[i]= toc_disc->tracks+i; + t= t->next; + } + toc_disc->session_count= session_count; + toc_disc->track_count= session_count; + return(toc_disc); + +libburn:; + /* This is a libburn provided TOC */ + toc_disc->disc= burn_drive_get_disc(d); + if(toc_disc->disc == NULL) { +failure:; + free((char *) toc_disc); + return(NULL); + } + s= burn_disc_get_sessions(toc_disc->disc, &session_count); + open_sessions= burn_disc_get_incomplete_sessions(toc_disc->disc); + for(i= 0; i < session_count + open_sessions; i++) { + tracks = burn_session_get_tracks(s[i], &num_tracks); + if(i == session_count + open_sessions - 1 && open_sessions > 0) { + /* Do not count the invisible track of the last incomplete session */ + num_tracks--; + } + track_count+= num_tracks; + } + if(session_count + open_sessions <= 0 || track_count <= 0) + goto failure; + ret= isoburn_toc_new_arrays(toc_disc, session_count + open_sessions, + track_count, 0); + if(ret<=0) + goto failure; + track_count= 0; + for(i= 0; i < session_count + open_sessions; i++) { + tracks = burn_session_get_tracks(s[i], &num_tracks); + if(i == session_count + open_sessions - 1 && open_sessions > 0) + num_tracks--; + toc_disc->sessions[i].session= s[i]; + toc_disc->sessions[i].track_pointers= toc_disc->track_pointers+track_count; + toc_disc->sessions[i].track_count= num_tracks; + toc_disc->session_pointers[i]= toc_disc->sessions+i; + for(j= 0; jtracks[track_count+j].track= tracks[j]; + toc_disc->track_pointers[track_count+j]= toc_disc->tracks+(track_count+j); + } + track_count+= num_tracks; + } + toc_disc->session_count= session_count; + toc_disc->incomplete_session_count= open_sessions; + toc_disc->track_count= track_count; + return(toc_disc); +} + + +int isoburn_toc_disc_get_sectors(struct isoburn_toc_disc *disc) +{ + struct isoburn_toc_entry *t; + int ret= 0, num_sessions, num_tracks, open_sessions= 0, session_idx= -1; + struct burn_session **sessions; + struct burn_track **tracks; + struct burn_toc_entry entry; + + if(disc==NULL) + return(0); + if(disc->toc!=NULL) { + for(t= disc->toc; t!=NULL; t= t->next) + ret= t->start_lba + t->track_blocks; + } else if(disc->disc!=NULL) { + sessions= burn_disc_get_sessions(disc->disc, &num_sessions); + open_sessions= burn_disc_get_incomplete_sessions(disc->disc); + if(num_sessions + open_sessions > 0) { + session_idx= num_sessions + open_sessions - 1; + tracks = burn_session_get_tracks(sessions[session_idx], &num_tracks); + if(open_sessions > 0) { + /* Do not count the invisible track of the last incomplete session */ + num_tracks--; + } + if(num_tracks <= 0) + session_idx--; + } + if(session_idx >= 0) { + tracks = burn_session_get_tracks(sessions[session_idx], &num_tracks); + if(session_idx == num_sessions + open_sessions - 1 && open_sessions > 0) { + /* Do not count the invisible track of the last incomplete session */ + num_tracks--; + } + if(num_tracks > 0) { + burn_track_get_entry(tracks[num_tracks - 1], &entry); + if(entry.extensions_valid & 1) + ret= entry.start_lba + entry.track_blocks; + } + } +/* + ret= burn_disc_get_sectors(disc->disc); +*/ + } + return(ret); +} + + +struct isoburn_toc_session **isoburn_toc_disc_get_sessions( + struct isoburn_toc_disc *disc, int *num) +{ + *num= disc->session_count; + return(disc->session_pointers); +} + + +int isoburn_toc_disc_get_incmpl_sess(struct isoburn_toc_disc *disc) +{ + return(disc->incomplete_session_count); +} + + +int isoburn_toc_session_get_sectors(struct isoburn_toc_session *s) +{ + struct isoburn_toc_entry *t; + int count= 0, i; + + if(s==NULL) + return(0); + if(s->toc_entry!=NULL) { + t= s->toc_entry; + for(i= 0; itrack_count; i++) { + count+= t->track_blocks; + t= t->next; + } + } else if(s->session!=NULL) + count= burn_session_get_sectors(s->session); + return(count); +} + + +int isoburn_toc_entry_finish(struct burn_toc_entry *entry, + int session_no, int track_no, int flag) +{ + int pmin, psec, pframe; + + entry->extensions_valid= 1; + entry->adr= 1; + entry->control= 4; + entry->session= session_no & 255; + entry->session_msb= (session_no >> 8) & 255; + entry->point= track_no & 255; + entry->point_msb= (track_no >> 8) & 255; + + burn_lba_to_msf(entry->start_lba, &pmin, &psec, &pframe); + if(pmin<=255) + entry->pmin= pmin; + else + entry->pmin= 255; + entry->psec= psec; + entry->pframe= pframe; + return(1); +} + + +void isoburn_toc_session_get_leadout_entry(struct isoburn_toc_session *s, + struct burn_toc_entry *entry) +{ + struct isoburn_toc_track *t; + + if(s==NULL) + return; + if(s->session!=NULL && s->toc_entry==NULL) { + burn_session_get_leadout_entry(s->session, entry); + return; + } + if(s->track_count<=0 || s->track_pointers==NULL || s->toc_entry==NULL) + return; + t= s->track_pointers[s->track_count-1]; + entry->start_lba= t->toc_entry->start_lba + t->toc_entry->track_blocks; + entry->track_blocks= 0; + isoburn_toc_entry_finish(entry, s->toc_entry->session, t->toc_entry->track_no, + 0); +} + + +struct isoburn_toc_track **isoburn_toc_session_get_tracks( + struct isoburn_toc_session *s, int *num) +{ + *num= s->track_count; + return(s->track_pointers); +} + + +void isoburn_toc_track_get_entry(struct isoburn_toc_track *t, + struct burn_toc_entry *entry) +{ + if(t==0) + return; + if(t->track!=NULL && t->toc_entry==NULL) { + burn_track_get_entry(t->track, entry); + return; + } + if(t->toc_entry==NULL) + return; + entry->start_lba= t->toc_entry->start_lba; + entry->track_blocks= t->toc_entry->track_blocks; + isoburn_toc_entry_finish(entry, t->toc_entry->session, t->toc_entry->track_no, + 0); +} + + +int isoburn_toc_track_get_emul(struct isoburn_toc_track *t, int *start_lba, + int *image_blocks, char volid[33], int flag) +{ + if(t->toc_entry == NULL) + return(0); + if(t->toc_entry->volid == NULL) + return(0); + *start_lba= t->toc_entry->start_lba; + *image_blocks= t->toc_entry->track_blocks; + strncpy(volid, t->toc_entry->volid, 32); + volid[32]= 0; + return(1); +} + + +void isoburn_toc_disc_free(struct isoburn_toc_disc *d) +{ + if(d->disc!=NULL) + burn_disc_free(d->disc); + isoburn_toc_destroy_arrays(d, 0); + free((char *) d); +} + + +int isoburn_get_track_lba(struct isoburn_toc_track *track, int *lba, int flag) +{ + struct burn_toc_entry entry; + + isoburn_toc_track_get_entry(track, &entry); + if (entry.extensions_valid & 1) + *lba= entry.start_lba; + else + *lba= burn_msf_to_lba(entry.pmin, entry.psec, entry.pframe); + return(1); +} + + +int isoburn_drive_set_msgs_submit(struct burn_drive *d, + int (*msgs_submit)(void *handle, int error_code, + char msg_text[], int os_errno, + char severity[], int flag), + void *submit_handle, int submit_flag, int flag) +{ + struct isoburn *o; + int ret; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0 || o==NULL) + return(-1); + o->msgs_submit= msgs_submit; + o->msgs_submit_handle= submit_handle; + o->msgs_submit_flag= submit_flag; + return(1); +} + + +/* @param flag bit0= with adr_mode 3: adr_value might be 16 blocks too high + bit1= insist in seeing a disc object with at least one session + bit2= with adr_mode 4: use adr_value as regular expression +*/ +int isoburn_set_msc1(struct burn_drive *d, int adr_mode, char *adr_value, + int flag) +{ + int ret, num_sessions= 0, num_tracks, adr_num, i, j, total_tracks; + int lba, best_lba, size, re_valid= 0, track_count= 0; + time_t start_time= 0, last_pacifier= 0, now; + char volid[33], *msg= NULL; + struct isoburn *o; + struct isoburn_toc_disc *disc= NULL; + struct isoburn_toc_session **sessions= NULL; + struct isoburn_toc_track **tracks= NULL; + static char mode_names[][20]= {"auto", "session", "track", "lba", "volid"}; + static int max_mode_names= 4; + regex_t re; + regmatch_t match[1]; + enum burn_disc_status s; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(o==NULL) + return(-1); + + msg= calloc(1, 160); + if(msg == NULL) + {ret= -1; goto ex;} + + start_time= last_pacifier= time(NULL); + adr_num= atoi(adr_value); + if(adr_mode!=3 || (flag & 2)) { + disc= isoburn_toc_drive_get_disc(d); + if(disc==NULL) { +not_found:; + if(adr_mode<0 || adr_mode>max_mode_names) + goto unknown_mode; + sprintf(msg, "Failed to find %s %s", mode_names[adr_mode], + strlen(adr_value)<=80 ? adr_value : "-oversized-string-"); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); + ret= 0; goto ex; + } + sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); + if(sessions==NULL || num_sessions<=0) + goto not_found; + } + if(adr_mode==0) { + /* Set fabricated_msc1 to last session in TOC */ + tracks= isoburn_toc_session_get_tracks(sessions[num_sessions-1], + &num_tracks); + if(tracks==NULL || num_tracks<=0) + goto not_found; + isoburn_get_track_lba(tracks[0], &(o->fabricated_msc1), 0); + + } else if(adr_mode==1) { + /* Use adr_num as session index (first session is 1, not 0) */ + if(adr_num<1 || adr_num>num_sessions) + goto not_found; + tracks= isoburn_toc_session_get_tracks(sessions[adr_num-1], &num_tracks); + if(tracks==NULL || num_tracks<=0) + goto not_found; + isoburn_get_track_lba(tracks[0], &(o->fabricated_msc1), 0); + + } else if(adr_mode==2) { + /* use adr_num as track index */ + total_tracks= 0; + for(i=0; ifabricated_msc1), 0); + ret= 1; goto ex; + } + } + } + goto not_found; + + } else if(adr_mode==3) { + o->fabricated_msc1= adr_num; + s= isoburn_disc_get_status(d); + if(o->fabricated_msc1 > 0 && s != BURN_DISC_FULL + && s != BURN_DISC_APPENDABLE) { + isoburn_msgs_submit(o, 0x00060000, + "Non-zero load offset given with blank input media", + 0, "FAILURE", 0); + ret= 0; goto ex; + } + if((flag & 1) && o->fabricated_msc1 >= 16) { + /* adr_num is possibly 16 blocks too high */ + ret= isoburn_read_iso_head(d, o->fabricated_msc1, &size,volid, 1|(1<<14)); + if(ret==2) + o->fabricated_msc1-= 16; + } + } else if(adr_mode==4) { + /* search for volume id that is equal to adr_value */ + if(flag & 4) { + ret= regcomp(&re, adr_value, 0); + if(ret != 0) + flag&= ~4; + else + re_valid= 1; + } + best_lba= -1; + for(i=0; i= 5 && track_count > 0) { + last_pacifier= now; + sprintf(msg, + "Scanned %d tracks for matching volid in %.f seconds", + track_count, (double) (now - start_time)); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); + } + track_count++; + ret= isoburn_toc_track_get_emul(tracks[0], &lba, &size, volid, 0); + if(ret < 0) + continue; + if(ret == 0) { + isoburn_get_track_lba(tracks[0], &lba, 0); + ret= isoburn_read_iso_head(d, lba, &size, volid, 1); + if(ret<=0) + continue; + } + if(flag & 4) { + ret= regexec(&re, volid, 1, match, 0); + if(ret != 0) + continue; + } else { + if(strcmp(volid, adr_value)!=0) + continue; + } + best_lba= lba; + } + } + if(best_lba<0) + goto not_found; + o->fabricated_msc1= best_lba; + + } else { +unknown_mode:; + sprintf(msg, "Program error: Unknown msc1 address mode %d", adr_mode); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FATAL", 0); + ret= 0; goto ex; + } + ret= 1; +ex:; + if(start_time != last_pacifier && track_count > 0) { + now= time(NULL); + sprintf(msg, + "Scanned %d tracks for matching volid in %.f seconds", + track_count, (double) (now - start_time)); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); + } + if(disc!=NULL) + isoburn_toc_disc_free(disc); + if((flag & 4) && re_valid) + regfree(&re); + if(msg != NULL) + free(msg); + return(ret); +} + + +int isoburn_get_mount_params(struct burn_drive *d, + int adr_mode, char *adr_value, + int *lba, int *track, int *session, + char volid[33], int flag) +{ + int msc1_mem, ret, total_tracks, num_sessions, num_tracks, i, j, track_lba; + int size, is_iso= 0; + struct isoburn *o; + struct isoburn_toc_disc *disc= NULL; + struct isoburn_toc_session **sessions= NULL; + struct isoburn_toc_track **tracks= NULL; + + *lba= *track= *session= -1; + volid[0]= 0; + ret= isoburn_find_emulator(&o, d, 0); + if(ret < 0 || o == NULL) + return(-1); + msc1_mem= o->fabricated_msc1; + ret= isoburn_set_msc1(d, adr_mode, adr_value, 2 | (flag & 4)); + if(ret <= 0) + return(ret); + *lba= o->fabricated_msc1; + + disc= isoburn_toc_drive_get_disc(d); + if(disc==NULL) + {ret= -1; goto ex;} /* cannot happen because checked by isoburn_set_msc1 */ + sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); + if(sessions==NULL || num_sessions<=0) + {ret= -1; goto ex;} /* cannot happen because checked by isoburn_set_msc1 */ + total_tracks= 0; + for(i=0; ifabricated_msc1= msc1_mem; + if(disc != NULL) + isoburn_toc_disc_free(disc); + return(2 - is_iso); +} + + diff --git a/libisoburn/branches/1.4.6/libisoburn/data_source.c b/libisoburn/branches/1.4.6/libisoburn/data_source.c new file mode 100644 index 00000000..92e4d1ba --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/data_source.c @@ -0,0 +1,370 @@ +/* + data source for libisoburn. + + Copyright 2007 - 2012 Vreixo Formoso Lopes + and Thomas Schmitt + Provided under GPL version 2 or later. +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include + +#include + + +#ifndef Xorriso_standalonE + +#include + +#include + +#else /* ! Xorriso_standalonE */ + +#include "../libisofs/libisofs.h" +#include "../libburn/libburn.h" + +#endif /* Xorriso_standalonE */ + + +#include "isoburn.h" + + +/* Cached reading of image tree data by multiple tiles */ + + +/* Debugging only: This reports cache loads on stderr. +#define Libisoburn_read_cache_reporT 1 +*/ + + +struct isoburn_cache_tile { + char *cache_data; + uint32_t cache_lba; + uint32_t last_error_lba; + uint32_t last_aligned_error_lba; + int cache_hits; + int age; +}; + +struct isoburn_cached_drive { + struct burn_drive *drive; + struct isoburn_cache_tile **tiles; + int num_tiles; + int tile_blocks; + int current_age; + + /** + Offset to be applied to all block addresses to compensate for an + eventual displacement of the block addresses relative to the image + start block address that was assumed when the image was created. + E.g. if track number 2 gets copied into a disk file and shall then + be loaded as ISO filesystem. + If displacement_sign is 1 then the displacement number will be + added to .read_block() addresses, if -1 it will be subtracted. + Else it will be ignored. + */ + uint32_t displacement; + int displacement_sign; + +}; + +#define Libisoburn_max_agE 2000000000 + +static int ds_inc_age(struct isoburn_cached_drive *icd, int idx, int flag); + + +int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) +{ + int ret, i, oldest, oldest_age; + struct burn_drive *d; + off_t count; + uint32_t aligned_lba; + char msg[80]; + struct isoburn_cache_tile **tiles; + struct isoburn_cached_drive *icd; + + if(src == NULL || buffer == NULL) + /* It is not required by the specs of libisofs but implicitly assumed + by its current implementation that a data source read result <0 is + a valid libisofs error code. + */ + return ISO_NULL_POINTER; + + icd = (struct isoburn_cached_drive *) src->data; + d = (struct burn_drive*) icd->drive; + + if(d == NULL) { + /* This would happen if libisoburn saw output data in the fifo and + performed early drive release and afterwards libisofs still tries + to read data. + That would constitute a bad conceptual problem in libisoburn. + */ + isoburn_msgs_submit(NULL, 0x00060000, + "Programming error: Drive released while libisofs still attempts to read", + 0, "FATAL", 0); + return ISO_ASSERT_FAILURE; + } + + tiles = icd->tiles; + + if(icd->displacement_sign == 1) { + if(lba + icd->displacement < lba) { +address_rollover:; + return ISO_DISPLACE_ROLLOVER; + } else + lba += icd->displacement; + } else if(icd->displacement_sign == -1) { + if(lba < icd->displacement ) + goto address_rollover; + else + lba -= icd->displacement; + } + + aligned_lba= lba & ~(icd->tile_blocks - 1); + + for (i = 0; i < icd->num_tiles; i++) { + if(aligned_lba == tiles[i]->cache_lba && + tiles[i]->cache_lba != 0xffffffff) { + (tiles[i]->cache_hits)++; + memcpy(buffer, tiles[i]->cache_data + (lba - aligned_lba) * 2048, 2048); + count= 2048; + ds_inc_age(icd, i, 0); + return 1; + } + } + + /* find oldest tile */ + oldest_age= Libisoburn_max_agE; + oldest= 0; + for(i = 0; i < icd->num_tiles; i++) { + if(tiles[i]->cache_lba == 0xffffffff) { + oldest= i; + break; + } + if(tiles[i]->age < oldest_age) { + oldest_age= tiles[i]->age; + oldest= i; + } + } + + tiles[oldest]->cache_lba= 0xffffffff; /* invalidate cache */ + if(tiles[oldest]->last_aligned_error_lba == aligned_lba) { + ret = 0; + } else { + ret = burn_read_data(d, (off_t) aligned_lba * (off_t) 2048, + (char *) tiles[oldest]->cache_data, + icd->tile_blocks * 2048, &count, 2); + } + if (ret <= 0 ) { + tiles[oldest]->last_aligned_error_lba = aligned_lba; + + /* Read-ahead failure ? Try to read 2048 directly. */ + if(tiles[oldest]->last_error_lba == lba) + ret = 0; + else + ret = burn_read_data(d, (off_t) lba * (off_t) 2048, (char *) buffer, + 2048, &count, 0); + if (ret > 0) + return 1; + tiles[oldest]->last_error_lba = lba; + sprintf(msg, "ds_read_block(%lu) returns %lX", + (unsigned long) lba, (unsigned long) ret); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "DEBUG", 0); + return ISO_DATA_SOURCE_MISHAP; + } + +#ifdef Libisoburn_read_cache_reporT + fprintf(stderr, "Tile %2.2d : After %3d hits, new load from %8x , count= %d\n", + oldest, tiles[oldest]->cache_hits, aligned_lba, (int) count); +#endif + + tiles[oldest]->cache_lba= aligned_lba; + tiles[oldest]->cache_hits= 1; + ds_inc_age(icd, oldest, 0); + + memcpy(buffer, tiles[oldest]->cache_data + (lba - aligned_lba) * 2048, 2048); + count= 2048; + + return 1; +} + + +static int ds_open(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + +static int ds_close(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + + +static int isoburn_cache_tile_destroy(struct isoburn_cache_tile **o, + int flag) +{ + if (*o == NULL) + return(0); + if ((*o)->cache_data != NULL) + free((*o)->cache_data); + free(*o); + *o = NULL; + return(1); +} + + +static int isoburn_cache_tile_new(struct isoburn_cache_tile **o, + int tile_blocks, int flag) +{ + struct isoburn_cache_tile *t; + + *o = t = calloc(1, sizeof(struct isoburn_cache_tile)); + if (t == NULL) + goto fail; + t->cache_data = NULL; + t->cache_lba = 0xffffffff; + t->cache_hits = 0; + t->last_error_lba = 0xffffffff; + t->last_aligned_error_lba = 0xffffffff; + t->age= 0; + + t->cache_data = calloc(1, tile_blocks * 2048); + if (t->cache_data == NULL) + goto fail; + + return(1); +fail:; + isoburn_cache_tile_destroy(o, 0); + return(-1); +} + + +static int isoburn_cached_drive_destroy(struct isoburn_cached_drive **o, + int flag) +{ + struct isoburn_cached_drive *c; + int i; + + if (*o == NULL) + return(0); + c= *o; + if (c->tiles != NULL) { + for (i = 0; i < c->num_tiles; i++) + isoburn_cache_tile_destroy(&(c->tiles[i]), 0); + free(c->tiles); + } + free(c); + *o= NULL; + return(1); +} + + +static int isoburn_cached_drive_new(struct isoburn_cached_drive **o, + struct burn_drive *d, int cache_tiles, + int tile_blocks, int flag) +{ + struct isoburn_cached_drive *icd; + int i, ret; + + *o = icd = calloc(1,sizeof(struct isoburn_cached_drive)); + if (*o == NULL) + return(-1); + icd->drive = d; + icd->tiles = NULL; + icd->num_tiles = cache_tiles; + icd->tile_blocks = tile_blocks; + icd->current_age = 0; + icd->displacement = 0; + icd->displacement_sign = 0; + + icd->tiles = calloc(1, sizeof(struct isoburn_cache_tile *) * icd->num_tiles); + if (icd->tiles == NULL) + goto fail; + for (i = 0; i < icd->num_tiles; i++) { + ret = isoburn_cache_tile_new(&(icd->tiles[i]), icd->tile_blocks, 0); + if (ret <= 0) + goto fail; + } + return(1); +fail:; + isoburn_cached_drive_destroy(o, 0); + return(-1); +} + + +static void ds_free_data(IsoDataSource *src) +{ + struct isoburn_cached_drive *icd; + + if(src->data != NULL) { + icd= (struct isoburn_cached_drive *) src->data; + isoburn_cached_drive_destroy(&icd, 0); + } + src->data= NULL; +} + + +int isoburn_data_source_shutdown(IsoDataSource *src, int flag) +{ + struct isoburn_cached_drive *icd; + + if(src==NULL) + return(0); + icd= (struct isoburn_cached_drive *) src->data; + icd->drive= NULL; + return(1); +} + + +IsoDataSource *isoburn_data_source_new(struct burn_drive *d, + uint32_t displacement, int displacement_sign, + int cache_tiles, int tile_blocks) +{ + IsoDataSource *src; + struct isoburn_cached_drive *icd= NULL; + int ret; + + if (d==NULL) + return NULL; + src = malloc(sizeof(IsoDataSource)); + if (src == NULL) + return NULL; + ret = isoburn_cached_drive_new(&icd, d, cache_tiles, tile_blocks, 0); + if (ret <= 0) { + free(src); + return NULL; + } + src->version = 0; + src->refcount = 1; + src->read_block = ds_read_block; + src->open = ds_open; + src->close = ds_close; + src->free_data = ds_free_data; + src->data = icd; + icd->displacement = displacement; + icd->displacement_sign = displacement_sign; + return src; +} + + +static int ds_inc_age(struct isoburn_cached_drive *icd, int idx, int flag) +{ + int i; + + (icd->current_age)++; + if(icd->current_age>=Libisoburn_max_agE) { /* reset all ages (allow waste) */ + for(i = 0; i < icd->num_tiles; i++) + (icd->tiles)[i]->age= 0; + icd->current_age= 1; + } + (icd->tiles)[idx]->age= icd->current_age; + return(1); +} + + diff --git a/libisoburn/branches/1.4.6/libisoburn/isoburn.c b/libisoburn/branches/1.4.6/libisoburn/isoburn.c new file mode 100644 index 00000000..01b07894 --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/isoburn.c @@ -0,0 +1,1957 @@ + +/* + cc -g -c isoburn.c +*/ + +/* + Class core of libisoburn. + + Copyright 2007 - 2016 Vreixo Formoso Lopes + Thomas Schmitt + + Provided under GPL version 2 or later. +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +/* ( derived from stub generated by CgeN on Sat, 01 Sep 2007 12:04:36 GMT ) */ + +#include +#include +#include +#include +#include +#include + +#ifndef Xorriso_standalonE + +#include + +#include + +#else /* ! Xorriso_standalonE */ + +#include "../libisofs/libisofs.h" +#include "../libburn/libburn.h" + +#endif /* Xorriso_standalonE */ + + +#include "libisoburn.h" + +#include "isoburn.h" + + +/* Default values for application provided msgs_submit methods. + To be attached to newly acquired drives. +*/ +int (*libisoburn_default_msgs_submit) + (void *handle, int error_code, char msg_text[], + int os_errno, char severity[], int flag)= NULL; +void *libisoburn_default_msgs_submit_handle= NULL; +int libisoburn_default_msgs_submit_flag= 0; + + +/* ----------------------- isoburn_toc_entry ---------------------- */ + + +int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt, + struct isoburn_toc_entry *boss, int flag) +{ + struct isoburn_toc_entry *o, *s; + + *objpt= o= (struct isoburn_toc_entry *) + malloc(sizeof(struct isoburn_toc_entry)); + if(o==NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot allocate memory for isoburn toc entry", + 0, "FATAL", 0); + return(-1); + } + o->session= 0; + o->track_no= 0; + o->start_lba= -1; + o->track_blocks= 0; + o->volid= NULL; + o->next= NULL; + if(boss!=NULL) { + for(s= boss; s->next!=NULL; s= s->next); + s->next= o; + } + return(1); +} + + +/* @param flag bit0= delete all subordinates too +*/ +int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag) +{ + if(*o==NULL) + return(0); + if(flag&1) + isoburn_toc_entry_destroy(&((*o)->next), flag); + if((*o)->volid != NULL) + free((*o)->volid); + free((char *) (*o)); + *o= NULL; + return(1); +} + + +/* --------------------- end isoburn_toc_entry -------------------- */ + +/* -------------------------- isoburn ----------------------- */ + + +/* The global list of isoburn objects. Usually there is only one. + >>> we are not ready for multiple control threads yet. See >>> mutex . + Multiple burns under one control thread should work. +*/ +struct isoburn *isoburn_list_start= NULL; + + +int isoburn_new(struct isoburn **objpt, int flag) +{ + struct isoburn *o; + int ret; + + *objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn)); + if(o==NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot allocate memory for isoburn control object", + 0, "FATAL", 0); + return(-1); + } + + o->drive= NULL; + o->emulation_mode= 0; + o->fabricated_msc1= -1; + o->fabricated_msc2= -1; + o->zero_nwa= Libisoburn_overwriteable_starT; + o->min_start_byte= o->zero_nwa * 2048; + o->nwa= o->zero_nwa; + o->truncate= 0; + o->iso_source= NULL; + o->fabricated_disc_status= BURN_DISC_UNREADY; + o->media_read_error= 0; + o->toc= NULL; + o->wrote_well= -1; + o->loaded_partition_offset= 0; + o->target_iso_head_size= Libisoburn_target_head_sizE; + o->target_iso_head= NULL; + o->image= NULL; + o->image_start_lba= -1; + o->iso_data_source= NULL; + o->read_pacifier= NULL; + o->read_pacifier_handle= NULL; + o->msgs_submit= NULL; + o->msgs_submit_handle= NULL; + o->msgs_submit_flag= 0; + o->do_tao= 0; + o->do_fsync= 1; + o->prev= NULL; + o->next= NULL; + o->target_iso_head= calloc(1, o->target_iso_head_size); + if(o->target_iso_head == NULL) { + isoburn_report_iso_error(ISO_OUT_OF_MEM, "Cannot allocate overwrite buffer", + 0, "FATAL", 0); + goto failed; + } + ret= iso_image_new("ISOIMAGE", &o->image); + if(ret<0) { + isoburn_report_iso_error(ret, "Cannot create image object", 0, "FATAL", 0); + goto failed; + } + ret= isoburn_root_defaults(o->image, 0); + if(ret <= 0) + goto failed; + isoburn_link(o, isoburn_list_start, 1); + return(1); +failed:; + isoburn_destroy(objpt, 0); + return(-1); +} + + +int isoburn_destroy(struct isoburn **objpt, int flag) +{ + struct isoburn *o; + + o= *objpt; + if(o==NULL) + return(0); + + /* >>> mutex */ + + if(o==isoburn_list_start) + isoburn_list_start= o->next; + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + + /* >>> end mutex */ + + if(o->image!=NULL) + iso_image_unref(o->image); + if(o->toc!=NULL) + isoburn_toc_entry_destroy(&(o->toc), 1); /* all */ + if(o->iso_source!=NULL) + burn_source_free(o->iso_source); + if(o->iso_data_source!=NULL) + iso_data_source_unref(o->iso_data_source); + if(o->target_iso_head != NULL) + free(o->target_iso_head); + free((char *) o); + *objpt= NULL; + return(1); +} + + +int isoburn_destroy_all(struct isoburn **objpt, int flag) +{ + struct isoburn *o,*n; + + o= *objpt; + if(o==NULL) + return(0); + for(;o->prev!=NULL;o= o->prev); + for(;o!=NULL;o= n) { + n= o->next; + isoburn_destroy(&o,0); + } + *objpt= NULL; + return(1); +} + + +int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag) +{ + *pt= o->image; + return(1); +} + + +int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag) +{ + *pt= o->prev; + return(1); +} + + +int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag) +{ + *pt= o->next; + return(1); +} + + +int isoburn_link(struct isoburn *o, struct isoburn *link, int flag) +/* + bit0= insert as link->prev rather than as link->next +*/ +{ + + /* >>> mutex */ + + if(isoburn_list_start==NULL || + (isoburn_list_start==link && (flag&1))) + isoburn_list_start= o; + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + o->prev= o->next= NULL; + if(link==NULL) + return(1); + if(flag&1) { + o->next= link; + o->prev= link->prev; + if(o->prev!=NULL) + o->prev->next= o; + link->prev= o; + } else { + o->prev= link; + o->next= link->next; + if(o->next!=NULL) + o->next->prev= o; + link->next= o; + } + + /* >>> end mutex */ + + return(1); +} + + +int isoburn_count(struct isoburn *o, int flag) +/* flag: bit1= count from start of list */ +{ + int counter= 0; + + if(flag&2) + for(;o->prev!=NULL;o= o->prev); + for(;o!=NULL;o= o->next) + counter++; + return(counter); +} + + +int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag) +/* flag: bit0= fetch first (idx<0) or last (idx>0) item in list + bit1= address from start of list */ +{ + int i,abs_idx; + struct isoburn *npt; + + if(flag&2) + for(;o->prev!=NULL;o= o->prev); + abs_idx= (idx>0?idx:-idx); + *pt= o; + for(i= 0;(i0) + npt= o->next; + else + npt= o->prev; + if(npt==NULL && (flag&1)) + break; + *pt= npt; + } + return(*pt!=NULL); +} + + +int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag) +{ + struct isoburn *o; + + *pt= NULL; + for(o= isoburn_list_start;o!=NULL;o= o->next) + if(o->drive==d) { + *pt= o; + return(1); + } + return(0); +} + + +int isoburn_msgs_submit(struct isoburn *o, int error_code, char msg_text[], + int os_errno, char severity[], int flag) +{ + int ret, use_drive_method= 0; + + if(o!=NULL) + if(o->msgs_submit!=NULL) + use_drive_method= 1; + if(use_drive_method) { + ret= o->msgs_submit(o->msgs_submit_handle, error_code, msg_text, os_errno, + severity, o->msgs_submit_flag); + return(ret); + } + if(libisoburn_default_msgs_submit != NULL) { + ret= libisoburn_default_msgs_submit(libisoburn_default_msgs_submit_handle, + error_code, msg_text, os_errno, severity, + libisoburn_default_msgs_submit_flag); + return(ret); + } + /* Fallback: use message queue of libburn */ + burn_msgs_submit(error_code, msg_text, os_errno, severity, NULL); + return(1); +} + + +/** Check whether the size of target_iso_head matches the given partition + offset. Eventually adjust size. +*/ +int isoburn_adjust_target_iso_head(struct isoburn *o, + uint32_t offst, int flag) +{ + uint8_t *new_buf; + uint32_t new_size; + + if((uint32_t) o->target_iso_head_size == + Libisoburn_target_head_sizE + 2048 * offst) + return(1); + new_size= Libisoburn_target_head_sizE + 2048 * offst; + new_buf= calloc(1, new_size); + if(new_buf == NULL) { + isoburn_msgs_submit(o, 0x00060000, + "Cannot re-allocate overwrite buffer", 0, "FATAL", 0); + return(-1); + } + memcpy(new_buf, o->target_iso_head, + (uint32_t) o->target_iso_head_size < new_size ? + (uint32_t) o->target_iso_head_size : new_size); + free(o->target_iso_head); + o->target_iso_head= new_buf; + o->target_iso_head_size= new_size; + if(o->nwa == o->zero_nwa) + o->nwa= Libisoburn_overwriteable_starT + offst; + o->zero_nwa= Libisoburn_overwriteable_starT + offst; + return(1); +} + + +/* @param out_o The output isoburn object may be NULL if no real write run is + desired with opts. + @param flag bit0= modifying rather than growing +*/ +static +int isoburn_make_iso_write_opts(struct isoburn *out_o, + struct isoburn_imgen_opts *opts, + int fifo_chunks, + IsoWriteOpts *wopts, + int flag) +{ + int ret, rec_mtime, new_img, lba, nwa, i, guid_mode; + struct burn_drive *out_d; + + new_img= flag&1; + + iso_write_opts_set_will_cancel(wopts, opts->will_cancel); + iso_write_opts_set_iso_level(wopts, opts->level); + iso_write_opts_set_rockridge(wopts, opts->rockridge); + iso_write_opts_set_joliet(wopts, opts->joliet); + iso_write_opts_set_hfsplus(wopts, opts->hfsplus); + iso_write_opts_set_hfsp_block_size(wopts, opts->hfsp_block_size, + opts->apm_block_size); + iso_write_opts_set_fat(wopts, opts->fat); + iso_write_opts_set_iso1999(wopts, opts->iso1999); + iso_write_opts_set_hardlinks(wopts, opts->hardlinks); + if(opts->hardlinks) + iso_write_opts_set_rrip_1_10_px_ino(wopts, 1); + iso_write_opts_set_aaip(wopts, opts->aaip); + iso_write_opts_set_old_empty(wopts, !!opts->old_empty); + iso_write_opts_set_untranslated_name_len(wopts, opts->untranslated_name_len); + iso_write_opts_set_allow_dir_id_ext(wopts, opts->allow_dir_id_ext); + iso_write_opts_set_omit_version_numbers(wopts, opts->omit_version_numbers); + iso_write_opts_set_allow_deep_paths(wopts, opts->allow_deep_paths); + iso_write_opts_set_rr_reloc(wopts, opts->rr_reloc_dir, opts->rr_reloc_flags); + iso_write_opts_set_allow_longer_paths(wopts, opts->allow_longer_paths); + iso_write_opts_set_max_37_char_filenames(wopts, opts->max_37_char_filenames); + iso_write_opts_set_no_force_dots(wopts, opts->no_force_dots); + iso_write_opts_set_allow_lowercase(wopts, opts->allow_lowercase); + iso_write_opts_set_allow_full_ascii(wopts, opts->allow_full_ascii); + iso_write_opts_set_allow_7bit_ascii(wopts, opts->allow_7bit_ascii); + iso_write_opts_set_relaxed_vol_atts(wopts, 1); + iso_write_opts_set_joliet_longer_paths(wopts, opts->joliet_longer_paths); + iso_write_opts_set_joliet_long_names(wopts, opts->joliet_long_names); + iso_write_opts_set_joliet_utf16(wopts, opts->joliet_utf16); + iso_write_opts_set_always_gmt(wopts, opts->always_gmt); + iso_write_opts_set_rrip_version_1_10(wopts, opts->rrip_version_1_10); + rec_mtime= 0; + if(opts->dir_rec_mtime) + rec_mtime|= 1; + else + rec_mtime|= (1 << 14); + if(opts->joliet_rec_mtime) + rec_mtime|= 2; + if(opts->iso1999_rec_mtime) + rec_mtime|= 4; + iso_write_opts_set_dir_rec_mtime(wopts, rec_mtime); + iso_write_opts_set_aaip_susp_1_10(wopts, opts->aaip_susp_1_10); + iso_write_opts_set_sort_files(wopts, opts->sort_files); + iso_write_opts_set_record_md5(wopts, opts->session_md5, opts->file_md5 & 3); + if(opts->scdbackup_tag_name[0] && opts->scdbackup_tag_time[0]) + iso_write_opts_set_scdbackup_tag(wopts, opts->scdbackup_tag_name, + opts->scdbackup_tag_time, + opts->scdbackup_tag_written); + iso_write_opts_set_replace_mode(wopts, opts->replace_dir_mode, + opts->replace_file_mode, opts->replace_uid, opts->replace_gid); + iso_write_opts_set_default_dir_mode(wopts, opts->dir_mode); + iso_write_opts_set_default_file_mode(wopts, opts->file_mode); + iso_write_opts_set_default_uid(wopts, opts->uid); + iso_write_opts_set_default_gid(wopts, opts->gid); + iso_write_opts_set_output_charset(wopts, opts->output_charset); + iso_write_opts_set_fifo_size(wopts, fifo_chunks); + ret = iso_write_opts_set_system_area(wopts, opts->system_area_data, + opts->system_area_options, 0); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot set content of System Area", + 0, "FAILURE", 0); + {ret= -1; goto ex;} + } + iso_write_opts_set_pvd_times(wopts, + opts->vol_creation_time, opts->vol_modification_time, + opts->vol_expiration_time, opts->vol_effective_time, + opts->vol_uuid); + guid_mode= opts->gpt_guid_mode; + if(opts->vol_uuid[0] == 0 && opts->gpt_guid_mode == 2) + guid_mode= 0; + iso_write_opts_set_gpt_guid(wopts, opts->gpt_guid, guid_mode); + iso_write_opts_attach_jte(wopts, opts->libjte_handle); + iso_write_opts_set_hfsp_serial_number(wopts, opts->hfsp_serial_number); + + if(out_o != NULL) { + out_d= out_o->drive; + ret= isoburn_adjust_target_iso_head(out_o, opts->partition_offset, 0); + if(ret <= 0) + {ret= -1; goto ex;} + if(out_o->nwa < out_o->zero_nwa) + out_o->zero_nwa= 0; + if(opts->no_emul_toc || opts->libjte_handle != NULL) { + if(out_o->nwa == out_o->zero_nwa && + out_o->zero_nwa == Libisoburn_overwriteable_starT + + opts->partition_offset + && out_o->emulation_mode == 1) { + out_o->nwa= 0; + out_o->zero_nwa= 0; + out_o->min_start_byte= 0; + } + } + ret = isoburn_disc_track_lba_nwa(out_d, NULL, 0, &lba, &nwa); + opts->effective_lba= nwa; + ret= isoburn_get_msc2(out_o, NULL, &nwa, 0); + if (ret != 1) { + isoburn_msgs_submit(out_o, 0x00060000, + "Cannot determine next writeable address", 0, "FAILURE", 0); + + /* >>> NWA_V : If burn_next_track_damaged: + ??? Close track and session ? + ??? Issue a hint for a repair command ? + */; + + {ret= -3; goto ex;} + } + iso_write_opts_set_ms_block(wopts, nwa); + iso_write_opts_set_appendable(wopts, !new_img); + iso_write_opts_set_overwrite_buf(wopts, + nwa>0 ? out_o->target_iso_head : NULL); + } + iso_write_opts_set_part_offset(wopts, opts->partition_offset, + opts->partition_secs_per_head, + opts->partition_heads_per_cyl); + iso_write_opts_set_tail_blocks(wopts, opts->tail_blocks); + if(opts->prep_partition != NULL) { + ret = iso_write_opts_set_prep_img(wopts, opts->prep_partition, + opts->prep_part_flag & 1); + if(ret < 0) { + isoburn_report_iso_error(ret, "Cannot set path for PreP partition", + 0, "FAILURE", 0); + {ret= -1; goto ex;} + } + } + if(opts->efi_boot_partition != NULL) { + ret = iso_write_opts_set_efi_bootp(wopts, opts->efi_boot_partition, + opts->efi_boot_part_flag & 1); + if(ret < 0) { + isoburn_report_iso_error(ret, "Cannot set path for EFI system partition", + 0, "FAILURE", 0); + {ret= -1; goto ex;} + } + } + for(i= 0; i < Libisoburn_max_appended_partitionS; i++) { + if(opts->appended_partitions[i] == NULL) + continue; + ret= iso_write_opts_set_partition_img(wopts, i + 1, + opts->appended_part_types[i], + opts->appended_partitions[i], + opts->appended_part_flags[i]); + if(ret < 0) { + isoburn_report_iso_error(ret, "Cannot set path for appended partition", + 0, "FAILURE", 0); + {ret= -1; goto ex;} + } + } + iso_write_opts_set_appended_as_gpt(wopts, opts->appended_as_gpt); + iso_write_opts_set_appended_as_apm(wopts, opts->appended_as_apm); + iso_write_opts_set_part_like_isohybrid(wopts, opts->part_like_isohybrid); + iso_write_opts_set_disc_label(wopts, opts->ascii_disc_label); + + ret= 1; +ex: + return(ret); +} + + +/* @param flag bit0= modifying rather than growing + bit1= prepare for early release of input drive: + wait until input and then disable image data source +*/ +static +int isoburn_prepare_disc_aux(struct burn_drive *in_d, struct burn_drive *out_d, + struct burn_disc **disc, + struct isoburn_imgen_opts *opts, int flag) +{ + struct burn_source *wsrc; + struct burn_session *session; + struct burn_track *track; + struct isoburn *in_o, *out_o; + IsoWriteOpts *wopts= NULL; + enum burn_disc_status state; + int ret, fifo_chunks, i, new_img, early_indev_release; + uint32_t data_start= -1; + size_t buffer_size= 0, buffer_free= 0; + char *msg= NULL; + + msg= calloc(1, 160); + if(msg == NULL) + {ret= -1; goto ex;} + + new_img= flag&1; + early_indev_release= flag&2; + + ret= isoburn_find_emulator(&in_o, in_d, 0); + if(ret<0 || in_o==NULL) + {ret= -1; goto ex;} + ret= isoburn_find_emulator(&out_o, out_d, 0); + if(ret<0 || out_o==NULL) + {ret= -1; goto ex;} + /* early end will be registered as failure */ + in_o->wrote_well= out_o->wrote_well= 0; + + if(new_img && early_indev_release) { + isoburn_msgs_submit(in_o, 0x00060000, + "Programming error: Wrong session setup: new_img && early_indev_release", + 0, "FATAL", 0); + {ret= -4; goto ex;} + } + + out_o->do_tao = opts->do_tao; + out_o->do_fsync = opts->do_fsync; + + state = isoburn_disc_get_status(in_d); + if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE && + state != BURN_DISC_FULL) { + isoburn_msgs_submit(in_o, 0x00060000, "Unsuitable source media state", + 0, "FAILURE", 0); + {ret= -2; goto ex;} + } + state = isoburn_disc_get_status(out_d); + if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { + isoburn_msgs_submit(out_o, 0x00060000, "Unsuitable target media state", + 0, "FAILURE", 0); + {ret= -2; goto ex;} + } + if (state != BURN_DISC_BLANK && opts->libjte_handle != NULL) { + isoburn_msgs_submit(out_o, 0x00060000, + "Jigdo Template Extraction works only on blank target media", + 0, "FAILURE", 0); + {ret= -2; goto ex;} + } + + fifo_chunks= 32; + if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){ + fifo_chunks= opts->fifo_size/2048; + if(fifo_chunks*2048 < opts->fifo_size) + fifo_chunks++; + } + + ret= iso_write_opts_new(&wopts, 0); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0); + goto ex; + } + ret= isoburn_make_iso_write_opts(out_o, opts, fifo_chunks, wopts, flag & 1); + if(ret < 0) + goto ex; + + ret = iso_image_create_burn_source(in_o->image, wopts, &wsrc); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create burn source", 0, "FAILURE", 0); + {ret= -1; goto ex;} + } + if (early_indev_release) { + for(i= 0; i<300; i++) { + + /* <<< ??? */ + if((i%30) == 0) { + sprintf(msg, "Waiting for data in fifo since %d seconds", i/30); + isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0); + } + + usleep(100000); + ret= iso_ring_buffer_get_status(wsrc, &buffer_size, &buffer_free); + if(ret >0 && buffer_size != buffer_free) + break; + } + + /* <<< ??? */ + sprintf(msg, + "After %.1f seconds: %d bytes of output available (fifo state=%d)", + ((double) i+1) / 10.0, (int) (buffer_size - buffer_free), ret); + isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0); + + if(in_o->iso_data_source!=NULL) + isoburn_data_source_shutdown(in_o->iso_data_source, 0); + } + + ret= iso_write_opts_get_data_start(wopts, &data_start, 0); + opts->data_start_lba= -1; + if(ret > 0 && data_start <= 0x7FFFFFFF) + opts->data_start_lba= data_start; + + /* TODO check return values for failure. propertly clean-up on error */ + + out_o->iso_source= wsrc; + + *disc = burn_disc_create(); + session = burn_session_create(); + burn_disc_add_session(*disc, session, BURN_POS_END); + track = burn_track_create(); + burn_track_set_source(track, out_o->iso_source); + burn_session_add_track(session, track, BURN_POS_END); + + /* give up local references */ + burn_track_free(track); + burn_session_free(session); + + in_o->wrote_well= out_o->wrote_well= -1; /* neutral */ + ret= 1; +ex: + if(wopts!=NULL) + {iso_write_opts_free(wopts); wopts= NULL;} + if(msg != NULL) + free(msg); + return ret; +} + + +int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_imgen_opts *opts) +{ + return isoburn_prepare_disc_aux(d, d, disc, opts, 0); +} + + +int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_imgen_opts *opts, + struct burn_drive *out_drive) +{ + int ret; + + ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 1); + if (ret<=0) + return ret; + return 1; +} + + +/* API since 0.2.2 */ +int isoburn_prepare_blind_grow(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_imgen_opts *opts, + struct burn_drive *out_drive, int nwa) +{ + int ret; + struct isoburn *o= NULL; + + ret= isoburn_find_emulator(&o, out_drive, 0); + if(ret<0 || o==NULL) + return(-1); + if(nwa >= 0) + o->fabricated_msc2= nwa; + if(o->nwa == o->zero_nwa) + o->nwa= o->zero_nwa= 0; + else + o->zero_nwa= 0; + o->min_start_byte= 0; + ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 2); + if (ret<=0) + return ret; + return(1); +} + + +/* API @since 0.1.0 + @param flag bit0= this is a regular end, not an abort + give up source reference +*/ +int isoburn_cancel_prepared_write(struct burn_drive *d, + struct burn_drive *output_drive, int flag) +{ + int ret; + struct isoburn *o= NULL; + + if(output_drive!=NULL) { + ret= isoburn_find_emulator(&o, output_drive, 0); + if(ret<0 || o==NULL) + o= NULL; + else if(o->iso_source==NULL) + o= NULL; + } + if(o==NULL) { + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(o==NULL) + return(0); + if(o->iso_source==NULL) + return(0); + } + if(o->iso_source->read!=NULL) + return(0); + if(o->iso_source->version<1) + return(0); + o->iso_source->cancel(o->iso_source); + burn_source_free(o->iso_source); + o->iso_source= NULL; + return(1); +} + + +/* API @since 0.1.0 */ +int isoburn_sync_after_write(struct burn_drive *d, + struct burn_drive *output_drive, int flag) +{ + return isoburn_cancel_prepared_write(d, output_drive, 1); +} + + +void isoburn_version(int *major, int *minor, int *micro) +{ + *major= isoburn_header_version_major; + *minor= isoburn_header_version_minor; + *micro= isoburn_header_version_micro; + +/* No more: values from version.h generated from version.h.in and + macro values defined in configure.ac + + *major = ISOBURN_MAJOR_VERSION; + *minor = ISOBURN_MINOR_VERSION; + *micro = ISOBURN_MICRO_VERSION; +*/ +} + + +int isoburn_is_compatible(int major, int minor, int micro, int flag) +{ + int own_major, own_minor, own_micro; + + isoburn_version(&own_major, &own_minor, &own_micro); + return(own_major > major || + (own_major == major && (own_minor > minor || + (own_minor == minor && own_micro >= micro)))); +} + + +/* ----------------------------------------------------------------------- */ +/* + Options for image reading. +*/ +/* ----------------------------------------------------------------------- */ + + +int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag) +{ + struct isoburn_read_opts *o; + + o= (*new_o)= calloc(1, sizeof(struct isoburn_read_opts)); + if(o==NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot allocate memory for read options", 0, "FATAL", 0); + return(-1); + } + o->cache_tiles= Libisoburn_default_cache_tileS; + o->cache_tile_blocks= Libisoburn_default_tile_blockS; + o->norock= 0; + o->nojoliet= 0; + o->noiso1999= 1; + o->do_ecma119_map= 0; + o->map_mode= 1; + o->noaaip= 1; + o->noacl= 1; + o->noea= 1; + o->noino= 1; + o->nomd5= 1; + o->preferjoliet= 0; + o->uid= geteuid(); + o->gid= getegid(); + o->mode= 0444; + o->dirmode= 0555; + o->input_charset= NULL; + o->truncate_mode= 1; + o->truncate_length= 255; + o->hasRR= 0; + o->hasJoliet= 0; + o->hasIso1999= 0; + o->hasElTorito= 0; + o->size= 0; + o->pretend_blank= 1; + o->displacement= 0; + o->displacement_sign= 0; + return(1); +} + + +int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag) +{ + if(*o==NULL) + return(0); + free(*o); + *o= NULL; + return(1); +} + + +int isoburn_ropt_set_data_cache(struct isoburn_read_opts *o, + int cache_tiles, int tile_blocks, int flag) +{ + int i; + char msg[80]; + + if(cache_tiles < 1) { + isoburn_msgs_submit(NULL, 0x00060000, + "Requested number of data cache tiles is too small (< 1)", + 0, "SORRY", 0); + return(0); + } + if(((double) cache_tiles) * ((double) tile_blocks) + > (double) Libisoburn_cache_max_sizE) { + sprintf(msg, "Requested size of data cache exceeds limit of %.f blocks", + (double) Libisoburn_cache_max_sizE); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "SORRY", 0); + return(0); + } + for(i = 1; i <= Libisoburn_cache_max_sizE; i = i << 1) + if(i == tile_blocks) + break; + if(i > Libisoburn_cache_max_sizE) { + isoburn_msgs_submit(NULL, 0x00060000, + "Requested number of blocks per data cache tiles is not a power of 2", + 0, "SORRY", 0); + return(0); + } + if(o != NULL) { + o->cache_tiles= cache_tiles; + o->cache_tile_blocks= tile_blocks; + } + return(1); +} + + +int isoburn_ropt_get_data_cache(struct isoburn_read_opts *o, + int *cache_tiles, int *tile_blocks, + int *set_flag, int flag) +{ + if((flag & 1) || o == NULL) { + *cache_tiles= Libisoburn_default_cache_tileS; + *tile_blocks= Libisoburn_default_tile_blockS; + *set_flag= 0; + return(1); + } + *cache_tiles= o->cache_tiles; + *tile_blocks= o->cache_tile_blocks; + *set_flag= 0; + return(1); +} + + +int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext) +{ + o->norock= !!(ext&1); + o->nojoliet= !!(ext&2); + o->noiso1999= !!(ext&4); + o->preferjoliet= !!(ext&8); + o->pretend_blank= !!(ext&16); + o->noaaip= !!(ext & 32); + o->noacl= !!(ext & 64); + o->noea= !!(ext & 128); + o->noino= !!(ext & 256); + o->nomd5= (ext >> 9) & 3; + o->do_ecma119_map= !!(ext & 2048); + o->map_mode= (ext >> 12) & 3; + return(1); +} + + +int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext) +{ + *ext= (!!o->norock) | ((!!o->nojoliet)<<1) | ((!!o->noiso1999)<<2) | + ((!!o->preferjoliet)<<3) | ((!!o->pretend_blank)<<4) | + ((!!o->noaaip) << 5) | ((!!o->noacl) << 6) | ((!!o->noea) << 7) | + ((!!o->noino) << 8) | ((o->nomd5 & 3) << 9) | + ((!!o->do_ecma119_map) << 11) | ((o->map_mode & 3) << 12); + return(1); +} + + +int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o, + uid_t uid, gid_t gid, mode_t mode) +{ + mode_t dirmode; + + o->uid= uid; + o->gid= gid; + o->mode= mode; + dirmode= mode; + if(dirmode & S_IRUSR) + dirmode|= S_IXUSR; + if(dirmode & S_IRGRP) + dirmode|= S_IXGRP; + if(dirmode & S_IROTH) + dirmode|= S_IXOTH; + o->dirmode= dirmode; + return(1); +} + + +int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o, + uid_t *uid, gid_t *gid, mode_t *mode) +{ + *uid= o->uid; + *gid= o->gid; + *mode= o->mode; + return(1); +} + + +int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o, + mode_t mode) +{ + o->dirmode= mode; + return(1); +} + + +int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o, + mode_t *mode) +{ + *mode= o->dirmode; + return(1); +} + + +int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o, + char *input_charset) +{ + o->input_charset= input_charset; + return(1); +} + + +int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o, + char **input_charset) +{ + *input_charset= o->input_charset; + return(1); +} + + +int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode) +{ + o->auto_input_charset= mode & 1; + return(1); +} + + +int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode) +{ + *mode= o->auto_input_charset; + return(1); +} + + +int isoburn_ropt_set_displacement(struct isoburn_read_opts *o, + uint32_t displacement, int displacement_sign) +{ + o->displacement= displacement; + o->displacement_sign= displacement_sign; + return(1); +} + + +int isoburn_ropt_get_displacement(struct isoburn_read_opts *o, + uint32_t *displacement, int *displacement_sign) +{ + *displacement= o->displacement; + *displacement_sign= o->displacement_sign; + return(1); +} + + +int isoburn_ropt_set_truncate_mode(struct isoburn_read_opts *o, + int mode, int length) +{ + if(mode < 0 || mode > 1) + mode= 1; + if(length < 64) + length= 64; + if(length > 255) + length= 255; + o->truncate_mode= mode; + o->truncate_length= length; + return(1); +} + + +int isoburn_ropt_get_truncate_mode(struct isoburn_read_opts *o, + int *mode, int *length) +{ + *mode= o->truncate_mode; + *length= o->truncate_length; + return(1); +} + + +int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, + uint32_t *size, int *has_what) +{ + *size= o->size; + *has_what= (!!o->hasRR) | ((!!o->hasJoliet)<<1) | + ((!!o->hasIso1999)<<2) | ((!!o->hasElTorito)<<3); + return(1); +} + + +/* ----------------------------------------------------------------------- */ +/* + Options for image generation by libisofs and image transport to libburn. +*/ +/* ----------------------------------------------------------------------- */ + + +int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag) +{ + struct isoburn_imgen_opts *o; + int i; + + o= (*new_o)= calloc(1, sizeof(struct isoburn_imgen_opts)); + if(o==NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot allocate memory for image generation options", + 0, "FATAL", 0); + return(-1); + } + o->level= 2; + o->rockridge= 1; + o->joliet= 0; + o->iso1999= 0; + o->hardlinks= 0; + o->aaip = 0; + o->session_md5= 0; + o->file_md5= 0; + o->no_emul_toc= 0; + o->old_empty= 0; + o->untranslated_name_len = 0; + o->allow_dir_id_ext = 0; + o->omit_version_numbers= 0; + o->allow_deep_paths= 1; + o->rr_reloc_dir= NULL; + o->rr_reloc_flags= 0; + o->allow_longer_paths= 0; + o->max_37_char_filenames= 0; + o->no_force_dots= 0; + o->allow_lowercase= 0; + o->allow_full_ascii= 0; + o->allow_7bit_ascii= 0; + o->joliet_longer_paths= 0; + o->joliet_long_names= 0; + o->joliet_utf16= 0; + o->always_gmt= 0; + o->rrip_version_1_10= 0; + o->dir_rec_mtime= 0; + o->aaip_susp_1_10= 0; + o->sort_files= 0; + o->replace_dir_mode= 0; + o->replace_file_mode= 0; + o->replace_uid= 0; + o->replace_gid= 0; + o->dir_mode= 0555; + o->file_mode= 0444; + o->uid= 0; + o->gid= 0; + o->output_charset= NULL; + o->fifo_size= 4*1024*1024; + o->effective_lba= -1; + o->data_start_lba= -1; + o->system_area_data= NULL; + o->system_area_options= 0; + o->partition_offset= 0; + o->partition_secs_per_head= 0; + o->partition_heads_per_cyl= 0; + o->vol_creation_time= 0; + o->vol_modification_time= 0; + o->vol_expiration_time= 0; + o->vol_effective_time= 0; + o->libjte_handle= NULL; + o->tail_blocks= 0; + o->prep_partition= NULL; + o->prep_part_flag= 0; + o->efi_boot_partition= NULL; + o->efi_boot_part_flag= 0; + for(i= 0; i < Libisoburn_max_appended_partitionS; i++) { + o->appended_partitions[i]= NULL; + o->appended_part_types[i]= 0; + o->appended_part_flags[i]= 0; + } + o->appended_as_gpt= 0; + o->appended_as_apm= 0; + o->part_like_isohybrid= 0; + memset(o->gpt_guid, 0, 16); + o->gpt_guid_mode= 0; + memset(o->hfsp_serial_number, 0, 8); + o->hfsp_block_size= 0; + o->apm_block_size= 0; + o->do_tao= 0; + o->do_fsync= 0; + return(1); +} + + +int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag) +{ + int i; + + if(*o==NULL) + return(0); + if((*o)->rr_reloc_dir != NULL) + free((*o)->rr_reloc_dir); + if((*o)->prep_partition != NULL) + free((*o)->prep_partition); + if((*o)->efi_boot_partition != NULL) + free((*o)->efi_boot_partition); + for(i= 0; i < Libisoburn_max_appended_partitionS; i++) + if((*o)->appended_partitions[i] != NULL) + free((*o)->appended_partitions[i]); + if ((*o)->system_area_data != NULL) + free((*o)->system_area_data); + free(*o); + *o= NULL; + return(1); +} + + +int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level) +{ + o->level= level; + return(1); +} + + +int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level) +{ + *level= o->level; + return(1); +} + + +int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext) +{ + o->rockridge= !!(ext&1); + o->joliet= !!(ext&2); + o->iso1999= !!(ext&4); + o->hardlinks= !!(ext & 8); + o->aaip= !!(ext & 32); + o->session_md5= !!(ext & 64); + o->file_md5= (ext & (128 | 256)) >> 7; + o->no_emul_toc= !!(ext & 512); + o->will_cancel= !!(ext & 1024); + o->old_empty= !!(ext & 2048); + o->hfsplus= !!(ext & 4096); + o->fat= !!(ext & 8192); + return(1); +} + + +int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext) +{ + *ext= (!!o->rockridge) | ((!!o->joliet)<<1) | ((!!o->iso1999)<<2) | + ((!!o->hardlinks) << 3) | ((!!o->aaip) << 5) | + ((!!o->session_md5) << 6) | ((o->file_md5 & 3) << 7) | + ((!!o->no_emul_toc) << 9) | ((o->will_cancel) << 10) | + ((!!o->old_empty) << 11) | ((!!o->hfsplus) << 12) | + ((!!o->fat) << 13); + return(1); +} + + +int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax) +{ + o->omit_version_numbers= (!!(relax&1)) | + (2 * !!(relax & isoburn_igopt_only_iso_versions)); + o->allow_deep_paths= !!(relax&2); + o->allow_longer_paths= !!(relax&4); + o->max_37_char_filenames= !!(relax&8); + o->no_force_dots= (!!(relax&16)) | + (2 * !!(relax & isoburn_igopt_no_j_force_dots)); + o->allow_lowercase= !!(relax&32); + o->allow_full_ascii= !!(relax&64); + o->joliet_longer_paths= !!(relax&128); + o->always_gmt= !!(relax & isoburn_igopt_always_gmt); + o->rrip_version_1_10= !!(relax & isoburn_igopt_rrip_version_1_10); + o->dir_rec_mtime= !!(relax & isoburn_igopt_dir_rec_mtime); + o->aaip_susp_1_10= !!(relax & isoburn_igopt_aaip_susp_1_10); + o->allow_dir_id_ext= !!(relax & isoburn_igopt_allow_dir_id_ext); + o->joliet_long_names= !!(relax & isoburn_igopt_joliet_long_names); + o->joliet_rec_mtime= !!(relax & isoburn_igopt_joliet_rec_mtime); + o->iso1999_rec_mtime= !!(relax & isoburn_igopt_iso1999_rec_mtime); + o->allow_7bit_ascii= !!(relax & isoburn_igopt_allow_7bit_ascii); + o->joliet_utf16= !!(relax & isoburn_igopt_joliet_utf16); + return(1); +} + + +int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax) +{ + *relax= (!!o->omit_version_numbers) | ((!!o->allow_deep_paths)<<1) | + ((!!o->allow_longer_paths)<<2) | ((!!o->max_37_char_filenames)<<3) | + ((!!(o->no_force_dots & 1))<<4)| ((!!o->allow_lowercase)<<5) | + ((!!o->allow_full_ascii)<<6) | ((!!o->joliet_longer_paths)<<7) | + ((!!o->always_gmt)<<8) | ((!!o->rrip_version_1_10)<<9) | + ((!!o->dir_rec_mtime)<<10) | ((!!o->aaip_susp_1_10)<<11) | + ((!!(o->omit_version_numbers & 2))<<12) | + ((!!(o->no_force_dots & 2))<<13) | + ((!!o->allow_dir_id_ext) << 14) | + ((!!o->joliet_long_names) << 15) | + ((!!o->joliet_rec_mtime) << 16) | + ((!!o->iso1999_rec_mtime) << 17) | + ((!!o->allow_full_ascii) << 18) | + ((!!o->joliet_utf16) << 19); + return(1); +} + + +int isoburn_igopt_set_rr_reloc(struct isoburn_imgen_opts *o, char *name, + int flags) +{ + if(o->rr_reloc_dir != name) { + if(o->rr_reloc_dir != NULL) + free(o->rr_reloc_dir); + o->rr_reloc_dir= NULL; + if(name != NULL) { + o->rr_reloc_dir= strdup(name); + if(o->rr_reloc_dir == NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot allocate memory for image generation options", + 0, "FATAL", 0); + return(-1); + } + } + } + o->rr_reloc_flags = flags & 1; + return 1; +} + + +int isoburn_igopt_get_rr_reloc(struct isoburn_imgen_opts *o, char **name, + int *flags) +{ + *name= o->rr_reloc_dir; + *flags= o->rr_reloc_flags; + return(1); +} + + +int isoburn_igopt_set_untranslated_name_len(struct isoburn_imgen_opts *o, + int len) +{ + int ret; + IsoWriteOpts *opts = NULL; + char *msg= NULL; + + msg= calloc(1, 160); + if(msg == NULL) + {ret= -1; goto ex;} + + ret= iso_write_opts_new(&opts, 0); + if(ret < 0) { + isoburn_msgs_submit(NULL, 0x00060000, + "Cannot create libisofs write options object", 0, "FATAL", 0); + {ret= 0; goto ex;} + } + ret= iso_write_opts_set_untranslated_name_len(opts, len); + if(ret < 0) { + ret= iso_write_opts_set_untranslated_name_len(opts, -1); + sprintf(msg, + "Improper value for maximum length of untranslated names (%d <-> -1 ... %d)", + len, ret); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0); + iso_write_opts_free(opts); + {ret= 0; goto ex;} + } + o->untranslated_name_len= ret; /* Normalized len value */ + iso_write_opts_free(opts); + ret= 1; +ex:; + if(msg != NULL) + free(msg); + return(ret); +} + + +int isoburn_igopt_get_untranslated_name_len(struct isoburn_imgen_opts *o, + int *len) +{ + *len = o->untranslated_name_len; + return(1); +} + + +int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value) +{ + o->sort_files= !!(value&1); + return(1); +} + + +int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value) +{ + *value= !!o->sort_files; + return(1); +} + + +int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o, + int replace_dir_mode, int replace_file_mode, + mode_t dir_mode, mode_t file_mode) +{ + o->replace_dir_mode= replace_dir_mode%3; + o->replace_file_mode= replace_file_mode%3; + o->dir_mode= dir_mode; + o->file_mode= file_mode; + return(1); +} + + +int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o, + int *replace_dir_mode, int *replace_file_mode, + mode_t *dir_mode, mode_t *file_mode) +{ + *replace_dir_mode= o->replace_dir_mode%3; + *replace_file_mode= o->replace_file_mode%3; + *dir_mode= o->dir_mode; + *file_mode= o->file_mode; + return(1); +} + + +int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o, + int replace_uid, int replace_gid, + uid_t uid, gid_t gid) +{ + o->replace_uid= replace_uid%3; + o->replace_gid= replace_gid%3; + o->uid= uid; + o->gid= gid; + return(1); +} + +int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o, + int *replace_uid, int *replace_gid, + uid_t *uid, gid_t *gid) +{ + *replace_uid= o->replace_uid%3; + *replace_gid= o->replace_gid%3; + *uid= o->uid; + *gid= o->gid; + return(1); +} + + +int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o, + char *output_charset) +{ + o->output_charset= output_charset; + return(1); +} + + +int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o, + char **output_charset) +{ + *output_charset= o->output_charset; + return(1); +} + + +int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size) +{ + o->fifo_size= fifo_size; + return(1); +} + + +int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size) +{ + *fifo_size= o->fifo_size; + return(1); +} + + +int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba) +{ + *lba= o->effective_lba; + return(1); +} + + +int isoburn_igopt_get_data_start(struct isoburn_imgen_opts *o, int *lba) +{ + *lba= o->data_start_lba; + return(1); +} + + +int isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts *o, char *name, + char *timestamp, char *tag_written) +{ + strncpy(o->scdbackup_tag_name, name, 80); + o->scdbackup_tag_name[80]= 0; + strncpy(o->scdbackup_tag_time, timestamp, 18); + o->scdbackup_tag_time[18]= 0; + o->scdbackup_tag_written = tag_written; + if(tag_written != NULL) + tag_written[0]= 0; + return(1); +} + + +int isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts *o, + char name[81], char timestamp[19], + char **tag_written) +{ + strncpy(name, o->scdbackup_tag_name, 80); + name[80]= 0; + strncpy(timestamp, o->scdbackup_tag_time, 18); + timestamp[18]= 0; + *tag_written= o->scdbackup_tag_written; + return(1); +} + + +int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *opts, + char data[32768], int options) +{ + if (data == NULL) { /* Disable */ + if (opts->system_area_data != NULL) + free(opts->system_area_data); + opts->system_area_data = NULL; + } else { + if (opts->system_area_data == NULL) { + opts->system_area_data = calloc(32768, 1); + if (opts->system_area_data == NULL) + return(-1); + } + memcpy(opts->system_area_data, data, 32768); + } + opts->system_area_options = options & 0xffff; + return(1); +} + + +int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *opts, + char data[32768], int *options) +{ + *options= opts->system_area_options; + if(opts->system_area_data == NULL) + return(0); + memcpy(data, opts->system_area_data, 32768); + return(1); +} + + +int isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts *opts, + time_t vol_creation_time, time_t vol_modification_time, + time_t vol_expiration_time, time_t vol_effective_time, + char *vol_uuid) +{ + opts->vol_creation_time = vol_creation_time; + opts->vol_modification_time = vol_modification_time; + opts->vol_expiration_time = vol_expiration_time; + opts->vol_effective_time = vol_effective_time; + strncpy(opts->vol_uuid, vol_uuid, 16); + opts->vol_uuid[16] = 0; + return(1); +} + + +int isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts *opts, + time_t *vol_creation_time, time_t *vol_modification_time, + time_t *vol_expiration_time, time_t *vol_effective_time, + char vol_uuid[17]) +{ + *vol_creation_time = opts->vol_creation_time; + *vol_modification_time = opts->vol_modification_time; + *vol_expiration_time = opts->vol_expiration_time; + *vol_effective_time = opts->vol_effective_time; + strcpy(vol_uuid, opts->vol_uuid); + return(1); +} + + +int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, int heads_per_cyl) +{ + if (block_offset_2k > 0 && block_offset_2k < 16) + return(0); + opts->partition_offset = block_offset_2k; + opts->partition_secs_per_head = secs_512_per_head; + opts->partition_heads_per_cyl = heads_per_cyl; + return(1); +} + + +int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts, + uint32_t *block_offset_2k, + int *secs_512_per_head, int *heads_per_cyl) +{ + *block_offset_2k = opts->partition_offset; + *secs_512_per_head = opts->partition_secs_per_head; + *heads_per_cyl = opts->partition_heads_per_cyl; + return 1; +} + + +int isoburn_igopt_attach_jte(struct isoburn_imgen_opts *opts, + void *libjte_handle) +{ + opts->libjte_handle = libjte_handle; + return 1; +} + + +int isoburn_igopt_detach_jte(struct isoburn_imgen_opts *opts, + void **libjte_handle) +{ + if(libjte_handle != NULL) + *libjte_handle = opts->libjte_handle; + opts->libjte_handle = NULL; + return 1; +} + + +int isoburn_igopt_set_tail_blocks(struct isoburn_imgen_opts *opts, + uint32_t num_blocks) +{ + opts->tail_blocks = num_blocks; + return 1; +} + +int isoburn_igopt_get_tail_blocks(struct isoburn_imgen_opts *opts, + uint32_t *num_blocks) +{ + *num_blocks = opts->tail_blocks; + return 1; +} + + +int isoburn_igopt_set_prep_partition(struct isoburn_imgen_opts *o, + char *path, int flag) +{ + if(o->prep_partition != NULL) + free(o->prep_partition); + o->prep_partition= NULL; + o->prep_part_flag= 0; + if(path != NULL) { + o->prep_partition= strdup(path); + if(o->prep_partition == NULL) { + isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0); + return(-1); + } + } + o->prep_part_flag= flag & 1; + return(1); +} + + +int isoburn_igopt_get_prep_partition(struct isoburn_imgen_opts *opts, + char **path, int flag) +{ + *path= opts->prep_partition; + if(flag & 1) + return(1 + (opts->prep_part_flag & 0x3fffffff)); + return(1); +} + + +int isoburn_igopt_set_efi_bootp(struct isoburn_imgen_opts *o, + char *path, int flag) +{ + if(o->efi_boot_partition != NULL) + free(o->efi_boot_partition); + o->efi_boot_partition= NULL; + o->efi_boot_part_flag= 0; + if(path != NULL) { + o->efi_boot_partition= strdup(path); + if(o->efi_boot_partition == NULL) { + isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0); + return(-1); + } + } + o->efi_boot_part_flag = flag & 1; + return(1); +} + + +int isoburn_igopt_get_efi_bootp(struct isoburn_imgen_opts *opts, + char **path, int flag) +{ + *path= opts->efi_boot_partition; + if(flag & 1) + return(1 + (opts->efi_boot_part_flag & 0x3fffffff)); + return(1); +} + + +int isoburn_igopt_set_partition_img(struct isoburn_imgen_opts *opts, + int partition_number, uint8_t partition_type, + char *image_path) +{ + char msg[80]; + + if (partition_number < 1 || + partition_number > Libisoburn_max_appended_partitionS) { + sprintf(msg, "Partition number is out of range (1 ... %d)", + Libisoburn_max_appended_partitionS); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0); + return(0); + } + if (opts->appended_partitions[partition_number - 1] != NULL) + free(opts->appended_partitions[partition_number - 1]); + opts->appended_partitions[partition_number - 1] = strdup(image_path); + if (opts->appended_partitions[partition_number - 1] == NULL) + return(-1); + opts->appended_part_types[partition_number - 1] = partition_type; + return(1); +} + + +int isoburn_igopt_get_partition_img(struct isoburn_imgen_opts *opts, + int num_entries, + uint8_t partition_types[], + char *image_paths[]) +{ + int i, max_entry= 0; + + for(i= 0; i < num_entries; i++) + image_paths[i]= NULL; + for(i= 0; i < Libisoburn_max_appended_partitionS; i++) { + if(opts->appended_partitions[i] == NULL) + continue; + if(i < num_entries) { + image_paths[i]= opts->appended_partitions[i]; + partition_types[i]= opts->appended_part_types[i]; + } + max_entry= i + 1; + } + return(max_entry); +} + + +int isoburn_igopt_set_part_flag(struct isoburn_imgen_opts *opts, + int partition_number, int flag) +{ + char msg[80]; + + if (partition_number < 1 || + partition_number > Libisoburn_max_appended_partitionS) { + sprintf(msg, "Partition number is out of range (1 ... %d)", + Libisoburn_max_appended_partitionS); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0); + return(0); + } + opts->appended_part_flags[partition_number - 1]= flag; + return(1); +} + + +int isoburn_igopt_get_part_flags(struct isoburn_imgen_opts *opts, + int num_entries, int part_flags[]) +{ + int i, max_entry= 0; + + for(i= 0; i < num_entries; i++) + part_flags[i]= 0; + for(i= 0; i < Libisoburn_max_appended_partitionS; i++) { + if(i < num_entries) + part_flags[i]= opts->appended_part_flags[i]; + max_entry= i + 1; + } + return(max_entry); +} + + +int isoburn_igopt_set_appended_as_gpt(struct isoburn_imgen_opts *opts, int gpt) +{ + opts->appended_as_gpt= !!gpt; + return(1); +} + + +int isoburn_igopt_get_appended_as_gpt(struct isoburn_imgen_opts *opts, + int *gpt) +{ + *gpt= opts->appended_as_gpt; + return(1); +} + + +int isoburn_igopt_set_appended_as_apm(struct isoburn_imgen_opts *opts, int apm) +{ + opts->appended_as_apm= !!apm; + return(1); +} + + +int isoburn_igopt_get_appended_as_apm(struct isoburn_imgen_opts *opts, + int *apm) +{ + *apm= opts->appended_as_apm; + return(1); +} + + +int isoburn_igopt_set_part_like_isohybrid(struct isoburn_imgen_opts *opts, + int alike) +{ + opts->part_like_isohybrid= !!alike; + return(1); +} + + +int isoburn_igopt_get_part_like_isohybrid(struct isoburn_imgen_opts *opts, + int *alike) +{ + *alike= opts->part_like_isohybrid; + return(1); +} + + +int isoburn_igopt_set_gpt_guid(struct isoburn_imgen_opts *opts, + uint8_t guid[16], int mode) +{ + if(mode < 0 || mode > 2) { + isoburn_msgs_submit(NULL, 0x00060000, + "Unrecognized GPT disk GUID setup mode. (0 ... 2)", + 0, "FAILURE", 0); + return(0); + } + opts->gpt_guid_mode= mode; + if(opts->gpt_guid_mode == 1) + memcpy(opts->gpt_guid, guid, 16); + return 1; +} + + +int isoburn_igopt_get_gpt_guid(struct isoburn_imgen_opts *opts, + uint8_t guid[16], int *mode) +{ + if(opts->gpt_guid_mode == 1) + memcpy(guid, opts->gpt_guid, 16); + *mode = opts->gpt_guid_mode; + return(1); +} + + +int isoburn_igopt_set_disc_label(struct isoburn_imgen_opts *opts, char *label) +{ + strncpy(opts->ascii_disc_label, label, Libisoburn_disc_label_sizE - 1); + opts->ascii_disc_label[Libisoburn_disc_label_sizE - 1] = 0; + return(1); +} + + +int isoburn_igopt_get_disc_label(struct isoburn_imgen_opts *opts, char **label) +{ + *label= opts->ascii_disc_label; + return(1); +} + + +int isoburn_igopt_set_hfsp_serial_number(struct isoburn_imgen_opts *opts, + uint8_t serial_number[8]) +{ + memcpy(opts->hfsp_serial_number, serial_number, 8); + return(1); +} + + +int isoburn_igopt_get_hfsp_serial_number(struct isoburn_imgen_opts *opts, + uint8_t serial_number[8]) +{ + memcpy(serial_number, opts->hfsp_serial_number, 8); + return(1); +} + + +int isoburn_igopt_set_hfsp_block_size(struct isoburn_imgen_opts *opts, + int hfsp_block_size, int apm_block_size) +{ + char msg[80]; + + msg[0]= 0; + if(hfsp_block_size != -1) { + if(hfsp_block_size != 0 && hfsp_block_size != 512 && + hfsp_block_size != 2048) { + sprintf(msg, "Not a supported HFS+ size (%d <-> 0, 512, 2048)", + hfsp_block_size); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0); + } + opts->hfsp_block_size = hfsp_block_size; + } + if(apm_block_size != -1) { + if(apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048) { + sprintf(msg, "Not a supported APM block size (%d <-> 0, 512, 2048)", + apm_block_size); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0); + } + opts->apm_block_size = apm_block_size; + } + if(msg[0]) + return(0); + return(1); +} + + +int isoburn_igopt_get_hfsp_block_size(struct isoburn_imgen_opts *opts, + int *hfsp_block_size, int *apm_block_size) +{ + *hfsp_block_size= opts->hfsp_block_size; + *apm_block_size= opts->apm_block_size; + return(1); +} + + +int isoburn_igopt_set_write_type(struct isoburn_imgen_opts *opts, int do_tao) +{ + if(do_tao < -1 || do_tao > 1) + return(0); + opts->do_tao= do_tao; + return(1); +} + + +int isoburn_igopt_get_write_type(struct isoburn_imgen_opts *opts, int *do_tao) +{ + *do_tao= opts->do_tao; + return(1); +} + +int isoburn_igopt_set_stdio_endsync(struct isoburn_imgen_opts *opts, + int do_sync) +{ + opts->do_fsync= !!do_sync; + return(1); +} + +int isoburn_igopt_get_stdio_endsync(struct isoburn_imgen_opts *opts, + int *do_sync) +{ + *do_sync= opts->do_fsync; + return(1); +} + +int isoburn_conv_name_chars(struct isoburn_imgen_opts *opts, + char *name, size_t name_len, + char **result, size_t *result_len, int flag) +{ + int ret; + IsoWriteOpts *wopts= NULL; + + ret = iso_write_opts_new(&wopts, 0); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0); + goto ex; + } + ret= isoburn_make_iso_write_opts(NULL, opts, 0, wopts, 0); + if(ret < 0) + goto ex; + ret= iso_conv_name_chars(wopts, name, name_len, result, result_len, flag); +ex:; + if(wopts != NULL) + iso_write_opts_free(wopts); + return(ret); +} diff --git a/libisoburn/branches/1.4.6/libisoburn/isoburn.h b/libisoburn/branches/1.4.6/libisoburn/isoburn.h new file mode 100644 index 00000000..b1d6a39d --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/isoburn.h @@ -0,0 +1,818 @@ + +/* + Class struct of libisoburn. + + Copyright 2007 - 2016 Vreixo Formoso Lopes + and Thomas Schmitt + Provided under GPL version 2 or later. +*/ + +#ifndef Isoburn_includeD +#define Isoburn_includeD + + +/* for uint8_t */ +#ifdef HAVE_STDINT_H +#include +#else +#ifdef HAVE_INTTYPES_H +#include +#endif +#endif + +/* For emulated TOC of overwriteable media. + Provides minimal info for faking a struct burn_toc_entry. +*/ +struct isoburn_toc_entry { + int session; + int track_no; /* point */ + int start_lba; + int track_blocks; + char *volid; /* For caching a volume id from emulated toc on overwriteables */ + + struct isoburn_toc_entry *next; +}; + +int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt, + struct isoburn_toc_entry *boss, int flag); + +/* @param flag bit0= delete all subordinates too +*/ +int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag); + + +/* Minimal size of target_iso_head which is to be written during + isoburn_activate_session(). + Within this size there is everything that is needed for image access with + no partition offset. The actual target_iso_head buffer must be larger by + the evential partition offset. +*/ +#define Libisoburn_target_head_sizE (32*2048) + + +/* Maximum number of appended partitions. Effectively usable number depends + on system area type. +*/ +#define Libisoburn_max_appended_partitionS 8 + +/* + Maximum length of a disc label text plus 1. +*/ +#define Libisoburn_disc_label_sizE 129 + + +struct isoburn { + + + /* The libburn drive to which this isoburn object is related + Most isoburn calls will use a burn_drive as object handle */ + struct burn_drive *drive; + + /* -1= inappropriate medium state detected + 0= libburn multi-session medium, resp. undecided yet + 1= random access medium */ + int emulation_mode; + + /* Although rarely used, libburn can operate on several + drives simultaneously. */ + struct isoburn *prev; + struct isoburn *next; + + + /* If >= 0, this address is used as reply for isoburn_disc_get_msc1() + */ + int fabricated_msc1; + + /* If >= 0, this address is used in isoburn_disc_track_lba_nwa() + as reply parameter nwa. + (The other nwa parameters below apply only to the effective write address + on random access media. msc2 is handed to libisofs but not to libburn.) + */ + int fabricated_msc2; + + + /* The nwa to be used for a first session on the present kind of overwriteable + media (usually Libisoburn_overwriteable_starT, but might be forced to 0) + */ + int zero_nwa; + + /* Start address as given by image examination (bytes, not blocks) */ + off_t min_start_byte; + + /* Aligned start address to be used for processing (counted in blocks) */ + int nwa; + + + /* Truncate to .nwa an eventual regular file serving as output drive */ + int truncate; + + /* Eventual freely fabricated isoburn_disc_get_status(). + BURN_DISC_UNREADY means that this variable is disabled + and normally emulated status is in effect. + */ + enum burn_disc_status fabricated_disc_status; + + /* To be set if read errors occurred during media evaluation. + */ + int media_read_error; + + /* Eventual emulated table of content read from the chain of ISO headers + on overwriteable media. + */ + struct isoburn_toc_entry *toc; + + /* Indicator wether the most recent burn run worked : + -1 = undetermined, ask libburn , 0 = failure , 1 = success + To be inquired by isoburn_drive_wrote_well() + */ + int wrote_well; + + + /* ISO head buffer to be filled by write run */ + int target_iso_head_size; + uint8_t *target_iso_head; + + /* The 2k offset which was read from a loaded image. + */ + uint32_t loaded_partition_offset; + + + /* Libisofs image context */ + IsoImage *image; + + /* The start LBA of the image */ + int image_start_lba; + + /* The block data source from which the existing image is read. + */ + IsoDataSource *iso_data_source; + + /* The burn source which transfers data from libisofs to libburn. + It has its own fifo. + */ + struct burn_source *iso_source; + + /* For iso_tree_set_report_callback() */ + int (*read_pacifier)(IsoImage*, IsoFileSource*); + + /* For iso_image_attach_data() */ + void *read_pacifier_handle; + + /* An application provided method to immediately deliver messages */ + int (*msgs_submit)(void *handle, int error_code, char msg_text[], + int os_errno, char severity[], int flag); + void *msgs_submit_handle; /* specific to application method */ + int msgs_submit_flag; /* specific to application method */ + + /* Forwarding an image generation option to the burn wrapper */ + int do_tao; + + /* Forwarding an image generation option to the burn wrapper */ + int do_fsync; + +}; + + +/* Creation and disposal function */ +int isoburn_new(struct isoburn **objpt, int flag); +int isoburn_destroy(struct isoburn **objpt, int flag); + +/* Eventual readers for public attributes */ +/* ( put into separate .h file then ) */ +int isoburn_get_emulation_mode(struct isoburn *o, int *pt, int flag); +int isoburn_get_target_volset(struct isoburn *o, IsoImage **pt, int flag); + +/* List management */ +int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag); +int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag); +int isoburn_destroy_all(struct isoburn **objpt, int flag); +int isoburn_link(struct isoburn *o, struct isoburn *link, int flag); +int isoburn_count(struct isoburn *o, int flag); +int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag); +int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag); + + +/* Non API inner interfaces */ + +/* Submit a libisofs error to the libburn messenger. An application message + reader shall recognize the error code range and attribute it to the + libisofs message channel to which one cannot submit via API. + @param iso_error_code return value <= 0 from a libisofs API call. + @param default_msg_text is to be put out if iso_error_code leads to no + error message + @param os_errno operating system errno, submit 0 if none is known + @param min_severity minimum severity, might be be increased if libisofs + error severity surpasses min_severity. + @param flag Bitfield, submit 0 for now +*/ +int isoburn_report_iso_error(int iso_error_code, char default_msg_text[], + int os_errno, char min_severity[], int flag); + +/* Calls from burn_wrap.c into isofs_wrap.c */ + +int isoburn_start_emulation(struct isoburn *o, int flag); +int isoburn_invalidate_iso(struct isoburn *o, int flag); + + +/* Calls from isofs_wrap.c into burn_wrap.c */ + +/** Get an eventual isoburn object which is wrapped around the drive. + @param pt Eventually returns a pointer to the found object. + It is allowed to become NULL if return value is -1 or 0. + In this case, the drive is a genuine libburn drive + with no emulation activated by isoburn. + @param drive The drive to be searched for + @param flag unused yet + @return -1 unsuitable medium, 0 generic medium, 1 emulated medium. +*/ +int isoburn_find_emulator(struct isoburn **pt, + struct burn_drive *drive, int flag); + +/* Deliver an event message. Either via a non-NULL o->msgs_submit() method + or via burn_msgs_submit() of libburn. +*/ +int isoburn_msgs_submit(struct isoburn *o, int error_code, char msg_text[], + int os_errno, char severity[], int flag); + +/** Set the start address for an emulated add-on session. The value will + be rounded up to the alignment necessary for the medium. The aligned + value will be divided by 2048 and then put into o->nwa . + @param o The isoburn object to be programmed. + @param value The start address in bytes + @param flag unused yet + @return <=0 is failure , >0 success +*/ +int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag); + +/** Obtains the image address offset to be used with image generation. + This is either the (emulated) drive nwa or a value set by + isoburn_prepare_blind_grow(). + In any case this is the address to tell to iso_write_opts_set_ms_block(). + @param o The isoburn object to be inquired + @param opts If not NULL: write parameters to be set on drive before query + @param msc2 The value to be used with iso_write_opts_set_ms_block() + @param flag unused yet + @return <=0 is failure , >0 success +*/ +int isoburn_get_msc2(struct isoburn *o, + struct burn_write_opts *opts, int *msc2, int flag); + +/** Get a data source suitable for read from a drive using burn_read_data() + function. + @param d drive to read from. Must be grabbed. + @param displacement will be added or subtracted to any block address + @param displacement_sign +1 = add , -1= subtract , else keep unaltered + @return the data source, NULL on error. Must be freed with libisofs + iso_data_source_unref() function. Note: this doesn't release + the drive. +*/ +IsoDataSource * +isoburn_data_source_new(struct burn_drive *d, + uint32_t displacement, int displacement_sign, + int cache_tiles, int tile_blocks); + +/** Default settings for above cache_tiles, tile_blocks in newly created + struct isoburn_read_opts. +*/ +#define Libisoburn_default_cache_tileS 32 +#define Libisoburn_default_tile_blockS 32 + +/** Maximum size of the cache in 2 kB blocks (1 GB) +*/ +#define Libisoburn_cache_max_sizE (1024 * 512) + + +/** Disable read capabilities of a data source which was originally created + by isoburn_data_source_new(). After this any attempt to read will yield + a FATAL programming error event. + This is usually done to allow libburn to release the drive while libisofs + still holds a reference to the data source object. libisofs is not supposed + to use this object for reading any more, nevertheless. The disabled state + of the data source is a safety fence around this daring situation. + @param src The data source to be disabled + @param flag unused yet + @return <=0 is failure , >0 success +*/ +int isoburn_data_source_shutdown(IsoDataSource *src, int flag); + + +/** Check whether the size of target_iso_head matches the given partition + offset. Eventually adjust size. +*/ +int isoburn_adjust_target_iso_head(struct isoburn *o, + uint32_t offst, int flag); + + +/** Initialize the root directory attributes of a freshly created image. +*/ +int isoburn_root_defaults(IsoImage *image, int flag); + + +/** + * Options for image reading. + (Comments here may be outdated. API getter/setter function descriptions + may override the descriptions here. Any difference is supposed to be a + minor correction only.) + */ +struct isoburn_read_opts { + int cache_tiles; /* number of cache tiles */ + int cache_tile_blocks; + + unsigned int norock:1; /*< Do not read Rock Ridge extensions */ + unsigned int nojoliet:1; /*< Do not read Joliet extensions */ + unsigned int noiso1999:1; /*< Do not read ISO 9660:1999 enhanced tree */ + + unsigned int do_ecma119_map:1; /* call iso_read_opts_set_ecma119_map() */ + unsigned int map_mode:2; /* argument for do_ecma119_map */ + + /* ts A90121 */ + unsigned int noaaip:1; /* Do not read AAIP for ACL and EA */ + unsigned int noacl:1; /* Do not read ACL from external file objects */ + unsigned int noea:1; /* Do not read XFS-style EA from externals */ + + /* ts A90508 */ + unsigned int noino:1; /* Discard eventual PX inode numbers */ + + /* ts A90810 */ + unsigned int nomd5:2; /* Do not read eventual MD5 array */ + + unsigned int preferjoliet:1; + /*< When both Joliet and RR extensions are present, the RR + * tree is used. If you prefer using Joliet, set this to 1. */ + uid_t uid; /**< Default uid when no RR */ + gid_t gid; /**< Default uid when no RR */ + mode_t mode; /**< Default mode when no RR (only permissions) */ + mode_t dirmode; /**< Default mode for directories + when no RR (only permissions) */ + + /** + * Input charset for RR file names. NULL to use default locale charset. + */ + char *input_charset; + + /** + * Enable or disable methods to automatically choose an input charset. + * This eventually overrides input_charset. + * + * bit0= set the input character set automatically from + * attribute "isofs.cs" of root directory + */ + int auto_input_charset; + + /** + * What to do in case of name longer than truncate_length: + * 0= throw FAILURE + * 1= truncate to truncate_length with MD5 of whole name at end + */ + int truncate_mode; + int truncate_length; + + /* modified by the function isoburn_read_image */ + unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present, + to 0 if not. */ + unsigned int hasJoliet:1; /*< It will be set to 1 if Joliet extensions are + present, to 0 if not. */ + + /** + * It will be set to 1 if the image is an ISO 9660:1999, i.e. it has + * a version 2 Enhanced Volume Descriptor. + */ + unsigned int hasIso1999:1; + + /** It will be set to 1 if El-Torito boot record is present, to 0 if not.*/ + unsigned int hasElTorito:1; + + uint32_t size; /**< Will be filled with the size (in 2048 byte block) of + * the image, as reported in the PVM. */ + unsigned int pretend_blank:1; /* always create empty image */ + + uint32_t displacement; + int displacement_sign; +}; + + +/** + * Options for image generation by libisofs and image transport to libburn. + (Comments here may be outdated. API getter/setter function descriptions + may override the descriptions here. Any difference is supposed to be a + minor correction only.) + */ +struct isoburn_imgen_opts { + + /* Options for image generation */ + + int will_cancel :1; + + int level; /**< ISO level to write at. */ + + /** Which extensions to support. */ + unsigned int rockridge :1; + unsigned int joliet :1; + unsigned int iso1999 :1; + unsigned int hfsplus :1; + unsigned int fat :1; + + /* Whether to mark suitable IsoNode as hardlinks in RRIP PX */ + unsigned int hardlinks :1; + + /* Write eventual AAIP info containing ACL and EA */ + unsigned int aaip :1; + + /* Produce and write a MD5 checksum of the whole session stream. */ + unsigned int session_md5 :1; + + /* Produce and write MD5 checksums for each single IsoFile. + See parameter "files" of iso_write_opts_set_record_md5(). + */ + unsigned int file_md5 :2; + + /* On overwriteable media or random access files do not write the first + session to LBA 32, but rather to LBA 0 directly. + */ + unsigned int no_emul_toc :1; + + /* For empty files, symbolic links, and devices use the old ECMA-119 block + addresses in the range [0,31] rather than the address of the dedicated + empty block. + */ + unsigned int old_empty :1; + + + /* relaxed constraints */ + + /* + * Relaxed constraints. Setting any of these to 1 break the specifications, + * but it is supposed to work on most moderns systems. Use with caution. + */ + + /* + * Extra Caution: This option breaks any assumptions about names that + * are supported by ECMA-119 specifications. + * Omit any translation which would make a file name compliant to the + * ECMA-119 rules. This includes and exceeds omit_version_numbers, + * max_37_char_filenames, no_force_dots bit0, allow_lowercase. + */ + unsigned int untranslated_name_len; + + /* + * Convert directory names for ECMA-119 similar to other file names, but do + * not force a dot or add a version number. + * This violates ECMA-119 by allowing one "." and especially ISO level 1 + * by allowing DOS style 8.3 names rather than only 8 characters. + * (mkisofs and its clones seem to do this violation.) + */ + unsigned int allow_dir_id_ext :1; + + /** + * Omit the version number (";1") at the end of the ISO-9660 identifiers. + * Version numbers are usually not used. + * bit0= omit version number with ECMA-119 and Joliet + * bit1= omit version number with Joliet alone + */ + unsigned int omit_version_numbers :2; + + /** + * Allow ISO-9660 directory hierarchy to be deeper than 8 levels. + */ + unsigned int allow_deep_paths :1; + + /** + * If not allow_deep_paths is in effect, then it may become + * necessary to relocate directories so that no ECMA-119 file path + * has more than 8 components. These directories are grafted into either + * the root directory of the ISO image or into a dedicated relocation + * directory. For details see libisofs.h, iso_write_opts_set_rr_reloc(). + */ + char *rr_reloc_dir; /* IsoNode name in root directory. NULL or + empty text means root itself. */ + int rr_reloc_flags; /* bit0= mark auto-created rr_reloc_dir by RE + bit1= not settable via API (used internally) + */ + + + + /** + * Allow path in the ISO-9660 tree to have more than 255 characters. + */ + unsigned int allow_longer_paths :1; + + /** + * Allow a single file or directory hierarchy to have up to 37 characters. + * This is larger than the 31 characters allowed by ISO level 2, and the + * extra space is taken from the version number, so this also forces + * omit_version_numbers. + */ + unsigned int max_37_char_filenames :1; + + /** + * ISO-9660 forces filenames to have a ".", that separates file name from + * extension. libisofs adds it if original filename doesn't has one. Set + * this to 1 to prevent this behavior + * bit0= no forced dot with ECMA-119 + * bit1= no forced dot with Joliet + */ + unsigned int no_force_dots :2; + + /** + * Allow lowercase characters in ISO-9660 filenames. By default, only + * uppercase characters, numbers and a few other characters are allowed. + */ + unsigned int allow_lowercase :1; + + /** + * Allow all ASCII characters to be appear on an ISO-9660 filename. Note + * that "/" and "\0" characters are never allowed, even in RR names. + */ + unsigned int allow_full_ascii :1; + + /** + * Like allow_full_ascii, but only allowing 7-bit characters. + * Lowercase letters get mapped to uppercase if not allow_lowercase is set. + * Gets overridden if allow_full_ascii is enabled. + */ + unsigned int allow_7bit_ascii :1; + + /** + * Allow paths in the Joliet tree to have more than 240 characters. + */ + unsigned int joliet_longer_paths :1; + + /** + * Allow leaf names in the Joliet tree to have up to 103 characters + * rather than 64. + */ + unsigned int joliet_long_names :1; + + /** + * Use UTF-16BE rather than its subset UCS-2 + */ + unsigned int joliet_utf16 :1; + + /** + * Store timestamps as GMT rather than in local time. + */ + unsigned int always_gmt :1; + + /** + * Write Rock Ridge info as of specification RRIP-1.10 rather than + * RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282", + * field PX without file serial number + */ + unsigned int rrip_version_1_10 :1; + + /** + * Store as ECMA-119 Directory Record timestamp the mtime + * of the source rather than the image creation time. + * The same can be ordered for Joliet and ISO 9660:1999 + */ + unsigned int dir_rec_mtime :1; + unsigned int joliet_rec_mtime :1; + unsigned int iso1999_rec_mtime :1; + + /** + * Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. + * I.e. without announcing it by an ER field and thus without the need + * to precede the RRIP fields by an ES and to precede the AA field by ES. + */ + unsigned int aaip_susp_1_10 :1; + + unsigned int sort_files:1; + /**< If files should be sorted based on their weight. */ + + /** + * The following options set the default values for files and directory + * permissions, gid and uid. All these take one of three values: 0, 1 or 2. + * If 0, the corresponding attribute will be kept as set in the IsoNode. + * Unless you have changed it, it corresponds to the value on disc, so it + * is suitable for backup purposes. If set to 1, the corresponding attrib. + * will be changed by a default suitable value. Finally, if you set it to + * 2, the attrib. will be changed with the value specified in the options + * below. Note that for mode attributes, only the permissions are set, the + * file type remains unchanged. + */ + unsigned int replace_dir_mode :2; + unsigned int replace_file_mode :2; + unsigned int replace_uid :2; + unsigned int replace_gid :2; + + mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */ + mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */ + uid_t uid; /** uid to use when replace_uid == 2. */ + gid_t gid; /** gid to use when replace_gid == 2. */ + + char *output_charset; /**< NULL to use default charset */ + + + /* Options for image transport */ + + /** The number of bytes to be used for the fifo which decouples libisofs + and libburn for better throughput and for reducing the risk of + interrupting signals hitting the libburn thread which operates the + MMC drive. + The size will be rounded up to the next full 2048. + Minimum is 64kiB, maximum is 1 GiB (but that is too much anyway). + */ + int fifo_size; + + + /** Output value: Block address of session start as evaluated from medium + and other options by libisoburn and libburn. + If <0 : Invalid + If >=0: Valid block number. Block size is always 2 KiB. + */ + int effective_lba; + + /** Output value: Block address of data section start as predicted by + libisofs. + If < 16: Invalid + If >=16: Valid block number. Block size is always 2 KiB. + */ + int data_start_lba; + + /** + * If not empty: Parameters "name" and "timestamp" for a scdbackup stream + * checksum tag. See scdbackup/README appendix VERIFY. + * It makes sense only for single session images which start at LBA 0. + * Such a tag may be part of a libisofs checksum tag block after the + * session tag line. It then covers the whole session up to its own start + * position. + * If scdbackup_tag_written is not NULL then it is a pointer to an + * application provided array with at least 512 characters. The effectively + * written scdbackup tag will be copied to this memory location. + */ + char scdbackup_tag_name[81]; + char scdbackup_tag_time[19]; + char *scdbackup_tag_written; + + + /* Content of an embedded boot image. Valid if not NULL. + * In that case it must point to a memory buffer at least 32 kB. + */ + char *system_area_data; + /* + * bit0= make bytes 446 - 512 of the system area a partition + * table which reserves partition 1 from byte 63*512 to the + * end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl. + * (GRUB protective msdos label.) + * This works with and without system_area_data. + */ + int system_area_options; + + /* User settable PVD time stamps */ + time_t vol_creation_time; + time_t vol_modification_time; + time_t vol_expiration_time; + time_t vol_effective_time; + /* To eventually override vol_modification_time by unconverted string + and timezone 0 */ + char vol_uuid[17]; + + /* The number of unclaimed 2K blocks before start of partition 1 as of + the MBR in system area. If not 0 this will cause double volume + descriptor sets and double tree. + */ + uint32_t partition_offset; + /* Partition table parameter: 1 to 63, 0= disabled/default */ + int partition_secs_per_head; + /* 1 to 255, 0= disabled/default */ + int partition_heads_per_cyl; + + /* Parameters and state of Jigdo Template Export environment. + */ + void *libjte_handle; + + /* A trailing padding of zero bytes which belongs to the image + */ + uint32_t tail_blocks; + + /* Disk file paths of content of PreP partition and EFI system partition */ + char *prep_partition; + int prep_part_flag; + char *efi_boot_partition; + int efi_boot_part_flag; + + /* Eventual disk file paths of prepared images which shall be appended + after the ISO image and described by partiton table entries in a MBR. + */ + char *appended_partitions[Libisoburn_max_appended_partitionS]; + uint8_t appended_part_types[Libisoburn_max_appended_partitionS]; + int appended_part_flags[Libisoburn_max_appended_partitionS]; + + /* If 1: With appended partitions: create protective MBR and mark by GPT + */ + int appended_as_gpt; + + /* If 1: With appended partitions: mark by APM + */ + int appended_as_apm; + + /* If 1: Apply isohybrid gestures to non-isohybrid situations + */ + int part_like_isohybrid; + + /* See libisoburn.h isoburn_igopt_set_gpt_guid() + */ + uint8_t gpt_guid[16]; + int gpt_guid_mode; + + /* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label. + */ + char ascii_disc_label[Libisoburn_disc_label_sizE]; + + /* HFS+ image serial number. + * 00...00 means that it shall be generated by libisofs. + */ + uint8_t hfsp_serial_number[8]; + + /* Allocation block size of HFS+ : 0= auto , 512, or 2048 + */ + int hfsp_block_size; + + /* Block size of and in APM : 0= auto , 512, or 2048 + */ + int apm_block_size; + + /* Write mode for optical media: + * 0 = auto + * 1 = TAO, Incremental, no RESERVE TRACK + * -1 = SAO, DAO, RESERVE TRACK + */ + int do_tao; + + /* Whether to fsync() stdio_drives after isoburn_activate_session() */ + int do_fsync; + +}; + + +/* Alignment for session starts on overwriteable media. + (Increased from 16 to 32 blocks for aligning to BD-RE clusters.) +*/ +#define Libisoburn_nwa_alignemenT 32 + + +/* Alignment for outer session scanning with -ROM drives. + (E.g. my DVD-ROM drive shows any DVD type as 0x10 "DVD-ROM" with + more or less false capacity and TOC.) +*/ +#define Libisoburn_toc_scan_alignemenT 16 + +/* Maximum gap to be bridged during a outer TOC scan. Gaps appear between the + end of a session and the start of the next session. + The longest gap found so far was about 38100 after the first session of a + DVD-R. +*/ +#define Libisoburn_toc_scan_max_gaP 65536 + + +/* Creating a chain of image headers which form a TOC: + + The header of the first session is written after the LBA 0 header. + So it persists and can give the end of its session. By help of + Libisoburn_nwa_alignemenT it should be possible to predict the start + of the next session header. + The LBA 0 header is written by isoburn_activate_session() already + with the first session. So the medium is mountable. + A problem arises with DVD-RW in Intermediate State. They cannot be + written by random access before they were written sequentially. + In this case, no copy of the session 1 header is maintained and no TOC + will be possible. Thus writing begins sequentially at LBA 0. + + IMPORTANT: This macro gives the minimal size of an image header. + It has to be enlarged by the eventual partition offset. +*/ +#define Libisoburn_overwriteable_starT \ + ((off_t) (Libisoburn_target_head_sizE/2048)) + + +/* Wrappers for emulation of TOC on overwriteable media */ + +struct isoburn_toc_track { + /* Either track or toc_entry are supposed to be NULL */ + struct burn_track *track; + struct isoburn_toc_entry *toc_entry; +}; + +struct isoburn_toc_session { + /* Either session or tracks and toc_entry are supposed to be NULL */ + struct burn_session *session; + struct isoburn_toc_track **track_pointers; + int track_count; + struct isoburn_toc_entry *toc_entry; +}; + +struct isoburn_toc_disc { + /* Either disc or sessions and toc are supposed to be NULL */ + struct burn_disc *disc; + struct isoburn_toc_session *sessions; /* storage array */ + struct isoburn_toc_session **session_pointers; /* storage array */ + struct isoburn_toc_track *tracks; /* storage array */ + struct isoburn_toc_track **track_pointers; /* storage array */ + int session_count; + int incomplete_session_count; + int track_count; + struct isoburn_toc_entry *toc; +}; + +#endif /* Isoburn_includeD */ + diff --git a/libisoburn/branches/1.4.6/libisoburn/isofs_wrap.c b/libisoburn/branches/1.4.6/libisoburn/isofs_wrap.c new file mode 100644 index 00000000..3dd140fc --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/isofs_wrap.c @@ -0,0 +1,718 @@ + +/* + cc -g -c isofs_wrap.c +*/ + +/* + libisofs related functions of libisoburn. + + Copyright 2007 - 2011 Vreixo Formoso Lopes + Thomas Schmitt + Provided under GPL version 2 or later. +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include + +#ifndef Xorriso_standalonE + +#include + +#include + +#else /* ! Xorriso_standalonE */ + +#include "../libisofs/libisofs.h" +#include "../libburn/libburn.h" + +#endif /* Xorriso_standalonE */ + +#include "libisoburn.h" +#include "isoburn.h" + +#define BP(a,b) [(b) - (a) + 1] + +struct ecma119_pri_vol_desc +{ + uint8_t vol_desc_type BP(1, 1); + uint8_t std_identifier BP(2, 6); + uint8_t vol_desc_version BP(7, 7); + uint8_t unused1 BP(8, 8); + uint8_t system_id BP(9, 40); + uint8_t volume_id BP(41, 72); + uint8_t unused2 BP(73, 80); + uint8_t vol_space_size BP(81, 88); + uint8_t unused3 BP(89, 120); + uint8_t vol_set_size BP(121, 124); + uint8_t vol_seq_number BP(125, 128); + uint8_t block_size BP(129, 132); + uint8_t path_table_size BP(133, 140); + uint8_t l_path_table_pos BP(141, 144); + uint8_t opt_l_path_table_pos BP(145, 148); + uint8_t m_path_table_pos BP(149, 152); + uint8_t opt_m_path_table_pos BP(153, 156); + uint8_t root_dir_record BP(157, 190); + uint8_t vol_set_id BP(191, 318); + uint8_t publisher_id BP(319, 446); + uint8_t data_prep_id BP(447, 574); + uint8_t application_id BP(575, 702); + uint8_t copyright_file_id BP(703, 739); + uint8_t abstract_file_id BP(740, 776); + uint8_t bibliographic_file_id BP(777, 813); + uint8_t vol_creation_time BP(814, 830); + uint8_t vol_modification_time BP(831, 847); + uint8_t vol_expiration_time BP(848, 864); + uint8_t vol_effective_time BP(865, 881); + uint8_t file_structure_version BP(882, 882); + uint8_t reserved1 BP(883, 883); + uint8_t app_use BP(884, 1395); + uint8_t reserved2 BP(1396, 2048); +}; + +static +uint32_t iso_read_lsb(const uint8_t *buf, int bytes) +{ + int i; + uint32_t ret = 0; + + for (i=0; iimage); + return o->image; +} + + +/* API */ +int isoburn_get_attached_start_lba(struct burn_drive *d) +{ + int ret; + struct isoburn *o= NULL; + + ret = isoburn_find_emulator(&o, d, 0); + if (ret < 0 || o == NULL) + return -1; + if(o->image == NULL) + return -1; + return o->image_start_lba; +} + + +static void isoburn_idle_free_function(void *ignored) +{ + return; +} + + +int isoburn_root_defaults(IsoImage *image, int flag) +{ + IsoNode *root_node; + mode_t root_mode= 0755; + + root_node= (IsoNode *) iso_image_get_root(image); + iso_node_set_permissions(root_node, root_mode); + return(1); +} + + +/* API function. See libisoburn.h +*/ +int isoburn_read_image(struct burn_drive *d, + struct isoburn_read_opts *read_opts, + IsoImage **image) +{ + int ret, int_num, dummy; + IsoReadOpts *ropts= NULL; + IsoReadImageFeatures *features= NULL; + uint32_t ms_block; + char *msg= NULL; + enum burn_disc_status status= BURN_DISC_BLANK; + IsoDataSource *ds= NULL; + struct isoburn *o= NULL; + IsoImage *new_image= NULL; + + msg= calloc(1, 160); + + if(d != NULL) { + ret = isoburn_find_emulator(&o, d, 0); + if (ret < 0 || o == NULL) + {ret= 0; goto ex;} + status = isoburn_disc_get_status(d); + o->image_start_lba= -1; + } + if(read_opts==NULL) { + isoburn_msgs_submit(o, 0x00060000, + "Program error: isoburn_read_image: read_opts==NULL", + 0, "FATAL", 0); + {ret= -1; goto ex;} + } + if (d == NULL || status == BURN_DISC_BLANK || read_opts->pretend_blank) { +create_blank_image:; + /* + * Blank disc, we create a new image without files. + */ + + if (d == NULL) { + /* New empty image without relation to a drive */ + if (image==NULL) { + isoburn_msgs_submit(o, 0x00060000, + "Program error: isoburn_read_image: image==NULL", + 0, "FATAL", 0); + {ret= -1; goto ex;} + } + /* create a new image */ + ret = iso_image_new("ISOIMAGE", image); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0); + goto ex; + } + iso_image_set_ignore_aclea(*image, + (!!(read_opts->noacl)) | ((!!read_opts->noea) << 1) ); + new_image= *image; + } else { + /* Blank new image for the drive */ + iso_image_unref(o->image); + ret = iso_image_new("ISOIMAGE", &o->image); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0); + goto ex; + } + if (image != NULL) { + *image = o->image; + iso_image_ref(*image); /*protects object from premature free*/ + } + iso_image_set_ignore_aclea(o->image, + (!!(read_opts->noacl)) | ((!!read_opts->noea) << 1) ); + + ret= isoburn_root_defaults(o->image, 0); + if(ret <= 0) + goto ex; + new_image= o->image; + } + ret= iso_image_set_truncate_mode(new_image, read_opts->truncate_mode, + read_opts->truncate_length); + if(ret < 0) + goto ex; + {ret= 1; goto ex;} + } + + if (status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL) { + isoburn_msgs_submit(o, 0x00060000, + "Program error: isoburn_read_image: incorrect disc status", + 0, "FATAL", 0); + {ret= -4; goto ex;} + } + + ret = isoburn_disc_get_msc1(d, &int_num); + if (ret <= 0) + {ret= -2; goto ex;} + ms_block= int_num; + if (o != NULL) + o->image_start_lba= ms_block; + ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0); + if (ret <= 0) { + sprintf(msg, "No ISO 9660 image at LBA %d. Creating blank image.", int_num); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); + goto create_blank_image; + } + + if(read_opts->displacement != 0 && abs(read_opts->displacement_sign) == 1) { + /* Apply reverse displacement to session start */ + if(read_opts->displacement_sign == -1) { + if(ms_block+ read_opts->displacement < ms_block) { +displacement_rollover:; + sprintf(msg, "Displacement offset leads outside 32 bit range."); + isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + ms_block+= read_opts->displacement; + } else { + if(ms_block < read_opts->displacement) + goto displacement_rollover; + ms_block-= read_opts->displacement; + } + } + + + /* create the data source */ + ret = iso_read_opts_new(&ropts, 0); + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0); + goto ex; + } + + /* Important: do not return until iso_read_opts_free() */ + + iso_read_opts_set_start_block(ropts, ms_block); + iso_read_opts_set_no_rockridge(ropts, read_opts->norock); + iso_read_opts_set_no_aaip(ropts, read_opts->noaaip); + if(read_opts->nomd5 == 2) + int_num= 2; + else if(read_opts->nomd5 == 1) + int_num= 1; + else + int_num= 0; + iso_read_opts_set_no_md5(ropts, int_num); + if(read_opts->do_ecma119_map) + iso_read_opts_set_ecma119_map(ropts, read_opts->map_mode); + iso_read_opts_set_new_inos(ropts, read_opts->noino); + + iso_read_opts_set_no_joliet(ropts, read_opts->nojoliet); + iso_read_opts_set_no_iso1999(ropts, read_opts->noiso1999); + iso_read_opts_set_preferjoliet(ropts, read_opts->preferjoliet); + iso_read_opts_set_default_permissions(ropts, + read_opts->mode, read_opts->dirmode); + iso_read_opts_set_default_uid(ropts, read_opts->uid); + iso_read_opts_set_default_gid(ropts, read_opts->gid); + iso_read_opts_set_input_charset(ropts, read_opts->input_charset); + iso_read_opts_auto_input_charset(ropts, read_opts->auto_input_charset); + iso_read_opts_load_system_area(ropts, 1); + iso_read_opts_keep_import_src(ropts, 1); + ret= iso_image_set_truncate_mode(o->image, read_opts->truncate_mode, + read_opts->truncate_length); + if(ret < 0) + goto ex; + + ds = isoburn_data_source_new(d, read_opts->displacement, + read_opts->displacement_sign, + read_opts->cache_tiles, read_opts->cache_tile_blocks); + if (ds == NULL) { + isoburn_report_iso_error(ret, "Cannot create IsoDataSource object", 0, + "FATAL", 0); + ret= -1; goto ex; + } + if(o->iso_data_source!=NULL) + iso_data_source_unref(o->iso_data_source); + o->iso_data_source= ds; + iso_image_attach_data(o->image, o->read_pacifier_handle, + isoburn_idle_free_function); + if(o->read_pacifier_handle==NULL) + iso_tree_set_report_callback(o->image, NULL); + else + iso_tree_set_report_callback(o->image, o->read_pacifier); + + ret = iso_image_import(o->image, ds, ropts, &features); + iso_tree_set_report_callback(o->image, NULL); + iso_read_opts_free(ropts); + ropts= NULL; + + if (ret < 0) { + isoburn_report_iso_error(ret, "Cannot import image", 0, "FAILURE", 0); + goto ex; + } + /* Important: do not return until free(features) */ + if (image!=NULL) { + *image = o->image; + iso_image_ref(*image); /*protects object from premature free*/ + } + read_opts->hasRR = iso_read_image_features_has_rockridge(features); + read_opts->hasJoliet = iso_read_image_features_has_joliet(features); + read_opts->hasIso1999 = iso_read_image_features_has_iso1999(features); + read_opts->hasElTorito = iso_read_image_features_has_eltorito(features); + read_opts->size = iso_read_image_features_get_size(features); + ret= 1; +ex:; + if(msg != NULL) + free(msg); + if(ropts != NULL) + iso_read_opts_free(ropts); + if(features != NULL) + iso_read_image_features_destroy(features); + return(ret); +} + + +/* API function. See libisoburn.h +*/ +int isoburn_attach_image(struct burn_drive *d, IsoImage *image) +{ + int ret; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, d, 0); + if (ret < 0 || o == NULL) + return 0; + if (image == NULL) { + isoburn_msgs_submit(o, 0x00060000, + "Program error: isoburn_attach_image: image==NULL", + 0, "FATAL", 0); + return -1; + } + if(o->image != NULL) + iso_image_unref(o->image); + o->image = image; + o->image_start_lba = -1; + return(1); +} + + +/* API */ +int isoburn_attach_start_lba(struct burn_drive *d, int lba, int flag) +{ + int ret; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, d, 0); + if(ret < 0) + return ret; + if(o == NULL) + return 0; + if(o->image == NULL) + return 0; + o->image_start_lba = lba; + return 1; +} + + +/* API function. See libisoburn.h +*/ +int isoburn_activate_session(struct burn_drive *drive) +{ + int ret, do_sync = 1; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, drive, 0); + if (ret < 0) + return -1; + + if (o->emulation_mode != 1) + return 1; /* don't need to activate session */ + if (o->fabricated_msc2 >= 0) + return 1; /* blind growing: do not alter anything outside the session */ + + if (!(o->fabricated_disc_status == BURN_DISC_APPENDABLE || + (o->fabricated_disc_status == BURN_DISC_BLANK && + o->zero_nwa > 0))) + return 1; + ret = burn_drive_get_drive_role(drive); + if (ret != 1) + do_sync = !! o->do_fsync; + + ret = burn_random_access_write(drive, (off_t) 0, (char*)o->target_iso_head, + o->target_iso_head_size, do_sync); + + return ret; +} + + +/** API @since 0.6.2 +*/ +int isoburn_get_img_partition_offset(struct burn_drive *drive, + uint32_t *block_offset_2k) +{ + int ret; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, drive, 0); + if(ret < 0 || o == NULL) + return -1; + *block_offset_2k= o->loaded_partition_offset; + if(o->loaded_partition_offset == 0) + return(0); + if(o->target_iso_head_size == (off_t) Libisoburn_target_head_sizE + + (off_t) 2048 * (off_t) o->loaded_partition_offset) + return(1); + return(2); +} + + +/* Check for MBR signature and a first partition that starts at a 2k block + and ends where the image ends. + If not too large or too small, accept its start as partition offset. +*/ +static int isoburn_inspect_partition(struct isoburn *o, uint32_t img_size, + int flag) +{ + uint8_t *mbr, *part, *buf= NULL; + uint32_t offst, numsec; + struct ecma119_pri_vol_desc *pvm; + off_t data_count; + int ret; + char *msg= NULL; + static int max_offst= 512 - 32; + + buf= (uint8_t *) calloc(1, 2048); + msg= calloc(1, 160); + if(buf == NULL || msg == NULL) + {ret= -1; goto ex;} + + mbr= o->target_iso_head; + part= mbr + 446; + if(mbr[510] != 0x55 || mbr[511] != 0xAA) + {ret= 2; goto ex;} /* not an MBR */ + + /* Does the first partition entry look credible ? */ + if(part[0] != 0x80 && part[0] != 0x00) + {ret= 2; goto ex;} /* Invalid partition status */ + if(part[1] == 0 && part[2] == 0 && part[3] == 0) + {ret= 2; goto ex;} /* Zero C/H/S start address */ + + /* Does it match the normal ISO image ? */ + offst= iso_read_lsb(part + 8, 4); + numsec= iso_read_lsb(part + 12, 4); + if(offst < 64) + {ret= 2; goto ex;} /* Zero or unusably small partition start */ + if((offst % 4) || (numsec % 4)) + {ret= 2; goto ex;} /* Not aligned to 2k */ + if(numsec < 72) + {ret= 2; goto ex;} /* No room for volume descriptors */ + offst/= 4; + numsec/= 4; + if(offst + numsec != img_size) + {ret= 2; goto ex;} /* Partition end does not match image end */ + + /* Is there a PVD at the partition start ? */ + ret = burn_read_data(o->drive, (off_t) (offst + 16) * (off_t) 2048, + (char*) buf, 2048, &data_count, 32); + if(ret <= 0) + {ret= 2; goto ex;} + pvm = (struct ecma119_pri_vol_desc *) buf; + if (strncmp((char*) pvm->std_identifier, "CD001", 5) != 0) + {ret= 2; goto ex;} /* not a PVD */ + if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 + || pvm->file_structure_version[0] != 1 ) + {ret= 2; goto ex;} /* failed sanity check */ + + if(iso_read_lsb(pvm->vol_space_size, 4) + offst != img_size) + {ret= 2; goto ex;} /* Image ends do not match */ + + /* Now it is credible. Not yet clear is whether it is acceptable. */ + o->loaded_partition_offset= offst; + + /* If the partition start is too large: Report but do not accept. */ + if(offst > (uint32_t) max_offst) {/* Not more than 1 MB of .target_iso_head */ + sprintf(msg, + "Detected partition offset of %.f blocks. Maximum for load buffer is %d", + (double) offst, max_offst); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "WARNING", 0); + {ret= 3; goto ex;} + } + + /* Accept partition start and adjust buffer size */ + ret= isoburn_adjust_target_iso_head(o, offst, 0); + if(ret <= 0) + goto ex; + + ret= 1; +ex:; + if(buf != NULL) + free(buf); + if(msg != NULL) + free(msg); + return(ret); +} + + +/** Initialize the emulation of multi-session on random access media. + The need for emulation is confirmed already. + @param o A freshly created isoburn object. isoburn_create_data_source() was + already called, nevertheless. + @param flag bit0= read-only + @return <=0 error , 1 = success +*/ +int isoburn_start_emulation(struct isoburn *o, int flag) +{ + int ret, i, capacity = -1, role, dummy; + off_t data_count, to_read; + struct burn_drive *drive; + struct ecma119_pri_vol_desc *pvm; + enum burn_disc_status s; + char *path= NULL, *msg= NULL; + + path= calloc(1, BURN_DRIVE_ADR_LEN); + msg= calloc(1, 2 * BURN_DRIVE_ADR_LEN); + if(path == NULL || msg == NULL) + {ret= -1; goto ex;} + + if(o==NULL) { + isoburn_msgs_submit(NULL, 0x00060000, + "Program error: isoburn_start_emulation: o==NULL", + 0, "FATAL", 0); + {ret= -1; goto ex;} + } + + drive= o->drive; + + if(flag & 1) + o->fabricated_disc_status= BURN_DISC_FULL; + + /* We can assume 0 as start block for image. + The data there point to the most recent session. + */ + role = burn_drive_get_drive_role(drive); + ret = burn_get_read_capacity(drive, &capacity, 0); + if (ret <= 0) + capacity = -1; + if (role == 5) { /* random access write-only medium */ + s = burn_disc_get_status(drive); + o->fabricated_disc_status= s; + burn_disc_track_lba_nwa(drive, NULL, 0, &dummy, &(o->nwa)); + if(o->nwa < o->zero_nwa) + o->zero_nwa= 0; + {ret= 1; goto ex;} + } else if (capacity > 0 || role == 2 || role == 4) { + /* Might be a block device on a system where libburn cannot determine its + size. Try to read anyway. */ + to_read = o->target_iso_head_size; + memset(o->target_iso_head, 0, to_read); + if(capacity > 0 && (off_t) capacity * (off_t) 2048 < to_read) + to_read = (off_t) capacity * (off_t) 2048; + ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, + to_read, &data_count, 32 | 8); + if (ret <= 0) { + /* an error means a disc with no ISO image */ + o->media_read_error= 1; + if (ret == -2) { + path[0]= 0; + burn_drive_d_get_adr(drive, path); + sprintf(msg, "Pseudo drive '%s' does not allow reading", path); + isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "NOTE", 0); + o->fabricated_disc_status= BURN_DISC_BLANK; + } else if (capacity > 0) + o->fabricated_disc_status= BURN_DISC_FULL; + else if(!(flag & 1)) + o->fabricated_disc_status= BURN_DISC_BLANK; + {ret= 1; goto ex;} + } + } else { + /* No read capacity means blank medium */ + if(!(flag & 1)) + o->fabricated_disc_status= BURN_DISC_BLANK; + {ret= 1; goto ex;} + } + + /* check first 64K. If 0's, the disc is treated as a blank disc, and thus + overwritten without extra check. */ + i = Libisoburn_target_head_sizE; + while (i && !o->target_iso_head[i-1]) + --i; + + if (!i) { + if(!(flag & 1)) + o->fabricated_disc_status= BURN_DISC_BLANK; + {ret= 1; goto ex;} + } + + pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048); + + if (strncmp((char*)pvm->std_identifier, "CD001", 5) == 0) { + off_t size; + + /* sanity check */ + if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 + || pvm->file_structure_version[0] != 1 ) { + /* TODO for now I treat this as a full disc */ + o->fabricated_disc_status= BURN_DISC_FULL; + {ret= 1; goto ex;} + } + + /* ok, PVM found, set size */ + size = (off_t) iso_read_lsb(pvm->vol_space_size, 4); + ret= isoburn_inspect_partition(o, (uint32_t) size, 0); + if (ret <= 0) + goto ex; + size *= (off_t) 2048; /* block size in bytes */ + isoburn_set_start_byte(o, size, 0); + if(!(flag & 1)) + o->fabricated_disc_status= BURN_DISC_APPENDABLE; + } else if (strncmp((char*)pvm->std_identifier, "CDXX1", 5) == 0 || + (strncmp((char*)pvm->std_identifier, "CDxx1", 5) == 0 && + pvm->vol_desc_type[0] == 'x')) { + + /* empty image */ + isoburn_set_start_byte(o, o->zero_nwa * 2048, 0); + if(!(flag & 1)) + o->fabricated_disc_status= BURN_DISC_BLANK; + } else { + /* treat any disc in an unknown format as full */ + o->fabricated_disc_status= BURN_DISC_FULL; + } + + ret= 1; +ex:; + if(path != NULL) + free(path); + if(msg != NULL) + free(msg); + return(ret); +} + + +/** Alters and writes the first 64 kB of a "medium" to invalidate + an ISO image. (It shall stay restorable by skilled humans, though). + The result shall especially keep libisoburn from accepting the medium + image as ISO filesystem. + @param o A fully activated isoburn object. isoburn_start_emulation() + was already called. + @return <=0 error , 1 = success +*/ +int isoburn_invalidate_iso(struct isoburn *o, int flag) +{ + int end_ed_found= 0, i; + char *head; + + head= (char *) o->target_iso_head; + /* + * replace CD001 with CDXX1 in PVM. + * I think this is enought for invalidating an iso image + */ + strncpy(head + 16 * 2048 + 1, "CDXX1", 5); + + /* Look for UDF volume recognition sequence and invalidate */ + for(i= 17 * 2048; i < 32 * 2048; i+= 2048) { + if(end_ed_found) { + if(head[i] == 0 && strncmp(head + i + 1, "BEA01", 5) == 0) + strncpy(head + i + 1, "BEAX1", 5); + else if(head[i] == 0 && strncmp(head + i + 1, "NSR", 3) == 0) + strncpy(head + i + 1, "NSRX", 4); + else if(head[i] == 0 && strncmp(head + i + 1, "TEA", 3) == 0) + strncpy(head + i + 1, "TEAX", 4); + } else { + if(((unsigned char *) head)[i] == 0xff && + strncmp(head + i + 1, "CD001", 5) == 0) + end_ed_found= 1; + } + } + + return isoburn_activate_session(o->drive); +} + + +/* API @since 0.1.0 */ +int isoburn_set_read_pacifier(struct burn_drive *drive, + int (*read_pacifier)(IsoImage*, IsoFileSource*), + void *read_handle) +{ + int ret; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, drive, 0); + if(ret < 0 || o == NULL) + return -1; + o->read_pacifier_handle= read_handle; + o->read_pacifier= read_pacifier; + return(1); +} + diff --git a/libisoburn/branches/1.4.6/libisoburn/libisoburn.h b/libisoburn/branches/1.4.6/libisoburn/libisoburn.h new file mode 100644 index 00000000..ba7286d5 --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/libisoburn.h @@ -0,0 +1,2640 @@ + +#ifndef LIBISOBURN_LIBISOBURN_H_ +#define LIBISOBURN_LIBISOBURN_H_ + +/* + Lower level API definition of libisoburn. + + Copyright 2007-2016 Vreixo Formoso Lopes + and Thomas Schmitt + Provided under GPL version 2 or later. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Overview + +libisoburn is a frontend for libraries libburn and libisofs which enables +creation and expansion of ISO-9660 filesystems on all CD/DVD/BD media supported +by libburn. This includes media like DVD+RW, which do not support multi-session +management on media level and even plain disk files or block devices. + +The price for that is thorough specialization on data files in ISO-9660 +filesystem images. So libisoburn is not suitable for audio (CD-DA) or any +other CD layout which does not entirely consist of ISO-9660 sessions. + +Note that there is a higher level of API: xorriso.h. One should not mix it +with the API calls of libisoburn.h, libisofs.h, and libburn.h. + + + Connector functions + +libisofs and libburn do not depend on each other but share some interfaces +by which they can cooperate. +libisoburn establishes the connection between both modules by creating the +necessary interface objects and attaching them to the right places. + + + Wrapper functions + +The principle of this frontend is that you may use any call of libisofs or +libburn unless it has a isoburn_*() wrapper listed in the following function +documentation. + +E.g. call isoburn_initialize() rather than iso_init(); burn_initialize(); +and call isoburn_drive_scan_and_grab() rather than burn_drive_scan_and_grab(). +But you may call burn_disc_get_profile() directly if you want to display +the media type. + +The wrappers will transparently provide the necessary emulations which +are appropriate for particular target drives and media states. +To learn about them you have to read both API descriptions: the one of +the wrapper and the one of the underlying libburn or libisofs call. + +Macros BURN_* and functions burn_*() are documented in +Macros ISO_* and functions iso_*() are documented in + + + Usage model + +There may be an input drive and an output drive. Either of them may be missing +with the consequence that no reading or no writing is possible. +Both drive roles can be fulfilled by the same drive. + +Input can be a random access readable libburn drive: + optical media, regular files, block devices. +Output can be any writeable libburn drive: + writeable optical media in burner, writeable file objects (no directories). + +libburn demands rw-permissions to drive device file or file object. + +If the input drive provides a suitable ISO RockRidge image, then its tree +may be loaded into memory and can then be manipulated by libisofs API calls. +The loading is done by isoburn_read_image() under control of +struct isoburn_read_opts which the application obtains from libisoburn +and manipulates by the family of isoburn_ropt_set_*() functions. + +Writing of result images is controlled by libisofs related parameters +in a struct isoburn_imgen_opts which the application obtains from libisoburn +and manipulates by the family of isoburn_igopt_set_*() functions. + +All multi-session aspects are handled by libisoburn according to these +settings. The application does not have to analyze media state and write +job parameters. It rather states its desires which libisoburn tries to +fulfill, or else will refuse to start the write run. + + + Setup for Growing, Modifying or Blind Growing + +The connector function family offers alternative API calls for performing +the setup for several alternative image generation strategies. + +Growing: +If input and output drive are the same, then isoburn_prepare_disc() is to +be used. It will lead to an add-on session on appendable or overwriteable +media with existing ISO image. With blank media it will produce a first +session. + +Modifying: +If the output drive is not the input drive, and if it bears blank media +or overwriteable without a valid ISO image, then one may produce a consolidated +image with old and new data. This will copy file data from an eventual input +drive with valid image, add any newly introduced data from the local +filesystem, and produce a first session on output media. +To prepare for such an image generation run, use isoburn_prepare_new_image(). + +Blind Growing: +This method reads the old image from one drive and writes the add-on session +to a different drive. That output drive is nevertheless supposed to +finally lead to the same medium from where the session was loaded. Usually it +will be stdio:/dev/fd/1 (i.e. stdout) being piped into some burn program +like with this classic gesture: + mkisofs -M $dev -C $msc1,$nwa | cdrecord -waiti dev=$dev +Blind growing is prepared by the call isoburn_prepare_blind_grow(). +The input drive should be released immediately after this call in order +to allow the consumer of the output stream to access that drive for writing. + +After either of these setups, some peripheral libburn drive parameter settings +like burn_write_opts_set_simulate(), burn_write_opts_set_multi(), + burn_drive_set_speed(), burn_write_opts_set_underrun_proof() should be made. +Do not set the write mode. It will be chosen by libisoburn so it matches job +and media state. + + Writing the image + +Then one may start image generation and write threads by isoburn_disc_write(). +Progress may be watched at the output drive by burn_drive_get_status() and +isoburn_get_fifo_status(). + +At some time, the output drive will be BURN_DRIVE_IDLE indicating that +writing has ended. +One should inquire isoburn_drive_wrote_well() to learn about overall success. + +Finally one must call isoburn_activate_session() which will complete any +eventual multi-session emulation. + + + Application Constraints + +Applications shall include libisofs/libisofs.h , libburn/libburn.h and this +file itself: libisoburn/libisoburn.h . +They shall link with -lisofs -lburn -lisoburn or with the .o files emerging +from building those libraries from their sources. + +Applications must use 64 bit off_t. +E.g. on 32-bit GNU/Linux by defining + #define _LARGEFILE_SOURCE + #define _FILE_OFFSET_BITS 64 +The minimum requirement is to interface with the library by 64 bit signed +integers where libisofs.h or libisoburn.h prescribe off_t. +Failure to do so may result in surprising malfunction or memory faults. + +Application files which include libisofs/libisofs.h or libisoburn/libisoburn.h +must provide definitions for uint32_t and uint8_t. +This can be achieved either: +- by using autotools which will define HAVE_STDINT_H or HAVE_INTTYPES_H + according to its ./configure tests, +- or by defining the macros HAVE_STDINT_H or HAVE_INTTYPES_H according + to the local situation, +- or by appropriately defining uint32_t and uint8_t by other means, + e.g. by including inttypes.h before including libisofs.h and libisoburn.h + +*/ +#ifdef HAVE_STDINT_H +#include +#else +#ifdef HAVE_INTTYPES_H +#include +#endif +#endif + + +/* Important: If you add a public API function then add its name to file + libisoburn/libisoburn.ver +*/ + + + /* API functions */ + + +/** Initialize libisoburn, libisofs and libburn. + Wrapper for : iso_init() and burn_initialize() + @since 0.1.0 + @param msg A character array for eventual messages (e.g. with errors) + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 indicates success, 0 is failure +*/ +int isoburn_initialize(char msg[1024], int flag); + + +/** Check whether all features of header file libisoburn.h from the given + major.minor.micro revision triple can be delivered by the library version + which is performing this call. + An application of libisoburn can easily memorize the version of the + libisoburn.h header in its own code. Immediately after isoburn_initialize() + it should simply do this check: + if (! isoburn_is_compatible(isoburn_header_version_major, + isoburn_header_version_minor, + isoburn_header_version_micro, 0)) + ...refuse to start the program with this dynamic library version... + @since 0.1.0 + @param major obtained at build time + @param minor obtained at build time + @param micro obtained at build time + @param flag Bitfield for control purposes. Unused yet. Submit 0. + @return 1= library can work for caller + 0= library is not usable in some aspects. Caller must restrict + itself to an earlier API version or must not use this libray + at all. +*/ +int isoburn_is_compatible(int major, int minor, int micro, int flag); + + +/** Obtain the three release version numbers of the library. These are the + numbers encountered by the application when linking with libisoburn, + i.e. possibly not before run time. + Better do not base the fundamental compatibility decision of an application + on these numbers. For a reliable check use isoburn_is_compatible(). + @since 0.1.0 + @param major The maturity version (0 for now, as we are still learning) + @param minor The development goal version. + @param micro The development step version. This has an additional meaning: + + Pare numbers indicate a version with frozen API. I.e. you can + rely on the same set of features to be present in all + published releases with that major.minor.micro combination. + Features of a pare release will stay available and ABI + compatible as long as the SONAME of libisoburn stays "1". + Currently there are no plans to ever change the SONAME. + + Odd numbers indicate that API upgrades are in progress. + I.e. new features might be already present or they might + be still missing. Newly introduced features may be changed + incompatibly or even be revoked before release of a pare + version. + So micro revisions {1,3,5,7,9} should never be used for + dynamic linking unless the proper library match can be + guaranteed by external circumstances. + + @return 1 success, <=0 might in future become an error indication +*/ +void isoburn_version(int *major, int *minor, int *micro); + + +/** The minimum version of libisofs to be used with this version of libisoburn + at compile time. + @since 0.1.0 +*/ +#define isoburn_libisofs_req_major 1 +#define isoburn_libisofs_req_minor 4 +#define isoburn_libisofs_req_micro 4 + +/** The minimum version of libburn to be used with this version of libisoburn + at compile time. + @since 0.1.0 +*/ +#define isoburn_libburn_req_major 1 +#define isoburn_libburn_req_minor 4 +#define isoburn_libburn_req_micro 5 + +/** The minimum compile time requirements of libisoburn towards libjte are + the same as of a suitable libisofs towards libjte. + So use these macros from libisofs.h : + iso_libjte_req_major + iso_libjte_req_minor + iso_libjte_req_micro + @since 0.6.4 +*/ + +/** The minimum version of libisofs to be used with this version of libisoburn + at runtime. This is checked already in isoburn_initialize() which will + refuse on outdated version. So this call is for information purposes after + successful startup only. + @since 0.1.0 + @param major isoburn_libisofs_req_major as seen at build time + @param minor as seen at build time + @param micro as seen at build time + @return 1 success, <=0 might in future become an error indication +*/ +int isoburn_libisofs_req(int *major, int *minor, int *micro); + + +/** The minimum version of libjte to be used with this version of libisoburn + at runtime. The use of libjte is optional and depends on configure + tests. It can be prevented by ./configure option --disable-libjte . + This is checked already in isoburn_initialize() which will refuse on + outdated version. So this call is for information purposes after + successful startup only. + @since 0.6.4 +*/ +int isoburn_libjte_req(int *major, int *minor, int *micro); + + +/** The minimum version of libburn to be used with this version of libisoburn + at runtime. This is checked already in isoburn_initialize() which will + refuse on outdated version. So this call is for information purposes after + successful startup only. + @since 0.1.0 + @param major isoburn_libburn_req_major as seen at build time + @param minor as seen at build time + @param micro as seen at build time + @return 1 success, <=0 might in future become an error indication +*/ +int isoburn_libburn_req(int *major, int *minor, int *micro); + + +/** These three release version numbers tell the revision of this header file + and of the API it describes. They are memorized by applications at build + time. + @since 0.1.0 +*/ +#define isoburn_header_version_major 1 +#define isoburn_header_version_minor 4 +#define isoburn_header_version_micro 5 +/** Note: + Above version numbers are also recorded in configure.ac because libtool + wants them as parameters at build time. + For the library compatibility check, ISOBURN_*_VERSION in configure.ac + are not decisive. Only the three numbers here do matter. +*/ +/** Usage discussion: + +Some developers of the libburnia project have differing +opinions how to ensure the compatibility of libaries +and applications. + +It is about whether to use at compile time and at runtime +the version numbers isoburn_header_version_* provided here. +Thomas Schmitt advises to use them. +Vreixo Formoso advises to use other means. + +At compile time: + +Vreixo Formoso advises to leave proper version matching +to properly programmed checks in the the application's +build system, which will eventually refuse compilation. + +Thomas Schmitt advises to use the macros defined here +for comparison with the application's requirements of +library revisions and to eventually break compilation. + +Both advises are combinable. I.e. be master of your +build system and have #if checks in the source code +of your application, nevertheless. + +At runtime (via *_is_compatible()): + +Vreixo Formoso advises to compare the application's +requirements of library revisions with the runtime +library. This is to allow runtime libraries which are +young enough for the application but too old for +the lib*.h files seen at compile time. + +Thomas Schmitt advises to compare the header +revisions defined here with the runtime library. +This is to enforce a strictly monotonous chain +of revisions from app to header to library, +at the cost of excluding some older libraries. + +These two advises are mutually exclusive. + +----------------------------------------------------- + +For an implementation of the Thomas Schmitt approach, +see libisoburn/burn_wrap.c : isoburn_initialize() +This connects libisoburn as "application" with libisofs +as "library". + +The compatible part of Vreixo Formoso's approach is implemented +in configure.ac LIBBURN_REQUIRED, LIBISOFS_REQUIRED. +In isoburn_initialize() it would rather test by + iso_lib_is_compatible(isoburn_libisofs_req_major,... +than by + iso_lib_is_compatible(iso_lib_header_version_major,... +and would leave out the ugly compile time traps. + +*/ + + +/** Announce to the library an application provided method for immediate + delivery of messages. It is used when no drive is affected directly or + if the drive has no own msgs_submit() method attached by + isoburn_drive_set_msgs_submit. + If no method is preset or if the method is set to NULL then libisoburn + delivers its messages through the message queue of libburn. + @param msgs_submit The function call which implements the method + @param submit_handle Handle to be used as first argument of msgs_submit + @param submit_flag Flag to be used as last argument of msgs_submit + @param flag Unused yet, submit 0 + @since 0.2.0 +*/ +int isoburn_set_msgs_submit(int (*msgs_submit)(void *handle, int error_code, + char msg_text[], int os_errno, + char severity[], int flag), + void *submit_handle, int submit_flag, int flag); + + +/** Acquire a target drive by its filesystem path or libburn persistent + address. + Wrapper for: burn_drive_scan_and_grab() + @since 0.1.0 + @param drive_infos On success returns a one element array with the drive + (cdrom/burner). Thus use with driveno 0 only. On failure + the array has no valid elements at all. + The returned array should be freed via burn_drive_info_free() + when the drive is no longer needed. But before this is done + one has to call isoburn_drive_release(drive_infos[0].drive). + @param adr The persistent address of the desired drive or the path + to a file object. + @param load 1 attempt to load the disc tray. 0 no attempt,rather failure. + @return 1 = success , 0 = drive not found , <0 = other error +*/ +int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], + char* adr, int load); + + +/** Acquire a target drive by its filesystem path or libburn persistent + address. This is a modern successor of isoburn_drive_scan_and_grab(). + Wrapper for: burn_drive_scan_and_grab() + @since 0.1.2 + @param drive_infos On success returns a one element array with the drive + (cdrom/burner). Thus use with driveno 0 only. On failure + the array has no valid elements at all. + The returned array should be freed via burn_drive_info_free() + when the drive is no longer needed. But before this is done + one has to call isoburn_drive_release(drive_infos[0].drive). + @param adr The persistent address of the desired drive or the path + to a file object. + @param flag bit0= attempt to load the disc tray. + Else: failure if not loaded. + bit1= regard overwriteable media as blank + bit2= if the drive is a regular disk file: + truncate it to the write start address when writing + begins + bit3= if the drive reports a read-only profile try to read + table of content by scanning for ISO image headers. + (depending on media type and drive this might + help or it might make the resulting toc even worse) + bit4= do not emulate table of content on overwriteable media + bit5= ignore ACL from external filesystems + bit6= ignore POSIX Extended Attributes from external + filesystems + bit7= pretend read-only profile and scan for table of content + bit8= re-assess already acquired (*drive_infos)[0] rather + than acquiring adr + @since 1.1.8 + bit9= when scanning for ISO 9660 sessions by bit3: + Do not demand a valid superblock at LBA 0, ignore it in + favor of one at LBA 32, and scan until end of medium. + @since 1.2.6 + @return 1 = success , 0 = drive not found , <0 = other error + + Please excuse the typo "aquire" in the function name. +*/ +int isoburn_drive_aquire(struct burn_drive_info *drive_infos[], + char* adr, int flag); + +/** Acquire a drive from the burn_drive_info[] array which was obtained by + a previous call of burn_drive_scan(). + Wrapper for: burn_drive_grab() + @since 0.1.0 + @param drive The drive to grab. E.g. drive_infos[1].drive . + Call isoburn_drive_release(drive) when it it no longer needed. + @param load 1 attempt to load the disc tray. 0 no attempt, rather failure. + @return 1 success, <=0 failure +*/ +int isoburn_drive_grab(struct burn_drive *drive, int load); + + +/** Attach to a drive an application provided method for immediate + delivery of messages. + If no method is set or if the method is set to NULL then libisoburn + delivers messages of the drive through the global msgs_submit() method + set by isoburn_set_msgs_submiti() or by the message queue of libburn. + @since 0.2.0 + @param d The drive to which this function, handle and flag shall apply + @param msgs_submit The function call which implements the method + @param submit_handle Handle to be used as first argument of msgs_submit + @param submit_flag Flag to be used as last argument of msgs_submit + @param flag Unused yet, submit 0 +*/ +int isoburn_drive_set_msgs_submit(struct burn_drive *d, + int (*msgs_submit)(void *handle, int error_code, + char msg_text[], int os_errno, + char severity[], int flag), + void *submit_handle, int submit_flag, int flag); + + +/** Inquire the medium status. Expect the whole spectrum of libburn BURN_DISC_* + with multi-session media. Emulated states with random access media are + BURN_DISC_BLANK and BURN_DISC_APPENDABLE. + Wrapper for: burn_disc_get_status() + @since 0.1.0 + @param drive The drive to inquire. + @return The status of the drive, or what kind of disc is in it. + Note: BURN_DISC_UNGRABBED indicates wrong API usage +*/ +#ifdef __cplusplus +enum burn::burn_disc_status isoburn_disc_get_status(struct burn_drive *drive); +#else +enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive); +#endif + + +/** Sets the medium status to BURN_DISC_FULL unconditionally. + @since 1.3.8 + @param drive The drive with the medium to be handled as if it was closed. + @ +*/ +int isoburn_disc_pretend_full_uncond(struct burn_drive *drive); + + +/** Tells whether the medium can be treated by isoburn_disc_erase(). + Wrapper for: burn_disc_erasable() + @since 0.1.0 + @param d The drive to inquire. + @return 0=not erasable , else erasable +*/ +int isoburn_disc_erasable(struct burn_drive *d); + + +/** Mark the medium as blank. With multi-session media this will call + burn_disc_erase(). With random access media, an eventual ISO-9660 + filesystem will get invalidated by altering its start blocks on the medium. + In case of success, the medium is in status BURN_DISC_BLANK afterwards. + Wrapper for: burn_disc_erase() + @since 0.1.0 + @param drive The drive with the medium to erase. + @param fast 1=fast erase, 0=thorough erase + With DVD-RW, fast erase yields media incapable of multi-session. +*/ +void isoburn_disc_erase(struct burn_drive *drive, int fast); + + +/** Set up isoburn_disc_get_msc1() to return a fabricated value. + This makes only sense between acquiring the drive and reading the + image. After isoburn_read_image() it will confuse the coordination + of libisoburn and libisofs. + Note: Sessions and tracks are counted beginning with 1, not with 0. + @since 0.1.6 + @param d The drive where msc1 is to be set + @param adr_mode Determines how to interpret adr_value and to set msc1. + If adr_value shall represent a number then decimal ASCII + digits are expected. + 0= start lba of last session in TOC, ignore adr_value + 1= start lba of session number given by adr_value + 2= start lba of track given number by adr_value + 3= adr_value itself is the lba to be used + 4= start lba of last session with volume id + given by adr_value + @param adr_value A string describing the value to be eventually used. + @param flag Bitfield for control purposes. + bit0= @since 0.2.2 + with adr_mode 3: adr_value might be 16 blocks too high + (e.g. -C stemming from growisofs). Probe for ISO head + at adr_value-16 and eventually adjust setting. + bit1= insist in seeing a disc object with at least one session + bit2= with adr_mode 4: use adr_value as regular expression +*/ +int isoburn_set_msc1(struct burn_drive *d, int adr_mode, char *adr_value, + int flag); + + +/* ----------------------------------------------------------------------- */ +/* + + Wrappers for emulation of TOC on overwriteable media + + Media which match the overwriteable usage model lack of a history of sessions + and tracks. libburn will not even hand out a burn_disc object for them and + always declare them blank. libisoburn checks for a valid ISO filesystem + header at LBA 0 and eventually declares them appendable. + Nevertheless one can only determine an upper limit of the size of the overall + image (by isoburn_get_min_start_byte()) but not a list of stored sessions + and their LBAs, as it is possible with true multi-session media. + + The following wrappers add the capability to obtain a session and track TOC + from emulated multi-session images on overwriteables if the first session + was written by libisoburn-0.1.6 or later (i.e. with a header copy at LBA 32). + + Be aware that the structs emitted by these isoburn calls are not compatible + with the libburn structs. I.e. you may use them only with isoburn_toc_* + calls. + isoburn_toc_disc needs to be freed after use. isoburn_toc_session and + isoburn_toc_track vanish together with their isoburn_toc_disc. +*/ + +/* Opaque handles to media, session, track */ +struct isoburn_toc_disc; +struct isoburn_toc_session; +struct isoburn_toc_track; + + +/** Obtain a master handle for the table of content. + This handle governs allocated resources which have to be released by + isoburn_toc_disc_free() when no longer needed. + Wrapper for: burn_drive_get_disc() + @since 0.1.6 + @param d The drive with the medium to inspect + @return NULL in case there is no content info, else it is a valid handle +*/ +struct isoburn_toc_disc *isoburn_toc_drive_get_disc(struct burn_drive *d); + + +/** Tell the number of 2048 byte blocks covered by the table of content. + This number includes the eventual gaps between sessions and tracks. + So this call is not really a wrapper for burn_disc_get_sectors(). + @since 0.1.6 + @param disc The master handle of the medium + @return Number of blocks, <=0 indicates unknown or unreadable state +*/ +int isoburn_toc_disc_get_sectors(struct isoburn_toc_disc *disc); + + +/** Get the array of session handles and the number of complete sessions + from the table of content. + The result array contains *num + isoburn_toc_disc_get_incmpl_sess() + elements. All above *num are incomplete sessions. + Typically there is at most one incomplete session with no track. + Wrapper for: burn_disc_get_sessions() + @since 0.1.6 + @param disc The master handle of the medium + @param num returns the number of sessions in the array + @return the address of the array of session handles +*/ +struct isoburn_toc_session **isoburn_toc_disc_get_sessions( + struct isoburn_toc_disc *disc, int *num); + + +/** Obtain the number of incomplete sessions which are recorded in the + result array of isoburn_toc_disc_get_sessions() after the complete + sessions. See above. + @since 1.2.8 + @param disc The master handle of the medium + @return the number of incomplete sessions +*/ +int isoburn_toc_disc_get_incmpl_sess(struct isoburn_toc_disc *disc); + + +/** Tell the number of 2048 byte blocks covered by a particular session. + Wrapper for: burn_session_get_sectors() + @since 0.1.6 + @param s The session handle + @return number of blocks, <=0 indicates unknown or unreadable state +*/ +int isoburn_toc_session_get_sectors(struct isoburn_toc_session *s); + + +/** Obtain a copy of the entry which describes the end of a particular session. + Wrapper for: burn_session_get_leadout_entry() + @since 0.1.6 + @param s The session handle + @param entry A pointer to memory provided by the caller. It will be filled + with info according to struct burn_toc_entry as defined + in libburn.h +*/ +void isoburn_toc_session_get_leadout_entry(struct isoburn_toc_session *s, + struct burn_toc_entry *entry); + + +/** Get the array of track handles from a particular session. + Wrapper for: burn_session_get_tracks() + @since 0.1.6 + @param s The session handle + @param num returns the number of tracks in the array + @return the address of the array of track handles, + NULL if no tracks are registered with session s +*/ +struct isoburn_toc_track **isoburn_toc_session_get_tracks( + struct isoburn_toc_session *s, int *num); + + +/** Obtain a copy of the entry which describes a particular track. + Wrapper for: burn_track_get_entry() + @since 0.1.6 + @param t The track handle + @param entry A pointer to memory provided by the caller. It will be filled + with info according to struct burn_toc_entry as defined + in libburn.h +*/ +void isoburn_toc_track_get_entry(struct isoburn_toc_track *t, + struct burn_toc_entry *entry); + + +/** Obtain eventual ISO image parameters of an emulated track. This info was + gained with much effort and thus gets cached in the track object. + If this call returns 1 then one can save a call of isoburn_read_iso_head() + with return mode 1 which could cause an expensive read operation. + @since 0.4.0 + @param t The track handle + @param start_lba Returns the start address of the ISO session + @param image_blocks Returns the number of 2048 bytes blocks + @param volid Caller provided memory for the volume id + @param flag unused yet, submit 0 + @return 0= not an emulated ISO session , 1= reply is valid +*/ +int isoburn_toc_track_get_emul(struct isoburn_toc_track *t, int *start_lba, + int *image_blocks, char volid[33], int flag); + + + +/** Release the memory associated with a master handle of a medium. + The handle is invalid afterwards and may not be used any more. + Wrapper for: burn_disc_free() + @since 0.1.6 + @param disc The master handle of the medium +*/ +void isoburn_toc_disc_free(struct isoburn_toc_disc *disc); + + +/** Try whether the data at the given address look like a ISO 9660 + image header and obtain its alleged size. Depending on the info mode + one other string of text information can be retrieved too. + @since 0.1.6 + @param d The drive with the medium to inspect + @param lba The block number from where to read + @param image_blocks Returns the number of 2048 bytes blocks in the session + @param info Caller provided memory, enough to take eventual info reply + @param flag bit0-7: info return mode + 0= do not return anything in info (do not even touch it) + 1= copy volume id to info (info needs 33 bytes) + 2= @since 0.2.2 : + copy 64 kB header to info (needs 65536 bytes) + bit13= @since 0.2.2: + Do not read head from medium but use first 64 kB from + info. + In this case it is permissible to submit d == NULL. + bit14= check both half buffers (not only second) + return 2 if found in first block + bit15= return -1 on read error + @return >0 seems to be a valid ISO image, 0 format not recognized, <0 error +*/ +int isoburn_read_iso_head(struct burn_drive *d, int lba, + int *image_blocks, char *info, int flag); + + +/** Try to convert the given entity address into various entity addresses + which would describe it. + Note: Sessions and tracks are counted beginning with 1, not with 0. + @since 0.3.2 + @param d The drive where msc1 is to be set + @param adr_mode Determines how to interpret the input adr_value. + If adr_value shall represent a number then decimal ASCII + digits are expected. + 0= start lba of last session in TOC, ignore adr_value + 1= start lba of session number given by adr_value + 2= start lba of track given number by adr_value + 3= adr_value itself is the lba to be used + 4= start lba of last session with volume id + given by adr_value + @param adr_value A string describing the value to be eventually used. + @param lba returns the block address of the entity, -1 means invalid + @param track returns the track number of the entity, -1 means invalid + @param session returns the session number of the entity, -1 means invalid + @param volid returns the volume id of the entity if it is a ISO session + @param flag Bitfield for control purposes. + bit2= with adr_mode 4: use adr_value as regular expression + @return <=0 error , 1 ok, ISO session, 2 ok, not an ISO session +*/ +int isoburn_get_mount_params(struct burn_drive *d, + int adr_mode, char *adr_value, + int *lba, int *track, int *session, + char volid[33], int flag); + + +/* ----------------------------------------------------------------------- */ +/* + + Options for image reading. + + An application shall create an option set object by isoburn_ropt_new(), + program it by isoburn_ropt_set_*(), use it with isoburn_read_image(), + and finally delete it by isoburn_ropt_destroy(). + +*/ +/* ----------------------------------------------------------------------- */ + +struct isoburn_read_opts; + +/** Produces a set of image read options, initialized with default values. + @since 0.1.0 + @param o the newly created option set object + @param flag Bitfield for control purposes. Submit 0 for now. + @return 1=ok , <0 = failure +*/ +int isoburn_ropt_new(struct isoburn_read_opts **o, int flag); + + +/** Deletes an option set which was created by isoburn_ropt_new(). + @since 0.1.0 + @param o The option set to work on + @param flag Bitfield for control purposes. Submit 0 for now. + @return 1= **o destroyed , 0= *o was already NULL (harmless) +*/ +int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag); + +/** Sets the size and granularity of the cache which libisoburn provides to + libisofs for reading of ISO image data. This cache consists of several + tiles which are buffers of a given size. The ISO image is divided into + virtual tiles of that size. A cache tile may hold an in-memory copy + of such a virtual image tile. + When libisofs requests to read a block, then first the cache is inquired + whether it holds that block. If not, then the block is read via libburn + together with its neighbors in their virtual image tile into a free + cache tile. If no cache tile is free, then the one will be re-used which + has the longest time of not being hit by a read attempt. + + A larger cache might speed up image loading by reducing the number of + libburn read calls on the directory tree. It might also help with + reading the content of many small files, if for some reason it is not an + option to sort access by LBA. + Caching will not provide much benefit with libburn "stdio:" drives, + because the operating system is supposed to provide the same speed-up + in a more flexible way. + + @since 1.2.2 + @param o The option set to work on. + It is permissible to submit NULL in order to just + have the parameters tested. + @param cache_tiles Number of tiles in the cache. Not less than 1. + Default is 32. + @param tile_blocks Number of blocks per tile. Must be a power of 2. + Default is 32. + cache_tiles * tile_blocks * 2048 must not exceed + 1073741824 (= 1 GiB). + @param flag Bitfield for control purposes. Unused yet. Submit 0. + @return <=0 error , >0 ok +*/ +int isoburn_ropt_set_data_cache(struct isoburn_read_opts *o, + int cache_tiles, int tile_blocks, int flag); + +/** Inquire the current settings of isoburn_set_data_cache(). + @since 1.2.2 + @param o The option set to work on. + NULL has the same effect as flag bit0. + @param cache_tiles Will return the number of tiles in the cache. + @param tile_blocks Will return the number of blocks per tile. + @param set_flag Will return control bits. None are defined yet. + @param flag Bitfield for control purposes + bit0= return default values rather than current ones + @return <=0 error , >0 reply is valid +*/ +int isoburn_ropt_get_data_cache(struct isoburn_read_opts *o, + int *cache_tiles, int *tile_blocks, + int *set_flag, int flag); + + +/** Which existing ISO 9660 extensions in the image to read or not to read. + Whether to read the content of an existing image at all. + The bits can be combined by | and inquired by &. + @since 0.1.0 + @param ext Bitfield: + bit0= norock + Do not read Rock Ridge extensions + bit1= nojoliet + Do not read Joliet extensions + bit2= noiso1999 + Do not read ISO 9660:1999 enhanced tree + bit3= preferjoliet + When both Joliet and RR extensions are present, the RR + tree is used. If you prefer using Joliet, set this to 1. + bit4= pretend_blank + Always create empty image.Ignore any image on input drive. + bit5= noaaip + @since 0.3.4 + Do not load AAIP information from image. This information + eventually contains ACL or XFS-style Extended Attributes. + bit6= noacl + @since 0.3.4 + Do not obtain ACL from external filesystem objects (e.g. + local filesystem files). + bit7= noea + @since 0.3.4 + Do not obtain XFS-style Extended Attributes from external + filesystem objects (e.g. local filesystem files). + bit8= noino + @since 0.4.0 + Do not load eventual inode numbers from RRIP entry PX, + but generate a new unique inode number for each imported + IsoNode object. + PX inode numbers mark families of hardlinks by giving all + family members the same inode number. libisofs keeps the + PX inode numbers unaltered when IsoNode objects get + written into an ISO image. + bit9= nomd5 + @since 0.4.2 + Do not load the eventual MD5 checksum array. + Do not check eventual session_md5 tags. + bit10= nomd5tag + @since 1.0.4 + Do not check eventual session_md5 tags although bit9 + is not set. + bit11= do_ecma119_map + @since 1.4.2 + Set iso_read_opts_set_ecma119_map() to map_mode rather + than relying on the default setting of libisofs. + bit12 - bit13= map_mode + @since 1.4.2 + How to convert file names if neither Rock Ridge nor + Joliet names are present and acceptable. + 0 = unmapped: Take name as recorded in ECMA-119 directory + record (not suitable for writing them to + a new ISO filesystem) + 1 = stripped: Like unmapped, but strip off trailing ";1" + or ".;1" + 2 = uppercase: Like stripped, but map {a-z} to {A-Z} + 3 = lowercase: Like stripped, but map {A-Z} to {a-z} + @return 1 success, <=0 failure +*/ +#define isoburn_ropt_norock 1 +#define isoburn_ropt_nojoliet 2 +#define isoburn_ropt_noiso1999 4 +#define isoburn_ropt_preferjoliet 8 +#define isoburn_ropt_pretend_blank 16 +#define isoburn_ropt_noaaip 32 +#define isoburn_ropt_noacl 64 +#define isoburn_ropt_noea 128 +#define isoburn_ropt_noino 256 +#define isoburn_ropt_nomd5 512 +#define isoburn_ropt_nomd5tag 1024 +#define isoburn_ropt_map_unmapped ( 2048 | 0 ) +#define isoburn_ropt_map_stripped ( 2048 | 4096 ) +#define isoburn_ropt_map_uppercase ( 2048 | 8192 ) +#define isoburn_ropt_map_lowercase ( 2048 | 12288 ) + +int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext); +int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext); + + +/** Default attributes to use if no RockRidge extension gets loaded. + @since 0.1.0 + @param o The option set to work on + @param uid user id number (see /etc/passwd) + @param gid group id number (see /etc/group) + @param mode permissions (not file type) as of man 2 stat. + With directories, r-permissions will automatically imply + x-permissions. See isoburn_ropt_set_default_dirperms() below. + @return 1 success, <=0 failure +*/ +int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o, + uid_t uid, gid_t gid, mode_t mode); +int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o, + uid_t *uid, gid_t *gid, mode_t *mode); + +/** Default attributes to use on directories if no RockRidge extension + gets loaded. + Above call isoburn_ropt_set_default_perms() automatically adds + x-permissions to r-permissions for directories. This call here may + be done afterwards to set independend permissions for directories, + especially to override the automatically added x-permissions. + @since 0.1.0 + @param o The option set to work on + @param mode permissions (not file type) as of man 2 stat. + @return 1 success, <=0 failure +*/ +int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o, + mode_t mode); +int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o, + mode_t *mode); + + +/** Set the character set for reading RR file names from ISO images. + @since 0.1.0 + @param o The option set to work on + @param input_charset Set this to NULL to use the default locale charset + For selecting a particular character set, submit its + name, e.g. as listed by program iconv -l. + Example: "UTF-8". + @return 1 success, <=0 failure +*/ +int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o, + char *input_charset); +int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o, + char **input_charset); + + +/** + Enable or disable methods to automatically choose an input charset. + This eventually overrides the name set via isoburn_ropt_set_input_charset() + @since 0.3.8 + @param o The option set to work on + @param mode Bitfield for control purposes: + bit0= set the input character set automatically from + attribute "isofs.cs" of root directory. + Submit any other bits with value 0. + @return 1 success, <=0 failure + */ +int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode); +int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode); + + +/** Control an offset to be applied to all block address pointers in the ISO + image in order to compensate for an eventual displacement of the image + relative to the start block address for which it was produced. + E.g. if track number 2 from CD gets copied into a disk file and shall then + be loaded as ISO filesystem, then the directory tree and all data file + content of the track copy will become readable by setting the track start + address as displacement and -1 as displacement_sign. + Data file content outside the track will of course not be accessible and + eventually produce read errors. + @since 0.6.6 + @param o The option set to work on + @param displacement 0 or a positive number + @param displacement_sign Determines wether to add or subtract displacement + to block addresses before applying them to the + storage object for reading: + +1 = add , -1= subtract , else keep unaltered +*/ +int isoburn_ropt_set_displacement(struct isoburn_read_opts *o, + uint32_t displacement, int displacement_sign); +int isoburn_ropt_get_displacement(struct isoburn_read_opts *o, + uint32_t *displacement, int *displacement_sign); + +/* If you get here because of a compilation error like + + /usr/include/libisoburn/libisoburn.h:895: error: + expected declaration specifiers or '...' before 'uint32_t' + + then see above paragraph "Application Constraints" about the definition + of uint32_t. +*/ + +/** Set the name truncation mode and the maximum name length for imported + file objects. + @since 1.4.2 + @param o The option set to work on + @param mode 0= Do not truncate but throw error + ISO_RR_NAME_TOO_LONG if a file name + is longer than parameter length. + 1= Truncate to length and overwrite the last + 32 bytes of that length by the hex + representation of ithe MD5 of the whole + oversized name. + Potential incomplete UTF-8 characters will + get their leading bytes replaced by '_'. + This is the default. + @param length Maximum byte count of a file name. Permissible + values are 64 to 255. Default is 255. + +*/ +int isoburn_ropt_set_truncate_mode(struct isoburn_read_opts *o, + int mode, int length); +int isoburn_ropt_get_truncate_mode(struct isoburn_read_opts *o, + int *mode, int *length); + + +/** After calling function isoburn_read_image() there are informations + available in the option set. + This info can be obtained as bits in parameter has_what. Like: + joliet_available = (has_what & isoburn_ropt_has_joliet); + @since 0.1.0 + @param o The option set to work on + @param size Number of image data blocks, 2048 bytes each. + @param has_what Bitfield: + bit0= has_rockridge + RockRidge extension info is available (POSIX filesystem) + bit1= has_joliet + Joliet extension info is available (suitable for MS-Windows) + bit2= has_iso1999 + ISO version 2 Enhanced Volume Descriptor is available. + This is rather exotic. + bit3= has_el_torito + El-Torito boot record is present + @return 1 success, <=0 failure +*/ +#define isoburn_ropt_has_rockridge 1 +#define isoburn_ropt_has_joliet 2 +#define isoburn_ropt_has_iso1999 4 +#define isoburn_ropt_has_el_torito 8 + +int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, + uint32_t *size, int *has_what); + +/* ts A90122 */ +/* >>> to be implemented: +#define isoburn_ropt_has_acl 64 +#define isoburn_ropt_has_ea 128 +*/ + + + +/* ----------------------------------------------------------------------- */ +/* End of Options for image reading */ +/* ----------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- */ +/* + + Options for image generation by libisofs and image transport to libburn. + + An application shall create an option set by isoburn_igopt_new(), + program it by isoburn_igopt_set_*(), use it with either + isoburn_prepare_new_image() or isoburn_prepare_disc(), and finally delete + it by isoburn_igopt_destroy(). + +*/ +/* ----------------------------------------------------------------------- */ + +struct isoburn_imgen_opts; + +/** Produces a set of generation and transfer options, initialized with default + values. + @since 0.1.0 + @param o the newly created option set object + @param flag Bitfield for control purposes. Submit 0 for now. + @return 1=ok , <0 = failure +*/ +int isoburn_igopt_new(struct isoburn_imgen_opts **o, int flag); + + +/** Deletes an option set which was created by isoburn_igopt_new(). + @since 0.1.0 + @param o The option set to give up + @param flag Bitfield for control purposes. Submit 0 for now. + @return 1= **o destroyed , 0= *o was already NULL (harmless) +*/ +int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag); + + +/** ISO level to write at. + @since 0.1.0 + @param o The option set to work on + @param level is a term of the ISO 9660 standard. It should be one of: + 1= filenames restricted to form 8.3 + 2= filenames allowed up to 31 characters + 3= file content may be larger than 4 GB - 1. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level); +int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level); + + +/** Which extensions to support. + @since 0.1.0 + @param o The option set to work on + @param ext Bitfield: + bit0= rockridge + Rock Ridge extensions add POSIX file attributes like + owner, group, access permissions, long filenames. Very + advisable if the designed audience has Unix style systems. + bit1= joliet + Longer filenames for Windows systems. + Weaker than RockRidge, but also readable with GNU/Linux. + bit2= iso1999 + This is rather exotic. Better do not surprise the readers. + bit3= hardlinks + Enable hardlink consolidation. IsoNodes which refer to the + same source object and have the same properties will get + the same ISO image inode numbers. + If combined with isoburn_igopt_rrip_version_1_10 below, + then the PX entry layout of RRIP-1.12 will be used within + RRIP-1.10 (mkisofs does this without causing visible trouble). + bit5= aaip + The libisofs specific SUSP based extension of ECMA-119 which + can encode ACL and XFS-style Extended Attributes. + bit6= session_md5 + @since 0.4.2 + Produce and write MD5 checksum tags of superblock, directory + tree, and the whole session stream. + bit7= file_md5 + @since 0.4.2 + Produce and write MD5 checksums for each single IsoFile. + bit8= file_stability (only together with file_md5) + @since 0.4.2 + Compute MD5 of each file before copying it into the image and + compare this with the MD5 of the actual copying. If they do + not match then issue MISHAP event. + See also libisofs.h iso_write_opts_set_record_md5() + bit9= no_emul_toc + @since 0.5.8 + On overwriteable media or random access files do not write + the first session to LBA 32 and do not copy the first 64kB + of the first session to LBA 0, but rather write the first + session to LBA 0 directly. + bit10= will_cancel + @since 0.6.6 + Announce to libisofs that only the image size is desired + and that the write thread will be cancelled by + isoburn_cancel_prepared_write() before actual image writing + occurs. Without this, cancellation can cause a MISHAP event. + bit11= old_empty + @since 1.0.2 + Let symbolic links and device files point to block 0, and let + empty data files point to the address of the Volume Descriptor + Set Terminator. This was done by libisofs in the past. + By default there is now a single dedicated block of zero bytes + after the end of the directory trees, of which the address + is used for all files without own content. + bit12= hfsplus + @since 1.2.4 + Produce a HFS+ partition inside the ISO image and announce it + by an Apple Partition Map in the System Area. + >>> GPT production ? + Caution: Interferes with isoburn_igopt_set_system_area() by + overwriting the first 8 bytes of the data, and + several blocks of 2 KiB after the first one. + bit13= fat + @since 1.2.4 + >>> Not yet implemented. Planned to co-exist with hfsplus. + Produce a FAT32 partition inside the ISO image and announce it + by an MBR partition entry in the System Area. + Caution: Interferes with isoburn_igopt_set_system_area() by + >>> what impact ? + + @return 1 success, <=0 failure +*/ +#define isoburn_igopt_rockridge 1 +#define isoburn_igopt_joliet 2 +#define isoburn_igopt_iso1999 4 +#define isoburn_igopt_hardlinks 8 +#define isoburn_igopt_aaip 32 +#define isoburn_igopt_session_md5 64 +#define isoburn_igopt_file_md5 128 +#define isoburn_igopt_file_stability 256 +#define isoburn_igopt_no_emul_toc 512 +#define isoburn_igopt_will_cancel 1024 +#define isoburn_igopt_old_empty 2048 +#define isoburn_igopt_hfsplus 4096 +#define isoburn_igopt_fat 8192 +int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext); +int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext); + +/** Relaxed constraints. Setting any of the bits to 1 break the specifications, + but it is supposed to work on most moderns systems. Use with caution. + @since 0.1.0 + @param o The option set to work on + @param relax Bitfield: + bit0= omit_version_numbers + Omit the version number (";1") at the end of the + ISO-9660 and Joliet identifiers. + Version numbers are usually not used by readers. + bit1= allow_deep_paths + Allow ISO-9660 directory hierarchy to be deeper + than 8 levels. + bit2= allow_longer_paths + Allow path in the ISO-9660 tree to have more than + 255 characters. + bit3= max_37_char_filenames + Allow a single file or directory hierarchy to have + up to 37 characters. This is larger than the 31 + characters allowed by ISO level 2, and the extra space + is taken from the version number, so this also forces + omit_version_numbers. + bit4= no_force_dots + ISO-9660 forces filenames to have a ".", that separates + file name from extension. libisofs adds it if original + filename has none. Set this to 1 to prevent this + behavior. + bit5= allow_lowercase + Allow lowercase characters in ISO-9660 filenames. + By default, only uppercase characters, numbers and + a few other characters are allowed. + bit6= allow_full_ascii + Allow all ASCII characters to be appear on an ISO-9660 + filename. Note that "/" and "\0" characters are never + allowed, even in RR names. + bit7= joliet_longer_paths + Allow paths in the Joliet tree to have more than + 240 characters. + bit8= always_gmt + Write timestamps as GMT although the specs prescribe local + time with eventual non-zero timezone offset. Negative + timezones (west of GMT) can trigger bugs in some operating + systems which typically appear in mounted ISO images as if + the timezone shift from GMT was applied twice + (e.g. in New York 22:36 becomes 17:36). + bit9= rrip_version_1_10 + Write Rock Ridge info as of specification RRIP-1.10 rather + than RRIP-1.12: signature "RRIP_1991A" rather than + "IEEE_1282", field PX without file serial number. + bit10= dir_rec_mtime + Store as ECMA-119 Directory Record timestamp the mtime + of the source rather than the image creation time. + bit11= aaip_susp_1_10 + Write AAIP fields without announcing AAIP by an ER field and + without distinguishing RRIP fields from the AAIP field by + prefixed ES fields. This saves 5 to 10 bytes per file and + might avoid problems with readers which only accept RRIP. + SUSP-1.10 allows it, SUSP-1.12 frowns on it. + bit12= only_iso_numbers + Same as bit1 omit_version_number but restricted to the names + in the eventual Joliet tree. + @since 0.5.4 + For reasons of backward compatibility it is not possible yet + to disable version numbers for ISO 9660 while enabling them + for Joliet. + bit13= no_j_force_dots + Same as no_force_dots but affecting the names in the eventual + Joliet tree rather than the ISO 9660 / ECMA-119 names. + @since 0.5.4 + Previous versions added dots to Joliet names unconditionally. + bit14= allow_dir_id_ext + Convert directory names for ECMA-119 similar to other file + names, but do not force a dot or add a version number. + This violates ECMA-119 by allowing one "." and especially + ISO level 1 by allowing DOS style 8.3 names rather than + only 8 characters. + (mkisofs and its clones obviously do this violation.) + @since 1.0.0 + bit15= joliet_long_names + Allow for Joliet leaf names up to 103 characters rather than + up to 64. + @since 1.0.6 + bit16= joliet_rec_mtime + Like dir_rec_mtime, but for the Joliet tree. + @since 1.2.0 + bit17= iso1999_rec_mtime + Like dir_rec_mtime, but for the ISO 9660:1999 tree. + @since 1.2.0 + bit18= allow_7bit_ascii + Like allow_full_ascii, but only allowing 7-bit characters. + Lowercase letters get mapped to uppercase if not + allow_lowercase is set. + Gets overridden if allow_full_ascii is enabled. + bit19= joliet_utf16 + Encode Joliet names by character set UTF-16BE rather than + UCS-2. The difference is with characters which are not present + in UCS-2 and get encoded in UTF-16 by 2 words of 16 bit each. + Both words then stem from a reserved subset of UCS-2. + @since 1.3.6 + @return 1 success, <=0 failure +*/ +#define isoburn_igopt_omit_version_numbers 1 +#define isoburn_igopt_allow_deep_paths 2 +#define isoburn_igopt_allow_longer_paths 4 +#define isoburn_igopt_max_37_char_filenames 8 +#define isoburn_igopt_no_force_dots 16 +#define isoburn_igopt_allow_lowercase 32 +#define isoburn_igopt_allow_full_ascii 64 +#define isoburn_igopt_joliet_longer_paths 128 +#define isoburn_igopt_always_gmt 256 +#define isoburn_igopt_rrip_version_1_10 512 +#define isoburn_igopt_dir_rec_mtime 1024 +#define isoburn_igopt_aaip_susp_1_10 2048 +#define isoburn_igopt_only_iso_versions 4096 +#define isoburn_igopt_no_j_force_dots 8192 +#define isoburn_igopt_allow_dir_id_ext 16384 +#define isoburn_igopt_joliet_long_names 32768 +#define isoburn_igopt_joliet_rec_mtime 0x10000 +#define isoburn_igopt_iso1999_rec_mtime 0x20000 +#define isoburn_igopt_allow_7bit_ascii 0x40000 +#define isoburn_igopt_joliet_utf16 0x80000 +int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax); +int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax); + + +/** If not isoburn_igopt_allow_deep_paths is in effect, then it may become + necessary to relocate directories so that no ECMA-119 file path + has more than 8 components. These directories are grafted into either + the root directory of the ISO image or into a dedicated relocation + directory. For details see libisofs.h. + Wrapper for: iso_write_opts_set_rr_reloc() + @since 1.2.2 + @param o The option set to work on + @param name The name of the relocation directory in the root directory. + Do not prepend "/". An empty name or NULL will direct + relocated directories into the root directory. This is the + default. + If the given name does not exist in the root directory when + isoburn_disc_write() is called, and if there are directories + at path level 8, then directory /name will be created + automatically. + @param flags Bitfield for control purposes. + bit0= Mark the relocation directory by a Rock Ridge RE entry, + if it gets created during isoburn_disc_write(). This + will make it invisible for most Rock Ridge readers. + bit1= not settable via API (used internally) + @return > 0 success, <= 0 failure +*/ +int isoburn_igopt_set_rr_reloc(struct isoburn_imgen_opts *o, char *name, + int flags); + +/** Obtain the settings of isoburn_igopt_set_rr_reloc(). + @since 1.2.2 + @param o The option set to work on + @param name Will return NULL or a pointer to the name of the relocation + directory in the root directory. Do not alter or dispose the + memory which holds this name. + @param flags Will return the flags bitfield. + @return > 0 success, <= 0 failure +*/ +int isoburn_igopt_get_rr_reloc(struct isoburn_imgen_opts *o, char **name, + int *flags); + + +/** Caution: This option breaks any assumptions about names that + are supported by ECMA-119 specifications. + Try to omit any translation which would make a file name compliant to the + ECMA-119 rules. This includes and exceeds omit_version_numbers, + max_37_char_filenames, no_force_dots bit0, allow_full_ascii. Further it + prevents the conversion from local character set to ASCII. + The maximum name length is given by this call. If a filename exceeds + this length or cannot be recorded untranslated for other reasons, then + image production gets aborted. + Currently the length limit is 96 characters, because an ECMA-119 directory + record may at most have 254 bytes and up to 158 other bytes must fit into + the record. Probably 96 more bytes can be made free for the name in future. + @since 1.0.0 + @param o The option set to work on + @param len 0 = disable this feature and perform name translation + according to other settings. + >0 = Omit any translation. Eventually abort image production + if a name is longer than the given value. + -1 = Like >0. Allow maximum possible length. + isoburn_igopt_get_untranslated_name_len() will tell the + effectively resulting value. + @return >0 success, <=0 failure +*/ +int isoburn_igopt_set_untranslated_name_len(struct isoburn_imgen_opts *o, + int len); +int isoburn_igopt_get_untranslated_name_len(struct isoburn_imgen_opts *o, + int *len); + + +/** Whether and how files should be sorted. + @since 0.1.0 + @param o The option set to work on + @param value Bitfield: bit0= sort_files_by_weight + files should be sorted based on their weight. + Weight is attributed to files in the image + by libisofs call iso_node_set_sort_weight(). + @return 1 success, <=0 failure +*/ +#define isoburn_igopt_sort_files_by_weight 1 +int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value); +int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value); + + +/** Set the override values for files and directory permissions. + The parameters replace_* these take one of three values: 0, 1 or 2. + If 0, the corresponding attribute will be kept as set in the IsoNode + at the time of image generation. + If set to 1, the corresponding attrib. will be changed by a default + suitable value. + With value 2, the attrib. will be changed with the value specified + in the corresponding *_mode options. Note that only the permissions + are set, the file type remains unchanged. + @since 0.1.0 + @param o The option set to work on + @param replace_dir_mode whether and how to override directories + @param replace_file_mode whether and how to override files of other type + @param dir_mode Mode to use on dirs with replace_dir_mode == 2. + @param file_mode; Mode to use on files with replace_file_mode == 2. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o, + int replace_dir_mode, int replace_file_mode, + mode_t dir_mode, mode_t file_mode); +int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o, + int *replace_dir_mode, int *replace_file_mode, + mode_t *dir_mode, mode_t *file_mode); + +/** Set the override values values for group id and user id. + The rules are like with above overriding of mode values. replace_* controls + whether and how. The other two parameters provide values for eventual use. + @since 0.1.0 + @param o The option set to work on + @param replace_uid whether and how to override user ids + @param replace_gid whether and how to override group ids + @param uid User id to use with replace_uid == 2. + @param gid Group id to use on files with replace_gid == 2. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o, + int replace_uid, int replace_gid, + uid_t uid, gid_t gid); +int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o, + int *replace_uid, int *replace_gid, + uid_t *uid, gid_t *gid); + +/** Set the charcter set to use for representing RR filenames in the image. + @since 0.1.0 + @param o The option set to work on + @param output_charset Set this to NULL to use the default output charset. + For selecting a particular character set, submit its + name, e.g. as listed by program iconv -l. + Example: "UTF-8". + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o, + char *output_charset); +int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o, + char **output_charset); + + +/** The number of bytes to be used for the fifo which decouples libisofs + and libburn for better throughput and for reducing the risk of + interrupting signals hitting the libburn thread which operates the + MMC drive. + The size will be rounded up to the next full 2048. + Minimum is 64kiB, maximum is 1 GiB (but that is too much anyway). + @since 0.1.0 + @param o The option set to work on + @param fifo_size Number of bytes to use + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size); +int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size); + + +/** Obtain after image preparation the block address where the session will + start on the medium. + This value cannot be set by the application but only be inquired. + @since 0.1.4 + @param o The option set to work on + @param lba The block number of the session start on the medium. + <0 means that no address has been determined yet. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba); + + +/** Obtain after image preparation the lowest block address of file content + data. Failure can occur if libisofs is too old to provide this information, + if the result exceeds 31 bit, or if the call is made before image + preparation. + This value cannot be set by the application but only be inquired. + @since 0.3.6 + @param o The option set to work on + @param lba The block number of the session start on the medium. + <0 means that no address has been determined yet. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_get_data_start(struct isoburn_imgen_opts *o, int *lba); + + +/** Set or get parameters "name" and "timestamp" for a scdbackup checksum + tag. It will be appended to the libisofs session tag if the image starts at + LBA 0. See isoburn_disc_track_lba_nwa. The scdbackup tag can be used + to verify the image by command scdbackup_verify $device -auto_end. + See scdbackup/README appendix VERIFY for its inner details. + @since 0.4.4 + @param o The option set to work on + @param name The tag name. 80 characters max. + An empty name disables production of an scdbackup tag. + @param timestamp A string of up to 13 characters YYMMDD.hhmmss + A9 = 2009, B0 = 2010, B1 = 2011, ... C0 = 2020, ... + @param tag_written Either NULL or the address of an array with at least 512 + characters. In the latter case the eventually produced + scdbackup tag will be copied to this array when the image + gets written. This call sets scdbackup_tag_written[0] = 0 + to mark its preliminary invalidity. + @return 1 success, <=0 failure + */ +int isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts *o, char *name, + char *timestamp, char *tag_written); +int isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts *o, + char name[81], char timestamp[19], + char **tag_written); + + +/** Attach 32 kB of binary data which shall get written to the first 32 kB + of the ISO image, the System Area. + options can cause manipulations of these data before writing happens. + If system area data are giveni or options bit0 is set, then bit1 of + el_torito_set_isolinux_options() is automatically disabled. + @since 0.5.4 + @param o The option set to work on + @param data Either NULL or 32 kB of data. Do not submit less bytes ! + @param options Can cause manipulations of submitted data before they + get written: + bit0= apply a --protective-msdos-label as of grub-mkisofs. + This means to patch bytes 446 to 512 of the system + area so that one partition is defined which begins + at the second 512-byte block of the image and ends + where the image ends. + This works with and without system_area_data. + bit1= apply isohybrid MBR patching to the system area. + This works only with system area data from + SYSLINUX plus an ISOLINUX boot image (see + iso_image_set_boot_image()) and only if not bit0 + is set. + bit2-7= System area type + 0= with bit0 or bit1: MBR + else: unspecified type + @since 0.6.4 + 1= MIPS Big Endian Volume Header + Submit up to 15 MIPS Big Endian boot files by + iso_image_add_mips_boot_file() of libisofs. + This will overwrite the first 512 bytes of + the submitted data. + 2= DEC Boot Block for MIPS Little Endian + The first boot file submitted by + iso_image_add_mips_boot_file() will be activated. + This will overwrite the first 512 bytes of + the submitted data. + @since 0.6.6 + 3= SUN Disk Label for SUN SPARC + Submit up to 7 SPARC boot images by + isoburn_igopt_set_partition_img() for partition + numbers 2 to 8. + This will overwrite the first 512 bytes of + the submitted data. + @since 1.3.8 + 4= HP-PA PALO boot sector header version 4 + Submit all five parameters of + iso_image_set_hppa_palo() as non-NULL texts. + 5= HP-PA PALO boot sector header version 5 + Submit all five parameters of + iso_image_set_hppa_palo() as non-NULL texts. + bit8-9= Only with System area type 0 = MBR + @since 1.0.4 + Cylinder alignment mode eventually pads the image + to make it end at a cylinder boundary. + 0 = auto (align if bit1) + 1 = always align to cylinder boundary + 2 = never align to cylinder boundary + bit10-13= System area sub type + @since 1.2.4 + With type 0 = MBR: + Gets overridden by bit0 and bit1. + 0 = no particular sub type + 1 = CHRP: A single MBR partition of type 0x96 + covers the ISO image. Not compatible with + any other feature which needs to have own + MBR partition entries. + bit14= Only with System area type 0 = MBR + GRUB2 boot provisions: + @since 1.3.0 + Patch system area at byte 0x1b0 to 0x1b7 with + (512-block address + 4) of the first boot image file. + Little-endian 8-byte. + Should be combined with options bit0. + Will not be in effect if options bit1 is set. + @return 1 success, 0 no data to get, <0 failure +*/ +int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *o, + char data[32768], int options); +int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *o, + char data[32768], int *options); + +/** Control production of a second set of volume descriptors (superblock) + and directory trees, together with a partition table in the MBR where the + first partition has non-zero start address and the others are zeroed. + The first partition stretches to the end of the whole ISO image. + The additional volume descriptor set and trees can be used to mount the + ISO image at the start of the first partition, while it is still possible + to mount it via the normal first volume descriptor set and tree at the + start of the image or storage device. + This makes few sense on optical media. But on USB sticks it creates a + conventional partition table which makes it mountable on e.g. Linux via + /dev/sdb and /dev/sdb1 alike. + @since 0.6.2 + @param opts + The option set to be manipulated. + @param block_offset_2k + The offset of the partition start relative to device start. + This is counted in 2 kB blocks. The partition table will show the + according number of 512 byte sectors. + Default is 0 which causes no second set and trees. + If it is not 0 then it must not be smaller than 16. + @param secs_512_per_head + Number of 512 byte sectors per head. 1 to 63. 0=automatic. + @param heads_per_cyl + Number of heads per cylinder. 1 to 255. 0=automatic. + @return 1 success, <=0 failure + */ +int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, int heads_per_cyl); +int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts, + uint32_t *block_offset_2k, + int *secs_512_per_head, int *heads_per_cyl); + + +/** Explicitly set the four timestamps of the emerging ISO image. + Default with all parameters is 0. + @since 0.5.4 + @param opts + The option set to work on + @param creation_time + ECMA-119 Volume Creation Date and Time + When "the information in the volume was created." + A value of 0 means that the timepoint of write start is to be used. + @param modification_time + ECMA-119 Volume Modification Date and Time + When "the informationin the volume was last modified." + A value of 0 means that the timepoint of write start is to be used. + @param expiration_time + ECMA-119 Volume Expiration Date and Time + When "the information in the volume may be regarded as obsolete." + A value of 0 means that the information never shall expire. + @param effective_time + ECMA-119 Volume Effective Date and Time + When "the information in the volume may be used." + A value of 0 means that not such retention is intended. + @param uuid + If this text is not empty, then it overrides vol_modification_time + by copying the first 16 decimal digits from uuid, eventually + padding up with decimal '1', and writing a NUL-byte as timezone GMT. + It should express a reasonable time in form YYYYMMDDhhmmsscc + E.g.: 2010040711405800 = 7 Apr 2010 11:40:58 (+0 centiseconds) + @return 1 success, <=0 failure + */ +int isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts *opts, + time_t creation_time, time_t modification_time, + time_t expiration_time, time_t effective_time, + char *uuid); +int isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts *opts, + time_t *creation_time, time_t *modification_time, + time_t *expiration_time, time_t *effective_time, + char uuid[17]); + + +/** Associate a libjte environment object to the upcoming write run. + libjte implements Jigdo Template Extraction as of Steve McIntyre and + Richard Atterer. + A non-NULL libjte_handle will cause failure to write if libjte was not + enabled in libisofs at compile time. + @since 0.6.4 + @param opts + The option set to work on + @param libjte_handle + Pointer to a struct libjte_env e.g. created by libjte_new(). + It must stay existent from the start of image writing by + isoburn_prepare_*() until the write thread has ended. + E.g. until libburn indicates the end of its write run. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_attach_jte(struct isoburn_imgen_opts *opts, + void *libjte_handle); + +/** Remove eventual association to a libjte environment handle. + @since 0.6.4 + @param opts + The option set to work on + @param libjte_handle + If not submitted as NULL, this will return the previously set + libjte handle. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_detach_jte(struct isoburn_imgen_opts *opts, + void **libjte_handle); + + +/** Set or get the number of trailing zero byte blocks to be written by + libisofs. The image size counter of the emerging ISO image will include + them. Eventual checksums will take them into respect. + They will be written immediately before the eventual image checksum area + which is at the very end of the image. + For a motivation see iso_write_opts_set_tail_blocks() in libisofs.h . + @since 0.6.4 + @param opts + The option set to work on + @param num_blocks + Number of extra 2 kB blocks to be written by libisofs. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_tail_blocks(struct isoburn_imgen_opts *opts, + uint32_t num_blocks); +int isoburn_igopt_get_tail_blocks(struct isoburn_imgen_opts *opts, + uint32_t *num_blocks); + + +/** Copy a data file from the local filesystem into the emerging ISO image. + Mark it by an MBR partition entry as PreP partition and also cause + protective MBR partition entries before and after this partition. + See libisofs.h iso_write_opts_set_prep_img(). + @since 1.2.4 + @param opts + The option set to be manipulated. + @param path + File address in the local file system. + @param flag + With isoburn_igopt_set_prep_partition(): + Control bits as of iso_write_opts_set_efi_bootp() + bit0= The path contains instructions for the interval libisofs + reader. See libisofs.h. + @since 1.4.0 + With isoburn_igopt_get_prep_partition(): + bit0= add the current flag setting & 0x3fffffff to return value 1. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_prep_partition(struct isoburn_imgen_opts *opts, + char *path, int flag); +int isoburn_igopt_get_prep_partition(struct isoburn_imgen_opts *opts, + char **path, int flag); + +/** Copy a data file from the local filesystem into the emerging ISO image + and mark it by a GPT entry as EFI system partition. + @since 1.2.4 + @param opts + The option set to be manipulated. + @param path + File address in the local file system. + Instead of a disk path, the word --efi-boot-image may be given. + It exposes in GPT the content of the first El Torito EFI boot image + as EFI system partition. + @param flag + With isoburn_igopt_get_efi_bootp(): + Control bits as of iso_write_opts_set_efi_bootp() + bit0= The path contains instructions for the interval libisofs + reader. See libisofs.h. + @since 1.4.0 + With isoburn_igopt_set_efi_bootp(): + bit0= add the current flag setting & 0x3fffffff to return value 1. + @return 1 success, <=0 failure +*/ +int isoburn_igopt_set_efi_bootp(struct isoburn_imgen_opts *opts, + char *path, int flag); +int isoburn_igopt_get_efi_bootp(struct isoburn_imgen_opts *opts, + char **path, int flag); + + +/** Cause an arbitrary data file to be appended to the ISO image and to be + described by a partition table entry in an MBR or SUN Disk Label at the + start of the ISO image. + The partition entry will bear the size of the image file rounded up to + the next multiple of 2048 bytes. + MBR or SUN Disk Label are selected by isoburn_igopt_set_system_area() + system area type: 0 selects MBR partition table. 3 selects a SUN partition + table with 320 kB start alignment. + @since 0.6.4 + @param opts + The option set to be manipulated. + @param partition_number + Depicts the partition table entry which shall describe the + appended image. + Range with MBR: 1 to 4. 1 will cause the whole ISO image to be + unclaimable space before partition 1. + @since 0.6.6 + Range with SUN Disk Label: 2 to 8. + @param image_path + File address in the local file system. + With SUN Disk Label: an empty name causes the partition to become + a copy of the next lower partition. + @param partition_type + The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06, + Linux Native Partition = 0x83. See fdisk command L. + This parameter is ignored with SUN Disk Label. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_partition_img(struct isoburn_imgen_opts *opts, + int partition_number, uint8_t partition_type, + char *image_path); + +/** Inquire the current settings made by isoburn_igopt_set_partition_img(). + @since 0.6.4 + @param opts + The option set to be inquired. + @param num_entries + Number of array elements in partition_types[] and image_paths[]. + @param partition_types + The partition type associated with the partition. Valid only if + image_paths[] of the same index is not NULL. + @param image_paths + Its elements get filled with either NULL or a pointer to a string + with a file address or an empty text. + @return + <0 = error + 0 = no partition image set + >0 highest used partition number +*/ +int isoburn_igopt_get_partition_img(struct isoburn_imgen_opts *opts, + int num_entries, + uint8_t partition_types[], + char *image_paths[]); + + +/** Set flag bits for a partition defined by isoburn_igopt_set_partition_img(). + The bits will be forwarded to libisofs iso_write_opts_set_partition_img(). + @since 1.4.0 + @param opts + The option set to be manipulated. + @param partition_number + Depicts the partition table entry to which shall the flags bits + shall apply. + @param flag + Control bits as of iso_write_opts_set_partition_img() + bit0= The path contains instructions for the interval libisofs + reader. See libisofs.h. + @since 1.4.0 + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_part_flag(struct isoburn_imgen_opts *opts, + int partition_number, int flag); + +/** Inquire the current settings made by isoburn_igopt_set_part_flags(). + @since 1.4.0 + @param opts + The option set to be inquired. + @param num_entries + Number of array elements in part_flags[]. + @param part_flags + The array elements 0 to num_entries - 1 will get filled by the + flag bits of the images of the corresponding partition. + @return + <0 = error + 0 = no partition image set + >0 highest used partition number +*/ +int isoburn_igopt_get_part_flags(struct isoburn_imgen_opts *opts, + int num_entries, int part_flags[]); + + +/** Control whether partitions created by iso_write_opts_set_partition_img() + are to be represented in MBR or as GPT partitions. + @since 1.4.0 + @param opts + The option set to be manipulated. + @param gpt + 0= represent as MBR partition; as GPT only if other GPT partitions + are present + 1= represent as GPT partition and cause protective MBR with a single + partition which covers the whole output data. + This may fail if other settings demand MBR partitions. + Do not use other values for now. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_appended_as_gpt(struct isoburn_imgen_opts *opts, + int gpt); + +/** Inquire the current setting made by isoburn_igopt_set_appended_as_gpt(). + @since 1.4.0 + @param opts + The option set to be inquired. + @param gpt + Returns the current value. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_appended_as_gpt(struct isoburn_imgen_opts *opts, + int *gpt); + + +/** Control whether partitions created by iso_write_opts_set_partition_img() + are to be represented in Apple Partition Map. + @since 1.4.4 + @param opts + The option set to be manipulated. + @param apm + 0= do not represent appended partitions in APM + 1= represent in APM, even if not + iso_write_opts_set_part_like_isohybrid() enables it and no + other APM partitions emerge. + Do not use other values for now. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_appended_as_apm(struct isoburn_imgen_opts *opts, + int apm); + +/** Inquire the current setting made by isoburn_igopt_set_appended_as_apm(). + @since 1.4.4 + @param opts + The option set to be inquired. + @param gpt + Returns the current value. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_appended_as_apm(struct isoburn_imgen_opts *opts, + int *apm); + + +/** Control whether bits 2 to 8 of el_torito_set_isolinux_options() + shall apply even if not isohybrid MBR patching is enabled (bit1 of + parameter options of isoburn_igopt_set_system_area()). + For details see iso_write_opts_set_part_like_isohybrid() in libisofs.h. + @since 1.4.4 + @param opts + The option set to be manipulated. + @param alike + 0= Apply isohybrid behavior only with ISOLINUX isohybrid. + Do not mention appended partitions in APM unless + isoburn_igopt_set_appended_as_apm() is enabled. + 1= Apply isohybrid behavior even without ISOLINUX isohybrid. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_part_like_isohybrid(struct isoburn_imgen_opts *opts, + int alike); + +/** Inquire the current setting of isoburn_igopt_set_part_like_isohybrid(). + @since 1.4.4 + @param opts + The option set to be inquired. + @param alike + Returns the current value. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_part_like_isohybrid(struct isoburn_imgen_opts *opts, + int *alike); + +/** Control whether the emerging GPT gets a pseudo-randomly generated disk GUID + or whether it gets a user supplied GUID. + The partition GUIDs will be generated in a reproducible way by exoring a + little-endian 32 bit counter with the disk GUID beginning at byte offset 9. + @since 1.4.6 + @param opts + The option set to be manipulated. + @param guid + 16 bytes of user supplied GUID. + The upper 4 bit of guid[6] and guid[7] should bear the value 4 to + express the version 4 in both endiannesses. Bit 7 of byte[8] should + be set to 1 and bit 6 be set to 0, in order to express the RFC 4122 + variant of GUID, where version 4 means "random". + @param mode + 0 = ignore parameter guid and produce the GPT disk GUID by a + pseudo-random algorithm. This is the default setting. + 1 = use parameter guid as GPT disk GUID + 2 = ignore parameter guid and derive the GPT disk GUID from + parameter uuid of isoburn_igopt_set_pvd_times(). + The 16 bytes of uuid get copied and bytes 6, 7, 8 get their + upper bits changed to comply to RFC 4122. + If no such uuid is given when ISO production starts, then + mode 2 defaults to mode 0. +*/ +int isoburn_igopt_set_gpt_guid(struct isoburn_imgen_opts *opts, + uint8_t guid[16], int mode); + +/** Inquire the current setting of isoburn_igopt_set_gpt_guid(). + @since 1.4.6 + @param opts + The option set to be inquired. + @param guid + Returns the current guid if current mode is 1. + @param mode + Returns the current value. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_gpt_guid(struct isoburn_imgen_opts *opts, + uint8_t guid[16], int *mode); + + +/** Set a name for the system area. This setting is ignored unless system area + type 3 "SUN Disk Label" is in effect by iso_write_opts_set_system_area(). + In this case it will replace the default text at the start of the image: + "CD-ROM Disc with Sun sparc boot created by libisofs" + @since 0.6.6 + @param opts + The option set to be manipulated. + @param label + A text of up to 128 characters. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_disc_label(struct isoburn_imgen_opts *opts, char *label); + +/** Inquire the current setting made by isoburn_igopt_set_disc_label(). + @since 0.6.6 + @param opts + The option set to be inquired. + @param label + Returns a pointer to the currently set label string. + Do not alter this string. + Use only as long as the opts object exists. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_disc_label(struct isoburn_imgen_opts *opts, + char **label); + +/** Set a serial number for the HFS+ extension of the emerging ISO image. + @since 1.2.4 + @param opts + The option set to be manipulated. + @param serial_number + 8 bytes which should be unique to the image. + If all bytes are 0, then the serial number will be generated as + random number by libisofs. This is the default setting. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_hfsp_serial_number(struct isoburn_imgen_opts *opts, + uint8_t serial_number[8]); + + +/** Inquire the current setting made by isoburn_igopt_set_disc_label() + @since 1.2.4 + @param opts + The option set to be inquired. + @param serial_number + Will get filled with the current setting. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_hfsp_serial_number(struct isoburn_imgen_opts *opts, + uint8_t serial_number[8]); + +/** Set the allocation block size for HFS+ production and the block size + for layout and address unit of Apple Partition map. + @since 1.2.4 + @param opts + The option set to be manipulated. + @param hfsp_block_size + -1 means that this setting shall be left unchanged + 0 allows the automatic default setting + 512 and 2048 enforce a size. + @param apm_block_size + -1 means that this setting shall be left unchanged + 0 allows the automatic default setting + 512 and 2048 enforce a size. + Size 512 cannot be combined with GPT production. + Size 2048 cannot be mounted -t hfsplus by Linux kernels at least up + to 2.6.32. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_hfsp_block_size(struct isoburn_imgen_opts *opts, + int hfsp_block_size, int apm_block_size); + +/** Inquire the current setting made by isoburn_igopt_set_hfsp_block_size + @since 1.2.4 + @param opts + The option set to be inquired. + @param hfsp_block_size + Will be set to a value as described above. Except -1. + @param apm_block_size + Will be set to a value as described above. Except -1. + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_get_hfsp_block_size(struct isoburn_imgen_opts *opts, + int *hfsp_block_size, int *apm_block_size); + + +/** Set or inquire the write type for the next write run on optical media. + @since 1.2.4 + @param opts + The option set to be manipulated or inquired. + @param do_tao + The value to be set or the variable where to return the current + setting: + 0 = Let libburn choose according to other write parameters. + This is advisable unless there are particular reasons not to + use one of the two write types. Be aware that 1 and -1 can + lead to failure if the write type is not appropriate for + the given media situation. + 1 = Use BURN_WRITE_TAO which does + TAO on CD, Incremental on DVD-R, + no track reservation on DVD+R and BD-R + -1 = Use BURN_WRITE_SAO which does + SAO on CD, DAO on DVD-R, + track reservation on DVD+R and BD-R + @return + <=0 = error, 1 = success +*/ +int isoburn_igopt_set_write_type(struct isoburn_imgen_opts *opts, int do_tao); +int isoburn_igopt_get_write_type(struct isoburn_imgen_opts *opts, int *do_tao); + +/** Set or inquire whether a final fsync(2) is performed when updating the + multi-session information of libburn stdio pseudo-drives by + isoburn_activate_session(). + Note: + fsync(2) calls during and at the end of isoburn_disc_write() are controlled + by libburn call burn_write_opts_set_stdio_fsync(). + @since 1.2.4 + @param opts + The option set to be manipulated or inquired. + @param do_sync + 1= call fsync(2) with stdio drives in isoburn_activate_session() + 0= do not + @return + <=0 = error, 1 = success + */ +int isoburn_igopt_set_stdio_endsync(struct isoburn_imgen_opts *opts, + int do_sync); +int isoburn_igopt_get_stdio_endsync(struct isoburn_imgen_opts *opts, + int *do_sync); + +/* ----------------------------------------------------------------------- */ +/* End of Options for image generation */ +/* ----------------------------------------------------------------------- */ + + +/** Frontend of libisofs call iso_conv_name_chars() controlled by + struct isoburn_imgen_opts rather than IsoWriteOpts. + See libisofs.h for a more detailed description. + @since 1.3.6 + @param opts + Defines options like output charset, UCS-2 versus UTF-16 for Joliet, + and naming restrictions. + @param name + The input text which shall be converted. + @param name_len + The number of bytes in input text. + @param result + Will return the conversion result in case of success. Terminated by + a trailing zero byte. + Use free() to dispose it when no longer needed. + @param result_len + Will return the number of bytes in result (excluding trailing zero) + @param flag + Bitfield for control purposes. + bit0-bit7= Name space + 0= generic (to_charset is valid, + no reserved characters, no length limits) + 1= Rock Ridge (to_charset is valid) + 2= Joliet (to_charset gets overridden by UCS-2 or UTF-16) + 3= ECMA-119 (to_charset gets overridden by the + dull ISO 9660 subset of ASCII) + 4= HFS+ (to_charset gets overridden by UTF-16BE) + bit8= Treat input text as directory name + (matters for Joliet and ECMA-119) + bit9= Do not issue error messages + bit15= Reverse operation (best to be done only with results of + previous conversions) + @return + 1 means success, <=0 means error +*/ +int isoburn_conv_name_chars(struct isoburn_imgen_opts *opts, + char *name, size_t name_len, + char **result, size_t *result_len, int flag); + + +/** Get the image attached to a drive, if any. + @since 0.1.0 + @param d The drive to inquire + @return A reference to attached image, or NULL if the drive has no image + attached. This reference needs to be released via iso_image_unref() + when it is not longer needed. +*/ +IsoImage *isoburn_get_attached_image(struct burn_drive *d); + +/** Get the start address of the image that is attached to the drive, if any. + @since 1.2.2 + @param d The drive to inquire + @return The logical block address where the System Area of the image + starts. <0 means that the address is invalid. +*/ +int isoburn_get_attached_start_lba(struct burn_drive *d); + + +/** Load the ISO filesystem directory tree from the medium in the given drive. + This will give libisoburn the base on which it can let libisofs perform + image growing or image modification. The loaded volset gets attached + to the drive object and handed out to the application. + Not a wrapper, but peculiar to libisoburn. + @since 0.1.0 + @param d The drive which holds an existing ISO filesystem or blank media. + d is allowed to be NULL which produces an empty ISO image. In + this case one has to call before writing isoburn_attach_volset() + with the volset from this call and with the intended output + drive. + @param read_opts The read options which can be chosen by the application + @param image the image read, if the disc is blank it will have no files. + This reference needs to be released via iso_image_unref() when + it is not longer needed. The drive, if not NULL, will hold an + own reference which it will release when it gets a new volset + or when it gets released via isoburn_drive_release(). + You can pass NULL if you already have a reference or you plan to + obtain it later with isoburn_get_attached_image(). Of course, if + you haven't specified a valid drive (i.e., if d == NULL), this + parameter can't be NULL. + @return <=0 error , 1 = success +*/ +int isoburn_read_image(struct burn_drive *d, + struct isoburn_read_opts *read_opts, + IsoImage **image); + +/** Set a callback function for producing pacifier messages during the lengthy + process of image reading. The callback function and the application handle + are stored until they are needed for the underlying call to libisofs. + Other than with libisofs the handle is managed entirely by the application. + An idle .free() function is exposed to libisofs. The handle has to stay + valid until isoburn_read_image() is done. It has to be detached by + isoburn_set_read_pacifier(drive, NULL, NULL); + before it may be removed from memory. + @since 0.1.0 + @param drive The drive which will be used with isoburn_read_image() + It has to be acquired by an isoburn_* wrapper call. + @param read_pacifier The callback function + @param app_handle The app handle which the callback function can obtain + via iso_image_get_attached_data() from its IsoImage* + @return 1 success, <=0 failure +*/ +int isoburn_set_read_pacifier(struct burn_drive *drive, + int (*read_pacifier)(IsoImage*, IsoFileSource*), + void *app_handle); + +/** Inquire the partition offset of the loaded image. The first 512 bytes of + the image get examined whether they bear an MBR signature and a first + partition table entry which matches the size of the image. In this case + the start address is recorded as partition offset and internal buffers + get adjusted. + See also isoburn_igopt_set_part_offset(). + @since 0.6.2 + @param drive The drive with the loaded image + @param block_offset_2k returns the recognized partition offset + @return <0 = error + 0 = no partition offset recognized + 1 = acceptable non-zero offset, buffers are adjusted + 2 = offset is credible but not acceptable for buffer size +*/ +int isoburn_get_img_partition_offset(struct burn_drive *drive, + uint32_t *block_offset_2k); + + +/** Set the IsoImage to be used with a drive. This eventually releases + the reference to the old IsoImage attached to the drive. + Caution: Use with care. It hardly makes sense to replace an image that + reflects a valid ISO image on the medium. + This call is rather intended for writing a newly created and populated + image to blank media. The use case in xorriso is to let an image survive + the change or demise of the outdev target drive. + @since 0.1.0 + @param d The drive which shall be write target of the volset. + @param image The image that represents the image to be written. + This image pointer MUST already be a valid reference suitable + for iso_image_unref(). + It may have been obtained by appropriate libisofs calls or by + isoburn_read_image() with d==NULL. + @return <=0 error , 1 = success +*/ +int isoburn_attach_image(struct burn_drive *d, IsoImage *image); + + +/** Set the start address of the image that is attached to the drive, if any. + @since 1.2.2 + @param d The drive to inquire + @param lba The logical block address where the System Area of the image + starts. <0 means that the address is invalid. + @param flag Bitfield, submit 0 for now. + @return <=0 error (e.g. because no image is attached), 1 = success +*/ +int isoburn_attach_start_lba(struct burn_drive *d, int lba, int flag); + + +/** Return the best possible estimation of the currently available capacity of + the medium. This might depend on particular write option settings and on + drive state. + An eventual start address for emulated multi-session will be subtracted + from the capacity estimation given by burn_disc_available_space(). + Negative results get defaulted to 0. + Wrapper for: burn_disc_available_space() + @since 0.1.0 + @param d The drive to query. + @param o If not NULL: write parameters to be set on drive before query + @return number of most probably available free bytes +*/ +off_t isoburn_disc_available_space(struct burn_drive *d, + struct burn_write_opts *o); + + +/** Obtain the start block number of the most recent session on the medium. In + case of random access media this will normally be 0. Successful return is + not a guarantee that there is a ISO-9660 image at all. The call will fail, + nevertheless,if isoburn_disc_get_status() returns not BURN_DISC_APPENDABLE + or BURN_DISC_FULL. + Note: The result of this call may be fabricated by a previous call of + isoburn_set_msc1() which can override the rule to load the most recent + session. + Wrapper for: burn_disc_get_msc1() + @since 0.1.0 + @param d The drive to inquire + @param start_lba Contains on success the start address in 2048 byte blocks + @return <=0 error , 1 = success +*/ +int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba); + + +/** Use this with trackno==0 to obtain the predicted start block number of the + new session. The interesting number is returned in parameter nwa. + Wrapper for: burn_disc_track_lba_nwa() + @since 0.1.0 + @param d The drive to inquire + @param o If not NULL: write parameters to be set on drive before query + @param trackno Submit 0. + @param lba return value: start lba + @param nwa return value: Next Writeable Address + @return 1=nwa is valid , 0=nwa is not valid , -1=error +*/ +int isoburn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, + int trackno, int *lba, int *nwa); + + +/** Obtain the size which was attributed to an emulated appendable on actually + overwriteable media. This value is supposed to be <= 2048 * nwa as of + isoburn_disc_track_lba_nwa(). + @since 0.1.0 + @param d The drive holding the medium. + @param start_byte The reply value counted in bytes, not in sectors. + @param flag Unused yet. Submit 0. + @return 1=stat_byte is valid, 0=not an emulated appendable, -1=error +*/ +int isoburn_get_min_start_byte(struct burn_drive *d, off_t *start_byte, + int flag); + + +/** Start production of an ISO 9660 image using the method of Growing: + Create a disc object for writing the new session from the created or loaded + iso_volset which has been manipulated via libisofs, to the same medium from + where the image was eventually loaded. + This call starts a libisofs thread which begins to produce the image. + It has to be revoked by isoburn_cancel_prepared_write() if for some reason + this image data stream shall not be consumed. + The returned struct burn_disc is ready for use by a subsequent call to + isoburn_disc_write(). After this asynchronous writing has ended and the + drive is BURN_DRIVE_IDLE again, the burn_disc object has to be disposed + by burn_disc_free(). + @since 0.1.0 + @param drive The combined source and target drive, grabbed with + isoburn_drive_scan_and_grab(). . + @param disc Returns the newly created burn_disc object. + @param opts Image generation options, see isoburn_igopt_*() + @return <=0 error , 1 = success +*/ +int isoburn_prepare_disc(struct burn_drive *drive, struct burn_disc **disc, + struct isoburn_imgen_opts *opts); + + +/** Start production of an ISO 9660 image using the method of Modifying: + Create a disc object for producing a new image from a previous image + plus the changes made by user. The generated burn_disc is suitable + to be written to a grabbed drive with blank writeable medium. + But you must not use the same drive for input and output, because data + will be read from the source drive while at the same time the target + drive is already writing. + This call starts a libisofs thread which begins to produce the image. + It has to be revoked by isoburn_cancel_prepared_write() if for some reason + this image data stream shall not be consumed. + The resulting burn_disc object has to be disposed when all its writing + is done and the drive is BURN_DRIVE_IDLE again after asynchronous + burn_disc_write(). + @since 0.1.0 + @param in_drive The input drive, grabbed with isoburn_drive_aquire() or + one of its alternatives. + @param disc Returns the newly created burn_disc object. + @param opts Options for image generation and data transport to the + medium. + @param out_drive The output drive, from isoburn_drive_aquire() et.al.. + @return <=0 error , 1 = success +*/ +int isoburn_prepare_new_image(struct burn_drive *in_drive, + struct burn_disc **disc, + struct isoburn_imgen_opts *opts, + struct burn_drive *out_drive); + + +/** Start production of an ISO 9660 image using the method of Blind Growing: + Create a disc object for writing an add-on session from the created or + loaded IsoImage which has been manipulated via libisofs, to a different + drive than the one from where it was loaded. + Usually output will be stdio:/dev/fd/1 (i.e. stdout) being piped + into some burn program like with this classic gesture: + mkisofs -M $dev -C $msc1,$nwa | cdrecord -waiti dev=$dev + Parameter translation into libisoburn: + $dev is the address by which parameter in_drive of this call was + acquired $msc1 was set by isoburn_set_msc1() before image reading + or was detected from the in_drive medium + $nwa is a parameter of this call + or can be used as detected from the in_drive medium + + This call starts a libisofs thread which begins to produce the image. + It has to be revoked by isoburn_cancel_prepared_write() if for some reason + this image data stream shall not be consumed. + This call waits for libisofs output to become available and then detaches + the input drive object from the data source object by which libisofs was + reading from the input drive. + So, as far as libisofs is concerned, that drive may be released immediately + after this call in order to allow the consumer to access the drive for + writing. + The consumer should wait for input to become available and only then open + its burn drive. With cdrecord this is caused by option -waiti. + + The resulting burn_disc object has to be disposed when all its writing + is done and the drive is BURN_DRIVE_IDLE again after asynchronous + burn_disc_write(). + @since 0.2.2 + @param in_drive The input drive,grabbed with isoburn_drive_scan_and_grab(). + @param disc Returns the newly created burn_disc object. + @param opts Options for image generation and data transport to media. + @param out_drive The output drive, from isoburn_drive_aquire() et.al.. + typically stdio:/dev/fd/1 . + @param nwa The address (2048 byte block count) where the add-on + session will be finally stored on a mountable medium + or in a mountable file. + If nwa is -1 then the address is used as determined from + the in_drive medium. + @return <=0 error , 1 = success +*/ +int isoburn_prepare_blind_grow(struct burn_drive *in_drive, + struct burn_disc **disc, + struct isoburn_imgen_opts *opts, + struct burn_drive *out_drive, int nwa); + + +/** + Revoke isoburn_prepare_*() instead of running isoburn_disc_write(). + libisofs reserves resources and maybe already starts generating the + image stream when one of above three calls is performed. It is mandatory to + either run isoburn_disc_write() or to revoke the preparations by the + call described here. + If this call returns 0 or 1 then the write thread of libisofs has ended. + @since 0.1.0 + @param input_drive The drive or in_drive which was used with the + preparation call. + @param output_drive The out_drive used with isoburn_prepare_new_image(), + NULL if none. + @param flag Bitfield, submit 0 for now. + bit0= -reserved for internal use- + @return <0 error, 0= no pending preparations detectable, 1 = canceled +*/ +int isoburn_cancel_prepared_write(struct burn_drive *input_drive, + struct burn_drive *output_drive, int flag); + + +/** + Override the truncation setting that was made with flag bit2 during the + call of isoburn_drive_aquire. This applies only to stdio pseudo drives. + @since 0.1.6 + @param drive The drive which was acquired and shall be used for writing. + @param flag Bitfield controlling the setting: + bit0= truncate (else do not truncate) + bit1= do not warn if call is inappropriate to drive + bit2= only set if truncation is currently enabled + do not warn if call is inappropriate to drive + @return 1 success, 0 inappropriate drive, <0 severe error +*/ +int isoburn_set_truncate(struct burn_drive *drive, int flag); + + +/** Start writing of the new session. + This call is asynchrounous. I.e. it returns quite soon and the progress has + to be watched by a loop with call burn_drive_get_status() until + BURN_DRIVE_IDLE is returned. + Wrapper for: burn_disc_write() + @since 0.1.0 + @param o Options which control the burn process. See burnwrite_opts_*() + in libburn.h. + @param disc Disc object created either by isoburn_prepare_disc() or by + isoburn_prepare_new_image(). +*/ +void isoburn_disc_write(struct burn_write_opts *o, struct burn_disc *disc); + + +/** Inquire state and fill parameters of the fifo which is attached to + the emerging track. This should be done in the pacifier loop while + isoburn_disc_write() or burn_disc_write() are active. + This works only with drives obtained by isoburn_drive_scan_and_grab() + or isoburn_drive_grab(). If isoburn_prepare_new_image() was used, then + parameter out_drive must have announced the track output drive. + Hint: If only burn_write_opts and not burn_drive is known, then the drive + can be obtained by burn_write_opts_get_drive(). + @since 0.1.0 + @param d The drive to which the track with the fifo gets burned. + @param size The total size of the fifo + @param free_bytes The current free capacity of the fifo + @param status_text Returns a pointer to a constant text, see below + @return <0 reply invalid, >=0 fifo status code: + bit0+1=input status, bit2=consumption status, i.e: + 0="standby" : data processing not started yet + 1="active" : input and consumption are active + 2="ending" : input has ended without error + 3="failing" : input had error and ended, + 4="unused" : ( consumption has ended before processing start ) + 5="abandoned" : consumption has ended prematurely + 6="ended" : consumption has ended without input error + 7="aborted" : consumption has ended after input error +*/ +int isoburn_get_fifo_status(struct burn_drive *d, int *size, int *free_bytes, + char **status_text); + + +/** Inquire whether the most recent write run was successful. + Wrapper for: burn_drive_wrote_well() + @since 0.1.0 + @param d The drive to inquire + @return 1=burn seems to have went well, 0=burn failed +*/ +int isoburn_drive_wrote_well(struct burn_drive *d); + + +/** Call this after isoburn_disc_write has finished and burn_drive_wrote_well() + indicates success. It will eventually complete the emulation of + multi-session functionality, if needed at all. Let libisoburn decide. + Not a wrapper, but peculiar to libisoburn. + @since 0.1.0 + @param d The output drive to which the session was written + @return 1 success , <=0 failure +*/ +int isoburn_activate_session(struct burn_drive *d); + + +/** Wait after normal end of operations until libisofs ended all write + threads and freed resource reservations. + This call is not mandatory. But without it, messages from the ending + threads might appear after the application ended its write procedure. + @since 0.1.0 + @param input_drive The drive or in_drive which was used with the + preparation call. + @param output_drive The out_drive used with isoburn_prepare_new_image(), + NULL if none. + @param flag Bitfield, submit 0 for now. + @return <=0 error , 1 = success +*/ +int isoburn_sync_after_write(struct burn_drive *input_drive, + struct burn_drive *output_drive, int flag); + + +/** Release an acquired drive. + Wrapper for: burn_drive_release() + @since 0.1.0 + @param drive The drive to be released + @param eject 1= eject medium from drive , 0= do not eject +*/ +void isoburn_drive_release(struct burn_drive *drive, int eject); + + +/** Shutdown all three libraries. + Wrapper for : iso_finish() and burn_finish(). + @since 0.1.0 +*/ +void isoburn_finish(void); + + +/* + The following calls are for expert applications only. + An application should have a special reason to use them. +*/ + + +/** Inquire wether the medium needs emulation or would be suitable for + generic multi-session via libburn. + @since 0.1.0 + @param d The drive to inquire + @return 0 is generic multi-session + 1 is emulated multi-session + -1 is not suitable for isoburn +*/ +int isoburn_needs_emulation(struct burn_drive *d); + + +/* ---------------------------- Test area ----------------------------- */ + +/* no tests active, currently */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LIBISOBURN_LIBISOBURN_H_ */ + diff --git a/libisoburn/branches/1.4.6/libisoburn/libisoburn.ver b/libisoburn/branches/1.4.6/libisoburn/libisoburn.ver new file mode 100644 index 00000000..70348095 --- /dev/null +++ b/libisoburn/branches/1.4.6/libisoburn/libisoburn.ver @@ -0,0 +1,350 @@ +LIBISOBURN1 { +global: +isoburn_activate_session; +isoburn_attach_image; +isoburn_attach_start_lba; +isoburn_conv_name_chars; +isoburn_cancel_prepared_write; +isoburn_disc_available_space; +isoburn_disc_erasable; +isoburn_disc_erase; +isoburn_disc_get_msc1; +isoburn_disc_get_status; +isoburn_disc_pretend_full_uncond; +isoburn_disc_track_lba_nwa; +isoburn_disc_write; +isoburn_drive_aquire; +isoburn_drive_grab; +isoburn_drive_release; +isoburn_drive_scan_and_grab; +isoburn_drive_set_msgs_submit; +isoburn_drive_wrote_well; +isoburn_finish; +isoburn_get_attached_image; +isoburn_get_attached_start_lba; +isoburn_get_fifo_status; +isoburn_get_min_start_byte; +isoburn_get_mount_params; +isoburn_igopt_attach_jte; +isoburn_igopt_destroy; +isoburn_igopt_detach_jte; +isoburn_igopt_get_appended_as_apm; +isoburn_igopt_get_appended_as_gpt; +isoburn_igopt_get_data_start; +isoburn_igopt_get_disc_label; +isoburn_igopt_get_effective_lba; +isoburn_igopt_get_efi_bootp; +isoburn_igopt_get_extensions; +isoburn_igopt_get_fifo_size; +isoburn_igopt_get_gpt_guid; +isoburn_igopt_get_hfsp_block_size; +isoburn_igopt_get_hfsp_serial_number; +isoburn_igopt_get_level; +isoburn_igopt_get_out_charset; +isoburn_igopt_get_over_mode; +isoburn_igopt_get_over_ugid; +isoburn_igopt_get_part_flags; +isoburn_igopt_get_part_like_isohybrid; +isoburn_igopt_get_partition_img; +isoburn_igopt_get_prep_partition; +isoburn_igopt_get_pvd_times; +isoburn_igopt_get_relaxed; +isoburn_igopt_get_rr_reloc; +isoburn_igopt_get_scdbackup_tag; +isoburn_igopt_get_sort_files; +isoburn_igopt_get_stdio_endsync; +isoburn_igopt_get_system_area; +isoburn_igopt_get_tail_blocks; +isoburn_igopt_get_untranslated_name_len; +isoburn_igopt_get_write_type; +isoburn_igopt_new; +isoburn_igopt_set_appended_as_apm; +isoburn_igopt_set_appended_as_gpt; +isoburn_igopt_set_disc_label; +isoburn_igopt_set_efi_bootp; +isoburn_igopt_set_extensions; +isoburn_igopt_set_fifo_size; +isoburn_igopt_set_gpt_guid; +isoburn_igopt_set_hfsp_block_size; +isoburn_igopt_set_hfsp_serial_number; +isoburn_igopt_set_level; +isoburn_igopt_set_out_charset; +isoburn_igopt_set_over_mode; +isoburn_igopt_set_over_ugid; +isoburn_igopt_set_part_flag; +isoburn_igopt_set_part_like_isohybrid; +isoburn_igopt_set_partition_img; +isoburn_igopt_set_prep_partition; +isoburn_igopt_set_pvd_times; +isoburn_igopt_set_relaxed; +isoburn_igopt_set_rr_reloc; +isoburn_igopt_set_scdbackup_tag; +isoburn_igopt_set_sort_files; +isoburn_igopt_set_stdio_endsync; +isoburn_igopt_set_system_area; +isoburn_igopt_set_tail_blocks; +isoburn_igopt_set_untranslated_name_len; +isoburn_igopt_set_write_type; +isoburn_initialize; +isoburn_is_compatible; +isoburn_libburn_req; +isoburn_libisofs_req; +isoburn_libjte_req; +isoburn_needs_emulation; +isoburn_prepare_blind_grow; +isoburn_prepare_disc; +isoburn_prepare_new_image; +isoburn_read_image; +isoburn_read_iso_head; +isoburn_ropt_destroy; +isoburn_ropt_get_auto_incharset; +isoburn_ropt_get_data_cache; +isoburn_ropt_get_default_dirperms; +isoburn_ropt_get_default_perms; +isoburn_ropt_get_displacement; +isoburn_ropt_get_extensions; +isoburn_ropt_get_input_charset; +isoburn_ropt_get_size_what; +isoburn_ropt_get_truncate_mode; +isoburn_ropt_new; +isoburn_ropt_set_auto_incharset; +isoburn_ropt_set_data_cache; +isoburn_ropt_set_default_dirperms; +isoburn_ropt_set_default_perms; +isoburn_ropt_set_displacement; +isoburn_ropt_set_extensions; +isoburn_ropt_set_input_charset; +isoburn_ropt_set_truncate_mode; +isoburn_set_msc1; +isoburn_set_msgs_submit; +isoburn_set_read_pacifier; +isoburn_set_truncate; +isoburn_sync_after_write; +isoburn_toc_disc_free; +isoburn_toc_disc_get_incmpl_sess; +isoburn_toc_disc_get_sectors; +isoburn_toc_disc_get_sessions; +isoburn_toc_drive_get_disc; +isoburn_toc_session_get_leadout_entry; +isoburn_toc_session_get_sectors; +isoburn_toc_session_get_tracks; +isoburn_toc_track_get_emul; +isoburn_toc_track_get_entry; +isoburn_version; +Xorriso__dispose_words; +Xorriso__get_patch_level_text; +Xorriso__is_compatible; +Xorriso__preset_signal_behavior; +Xorriso__severity_cmp; +Xorriso__severity_list; +Xorriso__version; +Xorriso_change_is_pending; +Xorriso_destroy; +Xorriso_dialog; +Xorriso_eval_problem_status; +Xorriso_execute_option; +Xorriso_fetch_outlists; +Xorriso_get_problem_status; +Xorriso_interpreter; +Xorriso_lst_destroy_all; +Xorriso_lst_get_next; +Xorriso_lst_get_prev; +Xorriso_lst_get_text; +Xorriso_make_return_value; +Xorriso_msgs_submit; +Xorriso_msgs_submit_void; +Xorriso_new; +Xorriso_option_abort_on; +Xorriso_option_abstract_file; +Xorriso_option_acl; +Xorriso_option_add; +Xorriso_option_add_plainly; +Xorriso_option_alter_date; +Xorriso_option_append_partition; +Xorriso_option_application_id; +Xorriso_option_application_use; +Xorriso_option_as; +Xorriso_option_assert_volid; +Xorriso_option_auto_charset; +Xorriso_option_backslash_codes; +Xorriso_option_ban_stdio_write; +Xorriso_option_biblio_file; +Xorriso_option_blank; +Xorriso_option_boot_image; +Xorriso_option_calm_drive; +Xorriso_option_cdi; +Xorriso_option_cdx; +Xorriso_option_changes_pending; +Xorriso_option_charset; +Xorriso_option_check_md5; +Xorriso_option_check_media; +Xorriso_option_check_media_defaults; +Xorriso_option_chgrpi; +Xorriso_option_chmodi; +Xorriso_option_chowni; +Xorriso_option_clone; +Xorriso_option_close; +Xorriso_option_close_damaged; +Xorriso_option_close_filter_list; +Xorriso_option_commit; +Xorriso_option_commit_eject; +Xorriso_option_compare; +Xorriso_option_compliance; +Xorriso_option_concat; +Xorriso_option_copyright_file; +Xorriso_option_cp_clone; +Xorriso_option_cpri; +Xorriso_option_cpx; +Xorriso_option_cut_out; +Xorriso_option_data_cache_size; +Xorriso_option_dev; +Xorriso_option_devices; +Xorriso_option_dialog; +Xorriso_option_disk_dev_ino; +Xorriso_option_disk_pattern; +Xorriso_option_displacement; +Xorriso_option_drive_class; +Xorriso_option_dummy; +Xorriso_option_dvd_obs; +Xorriso_option_early_drive_test; +Xorriso_option_ecma119_map; +Xorriso_option_eject; +Xorriso_option_end; +Xorriso_option_errfile_log; +Xorriso_option_error_behavior; +Xorriso_option_external_filter; +Xorriso_option_extract; +Xorriso_option_extract_cut; +Xorriso_option_file_name_limit; +Xorriso_option_file_size_limit; +Xorriso_option_find; +Xorriso_option_follow; +Xorriso_option_fs; +Xorriso_option_getfacli; +Xorriso_option_gid; +Xorriso_option_grow_blindly; +Xorriso_option_hardlinks; +Xorriso_option_help; +Xorriso_option_hfsplus; +Xorriso_option_hide; +Xorriso_option_history; +Xorriso_option_iso_rr_pattern; +Xorriso_option_jigdo; +Xorriso_option_joliet; +Xorriso_option_launch_frontend; +Xorriso_option_list_arg_sorting; +Xorriso_option_list_delimiter; +Xorriso_option_list_extras; +Xorriso_option_list_formats; +Xorriso_option_list_profiles; +Xorriso_option_list_speeds; +Xorriso_option_lnsi; +Xorriso_option_load; +Xorriso_option_logfile; +Xorriso_option_lsi; +Xorriso_option_lsx; +Xorriso_option_map; +Xorriso_option_map_l; +Xorriso_option_mark; +Xorriso_option_md5; +Xorriso_option_mkdiri; +Xorriso_option_modesty_on_drive; +Xorriso_option_mount; +Xorriso_option_mount_opts; +Xorriso_option_move; +Xorriso_option_msg_op; +Xorriso_option_mvi; +Xorriso_option_no_rc; +Xorriso_option_named_pipe_loop; +Xorriso_option_not_leaf; +Xorriso_option_not_list; +Xorriso_option_not_mgt; +Xorriso_option_not_paths; +Xorriso_option_options_from_file; +Xorriso_option_osirrox; +Xorriso_option_overwrite; +Xorriso_option_pacifier; +Xorriso_option_padding; +Xorriso_option_page; +Xorriso_option_paste_in; +Xorriso_option_path_list; +Xorriso_option_pathspecs; +Xorriso_option_pkt_output; +Xorriso_option_preparer_id; +Xorriso_option_print; +Xorriso_option_print_size; +Xorriso_option_prog; +Xorriso_option_prog_help; +Xorriso_option_prompt; +Xorriso_option_publisher; +Xorriso_option_pvd_info; +Xorriso_option_pwdi; +Xorriso_option_pwdx; +Xorriso_option_read_fs; +Xorriso_option_read_mkisofsrc; +Xorriso_option_reassure; +Xorriso_option_report_about; +Xorriso_option_report_el_torito; +Xorriso_option_report_system_area; +Xorriso_option_return_with; +Xorriso_option_rmi; +Xorriso_option_rockridge; +Xorriso_option_rollback; +Xorriso_option_rom_toc_scan; +Xorriso_option_rr_reloc_dir; +Xorriso_option_scdbackup_tag; +Xorriso_option_scsi_dev_family; +Xorriso_option_scsi_log; +Xorriso_option_session_log; +Xorriso_option_setfacli; +Xorriso_option_setfacl_listi; +Xorriso_option_setfattri; +Xorriso_option_setfattr_listi; +Xorriso_option_set_filter; +Xorriso_option_sh_style_result; +Xorriso_option_signal_handling; +Xorriso_option_sleep; +Xorriso_option_speed; +Xorriso_option_split_size; +Xorriso_option_status; +Xorriso_option_status_history_max; +Xorriso_option_stdio_sync; +Xorriso_option_stream_recording; +Xorriso_option_system_id; +Xorriso_option_tell_media_space; +Xorriso_option_temp_mem_limit; +Xorriso_option_toc; +Xorriso_option_toc_of; +Xorriso_option_uid; +Xorriso_option_unregister_filter; +Xorriso_option_update; +Xorriso_option_use_immed_bit; +Xorriso_option_use_readline; +Xorriso_option_version; +Xorriso_option_volid; +Xorriso_option_volset_id; +Xorriso_option_volume_date; +Xorriso_option_write_type; +Xorriso_option_xattr; +Xorriso_option_zisofs; +Xorriso_parse_line; +Xorriso_peek_outlists; +Xorriso_prescan_args; +Xorriso_process_errfile; +Xorriso_process_msg_queues; +Xorriso_program_arg_bsl; +Xorriso_pull_outlists; +Xorriso_push_outlists; +Xorriso_read_rc; +Xorriso_set_problem_status; +Xorriso_sieve_add_filter; +Xorriso_sieve_big; +Xorriso_sieve_clear_results; +Xorriso_sieve_dispose; +Xorriso_sieve_get_result; +Xorriso_start_msg_watcher; +Xorriso_startup_libraries; +Xorriso_stop_msg_watcher; +local: *; +}; + diff --git a/libisoburn/branches/1.4.6/releng/CHECKLIST b/libisoburn/branches/1.4.6/releng/CHECKLIST new file mode 100644 index 00000000..eecc7f3a --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/CHECKLIST @@ -0,0 +1,27 @@ +------------------------------------------------------------------------------ + http:libburnia-project.org +------------------------------------------------------------------------------ + + Release Engineering Check List + + TEST: releng + auto_* tests could be run altogether by ./run_all_auto + manual_* tests are to be run individually and manually + LOGS: http://people.debian.org/~danchev/libburnia/logs/releng/ + + TEST: cppcheck - static code checker + LOGS: http://people.debian.org/~danchev/libburnia/logs/cppcheck/ + + TEST: medistimator - checks the dialog mode of xorriso, size estimation + facility, and its ability of processing large trees. Running this + requires some specific knowledge of how the tool works, in order to + interpret the results and compare them with these from any previous + runs. The source is heavily commented. + FILE: http://anonscm.debian.org/gitweb/?p=users/danchev/medistimator.git;a=summary + LOGS: http://people.debian.org/~danchev/libburnia/logs/medistimator/ + + TEST: Debian ISO image builder logs + LOGS: http://cdbuilder.debian.org/cdimage-log/ + + TEST: Debian build daemon logs - several hardware architectures and kernels + LOGS: http://buildd.debian.org diff --git a/libisoburn/branches/1.4.6/releng/README b/libisoburn/branches/1.4.6/releng/README new file mode 100644 index 00000000..a80e266c --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/README @@ -0,0 +1,297 @@ +------------------------------------------------------------------------------ + http:libburnia-project.org +------------------------------------------------------------------------------ +libisoburn/releng. By George Danchev + and Thomas Schmitt + +Test suite for xorriso and libburnia libraries. +Copyright (C) 2011 - 2012 George Danchev, Thomas Schmitt +Provided under GPL version 2 or later. +------------------------------------------------------------------------------ + +The impatient tester will build libisoburn according to its README and then do + + cd ./releng + ./run_all_auto -x ../xorriso/xorriso + +More patient testers will first read the following description. + +Those who simply lack the interpreter /bin/bash, may do + ./change_shell_to_use +and then retry. + + + The test suite + +Directory ./releng of libisoburn contains a collection of test scripts and +auxiliary data. They exercise some typical use cases of building libisoburn +applications and running the ISO 9660 filesystem manipulation and CD/DVD/BD +burn program xorriso. + +It is assumed that libburn and libisofs are installed, so that libisoburn +can be configured and built. It is not mandatory that libisoburn is already +installed. The tests may use an installed xorriso program as well as a +freshly built one. + +The test scripts explicitely demand /bin/bash as interpreter, although they +would run on certain other shells too. If you get an error message like + ./run_all_auto: not found +then consider to install /bin/bash. +If you decide against that, see below "Alternative Shells". + + +There are two groups of test scripts: + + auto_* gets started and watched by script run_all_auto. + These tests have a moderate resource consumption and do + not cause mechanical movements of drive trays. + + manual_* gets started by the user if desired. + Manual tests may create larger sets of temporary files, + may download test data from the internet, may need + system privileges beyond the reach of a sandbox user, + and operate the mechanics of a CD drive. + + + Running automated tests + +The test scripts expect to get run while the working directory is + ./releng +of a libisoburn source tree. E.g.: libisoburn-1.1.4/releng +They create all their temporary files underneath + ./releng/releng_generated_data +Some of these files are persistent between tests. +Nevertheless it is safe to empty ./releng/releng_generated_data after +tests are done. The directory itself must be kept. + +To run the unobtrusive automatic tests, build libisoburn and xorriso, +go to directory ./releng, and execute + + ./run_all_auto -x ../xorriso/xorriso + +or if you want to use an installed xorriso program: + + ./run_all_auto -x $(which xorriso) + + ./run_all_auto -x $(type -p xorriso) + +There are several options which work with run_all_auto and any single test. + -x absolute or relative path to xorriso binary to be run. + -k keep self-generated data. + -c cleanup temporary data kept from previous run and exit. + -f simulate failure. + -h print this help text. + -- end of general options, begin of test specific options. +After option "--", there may be given options which are specific to +particular manually executable test scripts. + + + Manually executable tests + +Currently there are the following tests which should have the attention of +the user or require sysadmin considerations before they are run: + +./manual_devices -x ../xorriso/xorriso [-- [--dev device_file_to_use] + [--priv_cmd 'command [arg [arg ...]]']] + Exercises listing of all accessible optical drives and the examination of + a one of these drives. The user needs the permission to operate the CD + drives. This might involve the need for superuser authority. + The media tray of the examined drive will get loaded if it is not already. + If no option --dev is given, then the user gets asked which of the listed + drives to examine more closely. + If a privilege command and optional arguments are given with --priv_cmd, + then this command and arguments are used to launch the xorriso runs. + Command and arguments must be single words and be submitted altogether + as one single argument. On Solaris use: --priv_cmd pfexec + +./manual_burn -x ../xorriso/xorriso [-- [--dev device_file_to_use] + [--priv_cmd 'command [arg [arg ...]]'] + [--what ...directory...] [--any_media]] + Burns the content of the directory given with --what onto re-usable + media: CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE. + Other media types get refused, unless option --any_media is given. + Data, which are possibly present on the media, get overwritten. + The result gets check read and compared with the state of the input + directory. MD5 mismatch causes a test failure. Differences to the directory + state are reported but still regarded as success. + If a privilege command and optional arguments are given with --priv_cmd, + then this command and arguments are used to launch the xorriso runs. + Command and arguments must be single words and be submitted altogether + as one single argument. On Solaris use: + --priv_cmd pfexec + +./manual_isojigdo -x ../xorriso/xorriso + Exercises the production of a bootable Debian GNU/Linux image and its Jigdo + files. This test downloads a Debian daily image for i386 of about 270 MB, + extracts its content and composes a new image. Thus it needs about 850 MB + of disk space in releng/releng_generated_data when unpacked. Adding the daily + image size itself, the total space used would peak at about 1.2 GB. + This test will only work with GNU xorriso or if libjte was installed already + when libisofs was built. Further it needs the program jigit-mkimage. Both + are part of package jigit, version >= 1.18, available at: + http://www.einval.com/~steve/software/JTE/ + Currently jigit builds only in GNU environments. + + +Any auto_* script can be run on its own. Some of them demand option -x. +All general options are accepted. + +./auto_cxx + Not included in GNU xorriso. + Exercises inclusion of xorriso/xorriso.h and libisoburn/libisoburn.h + in C++ programs and linking of the libraries. It might be necessary + to set compiler options by shell variable CFLAGS before running the test. + It might be necessary to hand over the install directory of libburn and + libisofs in shell variable LD_LIBRARY_PATH. + E.g. if on FreeBSD the include headers libisofs.h , libburn.h are not found: + export CFLAGS="-I/usr/local/include" + E.g. on GNU/Hurd, where libburn and libisofs are not found by the linker: + export LD_LIBRARY_PATH="/usr/local/lib" + +./auto_isocontent -x ../xorriso/xorriso + Tests whether xorriso is able to record and restore two families of + hard links. + +./auto_printsize -x ../xorriso/xorriso + Tests how long xorriso needs to compose a medium sized directory tree. + If programs mkisofs and/or genisomage are available, then the same test + is done with them. + + +---------------------------------------------------------------------------- + + What to do with FAIL results + +The text output of the automatic tests is recorded in file + releng_generated_data/log.run_all_auto + +Script ./run_all_auto will detect failure of particular tests and report +lines from the log file which contain problem indicating keywords: + NEVER,ABORT,FATAL,FAILURE,MISHAP,SORRY,WARNING,HINT,FAIL,ERROR,WRONG + +If the program messages in log.run_all_auto do not explain the failure, +please contact mailing list libburn-hackers@pykix.org . + + +---------------------------------------------------------------------------- + + Alternative Shells + +If you decided against installing /bin/bash, you may try to use your +current $SHELL by running + ./change_shell_to_use +which will modify the test scripts named run_all_auto , auto_* ,manual_*. + +Known to be suitable are the following shells + GNU/Linux: /bin/bash + FreeBSD 8: /bin/sh + Solaris: /bin/bash , /bin/i86/ksh93 +In general, the shell should have Bourne shell ancestry. + +The script does not choose an interpreter explicitely and is safe to be run +inline: + . ./change_shell_to_use +One may set any interpreter path by running a sub shell and changing its +variable SHELL. E.g. by: + ( SHELL=/bin/my_shell" ; . ./change_shell_to_use ) + + +---------------------------------------------------------------------------- + + Creating a new test script + +If you want to provide an own test, manual or auto, then first invent a name +for it + test_name="releng/manual_"...some.name... +or + test_name="releng/auto_"...some.name... +Then copy file releng/template_new to $test_name. +Edit $test_name and process any line that begins by "# === TEMPLATE:". +Do what the line prescribes and then remove it from the script. You are +not done as long as such a line remains. + +Your test must not start if no file + ./inc/releng_getopts.inc +exists, i.e. if the current working directory is not ./releng. +If your test creates own files on disk, then it must do this underneath +directory + ./releng_generated_data/$test_name (or $GEN_DATA_DIR, see below). + +In case of failure, issue a line to stdout that begins by the word "FAIL", +followed by " : " and the name of the test (e.g. $SELF, see below). +Make sure that the test script finally returns a non-zero exit value. +This value should be between 1 and 28. Each type of failure should have its +own exit value. +Predefined are: + 31 = Unknown option or unusable argument with known option + 30 = Unexpected state of own directory for self generated files + 29 = Not in ./releng directory or missing essential parts of ./releng + +When exiting prematurely, make sure to call function cleanup. + + + Variables, general options, helper functions + +The master script run_all_auto sets this variable: + + RELENG_SCRIPT_RUN_BY_RUN_ALL_AUTO + 1=supervised, the script is run by run_all_auto script + else=standalone, the script is run in standalone mode + +The code piece inc/releng_getopts.inc should get executed inline at the +start of a test script. It initializes the following variables and sets +some of them according to the general options of the test suite: + + SELF basename $0 + + GEN_DATA_DIR releng_generated_data/${SELF} + + RELENG_XORRISO Path to xorriso binary. "" or "0" means no xorriso. + Default "0". Adjustable by option -x. + + SIMULATE_FAILURE 0=normal operation, 1=test script shall simulate a failure. + Default 0. Setable to 1 by option -f. + + CLEANUP 0=do not cleanup temporary data, 1=normal operation + Default 1. Setable to 0 by option -k. + + SPECIFIC_HELP 0=normal operation, 1=print help text of script and exit 0 + Default 0. Setable to 1 by option -h. + +The code piece inc/releng_getopts.inc defines the following functions +for use by the single tests: + + standalone_or_supervised This is internally called routine to print out + the running mode of the scripts - standalone, + supervised by run_all_auto. + No need to call it from the scripts themselves. + + print_help Prints the help text for general options. + + check_for_xorriso [-x] + Will exit with value 31 if no path to a xorriso binary + was defined by option -x of ./run_all_auto or a single + test. + Option -x of check_for_xorriso additionally tests whether + the given path leads to an executable program. + + cleanup Removes the directory tree GEN_DATA_DIR after making + some safety checks. + + boldify Try to set the terminal mode for future output to a more + noticeable style of writing. + unboldify Reset terminal mode to normal style of writing. + + + Specific options + +Options which are specific to the test should begin with a double dash. +They may have further arguments. +Implement them in the prepared interpreter loop which begins after line + next_is=ignore + +Specific options shall only be interpreted by tests which get run manually. +If you plan to introduce a specific option, look at the description of +existing tests whether one of them would match your needs. In that case, +please re-use the name of that existing option. + diff --git a/libisoburn/branches/1.4.6/releng/TODO b/libisoburn/branches/1.4.6/releng/TODO new file mode 100644 index 00000000..5df56f59 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/TODO @@ -0,0 +1,42 @@ + +* Manpage examples turned into tests + Convert most examples from xorriso(1) manpage into tests. + +* Enhance 'auto_isocontent' + Extend it to use some more demanding directory tree. + MD5s should be checked. + All file types as of stat(2) should be tested. + Test various comparisons: + xorriso provides built-in means for comparison: + xorriso -compare_r disk_path iso_rr_path + xorriso -indev my.iso -find / vs. find input_dir + bsdtar -xf my.iso vs. input_dir + +* Test for wrong CD sizes would need a new test and probably an + automatic CD changer. + +* Library unit tests - investigate the possibility to write some + cunit-based tests (http://cunit.sourceforge.net) for both + xorriso.h and libisoburn.h API's. The code samples could be put into + codesamples/ directory and run by auto_cxx or a separate auto_ script. + +* ??? Still to decide: + Delete debian-testing-i386-businesscard.iso with ./run_all_auto -c + Contra: Currently remaining large files (like downloaded ISO images) are + simply left behind to be re-used and a boldified info message is shown + so the users can decide for themselves what to remove or leave as well. + Pro: Leaving 70 MB of image is quite obtrusive. Option -c is not run + under normal circumstances. So it could well be used for total cleanup. + Alternative: Specific option --remove_image. + +* ??? Still to decide: + Have a script ./run_all_manual + Contra argument: if a releng sctipt is suitable to be run under a master + script run_all*, then this releng script should be put into auto_* + namespace , otherwise it is manual_*. + Pro: Tests may be manual because they demand lots of resources, not + because they need manual attention. In general the run_all_manual script + shall spare the user the plight to read the documentation. Instead it + shall present the manual tests, give an opportunity to skip the test, + and ask for parameters, + diff --git a/libisoburn/branches/1.4.6/releng/auto_cxx b/libisoburn/branches/1.4.6/releng/auto_cxx new file mode 100755 index 00000000..71ed53fe --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/auto_cxx @@ -0,0 +1,88 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Licensed under GNU GPL version 2 or later + +set -e + +not_in_releng_exit() { + printf "\nPlease execute the tests from releng directory.\n\n" + exit 1 +} + +. inc/releng_getopts.inc || not_in_releng_exit + +print_specific_help() { +cat << HLP +Specific options: + none yet. +Overview: + Tests both xorriso/xorriso.h and libisoburn/libisoburn.h + APIs for C++ cleanness. +HLP +} + +if test "$SPECIFIC_HELP" = 1; then + print_specific_help + exit 0 +fi + +# xorriso binary is not needed for that particular test +SAMPLE_CODE_DIR=codesamples +CC=g++ + +# check compiler +if ! which "${CC}" >/dev/null 2>&1; then + printf "\n${SELF}: Not found: ${CC}. Install ${CC}.\n" + cleanup + exit 5 +fi + +# check data dir +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use '${SELF} -c' to remove.\n" + exit 6 +else + mkdir "${GEN_DATA_DIR}" +fi + +INCLUDE_DIRS="-I../ -I../../libburn -I../../libisofs -I/usr/local/include -I/usr/pkg/include" + +# process sample code tests + for SMPL in `ls "${SAMPLE_CODE_DIR}"/*.cpp`; do + # CMD_CPL="${CC} -I../ -L ../libisoburn/.libs/ ${CFLAGS} -lisoburn -o ${SMPL}.obj ${SMPL}" + CMD_CPL="${CC} -c ${INCLUDE_DIRS} ${CFLAGS} -o ${SMPL}.obj ${SMPL}" + printf "${SELF}: ${CMD_CPL}" + set +e + ${CMD_CPL} + RET_CPL="$?" + if [ ${RET_CPL} = 0 -a -f ${SMPL}.obj ]; then + mv ${SMPL}.obj ${GEN_DATA_DIR} + printf "...ok\n" + else + printf "\nFAIL : ${SELF}: Compilation of ${SMPL}\n" + cleanup + exit 7 + fi +# BASE=$(basename ${SMPL}.obj) +# printf "${SELF}: Running LD_LIBRARY_PATH=../libisoburn/.libs/:${LD_LIBRARY_PATH} ${GEN_DATA_DIR}/${BASE}" +# LD_LIBRARY_PATH=../libisoburn/.libs/:${LD_LIBRARY_PATH} ${GEN_DATA_DIR}/${BASE} +# RET_SMPL="$?" +# case ${RET_SMPL} in +# 0) +# printf "...ok\n" +# ;; +# *) +# printf "exit code: ${RET_SMPL}\n" +# cleanup +# exit 8 +# ;; +# esac + set -e + done + +# clean +cleanup + +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/auto_isocontent b/libisoburn/branches/1.4.6/releng/auto_isocontent new file mode 100755 index 00000000..b708d40a --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/auto_isocontent @@ -0,0 +1,400 @@ +#!/bin/bash + +# Copyright 2011 Thomas Schmitt +# Copyright 2011 George Danchev +# Licensed under GNU GPL version 2 or later + +# Test the correct handling of hardlinks by xorriso options +# -update_r , -hardlinks perform_update , and -extract +# If there is support for ACLs or xattr in xorriso and on the local system, +# then test recording and restoring of these features. + +not_in_releng_exit() { + printf "\nPlease execute the tests from releng directory.\n\n" + exit 1 +} + +. inc/releng_getopts.inc || not_in_releng_exit + +print_specific_help() { +cat << HLP +Specific options: + none yet. +Overview: + Tests ISO image contents by performing various + image generation, extractions and comparisons. +HLP +} + +if test "$SPECIFIC_HELP" = 1; then + print_specific_help + exit 0 +fi + +if [ ! -x $RELENG_XORRISO ]; then + print_help + printf "\n${SELF}: -x absolute or relative path to binary to be run.\n\n" + exit 31 +fi + +# check data dir, if any and after checking -x xorriso +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use '${SELF} -c' to remove.\n" + exit 8 +else + mkdir "${GEN_DATA_DIR}" +fi + +export xorriso=${RELENG_XORRISO} +export workdir=${GEN_DATA_DIR} +export image_file="$workdir"/xorriso_hardlinks.iso +export on_disk="$workdir"/xorriso_hardlinks_test_dir +export in_iso="" +export copy_on_disk="$workdir"/xorriso_hardlinks_copy_dir +export failure=0 +export simulate_failure=${SIMULATE_FAILURE} +export next_is_xorriso=0 +export next_is_rc=0 +export bad=0 +export report_about="-report_about UPDATE" + +test -z "$in_iso" && in_iso="$on_disk" + +# mkdir "$workdir" || bad=1 +mkdir "$on_disk" || bad=1 +if test "$bad" = 1 +then + echo -e "\nFAIL : ${SELF} : Test environment error : Cannot make directories" + exit 3 +fi + + +# All must be set at this point +printf "\n${SELF}: Setting up $on_disk with several hardlinks\n" >&2 +echo test_content >"$on_disk"/file_1 || exit 1 +echo test_content >"$on_disk"/file_2 || exit 1 +ln "$on_disk"/file_1 "$on_disk"/file_1_link_a || exit 1 +ln "$on_disk"/file_1 "$on_disk"/file_1_link_b || exit 1 +ln "$on_disk"/file_2 "$on_disk"/file_2_link_a || exit 1 + +# trivial ISO 9660 image validation routine +is_valid_iso9660() { + ISOfile="$1" + if ! which file >/dev/null 2>&1; then + printf "\nFAIL : ${SELF}: Not found: file. Please install the file(1) utility.\n" + failure=1 + return + fi + if [ ! -f ${ISOfile} ]; then + failure=1 + printf "\nFAIL : ${SELF} : Not found: ${ISOfile}\n" + return + fi + + file ${ISOfile} + if file ${ISOfile} | grep "ISO *9660" >/dev/null 2>&1; then + printf "\n${SELF}: Resulting ${ISOfile} OK. Looks like ISO 9660 filesystem.\n" + else + failure=1 + printf "\nFAIL : ${SELF} : ${ISOfile} DOES NOT look like ISO 9660 filesystem data.\n" + fi +} + +# Retrieve and evaluate return value of command run under return_wrapper +check_xorriso_return() { + ret=$(cat "$return_value_file") + rm "$return_value_file" + if test "$ret" = 0 + then + return 0 + fi + failure=1 + echo + echo "FAIL : ${SELF} : xorriso run exited with value $ret" + return 1 +} + +# Create test file and find out whether ACLs and/or xattr are available. +# +# Users known on GNU/Linux and FreeBSD: root games daemon man +# Groups : daemon games bin sshd sys +# On both systems, ACLs are manipulated by setfacl/getfacl +# +acl_xattr_test_file="$on_disk"/acl_xattr_test_file +acl_xattr_copy_file="$copy_on_disk"/acl_xattr_test_file +acl_xattr_test_dir="$on_disk"/acl_xattr_test_dir +acl_xattr_iso_dir="$in_iso"/acl_xattr_test_dir +acl_xattr_copy_dir="$copy_on_disk"/acl_xattr_test_dir +mkdir "$acl_xattr_test_dir" +echo echo hello world >"$acl_xattr_test_file" || exit 1 +sys=$(uname -s) +acls=no +default_acls=no +setfacl_opts="" +if ( setfacl -m u::rwx,g::r-x,o::---,u:root:rwx,g:sys:rwx,u:daemon:r--,mask::rwx \ + "$acl_xattr_test_file" ) >/dev/null 2>&1 +then + if ( getfacl "$acl_xattr_test_file" ) >/dev/null 2>&1 + then + if ( setfacl -m u::rwx,g::r-x,o::---,u:root:rwx,g:sys:rwx,u:daemon:r--,mask::rwx \ + "$acl_xattr_test_dir" ) >/dev/null 2>&1 + then + acls=yes + # Setting of "default" ACLs will fail on FreeBSD. It will nevertheless be + # done in the image by a xorriso command. Restoring is supposed to skip + # "default" ACLs if none could be recorded. + if setfacl -m u::rwx,g::r-x,o::---,u:root:rwx,g:sys:rwx,u:daemon:r--,mask::rwx,d:u::rwx,d:g::r-x,d:o::---,d:u:root:rwx,d:g:sys:rwx,d:u:daemon:r--,d:mask::rwx "$acl_xattr_iso_dir" 2>/dev/null + then + default_acls=yes + fi + setfacl_opts="-setfacl u::rwx,g::r-x,o::---,u:root:rwx,g:sys:rwx,u:daemon:r--,mask::rwx,d:u::rwx,d:g::r-x,d:o::---,d:u:root:rwx,d:g:sys:rwx,d:u:daemon:r--,d:mask::rwx $acl_xattr_iso_dir --" + fi + fi +fi + +# GNU/Linux and FreeBSD have different tools for Extended Attributes +xattrs=no +extattrs=no +# Try GNU/Linux style setattr/getattr +if ( setfattr -n user.test_xattr -v test_value "$acl_xattr_test_file" ) \ + >/dev/null 2>&1 +then + if ( getfattr -d "$acl_xattr_test_file" ) >/dev/null 2>&1 + then + xattrs=yes + setfattr -n user.long_data -v 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 "$acl_xattr_test_file" + setfattr -n user.more_data -v 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 "$acl_xattr_test_file" + fi +fi +if test "$xattrs" = no +then + # Try FreeBSD style setextattr + if ( setextattr user test_xattr test_value "$acl_xattr_test_file" ) \ + >/dev/null 2>&1 + then + if ( getextattr user test_xattr "$acl_xattr_test_file" ) >/dev/null 2>&1 + then + setextattr user long_data 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 "$acl_xattr_test_file" + setextattr user more_data 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 "$acl_xattr_test_file" + if ( lsextattr user "$acl_xattr_test_file" ) >/dev/null 2>&1 + then + extattrs=yes + fi + fi + fi +fi + +echo +echo "${SELF}: Detected sys='$sys' , acls=$acls , d_acls=$default_acls , xattrs=$xattrs , extattrs=$extattrs" + +# Examine capabilities of xorriso +xorriso_acls=no +xorriso_xattrs=no +extras=$("$xorriso" -list_extras all 2>/dev/null) +if test "$?" = 0 +then + if echo "$extras" | fgrep 'Local ACL : yes' >/dev/null 2>&1 + then + xorriso_acls=yes + fi + if echo "$extras" | fgrep 'Local xattr : yes' >/dev/null 2>&1 + then + xorriso_xattrs=yes + fi +fi +if test "$xorriso_acls" = no +then + acls=no + setfacl_opts= +fi +if test "$xorriso_xattrs" = no +then + xattrs=no + extattrs=no +fi + +echo "${SELF}: Detected xorriso_acls=$xorriso_acls , xorriso_xattrs=$xorriso_xattrs" +echo +ls -l "$on_disk"/* + +echo -e "\n${SELF}: Producing simple image via -o" >&2 +"$xorriso" -as mkisofs "$on_disk" -o "$workdir"/image_minus_o.iso +is_valid_iso9660 "$workdir"/image_minus_o.iso + +echo -e "\n${SELF}: Producing simple image via redirect" >&2 +"$xorriso" -as mkisofs "$on_disk" > "$workdir"/image_redirected.iso +is_valid_iso9660 "$workdir"/image_redirected.iso + +echo -e "\n${SELF}: Producing simple image via pipe" >&2 +return_wrapper "$xorriso" -as mkisofs "$on_disk" | \ + cat > "$workdir"/image_piped.iso +check_xorriso_return +is_valid_iso9660 "$workdir"/image_piped.iso + +echo -e "\n${SELF}: Producing simple image with for_backup/update_r/hardlinks" >&2 +"$xorriso" \ + $report_about \ + -version \ + -for_backup \ + -padding 0 \ + -outdev "$image_file" \ + -volid TEST_AUTO_ISOCONTENT \ + -update_r "$on_disk" "$in_iso" \ + $setfacl_opts \ + -hardlinks perform_update +ret=$? + +if test "$ret" -gt 0 -a "$ret" -lt 32 +then + printf "\nFAIL : ${SELF} : xorriso write run failed\n\n" + cleanup + exit 1 +fi +is_valid_iso9660 "$image_file" + + +# It must refuse to load and go on with -assert_volid and non-matching pattern. +msg=$(\ +"$xorriso" \ + -abort_on FATAL \ + -return_with FAILURE 32 \ + -assert_volid 'NON_MATCHING*' FATAL \ + -indev "$image_file" \ + 2>&1 +) +ret=$? +if test "$ret" -gt 0 -a "$ret" -lt 32 +then + printf "\n${SELF}: Ok. -assert_volid snapped.\n" +elif test "$ret" -ne 0 +then + failure=1 + echo >&2 + echo "$msg" >&2 + printf "\nFAIL : ${SELF} : -assert_volid test not properly performed\n\n" +else + failure=1 + printf "\nFAIL : ${SELF} : -assert_volid did not snap\n\n" >&2 +fi + +echo -e "\n${SELF}: Copying from image to temporary disk tree" >&2 +"$xorriso" \ + $report_about \ + -for_backup \ + -assert_volid 'TEST_AUTO_ISOCONT*' FATAL \ + -indev "$image_file" \ + -osirrox on \ + -find "$in_iso" -exec lsdl -- \ + -extract "$in_iso" "$copy_on_disk" +ret=$? +if test "$ret" -gt 0 -a "$ret" -lt 32 +then + printf "\nFAIL : ${SELF} : xorriso file extraction run failed\n\n" + cleanup + exit 1 +fi + +if test "$simulate_failure" = 1 +then + echo -e "\n${SELF}: SIMULATING FAILURE BY REMOVING AN EXTRACTED FILE" >&2 + echo -e "\nFAIL : ${SELF} : Simulated failure caused by option -fail" + rm "$copy_on_disk"/file_1_link_b +fi + + +printf "\n${SELF}: Comparing original disk tree and temporary one..." >&2 +diff -r "$on_disk" "$copy_on_disk" +if test "$?" -ne 0 +then + echo -e "\nFAIL : ${SELF} : diff -r $on_disk $copy_on_disk reports differences" >&2 + echo -e "\nFAIL : ${SELF} : diff -r reports differences" + failure=1 +else + printf "OK" >&2 +fi + +printf "\n${SELF}: Checking for hardlinks being siblings...\n" +ls -l "$copy_on_disk"/* +x=$(echo $(ls -ld "$copy_on_disk"/*file* | awk '{print $2}')) +expected="1 3 3 3 2 2" +if test x"$x" = x"$expected" +then + printf "${SELF}: Checking for hardlinks being siblings done: ok.\n" >&2 +else + printf "\nFAIL : ${SELF} : Link count of extracted files is not as expected." >&2 + printf "\n${SELF}: Expected: $expected" >&2 + printf "\n${SELF}: Got : $x\n" >&2 + failure=1 +fi + +if test "$acls" = yes +then + printf "\n${SELF}: Checking ACLs ...\n" >&2 + acl_on_disk=$(getfacl "$acl_xattr_test_file" | grep -v '^# file:' | sort) + acl_in_copy=$(getfacl "$acl_xattr_copy_file" | grep -v '^# file:' | sort) + if test "$acl_on_disk" = "$acl_in_copy" + then + printf "${SELF}: Checking ACLs done: ok.\n" >&2 + else + printf "\nFAIL : ${SELF} : ACL mismatch between original and extracted copy\n" + printf "\nOriginal:\n${acl_on_disk}\n" + printf "\nCopy:\n${acl_in_copy}\n" + failure=1 + fi +fi + +if test "$xattrs" = yes +then + printf "\n${SELF}: Checking xattr via getfattr ...\n" >&2 + xattr_on_disk=$(getfattr "$acl_xattr_test_file" | \ + grep -v '^# file:' | grep -v '^$' | \sort) + xattr_in_copy=$(getfattr "$acl_xattr_copy_file" | + grep -v '^# file:' | grep -v '^$' | sort) + if test "$xattr_on_disk" = "$xattr_in_copy" + then + num_xattr=$(echo "$xattr_on_disk" | wc -l) + printf "${SELF}: Checking xattr done: $num_xattr attributes, ok.\n" >&2 + else + printf "\nFAIL : ${SELF} : xattr mismatch between original and extracted copy\n" + printf "\nOriginal:\n${xattr_on_disk}\n" + printf "\nCopy:\n${xattr_in_copy}\n" + failure=1 + fi +elif test "$extattrs" = yes +then + printf "\n${SELF}: Checking xattr via lsextattr and getextattr ...\n" >&2 + lsext_on_disk=$(lsextattr -q user "$acl_xattr_test_file") + xattr_on_disk=$(for i in $lsext_on_disk ; do echo $i $(getextattr -q user $i "$acl_xattr_test_file"); done | sort) + lsext_in_copy=$(lsextattr -q user "$acl_xattr_copy_file") + xattr_in_copy=$(for i in $lsext_in_copy ; do echo $i $(getextattr -q user $i "$acl_xattr_copy_file"); done | sort) + if test "$xattr_on_disk" = "$xattr_in_copy" + then + num_xattr=$(echo "$xattr_on_disk" | wc -l) + printf "${SELF}: Checking xattr done: $num_xattr attributes, ok.\n" >&2 + else + printf "\nFAIL : ${SELF} : xattr mismatch between original and extracted copy\n" + printf "\nOriginal:\n${xattr_on_disk}\n" + printf "\nCopy:\n${xattr_in_copy}\n" + failure=1 + fi + +fi + +# +echo +cleanup + +# Report result +echo +if test "$failure" = 1 +then + printf "${SELF}: FAILED" + echo + exit 1 +else + printf "${SELF}: Passed" + echo +fi + +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/auto_printsize b/libisoburn/branches/1.4.6/releng/auto_printsize new file mode 100755 index 00000000..fd00fab5 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/auto_printsize @@ -0,0 +1,149 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Licensed under GNU GPL version 2 or later + +set -e + +not_in_releng_exit() { + printf "\nPlease execute the tests from releng directory.\n\n" + exit 1 +} + +# Include common bits +. inc/releng_getopts.inc || not_in_releng_exit + +print_specific_help() { +cat << HLP +Specific options: + none yet. +Overview: + Test performance of print_size against various input tree. + Optionally compare with genisoimage and mkisofs. +HLP +} + +if test "$SPECIFIC_HELP" = 1; then + print_specific_help + exit 0 +fi + +# Each test should decide whether or not it needs +# a xorriso binary to test, since some do compilations only. +if [ ! -x $RELENG_XORRISO ]; then + print_help + printf "\n${SELF}: -x absolute or relative path to binary to be run.\n\n" + exit 31 +fi + +# check data dir, if any and after checking -x xorriso +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use '${SELF} -c' to remove.\n" + exit 8 +else + mkdir "${GEN_DATA_DIR}" +fi + +# +DIR_UPPER=32 +FILE_UPPER=10 + +# All must be set at this point +# TODO: work out a smarter way to quickly generate different +# types of trees (long, deep, etc) +printf "\n${SELF}: Generating sample tree in ${GEN_DATA_DIR} :\n" +count=0 +date + +# Hopefully the for-loops are much faster than while-loops with arithmetics +# This needs 7/4*DIR_UPPER+FILE_UPPER (= 66) while-iterations +# +i1_list= +i1=0 +o1=$(expr ${DIR_UPPER} / 4) +while test $i1 -lt $o1 +do + i1_list="$i1_list $i1" + i1=$(expr $i1 + 1) +done +i2_list= +i2=0 +o2=$(expr ${DIR_UPPER} / 2) +while test $i2 -lt $o2 +do + i2_list="$i2_list $i2" + i2=$(expr $i2 + 1) +done +i3_list= +i3=0 +while test $i3 -lt ${DIR_UPPER} +do + i3_list="$i3_list $i3" + i3=$(expr $i3 + 1) +done +i_file_list= +i_file=0 +while test $i_file -lt ${FILE_UPPER} +do + i_file_list="$i_file_list $i_file" + i_file=$(expr $i_file + 1) +done +# +# plus 1/8*DIR_UPPER*DIR_UPPER*DIR_UPPER*FILE_UPPER (= 40960) for-iterations +# +for i1 in $i1_list +do + for i2 in $i2_list + do + for i3 in $i3_list + do + mkdir -p ${GEN_DATA_DIR}/DirOne$i1/DirTwo$i2/DirThree$i3 + for i_file in $i_file_list + do + echo -n \ + > ${GEN_DATA_DIR}/DirOne$i1/DirTwo$i2/DirThree$i3/File_${i_file} + count=$((count + 1)) + done + done + done + echo " ${count} files created ..." +done + +printf "done.\n" +date +du -s "${GEN_DATA_DIR}" + +printf "\n${SELF}: Performing several print size runs to neutralize possible disk cache impact.\n" + +# run xorriso +if [ -x ${RELENG_XORRISO} ]; then + for run in 1 2 3; do + printf "\n${SELF}: Running ${RELENG_XORRISO} -as mkisofs -quiet -print-size ${GEN_DATA_DIR}. Trial: ${run}.\n" + time ${RELENG_XORRISO} -as mkisofs -quiet -print-size ${GEN_DATA_DIR} + done +fi + +# try to run genisoimage +if which genisoimage >/dev/null 2>&1; then + RELENG_GENISOIMAGE=`which genisoimage` + for run in 1 2 3; do + printf "\n${SELF}: Running ${RELENG_GENISOIMAGE} -quiet -print-size ${GEN_DATA_DIR}. Trial: ${run}.\n" + time ${RELENG_GENISOIMAGE} -quiet -print-size ${GEN_DATA_DIR} + done +fi + +# try to run mkisofs +if which mkisofs >/dev/null 2>&1; then + RELENG_MKISOFS=`which mkisofs` + for run in 1 2 3; do + printf "\n${SELF}: Running ${RELENG_MKISOFS} -quiet -print-size ${GEN_DATA_DIR}. Trial: ${run}.\n" + time ${RELENG_MKISOFS} -quiet -print-size ${GEN_DATA_DIR} + done +fi + +# +cleanup + +# +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/change_shell_to_use b/libisoburn/branches/1.4.6/releng/change_shell_to_use new file mode 100755 index 00000000..341cead6 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/change_shell_to_use @@ -0,0 +1,39 @@ + +# check whether we are in releng and create dir +mkdir_ret=29 +if test -d releng_generated_data +then + if test -d releng_generated_data/change_shell_to_use + then + mkdir_ret=0 + else + mkdir releng_generated_data/change_shell_to_use + mkdir_ret=$? + fi +fi + +if test "$mkdir_ret" = 0 +then + for i in run_all_auto auto_* manual_* + do + temp=releng_generated_data/change_shell_to_use/temp_file + c=$(wc -l "$i" | awk '{print $1}') + line=$(head -n 1 "$i") + + if echo x"$line" | grep '^x#!' >/dev/null 2>&1 + then + cp "$i" "$temp" + echo '#!'"$SHELL" > "$temp" + tail -n "$(expr $c - 1)" "$i" >> "$temp" + mv "$temp" "$i" + echo "Changed to #!$SHELL : $i" + fi + done + rmdir releng_generated_data/change_shell_to_use +else + echo "change_shell_to_use: Missing directory ./releng_generated_data" >&2 + echo "or cannot create directory ./releng_generated_data/change_shell_to_use" >&2 + echo "change_shell_to_use: Run aborted" + test 1 = 0 +fi + diff --git a/libisoburn/branches/1.4.6/releng/codesamples/api_3lib.cpp b/libisoburn/branches/1.4.6/releng/codesamples/api_3lib.cpp new file mode 100644 index 00000000..92611b3c --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/codesamples/api_3lib.cpp @@ -0,0 +1,34 @@ +// Just to ensure we are C++-clean. This should not spit too much noise + +/* Copyright 2011 George Danchev + * Released into the public domain + */ + +#if __WORDSIZE == 32 +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#include +#include + +//extern "C" { +#include "libburn/libburn.h" +#include "libisofs/libisofs.h" +// using namespace burn; +// (this was needed to before rev.4062 of libisoburn) +#include "libisoburn/libisoburn.h" +//} + +int main() { + int major=-1, minor=-1, micro=-1; + isoburn_version(&major, &minor, µ); + if (major<0 || minor<0 || micro<0) + return -1; + std::cout + << " major:" << major + << " minor:" << minor + << " micro:" << micro + ; + return 0; +} diff --git a/libisoburn/branches/1.4.6/releng/codesamples/api_xorriso.cpp b/libisoburn/branches/1.4.6/releng/codesamples/api_xorriso.cpp new file mode 100644 index 00000000..bcfcb3f1 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/codesamples/api_xorriso.cpp @@ -0,0 +1,30 @@ +// Just to ensure we are C++-clean. This should not spit too much noise + +/* Copyright 2011 George Danchev + * Released into the public domain + */ + +#if __WORDSIZE == 32 +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#include +#include + +//extern "C" { +#include "xorriso/xorriso.h" +//} + +int main() { + int major=-1, minor=-1, micro=-1; + Xorriso__version(&major, &minor, µ); + if (major<0 || minor<0 || micro<0) + return -1; + std::cout + << " major:" << major + << " minor:" << minor + << " micro:" << micro + ; + return 0; +} diff --git a/libisoburn/branches/1.4.6/releng/inc/releng_getopts.inc b/libisoburn/branches/1.4.6/releng/inc/releng_getopts.inc new file mode 100644 index 00000000..ecae07dc --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/inc/releng_getopts.inc @@ -0,0 +1,198 @@ +# Copyright 2011 George Danchev +# Copyright 2011 Thomas Schmitt +# Licensed under GNU GPL version 2 or later + +SELF=$(basename $0) +RELENG_XORRISO=0 +SIMULATE_FAILURE=0 +CLEANUP=1 +SPECIFIC_HELP=0 +START_DIR_DONT_CHANGE=`pwd` +GEN_DATA_DIR=releng_generated_data/${SELF} + +############################################# +standalone_or_supervised() { + case "${RELENG_SCRIPT_RUN_BY_RUN_ALL_AUTO}" in + 1) + echo "${SELF}: Running in Supervised mode" + ;; + *) + echo "${SELF}: Running in Standalone mode" + ;; + esac +} + +# Unconditionally shout out the invocation mode - standalone or supervised +standalone_or_supervised + +############################################# +print_help() { +cat << EOF + +Usage: $SELF -x path/to/xorriso [-k] [-f] [-c] [-h] + [-- ...test specific options...] +General options: + -x absolute or relative path to xorriso binary to be run. + -k keep self-generated data. + -c cleanup self-generated data kept from previous run and exit. + -f simulate failure. + -h print this help text + -- end of general options, begin of test specific options. +EOF +} + +############################################# +boldify() { + if which tput >/dev/null 2>&1; then tput smso; fi +} + +############################################# +unboldify() { + if which tput >/dev/null 2>&1; then tput rmso; fi +} + +############################################# +cleanup() { + if [ ${CLEANUP} -eq 1 ]; then + # safety net, just in case -> we want to be in the starting + # directory before removing whatever self-generated stuff + if [ -d "${GEN_DATA_DIR}" ]; then + cd "${START_DIR_DONT_CHANGE}" || exit 2 + + # Verify once again we are in the releng_generated_data directory + # Check for both returned code of grep and returned matching string + # There is no "readlink -e" on FreeBSD + READ_CANON_EXISTS=`cd "${GEN_DATA_DIR}" 2>/dev/null && pwd` + DIR_NAME_GEN_DATA=`dirname "${READ_CANON_EXISTS}"` + set +e + # There is no "grep -P" on FreeBSD + RET_NON_EMPTY_STRING=`echo "${DIR_NAME_GEN_DATA}" | grep "[a-zA-Z0-9_][a-zA-Z0-9_]*/releng_generated_data$"` + GREP_RET_GEN_DATA="$?" + case "${GREP_RET_GEN_DATA}" in + 0) + if [ x"${RET_NON_EMPTY_STRING}" != x"" ]; then + # now call the nastiness + chmod -R +w ${GEN_DATA_DIR} + rm -rf ${GEN_DATA_DIR} +# boldify + printf "${SELF}: Removed (self-generated) %s\n" ${GEN_DATA_DIR} +# unboldify + else + printf "FAIL : ${SELF} : Safety check for being in releng_generated_data directory.\n" + printf "FAIL : ${SELF} : GREP returned empty string: ${RET_NON_EMPTY_STRING}.\n" + printf "FAIL : ${SELF} : Skipped trying to remove ${GEN_DATA_DIR} directory. Exiting.\n" + fi + ;; + *) + printf "FAIL : ${SELF} : Safety check for being in releng_generated_data directory.\n" + printf "FAIL : ${SELF} : GREP returned code: ${GREP_RET_GEN_DATA}.\n" + printf "FAIL : ${SELF} : Skipped trying to remove ${GEN_DATA_DIR} directory. Exiting.\n" + exit 30 + ;; + esac + else + printf "${SELF}: ${GEN_DATA_DIR} does not exist. Nothing to clean.\n" + fi + else +# boldify + printf "${SELF}: Leaving (self-generated) %s\n" ${GEN_DATA_DIR} +# unboldify + fi +} + +############################################# +check_for_xorriso() { + # $1: if "-x" then check executability + + if test -z "$RELENG_XORRISO" -o "$RELENG_XORRISO" = "0" + then + print_help +# print_specific_help + echo + echo "${SELF}: Need -x absolute or relative path to xorriso binary." + echo + exit 31 + fi + if [ x"$1" = x"-x" -a ! -x "$RELENG_XORRISO" ] + then + print_help +# print_specific_help + echo + echo "${SELF}: Path given by option -x does not lead to an executable file." + echo "Given is: '$RELENG_XORRISO'" + if test "$RELENG_XORRISO" = "xorriso" + then + xorriso=$(type -p xorriso) + if test -n "xorriso" + then + echo "Hint: Try '$xorriso'" + fi + fi + echo + exit 31 + fi +} + + +############################################# + +# To catch the exit value of a command in a pipe +return_value_file="$GEN_DATA_DIR"/wrapper_"$$"_return_value +return_wrapper() +{ + cmd="$1" + shift 1 + "$cmd" "$@" + RET="$?" + echo "$RET" >"$return_value_file" + return "$RET" +} + +############################################# + +next_is= +for i in "$@" +do + if test "$next_is" = "ignore" + then : + elif test "$next_is" = "x" + then + RELENG_XORRISO="$i" + next_is= + elif test x"$i" = x"-x" + then + next_is="x" + elif test x"$i" = x"-k" + then + CLEANUP=0 + elif test x"$i" = x"-c" + then + CLEANUP=1 + cleanup + exit 0 + elif test x"$i" = x"-f" + then + SIMULATE_FAILURE=1 + elif test x"$i" = x"-h" + then + print_help + SPECIFIC_HELP=1 + elif test x"$i" = x"--" + then + # Begin of private arguments for caller + next_is="ignore" + else + echo >&2 + echo "Unknown general option: $i" >&2 + print_help + exit 31 + fi +done + +if test "$next_is" = x +then + echo >&2 + echo "Option -x expects an argument (the path to the xorriso program)" >&2 + print_help + exit 31 +fi diff --git a/libisoburn/branches/1.4.6/releng/inc/test_releng_getopt b/libisoburn/branches/1.4.6/releng/inc/test_releng_getopt new file mode 100755 index 00000000..740faf16 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/inc/test_releng_getopt @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +. releng_getopts.inc + +boldify +printf "\ntesting boldify and unboldify..." +unboldify + +printf "\nSELF =${SELF}" +printf "\nRELENG_XORRISO =${RELENG_XORRISO}" +printf "\nSIMULATE_FAILURE =${SIMULATE_FAILURE}" +printf "\nCLEANUP =${CLEANUP}" +printf "\nSPECIFIC_HELP =${SPECIFIC_HELP}" +printf "\nSTART_DIR_DONT_CHANGE =${START_DIR_DONT_CHANGE}" +printf "\nGEN_DATA_DIR =${GEN_DATA_DIR}" +printf "\n" + +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list b/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list new file mode 100755 index 00000000..381c441b --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list @@ -0,0 +1,175 @@ +#!/bin/sh + +# Copyright (c) 2010, 2011 George Danchev +# Copyright (c) 2010, 2011 Thomas Schmitt +# This script is distributed according to the terms of the GNU GPL v2. +# This should be better rewritten in C at some future point. Ref: pwd code. + +# Create a list of MD5sums encoded in hexidecimal format and print to standard output + +# Format Description +# A line in the emerging file is to be composed as follows: +# +# The MD5 checksum of the file content must be encoded in 32 hex digits +# [0-9afAF] +# +# Next come two blanks. +# +# The byte size of the file content must be encoded in 12 decimal digits +# or blanks. +# +# Next come two blanks. +# +# The rest of the line up to the newline character is a semi-literal file +# address. Its basename has to be the same as the basename of the data file +# when it is used as one of the input files for the jigdo file generator. + +# The semi-literal address and the address mapping define what will be +# listed as file address in the jigdo file. +# The address may bear at its start a literal text that shall be recognized by +# the address mapping (e.g. -jigdo-map) of the jigdo file generator. +# The rest of the address must be usable as file address in both situations: +# When the jigdo file gets generated, and when the jigdo file gets read +# to inflate the template file into the original payload image. +# The address mappings at both occasions can be used to adapt to a change +# of the absolute location of the listed files. +# Between both mappings, the parent directory is represented by a symbolic +# text, like "Debian:". + +# A simple strategy to cope with this is to write absolute paths into the +# .md5 file, and to use matching absolute paths in the -jigdo-map +# directives. Keep in mind that mapping is purely literal. Symbolic links +# are neither resolved nor can they confuse the mapping. + +set -e + +SELF=jigdo-gen-md5-list +VER=0.2 + +OPT_ABSOLUTE=1 + +# On FreeBSD there is "md5" rather than "md5sum". +# Furthermore, the FreeBSD shell reports missing commands to inherited stderr, +# regardless that the attempt itself has redirected stderr. Thus a sub shell +# is needed to hide the protest. +if ( md5sum --help ) >/dev/null 2>&1 +then + md5_cmd=md5sum +elif ( md5 -s test ) >/dev/null 2>&1 +then + md5_cmd=md5 +else + echo "$0 : Programs md5sum and md5 failed to work" >&2 + exit 2 +fi + +usage() { + cat << USAGE +usage: $SELF [option] DIR FILE ... + -a, --make-absolute make absolute paths, avoiding any symlinks (default) + -l, --keep-literal leave paths untouched, literally as supplied + -v, --version print version + -h, --help print help + -e, --examples print examples +USAGE +} + +examples() { + cat << EXAMPLES +examples: + $SELF datadir datafile + $SELF --keep-literal datadir datafile + find . -type f | xargs $SELF + find . -exec $SELF '{}' ';' +EXAMPLES +} + +md5list() { + item="$1" + if test $OPT_ABSOLUTE -eq 1; then + dn=`dirname "$item"` # dirname + fn=`basename "$item"` # filename + od=`pwd -P` # old dir + cd "$dn" || exit 1 + item=`pwd -P`/"$fn" # absolute physical file path, avoiding all symlinks + cd "$od" || exit 1 + fi + if test "$md5_cmd" = "md5sum" + then + MD5=`md5sum "$item" | awk '{print $1}'` + elif test "$md5_cmd" = "md5" + then + MD5=`md5 -q "$item"` + else + echo "$0 : No MD5 program found" >&2 + exit 2 + fi + SIZ=`ls -ld "$item" | awk '{print $5}'` + printf '%32s %12s %s\n' "$MD5" "$SIZ" "$item" +} + +walkdir() { + DR="$1" + for item in `find "$DR" -type f` + do + md5list "$item" + done +} + + +# main() +if test "$1" = "" ; then + usage + exit 1 +fi + +case "$1" in + --make-absolute|-a) + OPT_ABSOLUTE=1; + shift; + ;; + --keep-literal|-l) + OPT_ABSOLUTE=0; + shift; + ;; + --version|-v) + printf '%s %s\n' "$SELF" "$VER" + exit 0 + ;; + --help|-h) + usage + exit 0 + ;; + --examples|-e) + examples + exit 0 +# *) +# usage +# exit 1 +# ;; +esac + +for i in "$@" +do + + if test -d "$i" ; then + DR="$i" + if test $OPT_ABSOLUTE -eq 1; then + od=`pwd -P` # old dir + cd "$DR" || exit 1 + DR=`pwd -P` # absolute physical dir path, avoiding all symlinks + cd "$od" || exit 1 + fi + walkdir "$DR" + elif test -f "$i" ; then + FL="$i" + md5list "$FL" + else + usage + exit 1 + fi; + +done + +exit 0 + diff --git a/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list.1 b/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list.1 new file mode 100644 index 00000000..ae6ff061 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/jigdo-gen-md5-list.1 @@ -0,0 +1,30 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. +.TH JIGDO-GEN-MD5-LIST "1" "October 2010" "jigdo-gen-md5-list 0.1" "User Commands" +.SH NAME +jigdo-gen-md5-list \- create a list of MD5sums encoded in hexidecimal format and print to standard output +.SH DESCRIPTION +usage: jigdo\-gen\-md5\-list [option] DIR FILE ... +.TP +\fB\-a\fR, \fB\-\-make\-absolute\fR +make absolute paths, avoiding any symlinks (default) +.TP +\fB\-l\fR, \fB\-\-keep\-literal\fR +leave paths untouched, literally as supplied +.TP +\fB\-v\fR, \fB\-\-version\fR +print version +.TP +\fB\-h\fR, \fB\-\-help\fR +print help +.TP +\fB\-e\fR, \fB\-\-examples\fR +print examples +.SH FORMAT + +File format is described in the beginning of the script itself. + +.SH "SEE ALSO" +xorriso(1), jigdo-lite(1), jigit-mkimage(1) + +.SH AUTHOR +Written by George Danchev and Thomas Schmitt diff --git a/libisoburn/branches/1.4.6/releng/manual_burn b/libisoburn/branches/1.4.6/releng/manual_burn new file mode 100755 index 00000000..aabb87b1 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/manual_burn @@ -0,0 +1,256 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Copyright 2011 Thomas Schmitt +# +# Licensed under GNU GPL version 2 or later + +set -e +# set -x + +print_specific_help() { +cat << HLP +Specific options: + --dev path use path as drive address. Default: /dev/cdrw + --what path use path as address of the directory which shall + be copied into an ISO 9660 filesystem on media. + --any_media allow non re-usable MMC media, like CD-R or DVD+R. + Allow paths to non-existing files, but disallow paths + to existing regular files. + --priv_cmd 'command [arg [arg ...]]' + With drive operations execute xorriso as argument + of the given command (e.g. pfexec, sudo) with the + optionally given arguments: command arg arg xorriso ... + Command and arguments must be single words. +Overview: + Test burning to re-usable media CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE. + By default, one-time usable media will be rejected deliberately. +HLP +} + +wait_for_dev () { +# $1 = device address + timeout=30 + counter=0 + + while test "$counter" -lt "$timeout" + do + if test -e "$1" + then + echo + return 0 + fi + if test "$counter" = 0 + then + echo + echo "Not existing: $dev" + echo "Will wait up to $timeout seconds for it to appear." + fi + counter=$(expr $counter + 1) + echo -n "$counter " + sleep 1 + done + echo + return 1 +} + +getopts_inc=inc/releng_getopts.inc +if test -e "$getopts_inc" +then + . "$getopts_inc" + if test "$SPECIFIC_HELP" = 1 + then + print_specific_help + exit 0 + fi +else + echo >&2 + echo "File not found: $getopts_inc" >&2 + echo "Are we in the ./releng directory of a libisoburn SVN checkout ?" >&2 + echo "(Please execute the tests from that ./releng directory.)" >&2 + echo >&2 + exit 29 +fi + +# Set default values for specific option variables. +dev=/dev/cdrw +what=../xorriso +any_media=0 +priv_cmd= +# Interpret specific options, they begin after the first --. +next_is=ignore +for i in "$@" +do + if test "$next_is" = "ignore" + then + if test "$i" = "--" + then + next_is="" + fi + elif test "$next_is" = "dev" + then + dev="$i" + next_is="" + elif test "$next_is" = "what" + then + what="$i" + next_is="" + elif test "$next_is" = "priv_cmd" + then + priv_cmd="$i" + next_is="" + elif test "$i" = "--dev" + then + next_is="dev" + elif test "$i" = "--what" + then + next_is="what" + elif test "$i" = "--any_media" + then + any_media=1 + elif test "$i" = "--priv_cmd" + then + next_is="priv_cmd" + else + echo >&2 + echo "Unknown test specific option: $i" >&2 + print_help + print_specific_help + exit 31 + fi +done + + +check_for_xorriso -x + + +# check data dir, if any and after checking -x xorriso +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use '${SELF} -c' to remove.\n" + exit 30 +else + mkdir "${GEN_DATA_DIR}" +fi + + +##################################################################### + +# Inspect drive address +if test -e "$dev" +then + if test "$any_media" = 1 -a -f "$dev" + then + echo "FAIL : ${SELF} : --dev $dev leads to an existing regular file" + echo + cleanup + exit 31 + fi +else + if test "$any_media" = "0" + then + echo "FAIL : ${SELF} : --dev $dev does not lead to an existing file" + echo + cleanup + exit 31 + fi +fi + +# Inspect media +set +e +wait_for_dev "$dev" +res=$(${priv_cmd} "$RELENG_XORRISO" -outdev "$dev" 2>&1) +ret=$? +set -e +if test "$ret" -ne 0 +then + echo "$res" >&2 + echo "FAIL : ${SELF} : Non-zero exit value $ret with: ${priv_cmd} $RELENG_XORRISO -outdev $dev" + echo + cleanup + exit 1 +elif echo "$res" | grep '^Media current:' >/dev/null 2>&1 +then + media=$(echo "$res" | grep '^Media current:' | \ + sed -e 's/^Media current: //') + echo "Detected media: '$media'" + if test "$media" = "CD-RW" -o "$media" = "DVD-RW sequential recording" -o \ + "$media" = "DVD-RW restricted overwrite" -o "$media" = "DVD-RAM" -o \ + "$media" = "DVD+RW" -o "$media" = "BD-RE" + then + echo "Recognized as re-usable." + elif test "$media" = "is not recognizable" + then + echo "FAIL : ${SELF} : No recognizable media detected in: '$dev'" + echo + cleanup + exit 2 + elif test "$any_media" = 1 + then + echo "Accepted media only because of option --any_media : '$media'" + else + echo "FAIL : ${SELF} : No re-usable media detected, but: '$media'" + echo + cleanup + exit 2 + fi +fi + +# Perform burn run +echo ${priv_cmd} "$RELENG_XORRISO" -for_backup -outdev "$dev" -blank as_needed -map "$what" /test +set +e +wait_for_dev "$dev" +${priv_cmd} "$RELENG_XORRISO" \ + -for_backup \ + -outdev "$dev" \ + -blank as_needed \ + -map "$what" /test +ret=$? +set -e +if test "$ret" -ne 0 +then + echo "FAIL : ${SELF} : Non-zero exit value with burn run: $ret" + echo + cleanup + exit 1 +fi + +if test "$SIMULATE_FAILURE" = 1 +then + echo "FAIL : ${SELF} : Simulated failure caused by option -f" + if test -f "$dev" + then + # Alter image + dd if=/dev/urandom bs=2K count=1 \ + of="$dev" conv=notrunc seek=400 + else + cleanup + exit 1 + fi +fi + +# Check read +echo ${priv_cmd} "$RELENG_XORRISO" -for_backup -indev "$dev" \ + -check_media event=FATAL -- \ -check_md5_r FATAL / -- +set +e +wait_for_dev "$dev" +${priv_cmd} "$RELENG_XORRISO" \ + -for_backup \ + -indev "$dev" \ + -print '---check_media:' -check_media event=FATAL -- \ + -print '---check_md5_r:' -check_md5_r FATAL / -- \ + -print '---compare_r:' -md5 off -compare_r "$what" /test +ret=$? +set -e +if test "$ret" -ne 0 +then + echo "FAIL : ${SELF} : Non-zero exit value with checkread run: $ret" + echo + cleanup + exit 1 +fi + +echo "Ok. Burn test passed." +echo +cleanup +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/manual_devices b/libisoburn/branches/1.4.6/releng/manual_devices new file mode 100755 index 00000000..8b576635 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/manual_devices @@ -0,0 +1,188 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Copyright 2011 Thomas Schmitt +# Licensed under GNU GPL version 2 or later + +# set -e + +print_specific_help() { +cat << HLP +Specific options: + --dev path Suppress dialog and use path as drive address. + --priv_cmd 'command [arg [arg ...]]' + With drive operations execute xorriso as argument + of the given command (e.g. pfexec, sudo) with the + optionally given arguments: command arg arg xorriso ... + Command and arguments must be single words. +Overview: + Test device scanning and list of speeds. +HLP +} + +# Include common bits and interpret general options +getopts_inc=inc/releng_getopts.inc +if test -e "$getopts_inc" +then + . "$getopts_inc" + + if test "$SPECIFIC_HELP" = 1 + then + print_specific_help + exit 0 + fi +else + echo >&2 + echo "File not found: $getopts_inc" >&2 + echo "Are we in the ./releng directory of a libisoburn SVN checkout ?" >&2 + echo "(Please execute the tests from that ./releng directory.)" >&2 + echo >&2 + exit 2 +fi + +# Interpret private options, they begin after the first --. +dev= +priv_cmd= +next_is=ignore +for i in "$@" +do + if test "$next_is" = "ignore" + then + if test "$i" = "--" + then + next_is="" + fi + elif test "$next_is" = "dev" + then + dev="$i" + next_is="" + elif test "$next_is" = "priv_cmd" + then + priv_cmd="$i" + next_is="" + elif test "$i" = "--dev" + then + next_is="dev" + elif test "$i" = "--priv_cmd" + then + next_is="priv_cmd" + else + echo >&2 + echo "Unknown test specific option: $i" >&2 + print_help + print_specific_help + exit 31 + fi +done + +# Insist in having a xorriso +check_for_xorriso -x + +has_device_links=$("$RELENG_XORRISO" -help 2>/dev/null | fgrep ' -device_links') +if test -n "$has_device_links" +then + devices_opt="-device_links" +else + devices_opt="-devices" +fi + +# +get_speeds() { + echo -e "\n${SELF}: Running: ${priv_cmd} ${RELENG_XORRISO} -report_about WARNING -outdev ${1} -toc -list_formats -list_profiles out -list_speeds" + ${priv_cmd} "$RELENG_XORRISO" -report_about WARNING -outdev "$1" \ + -print '---toc :' -toc \ + -print '---list_formats :' -list_formats \ + -print '---list_profiles :' -list_profiles out \ + -print '---list_speeds :' -list_speeds +} + +cat_var() { +# $1 = variable to put out with line feeds +cat <<+ +$1 ++ +} + +get_devices() { + # $1 = if not empty: device lines from xorriso -devices or -device_links + # $2 = if not empty: suppress dialog and use $2 as input + + if test -n "$1" + then + DEVICES="$1" + else + DEVICES=$( ${priv_cmd} "$RELENG_XORRISO" $devices_opt 2>/dev/null | grep "\-dev") + fi + NUM_DEV=$(cat_var "$DEVICES" | wc -l) + case "${NUM_DEV}" in + 0) + echo -e "\n${SELF}: No drives found." + exit 1 + ;; + 1) + echo -e "\n${SELF}: 1 drive found:\n" + ;; + *) + echo -e "\n${SELF}: ${NUM_DEV} drives found:\n" + ;; + esac + echo ================================================================= + echo "$DEVICES" + echo ================================================================= + + OUTDEV=$( cat_var "$DEVICES" | head -1 | \ + sed -e "s/[0-9] *-dev '\//\//" -e "s/'.*$//" ) + if test -n "$2" + then + x="$2" + else + echo >&2 + echo "WARNING: The following tests might pull in the drive tray." >&2 + echo " Best is if you now put in a suitable media and" >&2 + echo " load it manually, so nobody gets surprised. :))" >&2 + echo >&2 + echo "Which drive to examine ? (Empty input = ${OUTDEV})" >&2 + read x + fi + if test -n "$x" + then + OUTDEV="$x" + fi + + get_speeds "$OUTDEV" +} + +# main +"$RELENG_XORRISO" -version +echo -e "\n${SELF}: Running: $RELENG_XORRISO $devices_opt ..." +devices=$( ${priv_cmd} "$RELENG_XORRISO" -report_about WARNING $devices_opt | grep "\-dev") +RET="$?" +if test "$SIMULATE_FAILURE" = 1 +then + echo "===" >&2 + echo "=== SIMULATING FAILURE BY OVERRIDING EXIT VALUE OF XORRISO" >&2 + echo "===" >&2 + echo "FAIL : ${SELF} : Simulated failure caused by option -f" + RET=1 +fi +case ${RET} in + 0) + get_devices "$devices" "$dev" + RET="$?" + if test "$RET" = 0 + then : + else + echo "FAIL : ${SELF} : Device scan or single drive listing failed" + exit "$RET" + fi + ;; + *) + boldify + echo -ne "\n${SELF}: ${priv_cmd} ${RELENG_XORRISO} $devices_opt returned ${RET}." + unboldify + echo -e "\n${SELF}: Already mounted?" + df -kh + exit 1 +esac + +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/manual_isojigdo b/libisoburn/branches/1.4.6/releng/manual_isojigdo new file mode 100755 index 00000000..a35a4b6c --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/manual_isojigdo @@ -0,0 +1,288 @@ +#!/bin/bash + +# Copyright 2011 Thomas Schmitt +# Copyright 2011 George Danchev +# Licensed under GNU GPL version 2 or later + +set -e + +not_in_releng_exit() { + printf "\nPlease execute the tests from releng directory.\n\n" + exit 1 +} + +. inc/releng_getopts.inc || not_in_releng_exit + +print_specific_help() { +cat << HLP +Specific options: + none yet. +Overview: + Match the resulting ISO image representation + against the jigdo representation. +HLP +} + +if test "$SPECIFIC_HELP" = 1; then + print_specific_help + exit 0 +fi + +if [ ! -x $RELENG_XORRISO ]; then + print_help + printf "\n${SELF}: -x absolute or relative path to binary to be run.\n\n" + exit 30 +fi + +# check data dir, if any and after checking -x xorriso +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use './${SELF} -c' to remove.\n" + exit 1 +else + mkdir "${GEN_DATA_DIR}" +fi + +TMP_DATA_DIR=releng_generated_data +IMG_EXTRACT_DIR=${GEN_DATA_DIR}/${SELF}_extracted_tree +RELENG_DIR="${IMG_EXTRACT_DIR}" +RELENG_ISOLINUX_BIN="isolinux/isolinux.bin" +RELENG_BOOT_CAT="isolinux/boot.cat" +RELENG_IMG=t1 +RES="" +REMOTE_URL="http://cdimage.debian.org/cdimage/daily-builds/daily/arch-latest/i386/iso-cd" +REMOTE_IMG="debian-testing-i386-netinst.iso" + +# check for required items +if [ "${RELENG_XORRISO}" = "" -o "${RELENG_DIR}" = "" -o "${RELENG_IMG}" = "" ]; then + echo -e "\n${SELF}: xorriso_cmd IN_dir and OUT_image are required\n" + exit 2 +fi + +# All must be set at this point +printf "${SELF}: Config items:" +printf "\n\txorriso_cmd=${RELENG_XORRISO}\n\tIN_dir=${RELENG_DIR}\n\tOUT_image=${RELENG_IMG}.iso" +printf "\n\tIN_isolinux=${RELENG_ISOLINUX_BIN}\n\tOUT_bootcat=${RELENG_BOOT_CAT}\n" +RES="${RELENG_IMG}.iso ${RELENG_IMG}.new ${RELENG_IMG}.md5 ${RELENG_IMG}.jigdo ${RELENG_IMG}.template" + +# xorriso version details, incl. underlying libraries +# "${RELENG_XORRISO}" -version + +# check whether the binary support JTE +set +e +RETSTR_VER_JTE=`"${RELENG_XORRISO}" --version 2>/dev/null | grep "libjte * in use"` +RETCODE_VER_JTE="$?" +set -e +case ${RETCODE_VER_JTE} in + 0) + printf "\n${SELF}: Found JTE support with ${RELENG_XORRISO} : ${RETSTR_VER_JTE}" + ;; + *) + printf "\nFAIL : ${SELF} : Not found JTE support in ${RELENG_XORRISO}. Quit." + printf "\n${SELF}: JTE not supported with this xorriso build. Install jigit >=1.18 and rebuild." + printf "\n${SELF}: http://www.einval.com/~steve/software/JTE/\n" + cleanup + exit 4 + ;; +esac + +# grab remote ISO image, to decompose +if [ ! -f "${TMP_DATA_DIR}"/"${REMOTE_IMG}" ]; then + printf "\n${SELF}: Downloading ${REMOTE_URL}/${REMOTE_IMG}\n" + if wget -V >/dev/null 2>&1 + then + set +e + wget --no-check-certificate -T20 -t3 \ + -O "${TMP_DATA_DIR}"/"${REMOTE_IMG}" "${REMOTE_URL}"/"${REMOTE_IMG}" + WGET_RET="$?" + set -e + elif fetch -T 20 -o "${TMP_DATA_DIR}"/"${REMOTE_IMG}" \ + "${REMOTE_URL}"/"${REMOTE_IMG}" + then + WGET_RET=0 + else + echo + echo "FAIL: ${SELF} : Neither wget nor fetch are present and willing to work" + cleanup + exit 10 + fi + case ${WGET_RET} in + 0) + echo -e "\n${SELF}: Downloading successfully completed.\n" + ;; + *) + echo -e "\nFAIL : ${SELF} : wget returned code: $WGET_RET\n" + rm "${TMP_DATA_DIR}"/"${REMOTE_IMG}" + cleanup + exit 5 + ;; + esac +else + printf "\n${SELF}: Found ISO image: ${TMP_DATA_DIR}/${REMOTE_IMG}\n" +fi + +# check for extraction directory existence +if [ -d "${IMG_EXTRACT_DIR}" ]; then + printf "\n${SELF}: Found ${IMG_EXTRACT_DIR}. Please cleanup.\n" + cleanup + exit 6 +else + mkdir "${IMG_EXTRACT_DIR}" +fi + +# extract image content +CMD_EXTRACT="${RELENG_XORRISO} -indev ${TMP_DATA_DIR}/${REMOTE_IMG} \ + -osirrox on:auto_chmod_on \ + -extract / ${IMG_EXTRACT_DIR} \ +" + +# TODO: drop set +e|-e block, catch exit code instead when +# the boot catalog warnings get completely resolved. +echo -e "${SELF}: Extracting ISO image:\n${CMD_EXTRACT}\n" +set +e +${CMD_EXTRACT} +set -e + +# grab an MBR +ISOHYBRID_MBR="${GEN_DATA_DIR}/isohybrid.mbr" +dd if="${TMP_DATA_DIR}/${REMOTE_IMG}" bs=1K count=32 of="${ISOHYBRID_MBR}" + +# create FAT partition +APPEND_PART="${GEN_DATA_DIR}/fatpart.fat" +MKFS_MSDOS="/sbin/mkfs.msdos" +if [ -x "${MKFS_MSDOS}" ]; then + "${MKFS_MSDOS}" -n Bla -C "${APPEND_PART}" 8192 + APPEND_PART_CMD="-append_partition 2 0x01 ${APPEND_PART}" +else + APPEND_PART_CMD= + +# printf "\nFAIL : ${SELF} : Not found: ${MKFS_MSDOS}" +# printf "\n${SELF}: Not found: "${MKFS_MSDOS}". Install dosfstools." +# printf "\n${SELF}: http://www.daniel-baumann.ch/software/dosfstools/\n" +# cleanup +# exit 7 +fi + +# GENERAL section +CMD="${RELENG_XORRISO} \ + -as mkisofs \ + -quiet \ + -o ${GEN_DATA_DIR}/${RELENG_IMG}.iso \ + -R \ + -V ISOJIGDO \ + -partition_offset 16 \ + -J -joliet-long \ +" + +# BOOT section +if [ -f "${IMG_EXTRACT_DIR}"/"${RELENG_ISOLINUX_BIN}" -a -f "${ISOHYBRID_MBR}" ] +then +CMD="$CMD \ + -b ${RELENG_ISOLINUX_BIN} \ + -c ${RELENG_BOOT_CAT} \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -isohybrid-mbr ${ISOHYBRID_MBR} \ + -partition_offset 16 \ +" +else + printf "\n${SELF}: FAIL to compose the boot section.\n" + cleanup + exit 8 +fi +if [ -n "${APPEND_PART_CMD}" -a -f "${APPEND_PART}" ]; then +CMD="$CMD \ + ${APPEND_PART_CMD} +" +fi + +# JIGDO section +JIGDO_JIGDO=${GEN_DATA_DIR}/${RELENG_IMG}.jigdo +JIGDO_TEMPLATE=${GEN_DATA_DIR}/${RELENG_IMG}.template + +JIGDO_MAP_RHV=$(cd ${RELENG_DIR} 2>/dev/null && pwd) + +JIGDO_MAP="Debian=${JIGDO_MAP_RHV}/" + +# create jigdo MD5 list in base64 format +JIGDO_GEN_MD5=${GEN_DATA_DIR}/${RELENG_IMG}.md5 + +printf "${SELF}: Creating MD5 list in hex format in ${JIGDO_GEN_MD5}..." +set +e +./jigdo-gen-md5-list ${RELENG_DIR} > ${JIGDO_GEN_MD5} +ret=$? +set -e + +if test "$ret" = 0 +then + printf "Done.\n" +else + printf "\nFAIL : ${SELF}: ./jigdo-gen-md5-list returns $ret" + cleanup + exit 9 +fi + + +CMD="$CMD \ + -jigdo-template-compress gzip \ + -checksum_algorithm_iso md5,sha1,sha256,sha512 \ + -checksum_algorithm_template md5,sha1,sha256,sha512 \ + -jigdo-jigdo ${JIGDO_JIGDO} \ + -jigdo-template ${JIGDO_TEMPLATE} \ + -jigdo-map ${JIGDO_MAP} \ + -md5-list ${JIGDO_GEN_MD5} \ + -jigdo-min-file-size 1024 \ +" + +CMD="$CMD ${RELENG_DIR}" + +# Run the whole compound command +echo -e "${SELF}: Creating ISO and jigdo representations:\n$CMD\n" +${CMD} + +# Create another imange this time from jigdo files +if which jigit-mkimage >/dev/null 2>&1; then + printf "${SELF}: Creating new ISO from jigdo files..." + jigit-mkimage \ + -t ${JIGDO_TEMPLATE} \ + -j ${JIGDO_JIGDO} \ + -m ${JIGDO_MAP} \ + -o ${GEN_DATA_DIR}/${RELENG_IMG}.new + printf "Done.\n" +else + printf "\n${SELF}: Not found: jigit-mkimage. Install jigit." + printf "\n${SELF}: http://www.einval.com/~steve/software/JTE/\n" + cleanup + exit 10 +fi + +# trap the exit code of diff and let the Universe explode +diff ${GEN_DATA_DIR}/${RELENG_IMG}.iso ${GEN_DATA_DIR}/${RELENG_IMG}.new +DIFF_RET="$?" +case ${DIFF_RET} in + 0) + echo -e "${SELF}: Match: diff ${GEN_DATA_DIR}/${RELENG_IMG}.iso ${GEN_DATA_DIR}/${RELENG_IMG}.new" + ;; + *) + echo -e "FAIL : ${SELF} : diff returned code: $DIFF_RET\n" + ;; +esac + +# sort out the cruft +cleanup + +# warn about downloaded image left behind +if [ -f "${TMP_DATA_DIR}"/"${REMOTE_IMG}" ]; then + printf "${SELF}: Leaving " + ls -sh "${TMP_DATA_DIR}"/"${REMOTE_IMG}" +fi + +# last hints +if [ -d ${GEN_DATA_DIR} ]; then + printf "\n${SELF}: HINT: manual checks remained to be done:\n" + printf " * ${GEN_DATA_DIR}/${RELENG_IMG}.iso boots from USB stick and/or optical media.\n" + printf " * appended FAT partition is mountable.\n" + printf " * xorriso -indev ${GEN_DATA_DIR}/${RELENG_IMG}.iso -pvd_info\n" + printf " * fdisk -lu ${GEN_DATA_DIR}/${RELENG_IMG}.iso\n" +fi + +exit 0 diff --git a/libisoburn/branches/1.4.6/releng/run_all_auto b/libisoburn/branches/1.4.6/releng/run_all_auto new file mode 100755 index 00000000..1ba8f774 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/run_all_auto @@ -0,0 +1,247 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Copyright 2011 - 2014 Thomas Schmitt +# Licensed under GNU GPL version 2 or later + +set -e + +export RELENG_SCRIPT_RUN_BY_RUN_ALL_AUTO=1 + +SELF=$(basename "$0") +GEN_DATA_DIR=releng_generated_data +CLOG=${GEN_DATA_DIR}/log.${SELF} +CLOG_PREV=${CLOG}.prev +PASSED_OPTIONS="$@" +RELENG_XORRISO= +CLEANUP_LOG=0 + +# It is not a good idea to include inc/releng_getopts.inc with the +# master script as it calls the subordinate scripts and they include +# this file too, and we want to avoid sharing variable with subshells +if [ ! -f inc/releng_getopts.inc ]; then + printf "\nPlease execute the tests from releng directory.\n\n" + exit 1 +fi + +# To catch the exit value of a command in a pipe +return_value_file="$GEN_DATA_DIR"/run_all_"$$"_return_value +return_wrapper() +{ + cmd="$1" + shift 1 + "$cmd" "$@" + RET="$?" + echo "$RET" >"$return_value_file" + return "$RET" +} + +# Using only bash builtin commands. +# On 4 year old amd64 x2 3000 MHz, xterm local,it counts 22471 lines per second +# On 2 year old amd64 x4 2600 MHz, ssh remote, it counts 35348 lines per second +count_lines() +{ + # $1 if not empty: start count + line= + if test -n "$1" + then + count="$1" + else + count=0 + fi + while read line + do + count=$(($count + 1)) + printf "\r %4d lines logged ... " "$count" >&2 + printf "%s\n" "$line" + done + return 0 +} + +############################################# +print_usage() +{ +cat << HLP + +${SELF} runs executables from releng directory starting with auto_*, +and passing them its own options. stdout/stderr output is stored in: +./${CLOG} (last run) and +./${CLOG_PREV} (previous run) + +Usage: ${SELF} -x path/to/xorriso [-k] [-c] [-h] + -x absolute or relative path to xorriso binary to be run. + -k keep self-generated data in ./${GEN_DATA_DIR}. + -c cleanup self-generated data kept from previous run and exit. + -h print this help text + +Examples: +# run xorriso and keep the self-generated data + $ ./${SELF} -x path/to/xorriso -k + +# clean up self-generated data from previous run + $ ./${SELF} -c + +HLP +} + +############################################# +if [ ! "${1}" ]; then + print_usage + exit 0 +fi +next_is= +for i in "$@" +do + if test x"$i" = x"-h" -o x"$i" = x"--h" -o x"$i" = x"-help" -o x"$i" = x"--help" + then : + print_usage + exit 0 + fi + + if test "$next_is" = "ignore" + then : + elif test "$next_is" = "x" + then + RELENG_XORRISO="$i" + next_is= + elif test x"$i" = x"-x" + then + next_is="x" + elif test x"$i" = x"-c" + then + CLEANUP_LOG=1 + fi +done +############################################# +if test "$next_is" = x +then + echo + echo "Option -x expects an argument (the path to the xorriso program)" + exit 31 +fi + + +######################################################## + if [ -f "${CLOG}" ]; then + mv "${CLOG}" "${CLOG_PREV}" + fi + > ${CLOG} + if [ -x "${RELENG_XORRISO}" ]; then + echo "_OVERVIEW_______________________________________________________________" >> ${CLOG} + date -u >> ${CLOG} + ${RELENG_XORRISO} --version >> ${CLOG} + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" >> ${CLOG} + fi + DSTART=`date -u` + echo "${SELF}: Started at ${DSTART}" | tee -a ${CLOG} + E1=`date '+%s'` + exit_value=0 + # require ^auto_, avoid running (your)self explicitly + for s in `ls | grep ^auto_ | grep -v ${SELF} | sort -n`; do + if [ -x ${s} -a ! -d ${s} ]; then + echo >> ${CLOG} + echo >> ${CLOG} + echo "_STARTING_TEST_________________________________________________________" >> ${CLOG} + echo "${SELF}: Running ./${s} ${PASSED_OPTIONS} :" \ + | tee -a ${CLOG} + T1=`date '+%s'` + set +e + + return_wrapper ./${s} ${PASSED_OPTIONS} 2>&1 | count_lines >> ${CLOG} + RET=$(cat "$return_value_file") + rm "$return_value_file" + +# echo "RET='$RET'" >/dev/tty + + T2=`date '+%s'` + TS=`expr ${T2} - ${T1}` + case ${RET} in + 0) + echo "done in ${TS} sec. ok." + ;; + *) + exit_value=2 + printf "done in ${TS} sec. " + which tput >/dev/null 2>&1 && tput smso + printf "FAIL -> EXIT CODE $RET" + which tput >/dev/null 2>&1 && tput rmso + echo + ;; + esac + set -e + fi + done + + DEND=`date -u` + echo | tee -a ${CLOG} + echo -n "${SELF}: Stopped at ${DEND}." | tee -a ${CLOG} + if [ "${CLEANUP_LOG}" -eq 1 ]; then + if [ -f "${CLOG}" ]; then + rm -f "${CLOG}" + echo # | tee -a ${CLOG} + echo -n "${SELF}: Removed my own log ${CLOG}." # | tee -a ${CLOG} + fi + if [ -f "${CLOG_PREV}" ]; then + rm -f "${CLOG_PREV}" + echo # | tee -a ${CLOG} + echo "${SELF}: Removed my own log ${CLOG_PREV}." # | tee -a ${CLOG} + fi + else + E2=`date '+%s'` + if [ ${E2} -eq ${E1} ]; then + echo " Total elapsed 0 sec." | tee -a ${CLOG} + else + ES=`expr ${E2} - ${E1}` + echo " Total elapsed ${ES} sec." | tee -a ${CLOG} + fi + ##### + echo >> ${CLOG} + echo "_SUMMARY________________________________________________________________" >> ${CLOG} + echo "${SELF}: Trivial log examination: ${CLOG}" | tee -a ${CLOG} + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" | tee -a ${CLOG} + # severity classes of libdax_msgs.h in libburn and libisofs + # List of boring keywords: + # 'UPDATE|NOTE|DEBUG|ALL' - not considered interesting for lazy log inspection. + # List of interesting keywords: + # thrown by xorriso and underlying libraries + LIST_KWD="NEVER|ABORT|FATAL|FAILURE|MISHAP|SORRY|WARNING|HINT" + # thrown by others + LIST_KWD="${LIST_KWD}|FAIL|ERROR|WRONG" + + if [ -f "${CLOG}" ]; then + set +e + # lines, perl regex, leading tabs + grep -n -E "${LIST_KWD}" "${CLOG}" + RET_GREP="$?" + case ${RET_GREP} in + 0) # found + ;; + 1) # not found + echo "${SELF}: Log file looks clear." # | tee -a ${CLOG} + ;; + *) # + echo "${SELF}: grep returned EXIT CODE: ${RET_GREP}." # | tee -a ${CLOG} + ;; + esac + set -e + fi + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" | tee -a ${CLOG} + + ##### TODO: work out a less noisy diff'ing technique! + if [ -f "${CLOG_PREV}" -a -f "${CLOG}" ]; then + echo "${SELF}: See diff against previous log file (might be long):" | tee -a ${CLOG} + echo "diff -Naur ${CLOG_PREV} ${CLOG} | less" | tee -a ${CLOG} + fi + + fi + + # + which tput >/dev/null 2>&1 && tput smso + echo # | tee -a ${CLOG} + echo "${SELF}: Leaving the following cruft in ${GEN_DATA_DIR}:" # | tee -a ${CLOG} + which tput >/dev/null 2>&1 && tput rmso + ls -lth "${GEN_DATA_DIR}" # | tee -a ${CLOG} + + # Fin + exit $exit_value + diff --git a/libisoburn/branches/1.4.6/releng/template_new b/libisoburn/branches/1.4.6/releng/template_new new file mode 100755 index 00000000..a14e3a36 --- /dev/null +++ b/libisoburn/branches/1.4.6/releng/template_new @@ -0,0 +1,135 @@ +#!/bin/bash + +# Copyright 2011 George Danchev +# Copyright 2011 Thomas Schmitt +# === TEMPLATE: Add your own copyright here +# +# Licensed under GNU GPL version 2 or later + +# === TEMPLATE: Remove this remark before releasing this script. +# +# This is a template for creating a new libisoburn/releng test. +# It is supposed that you have read releng/README before you begin to work +# here. +# +# Step 1: Invent a name for your test +# test_name="manual_"...some.name... +# or +# test_name="auto_"...some.name... +# +# Step 2: Copy releng/template_new to $test_name +# +# Step 3: Edit $test_name and process any line that begins by +# "# === TEMPLATE:". Do what the line prescribes and then remove it +# from the script. You are not done as long as such a line remains. +# +# === TEMPLATE: End of remark to remove + +set -e + + +# === TEMPLATE: Describe your own specific options (if any) and the test +print_specific_help() { +cat << HLP +Specific options: + --option Explanation of specific option +Overview: + Short explanation of test purpose and activities. +HLP +} + + +getopts_inc=inc/releng_getopts.inc +if test -e "$getopts_inc" +then + . "$getopts_inc" + + if test "$SPECIFIC_HELP" = 1 + then + print_specific_help + exit 0 + fi +else + echo >&2 + echo "File not found: $getopts_inc" >&2 + echo "Are we in the ./releng directory of a libisoburn SVN checkout ?" >&2 + echo "(Please execute the tests from that ./releng directory.)" >&2 + echo >&2 + exit 29 +fi + + +# === TEMPLATE: Decide whether the test will have own options, +# === TEMPLATE: apart from those interpreted by inc/releng_getopts.inc +# === TEMPLATE: If not, then remove this interpreter code. +# Set default values for specific option variables. E.g.: +# dev= +# Interpret specific options, they begin after the first --. +next_is=ignore +for i in "$@" +do + if test "$next_is" = "ignore" + then + if test "$i" = "--" + then + next_is="" + fi + +# === TEMPLATE: Implement interpretation of specific options. Like: +# elif test "$next_is" = "dev" +# then +# dev="$i" +# next_is="" +# elif test "$i" = "--dev" +# then +# next_is="dev" + + else + echo >&2 + echo "Unknown test specific option: $i" >&2 + print_help + print_specific_help + exit 31 + fi +done +# === TEMPLATE: End of own option interpreter code. + + +# Each test should decide whether or not it needs +# a xorriso binary to test, since some do compilations only. +# === TEMPLATE: Decide whether you need a xorriso program. +# === TEMPLATE: If not, then remove this function call +check_for_xorriso -x + + +# check data dir, if any and after checking -x xorriso +# === TEMPLATE: Decide whether your test will possibly create own files. +# === TEMPLATE: If yes, then create your files underneath ${GEN_DATA_DIR}. +# === TEMPLATE: The name in this variable is set by inc/releng_getopts.inc . +# === TEMPLATE: If not, then remove this if ... fi statement. +if [ -d "${GEN_DATA_DIR}" ]; then + printf "\n${SELF}: directory %s exists!" ${GEN_DATA_DIR} + printf "\n${SELF}: use '${SELF} -c' to remove.\n" + exit 30 +else + mkdir "${GEN_DATA_DIR}" +fi + + +##################################################################### + + +# === TEMPLATE: Perform your test activities here. + + +# === TEMPLATE: In case of failure, issue a line to stdout that begins by +# === TEMPLATE: the word "FAIL", and make sure that the test script finally +# === TEMPLATE: returns a non-zero exit value. +# === TEMPLATE: 31 = Unknown option or unusable argument with known option +# === TEMPLATE: 30 = Unexpected state of own directory for self generated files +# === TEMPLATE: 29 = Not in ./releng directory or missing essential parts +# === TEMPLATE: 1 to 28 = test specific exit values +# === TEMPLATE: When exiting prematurely, make sure to call cleanup. + +cleanup +exit 0 diff --git a/libisoburn/branches/1.4.6/test/compare_file.c b/libisoburn/branches/1.4.6/test/compare_file.c new file mode 100644 index 00000000..4f5bb04f --- /dev/null +++ b/libisoburn/branches/1.4.6/test/compare_file.c @@ -0,0 +1,307 @@ +/* + Compare two copies of a file object in as many aspects as i can imagine + to make sense. (E.g.: comparing atime makes no sense.) + + To compare tree /media/dvd and /original/dir : + find /media/dvd -exec compare_file '{}' /media/dvd /original/dir ';' + + Copyright 2008 - 2015 Thomas Schmitt, + + Provided under GPL version 2 or later. + + + cc -g -o compare_file compare_file.c +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* O_BINARY is needed for Cygwin but undefined elsewhere */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* @param flag bit0= single letters */ +char *Ftypetxt(mode_t st_mode, int flag) +{ + if(flag&1) + goto single_letters; + if(S_ISDIR(st_mode)) + return("directory"); + else if(S_ISREG(st_mode)) + return("regular_file"); + else if(S_ISLNK(st_mode)) + return("symbolic_link"); + else if(S_ISBLK(st_mode)) + return("block_device"); + else if(S_ISCHR(st_mode)) + return("char_device"); + else if(S_ISFIFO(st_mode)) + return("name_pipe"); + else if(S_ISSOCK(st_mode)) + return("unix_socket"); + return("unknown"); +single_letters:; + if(S_ISDIR(st_mode)) + return("d"); + else if(S_ISREG(st_mode)) + return("-"); + else if(S_ISLNK(st_mode)) + return("l"); + else if(S_ISBLK(st_mode)) + return("b"); + else if(S_ISCHR(st_mode)) + return("c"); + else if(S_ISFIFO(st_mode)) + return("p"); + else if(S_ISSOCK(st_mode)) + return("s"); + return("?"); +} + + +char *Ftimetxt(time_t t, char timetext[40], int flag) +{ + char *rpt; + struct tm tms, *tmpt; + static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + tmpt= localtime_r(&t, &tms); + rpt= timetext; + rpt[0]= 0; + if(tmpt==0) + sprintf(rpt+strlen(rpt), "%12.f", (double) t); + else if(time(NULL)-t < 180*86400 && time(NULL)-t >= 0) + sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d", + months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min); + else + sprintf(rpt+strlen(rpt), "%3s %2d %4.4d", + months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); + return(timetext); +} + + +/* @param flag bit0= compare atime + bit1= compare ctime +*/ +int Compare_2_files(char *adr1, char *adr2, char *adrc, int flag) +{ + struct stat s1, s2; + int ret, differs= 0, r1, r2, fd1= -1, fd2= -1, i, done; + char buf1[4096], buf2[4096], a[4096], ttx1[40], ttx2[40]; + off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1; + + ret= lstat(adr1, &s1); + if(ret==-1) { + printf("? %s : cannot lstat() : %s\n", adr1, strerror(errno)); + return(0); + } + strcpy(a, Ftypetxt(s1.st_mode, 1)); + strcat(a, " "); + if(adrc[0]) { + if(strlen(a) + strlen(adrc) < 4096) + strcat(a, adrc); + } else { + strcat(a, "."); + } + + ret= lstat(adr2, &s2); + if(ret==-1) { + printf("? %s : cannot lstat() : %s\n", adr2, strerror(errno)); + return(0); + } + + /* Attributes */ + if(s1.st_mode != s2.st_mode) { + if((s1.st_mode&~S_IFMT)!=(s2.st_mode&~S_IFMT)) + printf("%s : st_mode : %7.7o <> %7.7o\n", a, + (unsigned int) (s1.st_mode & ~S_IFMT), + (unsigned int) (s2.st_mode & ~S_IFMT)); + if((s1.st_mode&S_IFMT)!=(s2.st_mode&S_IFMT)) + printf("%s : type : %s <> %s\n", + a, Ftypetxt(s1.st_mode, 0), Ftypetxt(s2.st_mode, 0)); + differs= 1; + } + if(s1.st_uid != s2.st_uid) { + printf("%s : st_uid : %lu <> %lu\n", + a, (unsigned long) s1.st_uid, (unsigned long) s2.st_uid); + differs= 1; + } + if(s1.st_gid != s2.st_gid) { + printf("%s : st_gid : %lu <> %lu\n", + a, (unsigned long) s1.st_gid, (unsigned long) s2.st_gid); + differs= 1; + } + if((S_ISCHR(s1.st_mode) && S_ISCHR(s2.st_mode)) || + (S_ISBLK(s1.st_mode) && S_ISBLK(s2.st_mode))) { + if(s1.st_rdev != s2.st_rdev) { + printf("%s : %s st_rdev : %lu <> %lu\n", a, + (S_ISCHR(s1.st_mode) ? "S_IFCHR" : "S_IFBLK"), + (unsigned long) s1.st_rdev, (unsigned long) s1.st_rdev); + differs= 1; + } + } + if(S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) { + printf("%s : st_size : %.f <> %.f diff= %.f\n", + a, (double) s1.st_size, (double) s2.st_size, + ((double) s1.st_size) - (double) s2.st_size); + differs= 1; + } + if(s1.st_mtime != s2.st_mtime) { + printf("%s : st_mtime : %s <> %s diff= %.f s\n", + a, Ftimetxt(s1.st_mtime, ttx1, 0), + Ftimetxt(s2.st_mtime, ttx2, 0), + ((double) s1.st_mtime) - (double) s2.st_mtime); + differs= 1; + } + if(flag&1) { + if(s1.st_atime != s2.st_atime) { + printf("%s : st_atime : %s <> %s diff= %.f s\n", + a, Ftimetxt(s1.st_atime, ttx1, 0), + Ftimetxt(s2.st_atime, ttx2, 0), + ((double) s1.st_atime) - (double) s2.st_atime); + differs= 1; + } + } + if(flag&2) { + if(s1.st_ctime != s2.st_ctime) { + printf("%s : st_ctime : %s <> %s diff= %.f s\n", + a, Ftimetxt(s1.st_ctime, ttx1, 0), + Ftimetxt(s2.st_ctime, ttx2, 0), + ((double) s1.st_ctime) - (double) s2.st_ctime); + differs= 1; + } + } + if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)) { + fd1= open(adr1, O_RDONLY | O_BINARY); + if(fd1==-1) { + printf("- %s : cannot open() : %s\n", adr1, strerror(errno)); + return(0); + } + fd2= open(adr2, O_RDONLY | O_BINARY); + if(fd2==-1) { + printf("- %s : cannot open() : %s\n", adr2, strerror(errno)); + close(fd1); + return(0); + } + + /* Content */ + done= 0; + while(!done) { + r1= read(fd1, buf1, sizeof(buf1)); + r2= read(fd2, buf2, sizeof(buf2)); + if((r1==EOF && r2==EOF) || (r1==0 && r2==0)) + break; + if(r1==EOF || r1==0) { + if(r1==EOF) + r1= 0; + if(s1.st_size > r1count + r1) + printf("- %s : early EOF after %.f bytes\n", adr1, (double) r1count); + differs= 1; + } + r1count+= r1; + if(r2==EOF || r2 r2count + r2) + printf("- %s : early EOF after %.f bytes\n", adr2, (double) r2count); + differs= 1; + done= 1; + } + if(r2>r1) { + if(s1.st_size > r1count + r1) + printf("- %s : early EOF after %.f bytes\n", adr1, (double) r1count); + differs= 1; + done= 1; + } + r2count+= r2; + if(r1>r2) + r1= r2; + for(i= 0; i0 || r1count!=r2count) { + if(first_diff<0) + first_diff= (r1count>r2count ? r2count : r1count); + printf("%s : %s : differs by at least %.f bytes. First at %.f\n", a, + (s1.st_mtime==s2.st_mtime ? "CONTENT":"content"), + (double) (diffcount + abs(r1count-r2count)), (double) first_diff); + differs= 1; + } + } + if(fd1!=-1) + close(fd1); + if(fd2!=-1) + close(fd2); + return(!differs); +} + + +int main(int argc, char **argv) +{ + int ret, i, with_ctime= 1; + char adr1[4096], adr2[4096], adrc[4096]; + + if(sizeof(off_t) < 8) { + fprintf(stderr, + "%s : FATAL : Compile time misconfiguration. sizeof(off_t) too small.\n\n", + argv[0]); + exit(4); + } + if(argc<4) { + fprintf(stderr, "usage: %s path prefix1 prefix2\n", argv[0]); + exit(2); + } + for(i= 4; i= 4096) { + fprintf(stderr, "path exceeds size limit of 4095\n"); + exit(3); + } + if(strlen(argv[1]) - strlen(argv[2]) > 4000) { + fprintf(stderr, "common address part exceeds size limit of 4000\n"); + exit(3); + } + if(strlen(argv[3]) + 1 + strlen(argv[1]) - strlen(argv[2]) >= 4096) { + fprintf(stderr, "prefix2 exceeds size limit of 4095\n"); + exit(3); + } + strcpy(adr1, argv[1]); + strcpy(adrc, argv[1]+strlen(argv[2])); + sprintf(adr2, "%s%s%s", + argv[3], (adrc[0]=='/' || adrc[0]==0 ? "" : "/"), adrc); + + ret= Compare_2_files(adr1, adr2, adrc, (with_ctime<<1)); + exit(ret<=0); +} + diff --git a/libisoburn/branches/1.4.6/test/test.c b/libisoburn/branches/1.4.6/test/test.c new file mode 100644 index 00000000..ba0bdf2e --- /dev/null +++ b/libisoburn/branches/1.4.6/test/test.c @@ -0,0 +1,312 @@ +/* + Little test program for libisoburn. + It grows an iso filesystem on a disc. + + Copyright 2007 Vreixo Formoso Lopes + and Thomas Schmitt +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include "../src/libisoburn.h" + +const char * const optstring = "JRh"; +extern char *optarg; +extern int optind; + + +/** Activates the usage of function graft_point() rather than + plain iso_tree_radd_dir() from libisofs +*/ +#define With_graft_poinT 1 + + +static int graft_point(struct iso_volume *volume, const char *disk_path, + const char *img_path, struct iso_tree_radd_dir_behavior *behav) +{ + char path[4096], *apt, *npt; + struct iso_tree_node_dir *dir; + struct iso_tree_node *node; + int done= 0, is_dir= 0; + struct stat stbuf; + + strncpy(path, img_path, sizeof(path)-1); + path[sizeof(path)-1]= 0; + apt= npt= path; + + if(lstat(disk_path, &stbuf) == -1) { + fprintf(stderr, "Cannot determine attributes of '%s' : %s (%d)\n", + disk_path, (errno > 0 ? strerror(errno) : "unknown error"), errno); + return(0); + } + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) { + fprintf(stderr, "File object '%s' is of non-supported file type\n", + disk_path); + return(0); + } + + dir= iso_volume_get_root(volume); + if(dir==NULL) { + fprintf(stderr, "While grafting '%s' : no root node available\n", img_path); + return(0); + } + for(npt= apt; !done; apt= npt+1) { + npt= strchr(apt, '/'); + if(npt==NULL) { + npt= apt+strlen(apt); + done= 1; + } else + *npt= 0; + if(*apt==0) { + *apt= '/'; + apt++; + continue; + } + node= iso_tree_volume_path_to_node(volume,path); + if(node!=NULL) { + if(iso_tree_node_get_type(node)!=LIBISO_NODE_DIR) { + fprintf(stderr, "While grafting '%s' : '%s' is not a directory\n", + img_path, path); + return(0); + } + dir= (struct iso_tree_node_dir *) node; + } else { + dir= iso_tree_add_dir(dir, apt); + if(dir==NULL) { + fprintf(stderr, "While grafting '%s' : could not insert '%s'\n", + img_path, path); + return(0); + } + } + if(done) { + if(is_dir) { + iso_tree_radd_dir(dir, disk_path, behav); + } else { + node= iso_tree_add_node(dir, disk_path); + if(node == NULL) { + fprintf(stderr, "While grafting '%s'='%s' : libisofs_errno = %d\n", + img_path, disk_path, libisofs_errno); + } + } + } else + *npt= '/'; + } + fprintf(stderr, "NOTE: added %s '%s'='%s'\n", (is_dir ? "directory" : "node"), + img_path, disk_path); + return(1); +} + + +static +void usage() +{ + printf("test [OPTIONS] DRIVE DIRECTORY\n"); +} + +static +void help() +{ + printf( +"Options:\n" +" -J Add Joliet support\n" +" -R Add Rock Ridge support\n" +" -h Print this message\n" +); +} + +int main(int argc, char **argv) +{ + struct burn_drive_info *drives; + struct iso_volset *volset; + struct burn_drive *drive; + struct burn_disc *disc; + enum burn_disc_status state; + struct isoburn_read_opts ropts; + struct isoburn_source_opts sopts; + int c; + struct iso_tree_radd_dir_behavior behav = {0,0,0}; + int flags=0; + int ret=0, i; + int size, free_bytes; + char *status_text; + + while ((c = getopt(argc, argv, optstring)) != -1) { + switch(c) { + case 'h': + usage(); + help(); + exit(0); + break; + case 'J': + flags |= ECMA119_JOLIET; + break; + case 'R': + flags |= ECMA119_ROCKRIDGE; + break; + case '?': + usage(); + exit(1); + break; + } + } + + if (argc < optind + 1) { + fprintf(stderr, "Please supply device name\n"); + usage(); + exit(1); + } + if (argc < optind + 2) { + fprintf(stderr, "Please supply directory to add to disc\n"); + usage(); + exit(1); + } + + + if (!isoburn_initialize()) { + fprintf(stderr, "Can't init libisoburn\n"); + exit(1); + } + + /* TODO change this. maybe we can add wrapp in libisoburn */ + iso_msgs_set_severities("NEVER", "DEBUG", "libisofs : "); + burn_msgs_set_severities("NEVER", "DEBUG", "libburn : "); + burn_set_signal_handling("libisoburn/test/test : ", NULL, 0); + + printf("Growing drive %s\n", argv[optind]); + + if (isoburn_drive_scan_and_grab(&drives, argv[optind], 1) <= 0) { + fprintf(stderr, + "Can't open device. Are you sure it is a valid drive?\n"); + exit(1); + } + drive = drives[0].drive; + + /* check for invalid state */ + state = isoburn_disc_get_status(drive); + if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { + fprintf(stderr, "Unsuitable disc status\n"); + goto exit_cleanup; + } + + /* fill read opts */ + memset(&ropts, sizeof(ropts), 0); + ropts.norock = 0; + ropts.nojoliet = 0; + ropts.preferjoliet = 0; + ropts.uid = 0; + ropts.gid = 0; + ropts.mode = 0555; + ropts.pretend_blank= 0; + + if (isoburn_read_volset(drive, &ropts, &volset) <= 0) { + fprintf(stderr, "Can't read volset\n"); + goto exit_cleanup; + } + + +#ifdef With_graft_poinT + for (i = optind + 1; i < argc; i++) { + if (graft_point(iso_volset_get_volume(volset, 0), + argv[i], argv[i], &behav) <= 0) { + fprintf(stderr, "Canot graft '%s'\n", argv[optind+1]); + goto exit_cleanup; + } + } + +#else + struct iso_tree_node_dir *root; + root = iso_volume_get_root(iso_volset_get_volume(volset, 0)); + /* add a new dir */ + iso_tree_radd_dir(root, argv[optind+1], &behav); +#endif /* ! With_graft_poinT */ + + + sopts.level = 2; + sopts.flags = flags; + sopts.relaxed_constraints = 0; + sopts.copy_eltorito = 1; + sopts.no_cache_inodes = 0; + sopts.sort_files = 1; + sopts.default_mode = 0; + sopts.replace_dir_mode = 0; + sopts.replace_file_mode = 0; + sopts.replace_uid = 0; + sopts.replace_gid = 0; + sopts.dir_mode = 0555; + sopts.file_mode = 0444; + sopts.gid = 0; + sopts.uid = 0; + sopts.input_charset = NULL; + sopts.ouput_charset = NULL; + + if (isoburn_prepare_disc(drive, &disc, &sopts) <= 0) { + fprintf(stderr, "Can't prepare disc\n"); + goto volset_cleanup; + } + + /* a. write the new image */ + printf("Adding new data...\n"); + { + struct burn_write_opts *burn_options; + struct burn_progress progress; + + burn_options = burn_write_opts_new(drive); + burn_drive_set_speed(drive, 0, 0); + burn_write_opts_set_underrun_proof(burn_options, 1); + + /* ok, write the new track */ + isoburn_disc_write(burn_options, disc); + burn_write_opts_free(burn_options); + + while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) + usleep(100002); + + while (burn_drive_get_status(drive, &progress) + != BURN_DRIVE_IDLE) { + + printf("Writing: sector %d of %d", + progress.sector, progress.sectors); + ret = isoburn_get_fifo_status(drive, &size, + &free_bytes, &status_text); + if (ret > 0 ) + printf(" [fifo %s, %2d%% fill]", status_text, + (int) (100.0 - 100.0 * + ((double) free_bytes) / + (double) size)); + printf("\n"); + sleep(1); + } + } + + /* b. write the new vol desc */ + printf("Writing the new vol desc...\n"); + if (isoburn_activate_session(drive) <= 0) { + fprintf(stderr, "Ups, new vol desc write failed\n"); + } + + ret= 0; +volset_cleanup:; +/* + iso_volset_free(volset); +*/ + +exit_cleanup:; + isoburn_drive_release(drive, 0); + isoburn_finish(); + + exit(ret); +} + diff --git a/libisoburn/branches/1.4.6/version.h.in b/libisoburn/branches/1.4.6/version.h.in new file mode 100644 index 00000000..cf529233 --- /dev/null +++ b/libisoburn/branches/1.4.6/version.h.in @@ -0,0 +1,6 @@ + +/* <<< this file is on its way out +#define ISOBURN_MAJOR_VERSION @ISOBURN_MAJOR_VERSION@ +#define ISOBURN_MINOR_VERSION @ISOBURN_MINOR_VERSION@ +#define ISOBURN_MICRO_VERSION @ISOBURN_MICRO_VERSION@ +*/ diff --git a/libisoburn/branches/1.4.6/xorriso/AUTHORS_gnu_xorriso b/libisoburn/branches/1.4.6/xorriso/AUTHORS_gnu_xorriso new file mode 100644 index 00000000..cd4ebadc --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/AUTHORS_gnu_xorriso @@ -0,0 +1,15 @@ +Derek Foreman +Ben Jansens +Thomas Schmitt +Mario Danic +Vreixo Formoso Lopes +Colin Plumb +Tatu Ylonen +Jim Kingdon +Scott G. Miller +Ulrich Drepper +Richard Atterer +Steve McIntyre +George Danchev +and possibly others who gave their copyright to Free Software Foundation, Inc. + diff --git a/libisoburn/branches/1.4.6/xorriso/COPYING_gnu_xorriso b/libisoburn/branches/1.4.6/xorriso/COPYING_gnu_xorriso new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/COPYING_gnu_xorriso @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 of the License, 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/libisoburn/branches/1.4.6/xorriso/COPYRIGHT_gnu_xorriso b/libisoburn/branches/1.4.6/xorriso/COPYRIGHT_gnu_xorriso new file mode 100644 index 00000000..6f21ac08 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/COPYRIGHT_gnu_xorriso @@ -0,0 +1,34 @@ +Derek Foreman +Ben Jansens +Thomas Schmitt +Mario Danic , +Vreixo Formoso +Steve McIntyre +George Danchev + +GNU xorriso is a compilation of modules from libburnia-project.org : +xorriso Copyright (C) 2007-2011 Thomas Schmitt +libisoburn Copyright (C) 2007-2011 Vreixo Formoso, Thomas Schmitt +libisofs Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt +libburn Copyright (C) 2002-2006 Derek Foreman, Ben Jansens + 2006-2011 Mario Danic, Thomas Schmitt +Further included is : +libjte Copyright (C) 2000-2007 Free Software Foundation, Inc. + 2004-2011 Steve McIntyre + 2010-2011 George Danchev, Thomas Schmitt + +Originally they all are licensed directly or indirectly as GPLv2+. +GNU xorriso is licensed by the following statement: + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 + or later 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; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA diff --git a/libisoburn/branches/1.4.6/xorriso/README_gnu_xorriso b/libisoburn/branches/1.4.6/xorriso/README_gnu_xorriso new file mode 100644 index 00000000..71bfc91a --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/README_gnu_xorriso @@ -0,0 +1,528 @@ +------------------------------------------------------------------------------ + Contribution of libburnia-project.org to the GNU Operating System +------------------------------------------------------------------------------ +GNU xorriso. By Thomas Schmitt +Derived from and supported by libburnia-project.org, published via: +http://www.gnu.org/software/xorriso/xorriso_eng.html +http://www.gnu.org/software/xorriso/xorriso-1.4.5.tar.gz +Provided under GPL version 3 or later. No warranty. +------------------------------------------------------------------------------ + + +xorriso is a program which copies file objects from POSIX compliant +filesystems into Rock Ridge enhanced ISO 9660 filesystems and allows +session-wise manipulation of such filesystems. It can load the management +information of existing ISO images and it writes the session results to +optical media or to filesystem objects. +Vice versa xorriso is able to restore file objects from ISO 9660 filesystems. + +A special property of xorriso is that it needs neither an external ISO 9660 +formatter program nor an external burn program for CD or DVD but rather +incorporates the libraries of libburnia-project.org . + +Currently it is fully supported on GNU/Linux with kernels >= 2.4, +on FreeBSD with ATAPI/CAM support enabled in the kernel, see atapicam(4), +on OpenSolaris (tested with kernel 5.11), +on NetBSD (tested with 6.1.2 and 6.1.3). +On other X/Open compliant systems there will only be POSIX i/o with disk +file objects, but no direct MMC operation on CD/DVD/BD drives. + +By using this software you agree to the disclaimer at the end of this text: +"... without even the implied warranty ..." + + + Compilation, First Glimpse, Installation + +The most simple way to get xorriso from source code is the GNU xorriso tarball. + +Prerequisites: +The tarball contains everything that is needed except the following system +components: + libc, libpthread + plus on Solaris: libvolmgt + plus on FreeBSD: libiconv, libcam, IDE and SATA drives need atapicam +Optional at compile time are: + libreadline and the readline-dev headers, or libedit and its header, + make dialog mode more convenient. + zlib and zlib-devel allow zisofs compression. + on GNU/Linux: libacl and libacl-devel allow getting and setting ACLs. +If they were present at compile time, then the optional libraries have to +be present at runtime, too. + +Obtain xorriso-1.4.5.tar.gz, take it to a directory of your choice and do: + + tar xzf xorriso-1.4.5.tar.gz + cd xorriso-1.4.5 + +Within that directory execute: + + ./configure --prefix=/usr + make + +This will produce a binary named + ./xorriso/xorriso + +If you want xorriso to report a "Build timestamp" with its option -version : + make buildstamped + +You may strip the binary to reduce it in size + strip ./xorriso/xorriso + +You may copy or move it to a directory where it can be found by the shell, +or you may execute xorriso at the place where it was built, +or you may execute as superuser: + make install + +For general concepts, options and usage examples see + info xorriso + info xorrisofs + info xorrecord +or + man 1 xorriso + man 1 xorrisofs + man 1 xorrecord + +You may get a first glimpse by e.g. + info ./xorriso/xorriso.info + man ./xorriso/xorriso.1 + +The installation creates several alias links pointing to the xorriso binary: + xorrisofs starts xorriso with -as mkisofs emulation already enabled + xorrecord starts xorriso with -as cdrecord emulation already enabled + osirrox starts with -osirrox image-to-disk copying already enabled + + +By default xorriso will depend on libreadline if the library and its +development header files are present at compile time. If not, then it will +try to depend on libedit and its header file. +Both conditional dependencies can be avoided by running + ./configure --prefix=/usr --disable-libreadline + make clean ; make +Never omit the "make clean" command after switching enabling of libreadline. +If you want to explictely allow only the use of libedit, then do + ./configure --prefix=/usr --disable-libreadline --enable-libedit + +Other deliberate dependency reduction options of ./configure are: + --disable-libacl avoid use of ACL functions like acl_to_text() + --disable-xattr avoid use of xattr functions like listxattr() on Linux + or extattr_list_file() on FreeBSD + --disable-zlib avoid use of zlib functions like compress2() + this also avoids the use of libjte and option -jigdo. + +xorriso brings own system adapters which allow burning optical media on +GNU/Linux, FreeBSD, Solaris, NetBSD. +Alternatively it can use libcdio-0.83 or later for sending commands to +optical drives: + --enable-libcdio + +xorriso allows to use external processes as file content filters. This is +a potential security risk which may be avoided by ./configure option + --disable-external-filters + +By default the filter feature is disabled if effective user id and real +user id differ. This ban can be lifted by + --enable-external-filters-setuid + +Sometimes xorriso will yield better write performance on GNU/Linux if 64 KB are +transmitted in each write operation rather than 32 KB. See option -dvd_obs . +64k can be made default at configure time by: + --enable-dvd-obs-64k + +For xorriso -as cdrecord emulation only: +In some situations GNU/Linux may deliver a better write performance to drives +if the track input is read with O_DIRECT (see man 2 open). The included libburn +and the cdrecord emulation of xorriso can be told to use this peculiar read +mode by: + --enable-track-src-odirect + +Linux only: +libburn tries to avoid a collision with udev's drive examination by waiting +0.1 seconds before opening the device file for a longer time, after udev +might have been alarmed by drive scanning activities. +The waiting time can be set at ./configure time with microsecond granularity. +E.g. 2 seconds: + CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000" + ./configure ...options... +Waiting can be disabled by zero waiting time: + CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0" +Alternatively, libburn can try to be nice by opening the device file, +closing it immediately, waiting, and only then opening it for real: + CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000" + + + xorriso under control of a (GUI) frontend process + +The dialog mode allows frontend programs to connect via pipes to the standard +input and output of xorriso. Several commands of xorriso help with receiving +and parsing of reply messages. + +As a proof of concept, there is the Tcl/Tk script xorriso-tcltk which can +be launched by this shell command: + + xorriso-tcltk + +Or in the xorriso build directory, without installation of xorriso: + + xorriso/xorriso -launch_frontend frontend/xorriso-tcltk --stdio -- + +In the running GUI, click with the rightmost mouse button on any GUI element +to get its particular help text. The "Help" button at the upper right corner +gives a short introduction and instructions for some common use cases. +See also file frontend/README-tcltk. +See its Tcl code for getting an idea how this gets achieved. + +The script is part of the tarball and gets installed by make install. If a +xorriso distro package does not install it, you may get it directly from + http://libburnia-project.org/export/head/libisoburn/trunk/frontend/xorriso-tcltk + +Further there is the C program frontend/frontend_pipes_xorriso.c which +forks a xorriso process and shows the same communication gestures as +xorriso-tcltk. +In particular it connects to xorriso via two pipes, sends commands, waits +for all replies of a command, picks info out of the xorriso message sieve, +and parses reply message lines into words. + +The bash script frontend/sh_on_named_pipes.sh forks a xorriso process +connected to two pipes. It then runs a dialog loop, sends commands to xorriso, +and displays the replies. + +The sh script frontend/xorriso_broker.sh is intended to execute xorriso +commands on a permanently running xorriso process. +It gets an id_string by which it looks for named pipes with a running xorriso +process. If no such pipe is found, then it starts a xorriso connected to +newly created pipes. +After this is done, the optionally given xorriso arguments are written into +the stdin pipe from where xorriso will read and execute them. The script will +end but the xorriso process will go on and wait for more commands. + + + Drives and Disk File Objects + +The user of libisoburn applications needs rw-permission for the CD/DVD/BD +drives which shall be used, even if only reading is intended. +A list of rw-accessible drives can be obtained by + + xorriso -devices + +CD devices which offer not enough permission are invisible to normal users. +The superuser should be able to see any usable drive and then set the +permissions as needed. +On Linux, FreeBSD, and NetBSD, rw-permissions are needed. +On Solaris, the privilege "sys_devices" and r-permission are needed. + +The output of xorriso -devices might look like + +0 -dev '/dev/sr0' rwrw-- : 'TSSTcorp' 'CDDVDW SH-S203B' +1 -dev '/dev/hda' rwrw-- : 'HL-DT-ST' 'DVD-ROM GDR8162B' + +On Linux, full and insecure enabling of both for everybody would look like + chmod a+rw /dev/sr0 /dev/hda +This is equivalent to the traditional setup chmod a+x,u+s cdrecord. + +On FreeBSD, device permissions are to be set in /etc/devfs.rules. +On Solaris, pfexec privileges may be restricted to "basic,sys_devices". +On NetBSD, rw-permission may be granted by chmod a+rw /dev/rcd?d. +See below "System Dependent Drive Permission Examples". + +I strongly discourage to run xorriso with setuid root or via sudo ! +It is not checked for the necessary degree of hacker safety. +Better consider to grant the necessary permissions to group "floppy" +and to add users to it. + + +A possible source of problems are hald or other automounters. +If you can spot a process "hald-addon-storage" with the address of +your desired drive, then consider to kill it. +A similar process "udisks-daemon: polling ..." can be seen on newer Linuxes. + +On Debian GNU/Linux 6.0.2 amd64 there is + /lib/udev/rules.d/80-udisks.rules +where one can remove all CD drives ("sr*") from the list of automountable +devices: + KERNEL=="sd*|hd*|mmcblk*|mspblk*", ENV{UDISKS_PRESENTATION_NOPOLICY}="0" + # KERNEL=="sd*|hd*|sr*|mmcblk*|mspblk*", ENV{UDISKS_PRESENTATION_NOPOLICY}="0" +Copying the recognition criterion from + /etc/udev/rules.d/70-persistent-cd.rules +one can prevent automounting a single drive, too: + SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", ENV{ID_PATH}=="pci-0000:00:11.0-scsi-2:0:0:0", ENV{UDISKS_PRESENTATION_NOPOLICY}:="1" + +If you cannot get rid of the automounter, try whether it helps to always load +the drive tray manually before starting a write run of xorriso. Wait until the +drive light is off and the mounted media appears. +Then try to unmount the mounted media before a write run. + + +Besides true optical drives, xorriso can also address disk files as input or +output drives. By default paths to files under /dev are accepted only if the +device represents a real optical drive. Other device files may be addressed +by prepending "stdio:" to the path. +Like: + xorriso -dev stdio:/dev/sdb ...more arguments... +This rule may be changed by xorriso option -drive_class. +Prefix "mmc:" causes a path to be accepted only if it is a real optical drive +which is accessible by generic SCSI/MMC commands. + + + Testing + +For automated and manual tests of xorriso's functionality see file + releng/README + + + Result comparison with self produced ISO images + +We are quite sure that libisofs produces accurate representations of the disk +files. This opinion is founded on a lot of test burns and checks by a little +test program which compares files from the mounted image with the orignals +on disk. It uses the normal POSIX filesystem calls, i.e. no libburnia stuff. + +This program is not installed systemwide but stays in the installation +directory of the xorriso tarball as test/compare_file . Usually it is +run as -exec payload of a find command. It demands at least three arguments: +The path of the first file to compare, the prefix1 to be cut off from path +and the prefix2 which gets prepended afterwards to obtain the path of the +second file to compare. +As further argument there can be -no_ctime which suppresses the comparison +of ctime date stamps. +The exit value is 0 if no difference was detected, non-0 else. + +Example: After + xorriso ... -pathspecs on -add /=/original/dir -- -commit_eject all + mount /media/dvd + cd test +compare tree /media/dvd with tree /original/dir : + find /original/dir -exec ./compare_file '{}' /original/dir /media/dvd ';' \ + | less +and vice versa: + find /media/dvd -exec ./compare_file '{}' /media/dvd /original/dir ';' \ + | less + + + File Formats + + Sector Maps + +Sector maps describe the valid and invalid blocks on a media or a disk copy of +a media. xorriso creates and reads these file with its option -check_media. + +The file begins with 32 bytes of cleartext of which the last one is a +newline character. The first 25 say "xorriso sector bitmap v2 ", the +remaining six characters give the size of the info text as decimal number. +This number of bytes follows the first 32 and will not be interpreted +by xorriso. They are rather to inform a human reader about the media type +and its track layout. +After the info text there are two 4 byte signed integers, most significant +byte first. The first one, N, gives the number of bits in the following bitmap +and the second number S gives the number of 2 KiB blocks governed by a single +bit in the map. Then come the bits in form of 8-bit bytes. +Data block M is covered by bit B=M/S in the map, bit number B is stored in +byte B/8 as bit B%8. A valid readable data block has its bit set to 1. + + Checksum Tags + +Checksum tags are data blocks inside an ISO 9660 image which do not belong to +any file but rather tell the MD5 of a certain range of data blocks. + +The superblock checksum tag is written after the ECMA-119 volume descriptors. +The tree checksum tag is written after the ECMA-119 directory entries. +The session checksum tag is written after all payload including the checksum +array. (Then follows padding.) + +The tags are single lines of printable text, padded by 0 bytes. They have +the following format: + + Tag_id pos=# range_start=# range_size=# [session_start|next=#] md5=# self=#\n + +Parameters md5= and self= are 32 digit hex, the others are decimal numbers. + +Tag_id distinguishes the following tag types + "libisofs_rlsb32_checksum_tag_v1" Relocated 64 kB superblock tag + "libisofs_sb_checksum_tag_v1" Superblock tag + "libisofs_tree_checksum_tag_v1" Directory tree tag + "libisofs_checksum_tag_v1" Session end tag + +A relocated superblock may appear at LBA 0 of an image which was produced for +being stored in a disk file or on overwriteable media (e.g. DVD+RW, BD-RE). +xorriso records the first session at LBA 32. A follow-up session +begins at the next block address which is divisible by 32 and higher than the +address of the previous session's end tag. Normally no session starts after the +address given by relocated superblock parameter session_start=. +Session oriented media like CD-R[W], DVD-R, DVD+R, BD-R will have no relocated +superblock but rather bear a table-of-content on media level. + +A tag is valid if pos= tells its own block address and self= tells its own MD5 +up to the last hex digit of md5=. range_start= tells the first block that is +covered by md5=, range_size= tells the number of blocks covered by md5=. +Relocated superblocks tell the block address of their session by session_start=. +Superblock and tree tag tell the block address of the next tag by next=. +The newline character at the end is mandatory. + + + libisoburn + +xorriso is based on libisofs which does ISO 9660 filesystem aspects and on +libburn which does the input and output aspects. Parts of this foundation +are accessed via libisoburn, which is closely related to xorriso. + +libisoburn provides several services: +- Encapsulation of coordination between libisofs and libburn. +- Emulation of ISO 9660 multi-session on overwriteable media + or random access files. +- Implementation of the xorriso API. + +The sourcecode of all three libraries is included in the xorriso standalone +tarball. It is compiled with xorriso and linked statically. +But you may as well get and install releases of libburn and libisofs, in order +to be able to install a release of libisoburn which produces libisoburn.so.1 +and a matching dynamically linked xorriso binary. +This binary is very lean but depends on properly installed libraries of +suitable revision. + +Dynamic library and compile time header requirements for libisoburn-1.4.4 : +- libburn.so.4 , version libburn-1.4.4 or higher +- libisofs.so.6 , version libisofs-1.4.4 or higher +libisoburn and xorriso will not start with libraries which are older than their +headers seen at compile time. So compile in the oldest possible installation +setup unless you have reason to enforce a newer bug fix level. + +GNU xorriso has less runtime dependencies and can be moved more freely. + + + System Dependent Drive Permission Examples + +Accessing the optical drives requires privileges which usually are granted +only to the superuser. GNU/Linux, FreeBSD, Solaris, and NetBSD offer quite +different approaches for avoiding the need for unrestricted privileges. + +First check whether some friendly system setting already allows you to +access the drives as normal user: + xorriso -devices +Those drives of which you see address and type strings are already usable. + +If there remain drives invisible which the superuser can see by the same +command, then the following examples might help: + +--------------- +On all systems: +--------------- +Add the authorized users of CD drives to group "floppy" in /etc/group. +If missing: create this group. +Changes to /etc/group often only affect new login sessions. So log out and in +before making the first tests. + +------------- +On GNU/Linux: +------------- +Allow rw-access to the drives + chgrp floppy /dev/sr0 /dev/sr1 + chmod g+rw /dev/sr0 /dev/sr1 +It might be necessary to perform chgrp and chmod after each reboot or to +edit distro dependent device configuration files for permanent settings. + +----------- +On FreeBSD: +----------- +Edit /etc/devfs.rules and make sure to have these lines + [localrules=10] + add path 'acd*' mode 0664 group floppy + add path 'cd*' mode 0664 group floppy + add path 'pass*' mode 0664 group floppy + add path 'xpt*' mode 0664 group floppy + [localrules=5] + add path 'pass*' mode 0664 group floppy + add path 'cd*' mode 0664 group floppy + add path 'xpt*' mode 0664 group floppy + add path 'acd*' mode 0664 group floppy + +Edit /etc/rc.conf and add the following line if missing + devfs_system_ruleset="localrules" + +This gets into effect by reboot or by command + /etc/rc.d/devfs start + +----------- +On Solaris: +----------- +Run xorriso by + pfexec xorriso ...arguments... + +The following settings will make pfexec keep original UID and EUID and prevent +most superuser powers. Be aware that you still can manipulate all device files +if you have the file permissions for that. +Full root privileges for xorriso can then be acquired only by command su. + +Edit /etc/security/exec_attr and add this line to the other "Media Backup" +lines: + Media Backup:solaris:cmd:::/usr/local/bin/xorriso:privs=basic,sys_devices +Edit /etc/user_attr and add profile "Media Backup" to the user's line: + thomas::::profiles=Media Backup,Primary Administrator;roles=root +See also man privileges, man exec_attr, man user_attr. + +Then allow the group r-access to the drives + pfexec chgrp floppy /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2 + pfexec chmod g+r /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2 +The last two commands have to be executed after each boot. I do not know +the relevant device configuration files yet. + +---------- +On NetBSD: +---------- +Allow rw-access to the drives + chgrp floppy /dev/rcd[01]d + chmod g+rw /dev/rcd[01]d + +------------------------------------------------------------------------------ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 or later + 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; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +------------------------------------------------------------------------------ + + GNU xorriso is feature-wise equivalent to the dynamic compilation of + libburnia libraries and libburnia program xorriso. + It restricts itself to a technical form where the legal commitments of the + libburnia project and the legal intentions of FSF match completely. + + Libburnia project is committed to provide support for this copy in the same + way as for its own software releases. It is further committed to keep its + own licenses open for obtaining future copies under GPLv2+. + +------------------------------------------------------------------------------ +libburnia program xorriso is based on and sub project of: +libburnia-project.org +By Mario Danic , libburn, libisofs + Vreixo Formoso , libisofs, libisoburn + Thomas Schmitt , libburn, libisofs, + libisoburn, xorriso +Copyright (C) 2006-2016 Mario Danic, Vreixo Formoso, Thomas Schmitt. + +libburnia-project.org is inspired by and in libburn still containing parts +of old +Libburn. By Derek Foreman and + Ben Jansens +Copyright (C) 2002-2006 Derek Foreman and Ben Jansens + +GNU xorriso contains libjte out of source package jigit >= 1.17 +Copyright (C) 2000-2007 Free Software Foundation, Inc. + 2004-2011 Steve McIntyre + 2010-2011 George Danchev, Thomas Schmitt + +------------------------------------------------------------------------------ + +This text itself is +Copyright (c) 2007 - 2016 Thomas Schmitt +and is freely distributable. +It shall only be modified in sync with the technical properties of xorriso. +If you make use of the license to derive modified versions of xorriso +then you are entitled to modify this text under that same license. + diff --git a/libisoburn/branches/1.4.6/xorriso/aux_objects.c b/libisoburn/branches/1.4.6/xorriso/aux_objects.c new file mode 100644 index 00000000..f0245bf7 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/aux_objects.c @@ -0,0 +1,1032 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementations of classes: + + - SplitparT which represents byte intervals of data files. + + - DirseQ which crawls along a directory's content list. + + - ExclusionS which manages the list of excluded file paths and + leaf patterns. + Because of its structural identity it is also used for disk address + oriented hiding at insert time as of mkisofs. + + - Xorriso_lsT which provides a generic double-linked list. + + - LinkiteM, PermiteM which temporarily record relations and states. + +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" + + +/* ---------------------------- SplitparT ------------------------- */ + + +struct SplitparT { + char *name; + int partno; + int total_parts; + off_t offset; + off_t bytes; + off_t total_bytes; +}; + +static char Splitpart_wordS[][16]= {"part_", "_of_", "_at_", "_with_", "_of_"}; + + +int Splitparts_new(struct SplitparT **o, int count, int flag) +{ + int i; + + (*o)= TSOB_FELD(struct SplitparT, count); + if((*o)==NULL) + return(-1); + for(i= 0; i 1.0) + ept++; + *next_pt= ept; + return(1); +} + + +int Splitpart__parse(char *name, int *partno, int *total_parts, + off_t *offset, off_t *bytes, off_t *total_bytes, int flag) + +{ + int ret; + off_t num; + char *cpt, *ept; + + cpt= name; + if(strncmp(cpt, Splitpart_wordS[0], strlen(Splitpart_wordS[0])) != 0) + return(0); + ret= Splitpart__read_next_num(cpt, &ept, &num, 0); + if(ret<=0) + return(ret); + *partno= num; + cpt= ept; + if(strncmp(cpt, Splitpart_wordS[1], strlen(Splitpart_wordS[1])) != 0) + return(0); + ret= Splitpart__read_next_num(cpt, &ept, &num, 0); + if(ret<=0) + return(ret); + *total_parts= num; + cpt= ept; + if(strncmp(cpt, Splitpart_wordS[2], strlen(Splitpart_wordS[2])) != 0) + return(0); + ret= Splitpart__read_next_num(cpt, &ept, offset, 0); + if(ret<=0) + return(ret); + cpt= ept; + if(strncmp(cpt, Splitpart_wordS[3], strlen(Splitpart_wordS[3])) != 0) + return(0); + ret= Splitpart__read_next_num(cpt, &ept, bytes, 0); + if(ret<=0) + return(ret); + cpt= ept; + if(strncmp(cpt, Splitpart_wordS[4], strlen(Splitpart_wordS[4])) != 0) + return(0); + ret= Splitpart__read_next_num(cpt, &ept, total_bytes, 0); + if(ret<=0) + return(ret); + if(*ept != 0) + return(0); + return(1); +} + + +int Splitpart__is_part_path(char *path, int flag) +{ + int partno, total_parts, ret; + off_t offset, bytes, total_bytes; + char *name; + + name= strrchr(path, '/'); + if(name == NULL) + name= path; + else + name++; + ret= Splitpart__parse(name, &partno, &total_parts, &offset, &bytes, + &total_bytes, 0); + return(ret > 0); +} + + +/* part_#_of_#_at_#_with_#_of_# +*/ +int Splitpart__compose(char *adr, int partno, int total_parts, + off_t offset, off_t bytes, off_t total_bytes, int flag) +{ + sprintf(adr, "%s%d%s%d%s", Splitpart_wordS[0], partno, Splitpart_wordS[1], + total_parts, Splitpart_wordS[2]); + if((offset % (1024*1024))==0 && offset>0) { + Sfile_off_t_text(adr+strlen(adr), offset / (1024*1024), 0); + strcat(adr, "m"); + } else + Sfile_off_t_text(adr+strlen(adr), offset, 0); + strcat(adr, Splitpart_wordS[3]); + if((bytes % (1024*1024))==0) { + Sfile_off_t_text(adr+strlen(adr), bytes / (1024*1024), 0); + strcat(adr, "m"); + } else + Sfile_off_t_text(adr+strlen(adr), bytes, 0); + strcat(adr, Splitpart_wordS[4]); + Sfile_off_t_text(adr+strlen(adr), total_bytes, 0); + return(1); +} + + +int Splitparts_cmp(const void *v1, const void *v2) +{ + struct SplitparT *p1, *p2; + + p1= (struct SplitparT *) v1; + p2= (struct SplitparT *) v2; + + if(p1->partno>p2->partno) + return(1); + if(p1->partnopartno) + return(-1); + if(p1->offset>p2->offset) + return(1); + if(p1->offsetoffset) + return(-1); + return(0); +} + + +int Splitparts_sort(struct SplitparT *o, int count, int flag) +{ + qsort(o, (size_t) count, sizeof(struct SplitparT), Splitparts_cmp); + return(1); +} + + +/* ---------------------------- End SplitparT ------------------------- */ + + +/* ------------------------------ DirseQ ------------------------------ */ + + +static int Dirseq_buffer_sizE= 100; + +struct DirseQ { + char adr[SfileadrL]; + DIR *dirpt; + int count; + char **buffer; + int buffer_size; + int buffer_fill; + int buffer_rpt; + + struct DirseQ *next; +}; + +int Dirseq_destroy(struct DirseQ **o, int flag); +int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count, + int max_replies, int flag); + + +int Dirseq_new(struct DirseQ **o, char *adr, int flag) +/* + bit0= with non-fatal errors do not complain about failed opendir() +*/ +{ + int ret,i,severe_error; + struct DirseQ *m; + + m= *o= TSOB_FELD(struct DirseQ,1); + if(m==NULL) + return(-1); + m->adr[0]= 0; + m->dirpt= NULL; + m->count= 0; + m->buffer= NULL; + m->buffer_size= 0; + m->buffer_fill= 0; + m->buffer_rpt= 0; + m->next= NULL; + if(Sfile_str(m->adr, adr, 0)<=0) + {ret= -1; goto failed;} + m->buffer= TSOB_FELD(char *,Dirseq_buffer_sizE); + if(m->buffer==NULL) + {ret= -1; goto failed;} + m->buffer_size= Dirseq_buffer_sizE; + for(i= 0;ibuffer_size;i++) + m->buffer[i]= NULL; + if(adr[0]==0) + m->dirpt= opendir("."); + else + m->dirpt= opendir(adr); + if(m->dirpt==NULL) { + severe_error= (errno && errno!=ENOENT && errno!=EACCES && errno!=ENOTDIR); + if(severe_error || !(flag&1)) + fprintf(stderr,"opendir(%s) failed : %s\n",adr,strerror(errno)); + ret= -severe_error; + goto failed; + } + return(1); +failed:; + Dirseq_destroy(o,0); + return(ret); +} + + +int Dirseq_destroy(struct DirseQ **o, int flag) +{ + int i; + + if(*o==NULL) + return(0); + if((*o)->dirpt!=NULL) + closedir((*o)->dirpt); + if((*o)->buffer!=NULL) { + for(i=0;i<(*o)->buffer_size;i++) + if((*o)->buffer[i]!=NULL) + free((*o)->buffer[i]); + free((char *) (*o)->buffer); + } + free((char *) *o); + (*o)= NULL; + return(1); +} + + +int Dirseq_set_next(struct DirseQ *o, struct DirseQ *next, int flag) +{ + o->next= next; + return(1); +} + + +int Dirseq_get_next(struct DirseQ *o, struct DirseQ **next, int flag) +{ + *next= o->next; + return(1); +} + + +int Dirseq_get_adr(struct DirseQ *o, char **adrpt, int flag) +{ + *adrpt= o->adr; + return(1); +} + + +int Dirseq_rewind(struct DirseQ *o, int flag) +{ + rewinddir(o->dirpt); + return(1); +} + + +int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag) +/* +flag: + bit0= permission to use buffer + bit1= do not increment counter + bit2= ignore buffer in any case + bit3= do not exclude '.' and '..' + bit4= sort buffer + bit5= sort only incomplete last buffer +return: + <0 error + 0= no more entries available + 1= ok, reply is valid +*/ +{ + int ret; + struct dirent *entry; + char *name; + + static int override_flag_0= 0,override_flag_1= 32; + flag= (flag&~override_flag_0)|override_flag_1; + + if((flag&1) && o->buffer_rpt>=o->buffer_fill) { + /* permission to buffer and buffer empty : load a buffer */ + ret= Dirseq_next_adrblock(o,o->buffer,&(o->buffer_fill), + o->buffer_size,2|4|(flag&16)); + if(ret<=0) + return(ret); + o->buffer_rpt= 0; + if((flag&32) && o->buffer_fillbuffer_size && o->buffer_fill>0) + Sort_argv(o->buffer_fill,o->buffer,0); + } + if(o->buffer_rptbuffer_fill && !(flag&4)) { + ret= Sfile_str(reply,o->buffer[o->buffer_rpt],0); + Sregex_string(&(o->buffer[o->buffer_rpt]),NULL,0); + if(ret<=0) + return(-1); + (o->buffer_rpt)++; + if(!(flag&2)) + o->count++; + return(1); + } + do { + entry= readdir(o->dirpt); + if(entry==NULL) { + /* >>> how to distinguish error from EOF , do i need a (FILE *) ? */ + return(0); + } + if(strlen(entry->d_name)>=SfileadrL) { + fprintf(stderr,"--- oversized directory entry (number %d) :\n %s", + o->count+1,entry->d_name); + return(-1); + } + name= entry->d_name; + if(flag&8) + break; + /* skip "." and ".." */ + } while(name[0]=='.' && ((name[1]=='.' && name[2]==0) || name[1]==0)); + if(Sfile_str(reply,name,0)<=0) + return(-1); + if(!(flag&2)) + o->count++; + return(1); +} + + +int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count, + int max_replies, int flag) +/* @param replies A vector of Sregex_string pointers */ +/* +flag: + bit0= permission to use buffer + bit1= do not increment counter + bit2= ignore buffer in any case + bit4= sort replies +return: + <0 error + 0= no more entries available + 1= ok, reply is valid +*/ +{ + int i,ret; + char *reply= NULL; + + reply= TSOB_FELD(char, SfileadrL); + if(reply == NULL) + return(-1); + + *reply_count= 0; + for(i=0;itext= NULL; + s->next= s->prev= NULL; + + if(flag & 4) { + s->text= data; + } else { + if(data_len<=0) + goto failed; + s->text= Smem_malloC(data_len); + if(s->text==NULL) + goto failed; + if(!(flag&2)) + memcpy(s->text,data,data_len); + } + + if(link==NULL) { + ; + } else if(flag&1) { + s->next= link; + s->prev= link->prev; + if(link->prev!=NULL) + link->prev->next= s; + link->prev= s; + } else { + s->prev= link; + s->next= link->next; + if(link->next!=NULL) + link->next->prev= s; + link->next= s; + } + *lstring= s; + return(1); +failed:; + *lstring= s; + Xorriso_lst_destroy(lstring,0); + return(-1); +} + + +/* + @param flag Bitfield for control purposes + see Xorriso_lst_new_binary() +*/ +int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text, + struct Xorriso_lsT *link, int flag) +{ + int ret; + + ret= Xorriso_lst_new_binary(lstring,text,strlen(text)+1,link,flag); + return(ret); +} + + +/* + @param flag Bitfield for control purposes + bit0= do not set *lstring to NULL +*/ +int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag) +{ + struct Xorriso_lsT *s; + + s= *lstring; + if(s==NULL) + return(0); + if(s->prev!=NULL) + s->prev->next= s->next; + if(s->next!=NULL) + s->next->prev= s->prev; + if(s->text!=NULL) + Smem_freE(s->text); + Smem_freE((char *) s); + if(!(flag&1)) + *lstring= NULL; + return(1); +} + + +int Xorriso_lst_destroy_all(struct Xorriso_lsT **lstring, int flag) +{ + struct Xorriso_lsT *s,*next; + + if(lstring==NULL) + return(-1); + if((*lstring)==NULL) + return(0); + for(s= *lstring; s->prev!=NULL; s= s->prev); + for(;s!=NULL;s= next){ + next= s->next; + Xorriso_lst_destroy(&s,0); + } + *lstring= NULL; + return(1); +} + + +int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, + char *data, int data_len, int flag) +{ + struct Xorriso_lsT *target= NULL,*newby; + + if(*entry!=NULL) + for(target= *entry; target->next!=NULL; target= target->next); + if(Xorriso_lst_new_binary(&newby, data, data_len, target, flag & ~1)<=0) + return(-1); + if(*entry==NULL || (flag & 1)) + *entry= newby; + return(1); +} + + +struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag) +{ + return(entry->next); +} + + +struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag) +{ + return(entry->prev); +} + + +char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag) +{ + return(entry->text); +} + + +int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag) +{ + entry->text= NULL; + return(1); +} + + +int Xorriso_lst_get_last(struct Xorriso_lsT *entry, struct Xorriso_lsT **last, + int flag) +{ + *last= NULL; + if(entry != NULL) + for((*last)= entry; (*last)->next != NULL; (*last)= (*last)->next); + return(1); +} + + +int Xorriso_lst_concat(struct Xorriso_lsT *first, struct Xorriso_lsT *second, + int flag) +{ + struct Xorriso_lsT *last; + + Xorriso_lst_get_last(first, &last, 0); + if(last != NULL) + last->next= second; + if(second != NULL) + second->prev= last; + return(1); +} + +/* --------------------------- End Xorriso_lsT ---------------------------- */ + + +/* ------------------------------ ExclusionS ------------------------------ */ + + +struct ExclusionS { + + /* Absolute input patterns which lead to not_paths */ + struct Xorriso_lsT *not_paths_descr; + + /* Actually banned absolute paths */ + struct Xorriso_lsT *not_paths; + + /* Input patterns which lead to not_leafs */ + struct Xorriso_lsT *not_leafs_descr; + + /* Compiled not_leaf patterns. Caution: not char[] but regex_t */ + struct Xorriso_lsT *not_leafs; + +}; + + +int Exclusions_new(struct ExclusionS **o, int flag) +{ + struct ExclusionS *m; + + m= *o= TSOB_FELD(struct ExclusionS, 1); + if(m==NULL) + return(-1); + m->not_paths_descr= NULL; + m->not_paths= NULL; + m->not_leafs_descr= NULL; + m->not_leafs= NULL; + return(1); +} + + +int Exclusions_destroy(struct ExclusionS **o, int flag) +{ + struct Xorriso_lsT *s,*next; + + if((*o)==NULL) + return(0); + Xorriso_lst_destroy_all(&((*o)->not_paths_descr), 0); + Xorriso_lst_destroy_all(&((*o)->not_paths), 0); + Xorriso_lst_destroy_all(&((*o)->not_leafs_descr), 0); + for(s= (*o)->not_leafs; s!=NULL; s= next){ + next= s->next; + regfree((regex_t *) s->text); + Xorriso_lst_destroy(&s, 0); + } + free((char *) *o); + (*o)= NULL; + return(1); +} + + +int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs, + int pathc, char **paths, int flag) +{ + struct Xorriso_lsT *s, *new_s; + int i, ret; + + s= NULL; + if(o->not_paths_descr!=NULL) + for(s= o->not_paths_descr; s->next!=NULL; s= s->next); + for(i= 0; inot_paths_descr==NULL) + o->not_paths_descr= new_s; + s= new_s; + } + s= NULL; + if(o->not_paths!=NULL) + for(s= o->not_paths; s->next!=NULL; s= s->next); + for(i= 0; inot_paths==NULL) + o->not_paths= new_s; + s= new_s; + } + return(1); +} + + +/* @return -1=cannot store , 0=cannot compile regex , 1=ok +*/ +int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr, + regex_t *re, int flag) +{ + int ret; + + ret= Xorriso_lst_append_binary(&(o->not_leafs_descr), + not_leafs_descr, strlen(not_leafs_descr)+1, 0); + if(ret<=0) + return(-1); + ret= Xorriso_lst_append_binary(&(o->not_leafs), (char *) re, sizeof(regex_t), 0); + if(ret<=0) + return(-1); + return(1); +} + + +/* @param flag bit0= whole subtree is banned with -not_paths + @return 0=no match , 1=not_paths , 2=not_leafs, <0=error +*/ +int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag) +{ + struct Xorriso_lsT *s; + char *leaf= NULL, *leaf_pt; + regmatch_t match[1]; + int ret, was_non_slash, l; + + /* test abs_paths */ + if(flag&1) { + for(s= o->not_paths; s!=NULL; s= s->next) { + l= strlen(s->text); + if(strncmp(abs_path, s->text, l)==0) + if(abs_path[l]=='/' || abs_path[l]==0) + {ret= 1; goto ex;} + } + } else { + for(s= o->not_paths; s!=NULL; s= s->next) + if(strcmp(abs_path, s->text)==0) + {ret= 1; goto ex;} + } + + /* determine leafname */ + was_non_slash= 0; + for(leaf_pt= abs_path+strlen(abs_path); leaf_pt >= abs_path; leaf_pt--) { + if(*leaf_pt=='/') { + if(was_non_slash) { + leaf_pt++; + break; + } + } else if(*leaf_pt!=0) + was_non_slash= 1; + } + if(strlen(leaf_pt)>=SfileadrL) + {ret= -1; goto ex;} + leaf= strdup(leaf_pt); + leaf_pt= strchr(leaf, '/'); + if(leaf_pt!=NULL) + *leaf_pt= 0; + + /* test with leaf expressions */ + for(s= o->not_leafs; s!=NULL; s= s->next) { + ret= regexec((regex_t *) s->text, leaf, 1, match, 0); + if(ret==0) + {ret= 2; goto ex;} + } + ret= 0; +ex: + if(leaf != NULL) + free(leaf); + return(ret); +} + + +int Exclusions_get_descrs(struct ExclusionS *o, + struct Xorriso_lsT **not_paths_descr, + struct Xorriso_lsT **not_leafs_descr, int flag) +{ + *not_paths_descr= o->not_paths_descr; + *not_leafs_descr= o->not_leafs_descr; + return(1); +} + +/* ---------------------------- End ExclusionS ---------------------------- */ + + +/* ------------------------------ LinkiteM -------------------------------- */ + +struct LinkiteM { + char *link_path; + dev_t target_dev; + ino_t target_ino; + int link_count; + struct LinkiteM *next; +}; + + +int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev, + ino_t target_ino, struct LinkiteM *next, int flag) +{ + struct LinkiteM *m; + + m= *o= TSOB_FELD(struct LinkiteM,1); + if(m==NULL) + return(-1); + m->target_dev= target_dev; + m->target_ino= target_ino; + m->next= next; + m->link_count= 1; + if(next!=NULL) + m->link_count= m->next->link_count+1; + m->link_path= strdup(link_path); + if(m->link_path==NULL) + goto failed; + return(1); +failed:; + Linkitem_destroy(o, 0); + return(-1); +} + + +int Linkitem_destroy(struct LinkiteM **o, int flag) +{ + if((*o)==NULL) + return(0); + if((*o)->link_path!=NULL) + free((*o)->link_path); + free((char *) (*o)); + *o= NULL; + return(1); +} + + +int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag) +{ + struct LinkiteM *m, *m_next= NULL; + + /* Prevent memory corruption */ + for(m= *o; m!=to; m= m->next) + if(m==NULL) { /* this may actually not happen */ + *o= to; + return(-1); + } + + for(m= *o; m!=to; m= m_next) { + m_next= m->next; + Linkitem_destroy(&m, 0); + } + *o= to; + return(1); +} + + +int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino, + struct LinkiteM **result, int flag) +{ + struct LinkiteM *m; + + for(m= stack; m!=NULL; m= m->next) { + if(target_dev == m->target_dev && target_ino == m->target_ino) { + *result= m; + return(1); + } + } + return(0); +} + + +int Linkitem_get_link_count(struct LinkiteM *item, int flag) +{ + return(item->link_count); +} + + +/* ------------------------------ PermstacK ------------------------------- */ + + +struct PermiteM { + char *disk_path; + struct stat stbuf; + struct PermiteM *next; +}; + + +int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, + int flag) +{ + struct PermiteM *m; + + m= TSOB_FELD(struct PermiteM,1); + if(m==NULL) + return(-1); + m->disk_path= NULL; + memcpy(&(m->stbuf), stbuf, sizeof(struct stat)); + m->next= *o; + + m->disk_path= strdup(disk_path); + if(m->disk_path==NULL) + goto failed; + + *o= m; + return(1); +failed:; + if(m->disk_path!=NULL) + free(m->disk_path); + free((char *) m); + return(-1); +} + + +/* @param flag bit0= minimal transfer: access permissions only + bit1= do not set timestamps +*/ +int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, int flag) +{ + int ret; + struct utimbuf utime_buffer; + struct PermiteM *m, *m_next; + + if((*o)==stopper) + return(1); + for(m= *o; m!=NULL; m= m->next) + if(m->next==stopper) + break; + if(m==NULL) { + sprintf(xorriso->info_text, + "Program error: Permstack_pop() : cannot find stopper"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + + for(m= *o; m!=stopper; m= m_next) { + ret= chmod(m->disk_path, m->stbuf.st_mode); + if(ret==-1) { + if(xorriso!=NULL) { + sprintf(xorriso->info_text, + "Cannot change access permissions of disk directory: chmod %o ", + (unsigned int) (m->stbuf.st_mode & 07777)); + Text_shellsafe(m->disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + } + } + if(!(flag&1)) { + ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid); + /* don't complain if it fails */ + if(!(flag&2)) { + utime_buffer.actime= m->stbuf.st_atime; + utime_buffer.modtime= m->stbuf.st_mtime; + ret= utime(m->disk_path,&utime_buffer); + if(ret==-1 && xorriso!=NULL) { + sprintf(xorriso->info_text, + "Cannot change timestamps of disk directory: "); + Text_shellsafe(m->disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + } + } + } + m_next= m->next; + free(m->disk_path); + free((char *) m); + *o= m_next; + } + return(1); +} + + +/* ---------------------------- End PermstacK ----------------------------- */ + diff --git a/libisoburn/branches/1.4.6/xorriso/aux_objects.h b/libisoburn/branches/1.4.6/xorriso/aux_objects.h new file mode 100644 index 00000000..38cce337 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/aux_objects.h @@ -0,0 +1,185 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains declarations of classes: + + - SplitparT which represents byte intervals of data files. + + - DirseQ which crawls along a directory's content list. + + - ExclusionS which manages the list of excluded file paths and + leaf patterns. + + - Xorriso_lsT which provides a generic double-linked list. + + - LinkiteM, PermiteM which temporarily record relations and states. + +*/ + + +#ifndef Xorriso_pvt_auxobj_includeD +#define Xorriso_pvt_auxobj_includeD yes + +struct SplitparT; + +int Splitparts_new(struct SplitparT **o, int count, int flag); + +int Splitparts_destroy(struct SplitparT **o, int count, int flag); + +int Splitparts_set(struct SplitparT *o, int idx, + char *name, int partno, int total_parts, + off_t offset, off_t bytes, off_t total_bytes, int flag); + +int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno, + int *total_parts, off_t *offset, off_t *bytes, + off_t *total_bytes, int flag); + +int Splitpart__parse(char *name, int *partno, int *total_parts, + off_t *offset, off_t *bytes, off_t *total_bytes, int flag); + +int Splitpart__is_part_path(char *path, int flag); + +int Splitpart__compose(char *adr, int partno, int total_parts, + off_t offset, off_t bytes, off_t total_bytes, int flag); + +int Splitpart__read_next_num(char *base_pt, char **next_pt, off_t *num, + int flag); + +int Splitparts_sort(struct SplitparT *o, int count, int flag); + + + +struct DirseQ; + +int Dirseq_new(struct DirseQ **o, char *adr, int flag); + +int Dirseq_destroy(struct DirseQ **o, int flag); + +int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag); + +int Dirseq_rewind(struct DirseQ *o, int flag); + + + +struct Xorriso_lsT { + char *text; + struct Xorriso_lsT *prev,*next; +}; + +/** Create a new list item with arbitrary byte content. + @param lstring The newly created object or NULL on failure + @param data An array of bytes to be copied into the new object + @param data_len Number of bytes to be copied + @param link Xorriso_lsT object to which the new object shall be linked + @param flag Bitfield for control purposes + bit0= insert before link rather than after it + bit1= do not copy data (e.g. because *data is invalid) + bit2= attach data directly by pointer rather than by copying + @return <=0 error, 1 ok +*/ +int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data, + int data_len, struct Xorriso_lsT *link, int flag); + + +/** Create a new list item with a 0-terminated text as content. + @param lstring The newly created object or NULL on failure + @param text A 0-terminated array of bytes + @param link Xorriso_lsT object to which the new object shall be linked + @param flag see Xorriso_lst_new_binary + @return <=0 error, 1 ok +*/ +int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text, + struct Xorriso_lsT *link, int flag); + + +/** Create a new list item at the end of a given list. + @param entry Contains as input a pointer to a pointer to any existing + list item. As output this list item pointer may be + changed to the address of the new list item: + if ((*entry == 0) || (flag & 1)) + @param data An array of bytes to be copied into the new object + @param data_len Number of bytes to be copied + @param flag Bitfield for control purposes + bit0= Return new object address in *entry + bit1= do not copy data (e.g. because *data is invalid) + bit2= attach data directly by pointer rather than by copying + @return <=0 error, 1 ok +*/ +int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, + char *data, int data_len, int flag); + + +/** Destroy a single list item and connect its eventual list neighbors. + @param lstring pointer to the pointer to be freed and set to NULL + @param flag unused yet, submit 0 + @return 0= *lstring was alredy NULL, 1= ok +*/ +int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag); + + +struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag); + +struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag); + +char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag); + +int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag); + +int Xorriso_lst_get_last(struct Xorriso_lsT *entry, struct Xorriso_lsT **last, + int flag); + +int Xorriso_lst_concat(struct Xorriso_lsT *first, struct Xorriso_lsT *second, + int flag); + + +int Exclusions_new(struct ExclusionS **o, int flag); + +int Exclusions_destroy(struct ExclusionS **o, int flag); + +int Exclusions_get_descrs(struct ExclusionS *o, + struct Xorriso_lsT **not_paths_descr, + struct Xorriso_lsT **not_leafs_descr, int flag); + +/* @param flag bit0= whole subtree is banned with -not_paths + @return 0=no match , 1=not_paths , 2=not_leafs, <0=error +*/ +int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag); + +int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr, + regex_t *re, int flag); + +int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs, + int pathc, char **paths, int flag); + + + +struct LinkiteM; /* Trace of hops during symbolic link resolution */ + +int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev, + ino_t target_ino, struct LinkiteM *next, int flag); + +int Linkitem_destroy(struct LinkiteM **o, int flag); + +int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag); + +int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino, + struct LinkiteM **result, int flag); + +int Linkitem_get_link_count(struct LinkiteM *item, int flag); + + +struct PermiteM; /* Stack of temporarily altered access permissions */ + +int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, + int flag); + +int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, int flag); + + +#endif /* ! Xorriso_pvt_auxobj_includeD */ + diff --git a/libisoburn/branches/1.4.6/xorriso/base_obj.c b/libisoburn/branches/1.4.6/xorriso/base_obj.c new file mode 100644 index 00000000..9bc7d0c9 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/base_obj.c @@ -0,0 +1,772 @@ + + + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2016 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which are needed to read data + from ISO image. +*/ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_STDINT_H +#include +#else +#ifdef HAVE_INTTYPES_H +#include +#endif +#endif + +#ifdef Xorriso_standalonE + +#ifdef Xorriso_with_libjtE +#include "../libjte/libjte.h" +#endif + +#else + +#ifdef Xorriso_with_libjtE +#include +#endif + +#endif /* ! Xorriso_standalonE */ + +#include "xorriso.h" +#include "xorriso_private.h" + +#include "base_obj.h" +#include "lib_mgt.h" + + + +/* See Xorriso__preset_signal_behavior() */ +static int Xorriso_signal_behavioR= 1; + + +void Xorriso__version(int *major, int *minor, int *micro) +{ + *major= Xorriso_header_version_majoR; + *minor= Xorriso_header_version_minoR; + *micro= Xorriso_header_version_micrO; +} + + +int Xorriso__is_compatible(int major, int minor, int micro, int flag) +{ + int own_major, own_minor, own_micro; + + Xorriso__version(&own_major, &own_minor, &own_micro); + return(own_major > major || + (own_major == major && (own_minor > minor || + (own_minor == minor && own_micro >= micro)))); +} + + +char *Xorriso__get_patch_level_text(int flag) +{ + return(Xorriso_program_patch_leveL); +} + + +/** The list of startup file names */ +#define Xorriso_rc_nuM 4 + +static char Xorriso_sys_rc_nameS[Xorriso_rc_nuM][80]= { + "/etc/default/xorriso", + "/etc/opt/xorriso/rc", + "/etc/xorriso/xorriso.conf", + "placeholder for $HOME/.xorrisorc" +}; + + +int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) +{ + int i, ret; + struct XorrisO *m; + char *leafname= NULL; + + leafname= TSOB_FELD(char, SfileadrL); + if(leafname == NULL) + return(-1); + *xorriso= m= TSOB_FELD(struct XorrisO,1); + if(m==NULL) { + free(leafname); + return(-1); + } + + /* Base initialization by actions which must not fail */ + + m->libs_are_started= 0; + strncpy(m->progname,progname,sizeof(m->progname)-1); + m->progname[sizeof(m->progname)-1]= 0; + if(getcwd(m->initial_wdx,sizeof(m->initial_wdx)-1)==NULL) + m->initial_wdx[0]= 0; + m->no_rc= 0; + m->argument_emulation= 0; + + m->rc_filename_count= Xorriso_rc_nuM; + for(i=0;irc_filename_count-1;i++) + strcpy(m->rc_filenames[i],Xorriso_sys_rc_nameS[i]); + m->rc_filenames[m->rc_filename_count-1][0]= 0; + m->arrange_args= 0; + m->mkisofsrc_done= 0; + + m->wdi[0]= 0; + strcpy(m->wdx, m->initial_wdx); + m->did_something_useful= 0; + m->add_plainly= 0; + m->split_size= 0; + strcpy(m->list_delimiter, "--"); + m->ino_behavior= 1 | 2 | 4 | 32; /* off:no_lsl_count */ + m->iso_level= 3; + m->iso_level_is_default= 1; + m->do_joliet= 0; + m->do_hfsplus= 0; + m->do_fat= 0; + m->do_rockridge= 1; + m->do_iso1999= 0; + m->ecma119_map= 1; + m->do_aaip= 0; + m->do_md5= 0; + m->no_emul_toc= 0; + m->do_old_empty= 0; + m->scdbackup_tag_name[0]= 0; + m->scdbackup_tag_time[0]= 0; + m->scdbackup_tag_written[0]= 0; + m->scdbackup_tag_listname[0]= 0; + m->relax_compliance= 0; + m->allow_dir_id_ext_dflt= 1; + m->rr_reloc_dir[0]= 0; + m->rr_reloc_flags= 1; + m->untranslated_name_len= 0; + m->do_follow_pattern= 1; + m->do_follow_param= 0; + m->do_follow_links= 0; + m->follow_link_limit= 100; + m->resolve_link_rec_count= 0; + m->resolve_link_rec_limit= 100; + m->do_follow_concat= 0; + m->do_follow_mount= 1; + m->do_global_uid= 0; + m->global_uid= 0; + strcpy(m->volid, "ISOIMAGE"); + m->volid_default= 1; + m->loaded_volid[0]= 0; + m->assert_volid[0]= 0; + m->assert_volid_sev[0]= 0; + m->preparer_id[0]= 0; + m->publisher[0]= 0; + m->application_id[0]= 0; + m->system_id[0]= 0; + m->volset_id[0]= 0; + m->copyright_file[0]= 0; + m->biblio_file[0]= 0; + m->abstract_file[0]= 0; + strcpy(m->application_use, " "); + m->session_logfile[0]= 0; + m->session_lba= -1; + m->session_blocks= 0; + m->do_global_gid= 0; + m->global_gid= 0; + m->do_global_mode= 0; + m->global_dir_mode= 0555; + m->global_file_mode= 0444; + m->do_tao= 0; + m->filters= NULL; + m->filter_list_closed= 0; + m->zlib_level_default= m->zlib_level= 6; + m->zisofs_block_size= m->zisofs_block_size_default= (1 << 15); + m->zisofs_by_magic= 0; + m->do_overwrite= 2; + m->do_reassure= 0; + m->drive_blacklist= NULL; + m->drive_greylist= NULL; + m->drive_whitelist= NULL; + m->toc_emulation_flag= 0; + m->image_start_mode= 0; + m->image_start_value[0]= 0; + m->displacement= 0; + m->displacement_sign= 0; + m->read_fs= 0; + m->drives_exclusive= 1; + m->linux_scsi_dev_family= 0; + m->early_stdio_test= 0; + m->cache_num_tiles= 0; + m->cache_tile_blocks= 0; + m->cache_default= 1 | 2; + m->do_calm_drive= 1; + m->indev[0]= 0; + m->in_drive_handle= NULL; + m->in_volset_handle= NULL; + m->in_charset= NULL; + m->isofs_st_out= time(0) - 1; + m->indev_is_exclusive= 1; + m->indev_off_adr[0]= 0; + m->isofs_st_in= 0; + m->volset_change_pending= 0; + m->no_volset_present= 0; + m->in_sector_map= NULL; + m->check_media_default= NULL; + m->check_media_bad_limit= Xorriso_read_quality_invaliD; + m->outdev[0]= 0; + m->out_drive_handle= NULL; + m->out_charset= NULL; + m->dev_fd_1= -1; + m->outdev_is_exclusive= 1; + m->outdev_off_adr[0]= 0; + m->grow_blindly_msc2= -1; + m->ban_stdio_write= 0; + m->do_dummy= 0; + m->do_close= 0; + m->auto_close= 0; + m->write_speed= 0; /* max */ + m->read_speed= -2; /* do not set */ + m->fs= 4*512; /* 4 MiB */ + m->padding= 300*1024; + m->do_padding_by_libisofs= 0; + m->alignment= 0; + m->do_stream_recording= 0; + m->dvd_obs= 0; + m->modesty_on_drive= 0; + m->min_buffer_usec= 5000; + m->max_buffer_usec= 25000; + m->buffer_timeout_sec= 120; + m->min_buffer_percent= 90; + m->max_buffer_percent= 95; + m->use_immed_bit= 0; + m->use_immed_bit_default= 0; + m->stdio_sync= 0; + m->stdio_sync_is_default= 1; + m->keep_boot_image= 0; + m->boot_image_cat_path[0]= 0; + m->boot_image_cat_hidden= 0; + m->boot_count= 0; + m->boot_platform_id= 0x00; /* El Torito Boot Catalog Platform ID: 0 = 80x86 */ + m->patch_isolinux_image= 0; + m->boot_image_bin_path[0]= 0; + m->boot_image_bin_form[0]= 0; + m->boot_image_emul= 0; + m->boot_emul_default= 1; + m->boot_image_load_size= 4 * 512; /* hearsay out of libisofs/demo/iso.c */ + memset(m->boot_id_string, 0, sizeof(m->boot_id_string)); + memset(m->boot_selection_crit, 0, sizeof(m->boot_selection_crit)); + +#ifdef Xorriso_with_isohybriD + m->boot_image_isohybrid= 1; +#else + m->boot_image_isohybrid= 0; +#endif + + m->boot_efi_default= 0; + m->system_area_disk_path[0]= 0; + m->system_area_clear_loaded= 0; + m->system_area_options= 0; + m->patch_system_area= 0; + m->partition_offset= 0; + m->partition_secs_per_head= 0; + m->partition_heads_per_cyl= 0; + m->prep_partition[0]= 0; + m->efi_boot_partition[0]= 0; + for(i= 0; i < Xorriso_max_appended_partitionS; i++) { + m->appended_partitions[i]= NULL; + m->appended_part_types[i]= 0; + } + m->appended_as_gpt= 0; + m->appended_as_apm= 0; + m->part_like_isohybrid= 0; + memset(m->gpt_guid, 0, 16); + m->gpt_guid_mode= 0; + m->ascii_disc_label[0]= 0; + m->grub2_sparc_core[0]= 0; + memset(m->hfsp_serial_number, 0, 8); + m->hfsp_block_size= 0; + m->apm_block_size= 0; + m->vol_creation_time= 0; + m->vol_modification_time= 0; + m->vol_expiration_time= 0; + m->vol_effective_time= 0; + m->vol_uuid[0]= 0; + m->all_file_dates[0]= 0; + +#ifdef Xorriso_with_libjtE + m->libjte_handle= NULL; +#endif + + m->jigdo_params= NULL; + m->jigdo_values= NULL; + m->libjte_params_given= 0; + m->loaded_boot_bin_lba= 0; + m->loaded_boot_cat_path[0]= 0; + m->allow_graft_points= 0; + m->allow_restore= 0; + m->do_concat_split= 1; + m->do_auto_chmod= 0; + m->do_restore_sort_lba= 0; + m->do_strict_acl= 0; + m->dialog= 0; + m->buffered_dialog= NULL; + m->bsl_interpretation= 0; + m->sh_style_result= 0; + m->search_mode= 0; + m->structured_search= 1; + m->do_iso_rr_pattern= 1; + m->do_disk_pattern= 2; + m->temp_mem_limit= 16*1024*1024; + m->file_size_limit= Xorriso_default_file_size_limiT; + m->file_name_limit= 255; + m->disk_exclusions= NULL; + m->iso_rr_hidings= NULL; + m->joliet_hidings= NULL; + m->hfsplus_hidings= NULL; + m->disk_excl_mode= 1; + m->use_stdin= 0; + m->tolerate_stdin_eof= 0; + m->result_page_length= 0; + m->result_page_width= 80; + m->mark_text[0]= 0; + m->packet_output= 0; + for(i=0; i<4; i++) { + m->logfile[i][0]= 0; + m->logfile_fp[i]= NULL; + } + m->pktlog_fp= NULL; + m->stderr_fp= NULL; + for(i= 0; i < Xorriso_max_outlist_stacK; i++) { + m->result_msglists[i]= NULL; + m->info_msglists[i]= NULL; + m->msglist_flags[i]= 0; + } + m->lib_msg_queue_lock_ini= 0; + m->result_msglists_lock_ini= 0; + m->write_to_channel_lock_ini= 0; + m->msg_watcher_lock_ini= 0; + m->msg_watcher_state= 0; + m->msgw_result_handler= NULL; + m->msgw_result_handle= NULL; + m->msgw_info_handler= NULL; + m->msgw_info_handle= NULL; + m->msgw_stack_handle= -1; + m->msgw_msg_pending= 0; + m->msgw_fetch_lock_ini= 0; + m->msg_sieve= NULL; + m->msg_sieve_disabled= 0; + m->msglist_stackfill= 0; + m->status_history_max= Xorriso_status_history_maX; + m->scsi_log= 0; + strcpy(m->report_about_text, "UPDATE"); + Xorriso__text_to_sev(m->report_about_text, &m->report_about_severity, 0); + m->library_msg_direct_print= 0; + strcpy(m->abort_on_text,"FAILURE"); + Xorriso__text_to_sev(m->abort_on_text, &m->abort_on_severity, 0); + m->abort_on_is_default= 1; + m->problem_status= 0; + m->problem_status_lock_ini= 0; + m->problem_status_text[0]= 0; + m->errfile_log[0]= 0; + m->errfile_mode= 0; + m->errfile_fp= NULL; + + m->img_read_error_mode= 1; /* abort faulty image reading with FAILURE */ + m->extract_error_mode= 1; /* keep extracted files after read error */ + strcpy(m->return_with_text, "SORRY"); + Xorriso__text_to_sev(m->return_with_text, &m->return_with_severity, 0); + m->return_with_value= 32; + m->eternal_problem_status= 0; + m->eternal_problem_status_text[0]= 0; + m->re= NULL; + /* >>> ??? how to initialize m->match[0] ? */ + m->re_constants= NULL; + m->re_count= 0; + m->re_fill= 0; + m->reg_expr[0]= 0; + m->run_state= 0; + m->is_dialog= 0; + m->bar_is_fresh= 0; + m->pending_option[0]= 0; + m->request_to_abort= 0; + m->request_not_to_ask= 0; + m->idle_time= 0.0; + m->re_failed_at= -1; + m->prepended_wd= 0; + m->insert_count= 0; + m->insert_bytes= 0; + m->error_count= 0; + m->launch_frontend_banned= 0; + m->pacifier_style= 0; + m->pacifier_interval= 1.0; + m->pacifier_count= 0; + m->pacifier_prev_count= 0; + m->pacifier_total= 0; + m->pacifier_byte_count= 0; + m->pacifier_fifo= NULL; + m->start_time= 0.0; + m->last_update_time= 0.0; + m->find_compare_result= 1; + m->find_check_md5_result= 0; + m->last_abort_file_time= 0.0; + + m->node_counter= 0; + m->node_array_size= 0; + m->node_array= NULL; + m->node_disk_prefixes= NULL; + m->node_img_prefixes= NULL; + + m->hln_count= 0; + m->hln_array= NULL; + m->hln_targets= NULL; + m->hln_change_pending= 0; + m->di_do_widen= NULL; + m->di_disk_paths= NULL; + m->di_iso_paths= NULL; + + m->node_targets_availmem= 0; + + m->di_count= 0; + m->di_array= NULL; + + m->perm_stack= NULL; + + m->update_flags= 0; + + m->show_hfs_cmd_flag= 0; + m->show_hfs_cmd_count= 0; + m->show_hfs_cmds= NULL; + + m->result_line[0]= 0; + m->result_line_counter= 0; + m->result_page_counter= 0; + m->result_open_line_len= 0; + + m->info_text[0]= 0; + + + /* Here begin actions which might fail */ + + ret= Sfile_leafname(progname, leafname, 0); + if(ret<=0) + goto failure; + if(strcmp(leafname, "osirrox")==0) { + m->allow_restore= 1; + m->drives_exclusive= 0; + } else if(strcmp(leafname, "xorrisofs")==0 || strcmp(leafname, "genisofs")==0 || + strcmp(leafname, "mkisofs")==0 || strcmp(leafname, "genisoimage")==0) { + m->argument_emulation= 1; + m->pacifier_style= 1; + Xorriso_protect_stdout(*xorriso, 0); + } else if(strcmp(leafname, "xorrecord")==0 || strcmp(leafname, "wodim")==0 || + strcmp(leafname, "cdrecord")==0 || strcmp(leafname, "cdrskin")==0) { + m->argument_emulation= 2; + m->pacifier_style= 2; + } + ret= Exclusions_new(&(m->disk_exclusions), 0); + if(ret<=0) + goto failure; + ret= Exclusions_new(&(m->iso_rr_hidings), 0); + if(ret<=0) + goto failure; + ret= Exclusions_new(&(m->joliet_hidings), 0); + if(ret<=0) + goto failure; + ret= Exclusions_new(&(m->hfsplus_hidings), 0); + if(ret<=0) + goto failure; + Xorriso_relax_compliance(m, "default", 0); + ret= Xorriso_lst_new(&(m->drive_greylist), "/dev", m->drive_greylist, 1); + if(ret <= 0) + goto failure; + Xorriso_preparer_string(m, m->preparer_id, 1); /* avoids library calls */ + ret= pthread_mutex_init(&(m->lib_msg_queue_lock), NULL); + if(ret != 0) + goto failure; + m->lib_msg_queue_lock_ini= 1; + ret= pthread_mutex_init(&(m->result_msglists_lock), NULL); + if(ret != 0) + goto failure; + m->result_msglists_lock_ini= 1; + ret= pthread_mutex_init(&(m->write_to_channel_lock), NULL); + if(ret != 0) + goto failure; + m->result_msglists_lock_ini= 1; + ret= pthread_mutex_init(&(m->problem_status_lock), NULL); + if(ret != 0) + goto failure; + m->problem_status_lock_ini= 1; + ret= pthread_mutex_init(&(m->msg_watcher_lock), NULL); + if(ret != 0) + goto failure; + m->msg_watcher_lock_ini= 1; + ret= pthread_mutex_init(&(m->msgw_fetch_lock), NULL); + if(ret != 0) + goto failure; + m->msgw_fetch_lock_ini= 1; + + if(leafname != NULL) + free(leafname); + return(1); +failure:; + Xorriso_destroy(xorriso, 0); + if(leafname != NULL) + free(leafname); + return(-1); +} + + +int Xorriso_destroy_re(struct XorrisO *m, int flag) +{ + int i; + + if(m->re!=NULL) { + for(i=0;ire_fill;i++) { + if(m->re_constants!=NULL) + if(m->re_constants[i]!=NULL) + continue; /* ,->re[i] was never subject to regcomp() */ + regfree(&(m->re[i])); + } + free((char *) m->re); + m->re= NULL; + } + + if(m->re_constants!=NULL) { + for(i=0;ire_fill;i++) + if(m->re_constants[i]!=NULL) + free(m->re_constants[i]); + free((char *) m->re_constants); + m->re_constants= NULL; + } + m->re_count= 0; + m->re_fill= 0; + return(1); +} + + +/* @param flag bit0= global shutdown of libraries */ +int Xorriso_destroy(struct XorrisO **xorriso, int flag) +{ + struct XorrisO *m; + int i; + + m= *xorriso; + if(m==NULL) + return(0); + + /* Give up drives and image to unref all connected xorriso objects */ + Xorriso_give_up_drive(m, 3); + + if(m->in_charset!=NULL) + free(m->in_charset); + if(m->out_charset!=NULL) + free(m->out_charset); + Checkmediajob_destroy(&(m->check_media_default), 0); + Sectorbitmap_destroy(&(m->in_sector_map), 0); + Xorriso_destroy_re(m,0); + Exclusions_destroy(&(m->disk_exclusions), 0); + Exclusions_destroy(&(m->iso_rr_hidings), 0); + Exclusions_destroy(&(m->joliet_hidings), 0); + Exclusions_destroy(&(m->hfsplus_hidings), 0); + Xorriso_destroy_all_extf(m, 0); + Xorriso_lst_destroy_all(&(m->drive_blacklist), 0); + Xorriso_lst_destroy_all(&(m->drive_greylist), 0); + Xorriso_lst_destroy_all(&(m->drive_whitelist), 0); + Xorriso_destroy_node_array(m, 0); + Xorriso_destroy_hln_array(m, 0); + Xorriso_destroy_di_array(m, 0); + +#ifdef Xorriso_with_libjtE + if(m->libjte_handle) + libjte_destroy(&(m->libjte_handle)); +#endif + + Xorriso_lst_destroy_all(&(m->jigdo_params), 0); + Xorriso_lst_destroy_all(&(m->jigdo_values), 0); + for(i= 0; i < Xorriso_max_appended_partitionS; i++) + if(m->appended_partitions[i] != NULL) + free(m->appended_partitions[i]); + + Xorriso_detach_libraries(m, flag&1); + + if(m->lib_msg_queue_lock_ini) + pthread_mutex_destroy(&(m->lib_msg_queue_lock)); + if(m->result_msglists_lock_ini) + pthread_mutex_destroy(&(m->result_msglists_lock)); + if(m->write_to_channel_lock_ini) + pthread_mutex_destroy(&(m->write_to_channel_lock)); + if(m->problem_status_lock_ini) + pthread_mutex_destroy(&(m->problem_status_lock)); + if(m->msg_watcher_lock_ini) + pthread_mutex_destroy(&(m->msg_watcher_lock)); + if(m->msgw_fetch_lock_ini) + pthread_mutex_destroy(&(m->msgw_fetch_lock)); + Xorriso_sieve_dispose(m, 0); + + free((char *) m); + *xorriso= NULL; + return(1); +} + + +int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag) +{ + int i; + + if(xorriso->node_array != NULL) { + for(i= 0; i < xorriso->node_counter; i++) + iso_node_unref((IsoNode *) xorriso->node_array[i]); + free(xorriso->node_array); + } + xorriso->node_array= NULL; + xorriso->node_counter= xorriso->node_array_size= 0; + Xorriso_lst_destroy_all(&(xorriso->node_disk_prefixes), 0); + Xorriso_lst_destroy_all(&(xorriso->node_img_prefixes), 0); + return(1); +} + + +/* @param flag bit0= do not destroy hln_array but only hln_targets +*/ +int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag) +{ + int i; + + + if(xorriso->hln_array != NULL && !(flag & 1)) { + for(i= 0; i < xorriso->hln_count; i++) + iso_node_unref((IsoNode *) xorriso->hln_array[i]); + free(xorriso->hln_array); + xorriso->hln_array= NULL; + xorriso->hln_count= 0; + } + if(xorriso->hln_targets != NULL) { + for(i= 0; i < xorriso->hln_count; i++) + if(xorriso->hln_targets[i] != NULL) + free(xorriso->hln_targets[i]); + free(xorriso->hln_targets); + xorriso->hln_targets= NULL; + } + xorriso->node_targets_availmem= 0; + return(1); +} + + +int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag) +{ + int i; + + if(xorriso->di_array != NULL) { + for(i= 0; i < xorriso->di_count; i++) + if(xorriso->di_array[i] != NULL) + iso_node_unref((IsoNode *) xorriso->di_array[i]); + free(xorriso->di_array); + xorriso->di_array= NULL; + } + if(xorriso->di_do_widen != NULL) { + free(xorriso->di_do_widen); + xorriso->di_do_widen= NULL; + } + Xorriso_lst_destroy_all(&(xorriso->di_disk_paths), 0); + Xorriso_lst_destroy_all(&(xorriso->di_iso_paths), 0); + xorriso->di_count= 0; + +#ifdef NIX + /* <<< */ + fprintf(stderr, "xorriso_DEBUG: get_di_count= %lu\n", + Xorriso_get_di_counteR); +#endif /* NIX */ + + return(1); +} + + +int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, + int addon_nodes, int flag) +{ + int i; + + if(xorriso->node_counter <= 0) + return(1); + + xorriso->node_array= calloc(xorriso->node_counter + addon_nodes, + sizeof(IsoNode *)); + if(xorriso->node_array == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + for(i= 0; i < xorriso->node_counter + addon_nodes; i++) + xorriso->node_array[i]= NULL; + xorriso->node_array_size= xorriso->node_counter + addon_nodes; + xorriso->node_counter= 0; + return(1); +} + + +/* @param flag bit0= do not allocate hln_array but only hln_targets +*/ +int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag) +{ + int i; + + Xorriso_destroy_hln_array(xorriso, flag & 1); + if(xorriso->hln_count <= 0) + return(1); + + if(!(flag & 1)) { + xorriso->hln_array= calloc(xorriso->hln_count, sizeof(char *)); + if(xorriso->hln_array == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + for(i= 0; i < xorriso->hln_count; i++) + xorriso->hln_array[i]= NULL; + } + + xorriso->hln_targets= calloc(xorriso->hln_count, sizeof(char *)); + if(xorriso->hln_targets == NULL) { + if(!(flag & 1)) { + free(xorriso->hln_array); + xorriso->hln_array= NULL; + } + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + for(i= 0; i < xorriso->hln_count; i++) + xorriso->hln_targets[i]= NULL; + xorriso->node_targets_availmem= mem_limit + - xorriso->hln_count * sizeof(void *) + - xorriso->hln_count * sizeof(char *); + if(xorriso->node_targets_availmem < 0) + xorriso->node_targets_availmem= 0; + return(1); +} + + +int Xorriso__preset_signal_behavior(int behavior, int flag) +{ + if(behavior < 0 || behavior > 3) + return(0); + Xorriso_signal_behavioR= behavior; + return(1); +} + + +int Xorriso__get_signal_behavior(int flag) +{ + return(Xorriso_signal_behavioR); +} + diff --git a/libisoburn/branches/1.4.6/xorriso/base_obj.h b/libisoburn/branches/1.4.6/xorriso/base_obj.h new file mode 100644 index 00000000..7fb60eba --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/base_obj.h @@ -0,0 +1,31 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains declarations of functions which perform the + fundamental operations of the XorrisO object. +*/ + + +#ifndef Xorriso_pvt_base_obj_includeD +#define Xorriso_pvt_base_obj_includeD yes + + +#ifdef NIX +/* <<< */ +unsigned long Xorriso_get_di_counteR= 0; +#endif /* NIX */ + +struct XorrisO; + + +int Xorriso_destroy_re(struct XorrisO *m, int flag); + +int Xorriso__get_signal_behavior(int flag); + + +#endif /* ! Xorriso_pvt_base_obj_includeD */ + diff --git a/libisoburn/branches/1.4.6/xorriso/changelog.txt b/libisoburn/branches/1.4.6/xorriso/changelog.txt new file mode 100644 index 00000000..f2af2622 --- /dev/null +++ b/libisoburn/branches/1.4.6/xorriso/changelog.txt @@ -0,0 +1,18652 @@ +------------------------------------------------------------------------------ + libburnia-project.org libisoburn , xorriso +------------------------------------------------------------------------------ + +------------------------------------------------------------------------------ + Changelog +------------------------------------------------------------------------------ + + +1 Sep 2007 [983] +libisoburn/libisoburn.h +libisoburn/isoburn.h +libisoburn/isoburn.c +libisoburn/burn_wrap.c +libisoburn/isofs_wrap.c +Initial content of libisoburn + +1 Sep 2007 [985] +libisoburn/libisoburn.h +libisoburn/isoburn.h +libisoburn/isoburn.c +libisoburn/isofs_wrap.c +Should have used copy+paste when writing Vreixos name + +5 Sep 2007 [990] +libisoburn/isoburn.h +libisoburn/isoburn.c +libisoburn/burn_wrap.c +Implemented use of stdio-pseudo-drives + +5 Sep 2007 [993] +libisoburn/libisoburn.h +libisoburn/isoburn.h +libisoburn/isoburn.c +libisoburn/burn_wrap.c +Changes in plans as discussed up to Sep 5 2007 + +5 Sep 2007 [994] +libisoburn/libisoburn.h +Updated explanations about the usage principles of libisoburn + +6 Sep 2007 [998] +libisoburn/libisoburn.h +libisoburn/isoburn.h +libisoburn/isoburn.c +libisoburn/burn_wrap.c +Updated to state of discussion + +9 Sep 2007 [1025] +libisoburn/burn_wrap.c +New wrapper isoburn_disc_erasable() declares ISO DVD-RAM, DVD+RW erasable + +10 Sep 2007 [1027] +libisoburn/libisoburn.h +New wrapper isoburn_disc_erasable() declares ISO DVD-RAM, DVD+RW erasable + +11 Sep 2007 [1029] +libisoburn/burn_wrap.c +libisoburn/isoburn.h +New inner function isoburn_set_start_byte() + +12 Sep 2007 [1031] +libisoburn/libisoburn.h +libisoburn/burn_wrap.c +Removed isoburn_write_opts_set_start_byte() + +13 Sep 2007 [1043] +libisoburn/burn_wrap.c +Took into respect fabricated_disc_status + +21 Sep 2007 [1092] +Makefile.am +Removed libburn file addresses + +22 Sep 2007 [1093] ++ doc/doxygen.conf.in +Added file demanded by build system + +22 Sep 2007 [1094] +src/burn_wrap.c +Prevented SIGSEGV in isoburn_drive_scan_and_grab() + +22 Sep 2007 [1095] +src/burn_wrap.c +Enabled treatment==2 in isoburn_drive_scan_and_grab() + +22 Sep 2007 [1099] +src/burn_wrap.c +Made use of burn_msgs_submit() for error messages + +23 Sep 2007 [1102] +src/burn_wrap.c +Removed all references to isoburn.treatment from burn_wrap.c + +23 Sep 2007 [1105] +src/burn_wrap.c +Called isoburn_create_data_source() and isoburn_free_data_source() + +28 Sep 2007 [1129] libisofs +libisofs/libiso_msgs.h +Removed apostrophes which my compiler does not like + +29 Sep 2007 [1133] +src/burn_wrap.c +Added optional code for a pseudo CD-RW to test the code for MMC multi-session + +29 Sep 2007 [1134] +src/burn_wrap.c +Released drive in case welcome_media fails + +1 Oct 2007 [1141] +src/burn_wrap.c +Allowed isoburn_disc_get_msc1() for closed media + +2 Oct 2007 [1149] +test/test.c +Function graft_point(),some general polishing, call of iso_volset_free disabled + +8 Oct 2007 [1169] +src/libisoburn.h +src/isoburn.h +src/isoburn.c +src/burn_wrap.c +Introduced fifo reference into isoburn object + +8 Oct 2007 [1170] +test/test.c +Several directories and files in one session, added display of fifo + +12 Oct 2007 [1171] ++ test/xorriso.h ++ test/xorriso.c ++ test/xorriso.txt +The stub of new application xorriso + +12 Oct 2007 [1172] ++ test/compile_xorriso.sh ++ test/make_timestamp.sh ++ test/xorriso_timestamp.h +A build facility to circumvent autotools during development + +12 Oct 2007 [1173] +test/xorriso.c +Introduced version and build timestamps, library headers + +13 Oct 2007 [1174] +test/xorriso.c ++ test/changelog.txt +Made -dialog and -options_from_file work + +2007.10.13.141503 [1175] +test/xorriso.c +Implemented -speed and enlarged -status list + +2007.10.13.152252 [1176] +test/xorriso.c +test/xorriso.txt +Implemented xorriso setter level of -fs, -gid, -uid + +2007.10.14.110003 [1177] +test/xorriso.c +Implemented setter level of -abort_on, fixed bugs about -f,-no_rc,startup files + +2007.10.14.122456 [1178] +test/xorriso.c ++ test/xorriso_private.h ++ test/xorrisoburn.h ++ test/xorrisoburn.c +Began to implement interface to our libraries + +2007.10.15.152705 [1183] +test/xorriso.h +test/xorriso.c +test/xorriso_private.h +test/xorrisoburn.h +test/xorrisoburn.c +Implemented -dev, -add, -commit + +2007.10.15.160303 [1184] +test/xorriso.c +Made -end give up drives + +2007.10.15.203554 [1185] +test/xorriso.c +Some safety precautions against malicious input, enabled -cdx, -cdi for -add + +2007.10.15.203714 [1186] +test/xorrisoburn.c +Corrected image path bug with -add of regular files, and -add /=/some/dir + +2007.10.15.224005 [1187] +test/xorriso.c +test/xorrisoburn.c +Implemented -rollback + +2007.10.16.210911 [1188] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Worked on failure severities, message system, program abort decision + +2007.10.17.130041 [1190] [1191 +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Worked on failure severities, message system, program abort decision + +2007.10.17.130311 [1192] +src/isofs_wrap.c +Told burn_read_data() to stay silent on non-existent drive or read error + +2007.10.17.150142 [1193] +test/xorriso.c +test/xorrisoburn.c +Reinstated the distinction of message sources, respected '#' in dialog + +2007.10.17.165352 [1194] +test/xorriso.c +Prepended a "-" to any input line if missing + +2007.10.17.183024 [1195] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Implemented core of option -toc + +2007.10.17.200241 [1196] +test/xorrisoburn.c +Continued work with -toc + +2007.10.17.213852 [1197] +test/compile_xorriso.sh +Forgot to make off_t 64 bit + +2007.10.17.214228 [1198] +src/libisoburn.h +src/burn_wrap.c +test/xorrisoburn.c +Rounding up fabricated nwa to full 32k addresses, API call for exact image size + +2007.10.17.215809 [1199] +test/xorriso.c +Activated -ban_stdio_write + +2007.10.17.224924 [1200] +test/xorrisoburn.c +Fixed obvious bug with -J. (Still wondering wether it works) + +2007.10.17.225039 [1201] +test/xorriso.c +Fixed bug with -speed. + +2007.10.17.225837 [1202] +test/xorriso.c +Fixed bug with -prompt. Fixed bug with # comments. (of rev 1194) + +18 Oct 2007 [1203] +test/changelog.txt +Updated changelog and todo list + +2007.10.18.144841 [1205] +src/isofs_wrap.c +test/xorrisoburn.c +isoburn_read_volset() now hands out an official volset reference + +2007.10.18.171415 [1206] +test/xorriso.c +test/xorriso.txt +test/xorrisoburn.h +test/xorrisoburn.c +Implemented option -devices + +2007.10.18.183200 [1207] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Implemented option -tell_media_space + +2007.10.18.185731 [1208] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +Fixed a SIGSEGV with xorriso -version run + +2007.10.18.221756 [1211] +test/xorrisoburn.c +src/libisoburn.h +Took care of disposal of burn_disc ovbject + +18 Oct 2007 [1212] +test/test.c +Silenced compile warning + +2007.10.18.225654 [1213] +src/isofs_wrap.c +test/xorriso.c +test/xorrisoburn.c +Fixed a SIGSEGV with empty drive + +2007.10.19.140031 [1218] +test/xorrisoburn.c +Made reports with -add normal infos (formerly NOTE events) + +2007.10.19.151339 [1219] +test/xorriso.c +test/xorrisoburn.c +test/xorriso.txt +Implemented -print-size + +2007.10.19.164957 [1220] +test/xorriso_private.h +test/xorriso.c +test/xorriso.h +test/xorrisoburn.c +test/xorriso.txt +Implemented verbosity control by option -report_about + +2007.10.19.173547 [1221] +test/xorriso.c +test/xorrisoburn.c +test/xorriso.txt +Implemented option -eject + +2007.10.19.204155 [1222] +test/xorriso_private.h +test/xorriso.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Implemented option -blank + +2007.10.20.170731 [1223] +src/burn_wrap.c +Directed write mode failure message to libburn queue, repaired wrote_well + +2007.10.20.171046 [1224] +test/xorrisoburn.c +test/xorriso_private.h +test/xorriso.c +Implemented options -format and -blank deformat, -close and closed media + +20 Oct 2007 [1225] +test/xorriso.txt ++ test/xorriso.1 +test/changelog.txt +Splitted think text from emerging man page, formatted man page + +2007.10.20.194918 [1226] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Completed -tell_media_space, checked space before burn, failed -end exits >0 + +20 Oct 2007 [1227] +test/xorriso.1 +Polished man page + +2007.10.21.094818 [1228] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented -rm and -rm_r + +2007.10.21.105228 [1229] +src/data_source.c +Silenced compiler warning about C++ style comment + +2007.10.21.124315 [1230] +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +Began to implement -ls and -ls_l, enhanced -cdi, not done yet + +2007.10.21.151124 [1231] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +Hopefully completed -cd alias -cdi + +2007.10.21.185248 [1232] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Hopefully completed -cdx + +2007.10.21.213303 [1233] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented sorting of -ls by node name, implemented leaf name search patterns + +2007.10.22.211928 [1237] +test/xorrisoburn.c +test/xorriso.1 +Implemented file size and mtime for -ls_l + +2007.10.23.122349 [1238] +src/libisoburn.h +src/isoburn.c +Added fifo_size to struct isoburn_source_opts + +2007.10.23.122753 [1239] +test/xorrisoburn.c +test/xorriso.c +test/xorriso.1 +Made use of isoburn_source_opts.fifo_size + +2007.10.24.100156 [1244] +test/xorriso.c +test/xorrisoburn.c +Normalized paths to target and source before adding or removing from image + +2007.10.24.105424 [1245] +test/xorriso.c +test/xorriso.h +Implemented option -path-list + +2007.10.24.175337 [1247] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Made -cd useable with no image loaded + +2007.10.27.224148 [1257] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented option -mv + +2007.10.27.230512 [1258] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Bug fixes with option -mv + +2007.10.28.125501 [1260] +test/xorriso.c +test/xorrisoburn.c +Prevented some interesting pitfalls with -mv + +2007.10.28.165516 [1261] +test/xorriso.c +test/xorriso.1 +test/xorrisoburn.h +test/xorrisoburn.c +Implemented option -mkdir + +2007.10.28.174550 [1262] +test/xorriso.c +Warning of wildcards in paths + +28 Oct 2007 [1263] +test/xorriso.1 +Updated man page about -path-list + +2007.10.29.213920 [1273] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Structured patterns for options -ls and -ls_l + +2007.10.30.214242 [1274] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +test/compile_xorriso.sh +Multiple structured patterns, changed option -ls from single to multi args + +2007.10.31.103338 [1275] +test/xorriso_private.h +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented new option -temp_mem_limit + +2007.10.31.165413 [1276] +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +Gave simple -ls an implemention with minimal memory consumption + +31 Oct 2007 [1277] +test/xorriso.1 +Overhauled info paragraphs of man page + +2007.10.31.175916 [1278] +test/xorriso_private.h +Overhauled comments in struct XorrisO + +31 Oct 2007 [1279] +test/changelog.txt +Updating changelog + +2007.11.01.111351 [1280] +test/xorrisoburn.c +Got rid of bad pacifier text at end of CD writing + +2007.11.01.191106 [1281] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +test/xorriso.1 +Implemented option -du + +2007.11.02.143549 [1282] +test/xorrisoburn.h +test/xorrisoburn.c +Clearer status messages after reading new volume and after burning + +2007.11.02.143658 [1283] +test/xorriso.c +Made -abort_on and -report_about complain with bad severity names + +2007.11.02.184705 [1284] +test/xorrisoburn.c +test/xorriso.1 +Polished write success message and man page + +2007.11.06.163305 [1285] +test/xorriso_private.h +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented -overwrite control + +2007.11.06.163929 [1286] +src/libisoburn.h +Corrected a typo in a comment + +2007.11.06.164029 [1287] +src/isoburn.c +Closed memory leak by freeing session and track in isoburn_prepare_disc_aux() + +2007.11.07.123744 [1288] +test/xorriso_private.h +test/xorriso.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented option -reassure + +2007.11.07.150157 [1289] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented option -rmdir + +2007.11.07.191915 [1290] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +Implemented option -chmod (does not get written into image, though) + +2007.11.07.225624 [1291] +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +Implemented options -chown and -chgrp (not written into image, though) + +2007.11.08.144451 [1292] +test/xorriso.c +test/xorrisoburn.c +test/xorrisoburn.h +test/xorriso.1 +Implemented option -alter_date, corrected write problem with mode and ownership + +2007.11.08.145016 [1293] +test/xorriso_private.h +Forgotten source file for rev 1292 + +8 Nov 2007 [1294] +test/xorriso.1 +Enhanced man page text for options -chmod, -chown, -chgrp + +2007.11.08.160302 [1295] +test/xorriso.c +Fixed bug with -chmod go=r + +2007.11.08.161215 [1296] +test/xorriso.c +test/xorrisoburn.c +Enlarged string size limit of Text_shellsafe() + +2007.11.09.193142 [1297] +test/xorriso_private.h +test/xorriso.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +New option -iso_rr_pattern, influencing several options with multiple args + +2007.11.11.112321 [1298] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +Gave problem handling finer granularity within loops + +11 Nov 2007 [1299] +test/xorriso.1 +Clarified man page + +2007.11.11.154453 [1300] +test/xorriso.c +Added missing commit to normal end of program + +11 Nov 2007 [1301] +test/xorriso.1 +Added some examples to man page + +2007.11.14.142904 [1302] +src/libisoburn.h +src/isofs_wrap.c +src/isoburn.c +test/test.c +New API call isoburn_attach_volset(), changes with isoburn_read_volset() + +2007.11.14.143119 [1303] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented options -outdev and -indev + +2007.11.14.175446 [1304] +test/xorriso.c +Corrected premature abort bug with misspelled command words + +14 Nov 2007 [1305] +test/xorriso.1 +Polished xorriso man page + +14 Nov 2007 [1306] +test/changelog.txt +Updated xorriso changelog + +2007.11.26.192113 [1311] +test/xorriso.c +test/xorrisoburn.c +Reacted on warnings on a 64 bit system + +2007.12.04.074340 [1314] +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented -disk_pattern, -lsx, ls_lx, -dux, -du_lx + +2007.12.04.205919 [1315] +test/xorrisoburn.c +test/xorriso_private.h +test/xorriso.c +Removed some redundancy of disk_pattern and iso_rr_pattern matching + +4 Dec 2007 [1316] +test/xorriso.1 +Polished man page + +2007.12.05.090438 [1317] +test/xorriso.h +test/xorriso.c +test/xorriso.1 +Option -f-off as counterpart of option -f + +2007.12.05.143632 [1318] +test/xorriso.c +Made dashes at options optional + +5 Dec 2007 [1319] +test/xorriso.1 +Overhauled description of media types, states and expansion methods + +2007.12.06.150102 [1320] +test/xorriso.h +test/xorriso.c +test/xorriso.1 +Changed -f, -f-off to -follow, -graft-points, -graf-points-off to -pathspecs + +6 Dec 2007 [1321] +test/xorriso.1 +Removed references to option -graft-points + +2007.12.06.192437 [1322] +test/xorriso.c +Corrected warning function about wildcards + +8 Dec 2007 [1326] +test/xorriso.1 +Explained result pager + +2007.12.08.175117 [1327] +test/xorriso.c +test/xorriso_private.h +test/xorrisoburn.c +Removed more code redundancies and fd leak with Xorriso_obtain_pattern_files_x() + +2007.12.15.162039 [1328] +test/compile_xorriso.sh +Added -O0 to -g to get better gdb behavior on my new system + +2007.12.15.183022 [1329] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented option -follow + +2007.12.16.103456 [1330] +test/xorriso.c +test/xorriso.1 +Added link hop limit to option -follow + +2007.12.16.122626 [1331] +test/xorrisoburn.c +Added copying of attributes from symbolic link into image + +2007.12.16.144615 [1332] +test/xorrisoburn.c +Removed waste of time in Xorriso_show_du_subs() + +2007.12.18.175924 [1333] +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Changed options -ls* to -lsd*, introduced new family of -ls* without d + +2007.12.20.111338 [1334] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Changed -du_s* into -dus* + +2007.12.21.131538 [1335] +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented option -find alias -findi + +2007.12.21.132017 [1336] +test/xorriso.c +test/xorriso.1 +Corrected documentation about -find + +2007.12.22.143803 [1337] +test/xorriso.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented option -findx + +2007.12.24.161107 [1339] +test/xorriso.c +Repaired options -dus and -dusx + +24 Dec 2007 [1340] +test/changelog.txt +Updated changelog + +2007.12.25.160100 [1341] +test/xorriso.h +test/xorriso.c +test/xorriso.1 +Implemented option -cpr + +2007.12.26.160040 [1342] +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Changed option -J to -joliet "on"|"off", implemented option -volid + +2007.12.28.132741 [1343] +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +Made leaner the local memory of recursive functions (because of ulimit -s) + +2007.12.30.190138 [1344] +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.c +test/xorriso.1 +Implemented -find option -exec echo, chown, chgrp, chmod, alter_date, lsdl + +2007.12.30.203336 [1345] +test/xorriso.c +Corrected superuser behavior of Sfile_lookup_permissions() + +2007.12.31.095229 [1346] +test/xorriso.c +test/xorrisoburn.c +Repaired some bugs in -find and -findx + +2007.12.31.135237 [1347] +test/xorriso.h +test/xorriso.c +test/xorriso.1 +Implemented options -chown_r, -chgrp_r, -chmod_r, -alter_date_r + +2007.12.31.135330 [1348] +test/xorrisoburn.c +Repaired a bug in -find + +2008.01.01.123118 [1349] +test/xorriso.h +test/xorriso_private.h +test/xorriso.c +test/xorrisoburn.h +test/xorrisoburn.c +test/xorriso.1 +Implemented -find actions chown_r, chgrp_r, chmod_r, alter_date_r, find + +2008.01.02.175011 [1350] +test/xorriso.c +test/xorriso.1 +Implemented -find test -type + +2008.01.09.175418 [1351] +test/xorrisoburn.c +Corrections made during porting to nglibisofs + +2008.01.10.114451 [1352] ++ test/ng_xorrisoburn.h ++ test/ng_xorrisoburn.c +test/compile_xorriso.sh +Begin of porting to next generation libisofs + +2008.01.10.151924 [1353] +Makefile.am ++ ng_src ++ ng_src/libisoburn.h ++ ng_src/isoburn.h ++ ng_src/isoburn.c ++ ng_src/isofs_wrap.c ++ ng_src/data_source.c ++ ng_src/burn_wrap.c +Begin of porting to next generation libisofs + +2008.01.10.152353 [1354] +test/ng_xorrisoburn.c +test/compile_xorriso.sh +Made compile_xorriso.sh -nglibisofs work on ./ng_src + +2008.01.10.154948 [1355] +test/ng_xorrisoburn.c +test/compile_xorriso.sh +Made compile_xorriso.sh -oglibisofs work on ./og_src + +2008.01.11.133319 [1356] +test/compile_xorriso.sh +Adapted to existence of nglibisofs eltorito.o + +2008.01.11.133631 [1357] +test/xorriso.c +test/ng_xorrisoburn.c +test/xorrisoburn.c +Removed old and new bugs + +2008.01.11.174733 [1358] +test/xorriso.c +test/ng_xorrisoburn.c +test/xorrisoburn.c +Tracing the different behavior of isoburn_read_image() + +2008.01.11.175423 [1359] +test/ng_xorrisoburn.c +ng_src/isoburn.c +ng_src/libisoburn.h +Changed isoburn_source_opts.ouput_charset