From dd4cbe53396c79a091f6ce637fe1ab32d82cdf08 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Wed, 12 Mar 2008 09:27:23 +0000 Subject: [PATCH] Removed libisofs Xorriso tag --- libisofs/tags/ForXorrisoZeroOneTwo/AUTHORS | 3 - libisofs/tags/ForXorrisoZeroOneTwo/COPYING | 280 -- libisofs/tags/ForXorrisoZeroOneTwo/COPYRIGHT | 19 - libisofs/tags/ForXorrisoZeroOneTwo/ChangeLog | 1 - libisofs/tags/ForXorrisoZeroOneTwo/INSTALL | 234 -- .../tags/ForXorrisoZeroOneTwo/Makefile.am | 191 - libisofs/tags/ForXorrisoZeroOneTwo/NEWS | 20 - libisofs/tags/ForXorrisoZeroOneTwo/README | 341 -- libisofs/tags/ForXorrisoZeroOneTwo/Roadmap | 33 - libisofs/tags/ForXorrisoZeroOneTwo/TODO | 35 - .../tags/ForXorrisoZeroOneTwo/acinclude.m4 | 22 - libisofs/tags/ForXorrisoZeroOneTwo/bootstrap | 10 - .../tags/ForXorrisoZeroOneTwo/configure.ac | 155 - libisofs/tags/ForXorrisoZeroOneTwo/demo/cat.c | 74 - .../ForXorrisoZeroOneTwo/demo/cat_buffer.c | 127 - .../ForXorrisoZeroOneTwo/demo/ecma119_tree.c | 136 - libisofs/tags/ForXorrisoZeroOneTwo/demo/iso.c | 176 - .../tags/ForXorrisoZeroOneTwo/demo/iso_cat.c | 95 - .../tags/ForXorrisoZeroOneTwo/demo/iso_grow.c | 257 -- .../ForXorrisoZeroOneTwo/demo/iso_modify.c | 109 - .../tags/ForXorrisoZeroOneTwo/demo/iso_ms.c | 114 - .../tags/ForXorrisoZeroOneTwo/demo/iso_read.c | 167 - libisofs/tags/ForXorrisoZeroOneTwo/demo/lsl.c | 130 - .../tags/ForXorrisoZeroOneTwo/demo/tree.c | 107 - .../tags/ForXorrisoZeroOneTwo/doc/Tutorial | 506 --- libisofs/tags/ForXorrisoZeroOneTwo/doc/Wiki | 32 - .../doc/devel/1. Overview | 0 .../doc/devel/2. Features | 193 - .../doc/devel/3. Use Cases | 193 - .../ForXorrisoZeroOneTwo/doc/devel/4. Design | 0 .../doc/devel/5. Implementation | 0 .../ForXorrisoZeroOneTwo/doc/devel/README | 7 - .../doc/devel/UML/BuilderSec.png | Bin 25202 -> 0 bytes .../doc/devel/UML/BuilderSec.violet | 821 ---- .../doc/devel/UML/builder.violet | 884 ---- .../doc/devel/UML/builder.violet.png | Bin 34098 -> 0 bytes .../doc/devel/UML/burn_source.class.violet | 634 --- .../doc/devel/UML/burn_source.png | Bin 35652 -> 0 bytes .../doc/devel/UML/eltorito.violet | 552 --- .../doc/devel/UML/eltorito.violet.png | Bin 24861 -> 0 bytes .../doc/devel/UML/iso_tree.violet | 748 ---- .../doc/devel/UML/iso_tree.violet.png | Bin 38189 -> 0 bytes .../doc/devel/UML/nglibisofs.violet | 1059 ----- .../doc/devel/UML/stream.violet | 492 --- .../doc/devel/UML/stream.violet.png | Bin 21694 -> 0 bytes .../doc/devel/codestyle.xml | 91 - .../doc/devel/cookbook/ISO 9660-1999 | 119 - .../ForXorrisoZeroOneTwo/doc/doxygen.conf.in | 1298 ------ .../ForXorrisoZeroOneTwo/libisofs-1.pc.in | 11 - .../ForXorrisoZeroOneTwo/libisofs/buffer.c | 328 -- .../ForXorrisoZeroOneTwo/libisofs/buffer.h | 95 - .../ForXorrisoZeroOneTwo/libisofs/builder.c | 208 - .../ForXorrisoZeroOneTwo/libisofs/builder.h | 81 - .../libisofs/data_source.c | 195 - .../ForXorrisoZeroOneTwo/libisofs/ecma119.c | 1579 ------- .../ForXorrisoZeroOneTwo/libisofs/ecma119.h | 476 --- .../libisofs/ecma119_tree.c | 846 ---- .../libisofs/ecma119_tree.h | 90 - .../ForXorrisoZeroOneTwo/libisofs/eltorito.c | 908 ---- .../ForXorrisoZeroOneTwo/libisofs/eltorito.h | 103 - .../ForXorrisoZeroOneTwo/libisofs/filesrc.c | 387 -- .../ForXorrisoZeroOneTwo/libisofs/filesrc.h | 84 - .../ForXorrisoZeroOneTwo/libisofs/filter.c | 49 - .../ForXorrisoZeroOneTwo/libisofs/filter.h | 62 - .../libisofs/filters/xor_encrypt.c | 187 - .../tags/ForXorrisoZeroOneTwo/libisofs/find.c | 629 --- .../ForXorrisoZeroOneTwo/libisofs/fs_image.c | 2642 ------------ .../ForXorrisoZeroOneTwo/libisofs/fs_local.c | 645 --- .../ForXorrisoZeroOneTwo/libisofs/fsource.c | 111 - .../ForXorrisoZeroOneTwo/libisofs/fsource.h | 33 - .../ForXorrisoZeroOneTwo/libisofs/image.c | 277 -- .../ForXorrisoZeroOneTwo/libisofs/image.h | 112 - .../ForXorrisoZeroOneTwo/libisofs/iso1999.c | 1016 ----- .../ForXorrisoZeroOneTwo/libisofs/iso1999.h | 59 - .../ForXorrisoZeroOneTwo/libisofs/joliet.c | 1081 ----- .../ForXorrisoZeroOneTwo/libisofs/joliet.h | 56 - .../libisofs/libiso_msgs.c | 439 -- .../libisofs/libiso_msgs.h | 682 --- .../ForXorrisoZeroOneTwo/libisofs/libisofs.h | 3644 ----------------- .../ForXorrisoZeroOneTwo/libisofs/messages.c | 428 -- .../ForXorrisoZeroOneTwo/libisofs/messages.h | 49 - .../tags/ForXorrisoZeroOneTwo/libisofs/node.c | 1171 ------ .../tags/ForXorrisoZeroOneTwo/libisofs/node.h | 344 -- .../ForXorrisoZeroOneTwo/libisofs/rockridge.c | 1208 ------ .../ForXorrisoZeroOneTwo/libisofs/rockridge.h | 267 -- .../libisofs/rockridge_read.c | 419 -- .../ForXorrisoZeroOneTwo/libisofs/stream.c | 434 -- .../ForXorrisoZeroOneTwo/libisofs/stream.h | 45 - .../tags/ForXorrisoZeroOneTwo/libisofs/tree.c | 804 ---- .../tags/ForXorrisoZeroOneTwo/libisofs/tree.h | 21 - .../tags/ForXorrisoZeroOneTwo/libisofs/util.c | 1264 ------ .../tags/ForXorrisoZeroOneTwo/libisofs/util.h | 438 -- .../libisofs/util_htable.c | 340 -- .../libisofs/util_rbtree.c | 296 -- .../ForXorrisoZeroOneTwo/libisofs/writer.h | 43 - .../ForXorrisoZeroOneTwo/test/mocked_fsrc.c | 378 -- .../ForXorrisoZeroOneTwo/test/mocked_fsrc.h | 31 - .../tags/ForXorrisoZeroOneTwo/test/test.c | 26 - .../tags/ForXorrisoZeroOneTwo/test/test.h | 14 - .../ForXorrisoZeroOneTwo/test/test_image.c | 354 -- .../ForXorrisoZeroOneTwo/test/test_node.c | 690 ---- .../test/test_rockridge.c | 1395 ------- .../ForXorrisoZeroOneTwo/test/test_stream.c | 155 - .../ForXorrisoZeroOneTwo/test/test_tree.c | 566 --- .../ForXorrisoZeroOneTwo/test/test_util.c | 1072 ----- .../tags/ForXorrisoZeroOneTwo/version.h.in | 3 - 106 files changed, 39835 deletions(-) delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/AUTHORS delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/COPYING delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/COPYRIGHT delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/ChangeLog delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/INSTALL delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/Makefile.am delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/NEWS delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/README delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/Roadmap delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/TODO delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/acinclude.m4 delete mode 100755 libisofs/tags/ForXorrisoZeroOneTwo/bootstrap delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/configure.ac delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/cat.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/cat_buffer.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/ecma119_tree.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_cat.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_grow.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_modify.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_ms.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_read.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/lsl.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/demo/tree.c delete mode 100755 libisofs/tags/ForXorrisoZeroOneTwo/doc/Tutorial delete mode 100755 libisofs/tags/ForXorrisoZeroOneTwo/doc/Wiki delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/1. Overview delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/2. Features delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/3. Use Cases delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/4. Design delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/5. Implementation delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/README delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/burn_source.class.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/burn_source.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/nglibisofs.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet.png delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/codestyle.xml delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/cookbook/ISO 9660-1999 delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/doc/doxygen.conf.in delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs-1.pc.in delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/data_source.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filters/xor_encrypt.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/find.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_image.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_local.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libisofs.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge_read.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_htable.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_rbtree.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/libisofs/writer.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test.h delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_image.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_node.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_rockridge.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_stream.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_tree.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/test/test_util.c delete mode 100644 libisofs/tags/ForXorrisoZeroOneTwo/version.h.in diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/AUTHORS b/libisofs/tags/ForXorrisoZeroOneTwo/AUTHORS deleted file mode 100644 index 4b186770..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Vreixo Formoso -Mario Danic -Thomas Schmitt diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/COPYING b/libisofs/tags/ForXorrisoZeroOneTwo/COPYING deleted file mode 100644 index 5a965fbc..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/COPYING +++ /dev/null @@ -1,280 +0,0 @@ - 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/libisofs/tags/ForXorrisoZeroOneTwo/COPYRIGHT b/libisofs/tags/ForXorrisoZeroOneTwo/COPYRIGHT deleted file mode 100644 index 8d562a3d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/COPYRIGHT +++ /dev/null @@ -1,19 +0,0 @@ -Vreixo Formoso , -Mario Danic , -Thomas Schmitt -Copyright (C) 2007-2008 Vreixo Formoso, Mario Danic, Thomas Schmitt - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/ChangeLog b/libisofs/tags/ForXorrisoZeroOneTwo/ChangeLog deleted file mode 100644 index 8b137891..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/ChangeLog +++ /dev/null @@ -1 +0,0 @@ - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/INSTALL b/libisofs/tags/ForXorrisoZeroOneTwo/INSTALL deleted file mode 100644 index 5458714e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/INSTALL +++ /dev/null @@ -1,234 +0,0 @@ -Installation Instructions -************************* - -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/libisofs/tags/ForXorrisoZeroOneTwo/Makefile.am b/libisofs/tags/ForXorrisoZeroOneTwo/Makefile.am deleted file mode 100644 index 6101ec9c..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/Makefile.am +++ /dev/null @@ -1,191 +0,0 @@ -pkgconfigdir=$(libdir)/pkgconfig -libincludedir=$(includedir)/libisofs - -lib_LTLIBRARIES = libisofs/libisofs.la - -## ========================================================================= ## - -# Build libraries - -libisofs_libisofs_la_LDFLAGS = \ - -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -libisofs_libisofs_la_SOURCES = \ - libisofs/builder.h \ - libisofs/builder.c \ - libisofs/node.h \ - libisofs/node.c \ - libisofs/tree.h \ - libisofs/tree.c \ - libisofs/find.c \ - libisofs/image.h \ - libisofs/image.c \ - libisofs/fsource.h \ - libisofs/fsource.c \ - libisofs/fs_local.c \ - libisofs/fs_image.c \ - libisofs/messages.h \ - libisofs/messages.c \ - libisofs/libiso_msgs.h \ - libisofs/libiso_msgs.c \ - libisofs/stream.h \ - libisofs/stream.c \ - libisofs/filter.h \ - libisofs/filter.c \ - libisofs/filters/xor_encrypt.c \ - libisofs/util.h \ - libisofs/util.c \ - libisofs/util_rbtree.c \ - libisofs/util_htable.c \ - libisofs/filesrc.h \ - libisofs/filesrc.c \ - libisofs/ecma119.h \ - libisofs/ecma119.c \ - libisofs/ecma119_tree.h \ - libisofs/ecma119_tree.c \ - libisofs/writer.h \ - libisofs/buffer.h \ - libisofs/buffer.c \ - libisofs/rockridge.h \ - libisofs/rockridge.c \ - libisofs/rockridge_read.c \ - libisofs/joliet.h \ - libisofs/joliet.c \ - libisofs/eltorito.h \ - libisofs/eltorito.c \ - libisofs/iso1999.h \ - libisofs/iso1999.c \ - libisofs/data_source.c -libisofs_libisofs_la_LIBADD= \ - $(THREAD_LIBS) -libinclude_HEADERS = \ - libisofs/libisofs.h - -## ========================================================================= ## - -## Build demo applications -noinst_PROGRAMS = \ - demo/lsl \ - demo/cat \ - demo/catbuffer \ - demo/tree \ - demo/find \ - demo/ecma119tree \ - demo/iso \ - demo/isoread \ - demo/isocat \ - demo/isomodify \ - demo/isoms \ - demo/isogrow - -demo_lsl_CPPFLAGS = -Ilibisofs -demo_lsl_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_lsl_SOURCES = demo/lsl.c - -demo_cat_CPPFLAGS = -Ilibisofs -demo_cat_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_cat_SOURCES = demo/cat.c - -demo_catbuffer_CPPFLAGS = -Ilibisofs -demo_catbuffer_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_catbuffer_SOURCES = demo/cat_buffer.c - -demo_tree_CPPFLAGS = -Ilibisofs -demo_tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_tree_SOURCES = demo/tree.c - -demo_find_CPPFLAGS = -Ilibisofs -demo_find_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_find_SOURCES = demo/find.c - -demo_ecma119tree_CPPFLAGS = -Ilibisofs -demo_ecma119tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_ecma119tree_SOURCES = demo/ecma119_tree.c - -demo_iso_CPPFLAGS = -Ilibisofs -demo_iso_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_iso_SOURCES = demo/iso.c - -demo_isoread_CPPFLAGS = -Ilibisofs -demo_isoread_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_isoread_SOURCES = demo/iso_read.c - -demo_isocat_CPPFLAGS = -Ilibisofs -demo_isocat_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_isocat_SOURCES = demo/iso_cat.c - -demo_isomodify_CPPFLAGS = -Ilibisofs -demo_isomodify_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_isomodify_SOURCES = demo/iso_modify.c - -demo_isoms_CPPFLAGS = -Ilibisofs -demo_isoms_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -demo_isoms_SOURCES = demo/iso_ms.c - -demo_isogrow_CPPFLAGS = -Ilibisofs -Ilibburn -demo_isogrow_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -lburn -demo_isogrow_SOURCES = demo/iso_grow.c - - -## Build unit test - -check_PROGRAMS = \ - test/test - -test_test_CPPFLAGS = -Ilibisofs -test_test_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS) -lcunit -test_test_LDFLAGS = -L.. -lm - -test_test_SOURCES = \ - test/test.h \ - test/test.c \ - test/test_node.c \ - test/test_image.c \ - test/test_tree.c \ - test/test_util.c \ - test/test_rockridge.c \ - test/test_stream.c \ - test/mocked_fsrc.h \ - test/mocked_fsrc.c - -## ========================================================================= ## - -## Build documentation (You need Doxygen for this to work) - -docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION) - -doc: doc/html - -doc/html: doc/doxygen.conf - $(RM) -r doc/html; \ - doxygen doc/doxygen.conf; - -install-data-local: - if [ -d doc/html ]; then \ - $(mkinstalldirs) $(docdir)/html; \ - $(INSTALL_DATA) doc/html/* $(docdir)/html; \ - fi - -uninstall-local: - rm -rf $(docdir) - -## ========================================================================= ## - -# Extra things -nodist_pkgconfig_DATA = \ - libisofs-1.pc - -EXTRA_DIST = \ - libisofs-1.pc.in \ - version.h.in \ - doc/doxygen.conf.in \ - doc/Tutorial \ - README \ - AUTHORS \ - COPYRIGHT \ - COPYING \ - NEWS \ - INSTALL \ - TODO \ - ChangeLog \ - Roadmap - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/NEWS b/libisofs/tags/ForXorrisoZeroOneTwo/NEWS deleted file mode 100644 index 8acff7bc..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/NEWS +++ /dev/null @@ -1,20 +0,0 @@ -== unknown == - -Libisofs v0.6.4 -=============== - -- - -== Fri Feb 22 2008 == - -Libisofs v0.6.2.1 -================= - -- FIX: missing buffer.h in tarball - -== Thu Feb 14 2008 == - -Libisofs v0.6.2 -================ - -- Initial release diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/README b/libisofs/tags/ForXorrisoZeroOneTwo/README deleted file mode 100644 index 1ead917f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/README +++ /dev/null @@ -1,341 +0,0 @@ ------------------------------------------------------------------------------- - libisofs ------------------------------------------------------------------------------- - -Released under GPL (see COPYING file for details). - -Copyright (C) 2008 Vreixo Formoso, Mario Danic, Thomas Schmitt - -libisofs is part of the libburnia project (libburnia-project.org) ------------------------------------------------------------------------------- - -libisofs is a library to create an ISO-9660 filesystem, and supports extensions -like RockRidge or Joliet. It is also a full featured ISO-9660 editor, allowing -you to modify an ISO image or multisession disc, including file addition and -removal, change of file names and attributes, etc - -Features: ---------- - -- Image creation - - Creates ISO-9660 images from local files. - - Support for RockRidge and Joliet extensions. - - Support for ISO-9660:1999 (version 2) - - Support for El-Torito bootable images. - - Full featured edition of file names and attributes on the image. - - Several options to relax ISO-9660 constraints. - - Special options for images intended for distribution (suitable default - modes for files, hiding of real timestamps...) -- Multisession - - Support for growing an existing image - - Full-featured edition of the image files, including: addition of new - files, removing of existent files, moving files, renaming files, - change file attributes (permissions, timestamps...) - - Support for "emulated multisession" or image growing, suitable for non - multisession media such as DVD+RW -- Image modification - - It can create a completely new image from files on another image. - - Full-featured edition of image contents -- Others - - Handling of different input and output charset - - Good integration with libburn for image burning. - - Reliable, good handling of different kind of errors. - -Requirements: -------------- - -- libburn 0.4.2 headers must be installed at compile time. It is not required - at runtime. - -Know bugs: ----------- - -Multisession and image growing can lead to undesired results in several cases: - -a) Images with unsupported features, such as: - - UDF. - - HSF/HFS+ or other Mac extensions. - - El-Torito with multiple entries. - - ECMA-119 with extended attributes, multiple extends per file. - - Non El-Torito boot info. - - zisofs compressed images. - - ... - In all these cases, the resulting new image (or new session) could lack some - features of the original image. - In some cases libisofs will issue warning messages, or even refuse to grow - or modify the image. Others remain undetected. Images created with libisofs - do not have this problems. - -b) Bootable El-Torito images may have several problems, that result in a new - image that is not bootable, or that boots from an outdated session. In many - cases it is recommended to add boot info again in the new session. - - - isolinux images won't be bootable after a modify. This is because - isolinux images need to have hardcoded the root dir lba. libisofs cannot - know whether an image is an isolinux image or not, so the user is - responsible to tell libisofs that it must patch the image, with the - el_torito_patch_isolinux_image() function. This problem could also exists - on other boot images. - - Most boot images are highly dependent of the image contents, so if the - user moves or removes some files on image it is possible they won't boot - anymore. - - There is no safer way to modify hidden boot images, as the size of the - boot image can't be figured out. - -c) Generated images could have different ECMA-119 low level names, due to - different way to mangle names, to new files added that force old files to - be renamed, to different relaxed contraints... This only affect the - ISO-9660 info, not the RR names, so it shouldn't be a problem in most - cases. If your app. relies on low level ISO-9660 names, you will need to - ensure all node names are valid ISO names (maybe together with some - relaxed contraints), otherwise libisofs might arbitrarily change the names. - - ------------------------------------------------------------------------------- - - Download, Build and Installation - -libisofs code is mantained in a Bazaar repository at Launchpad -(https://launchpad.net/libisofs/). You can download it with: - -$ bzr branch lp:libisofs - -Our build system is based on autotools. For preparing the build you will need -autotools of at least version 1.7. If you have download the code from the -repository, first of all you need to execute - - ./autogen.sh - -on toplevel dir to execute autotools. - -Alternatively you may unpack a release tarball for which you do not need -autotools installed. - -To build libisofs it should be sufficient to go into its toplevel directory -and execute - - ./configure --prefix=/usr - make - -To make the libraries accessible for running resp. developing applications - make install - -See INSTALL file for further details. - - ------------------------------------------------------------------------------- - - Overview of libburnia-project.org - -libburnia-project.org is an open-source software project for reading, mastering -and writing optical discs. -For now this means only CD media and all single layer DVD media except DVD+R. - -The project comprises of several more or less interdependent parts which -together strive to be a usable foundation for application development. -These are libraries, language bindings, and middleware binaries which emulate -classical (and valuable) Linux tools. - -Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems -we would need : login on a development machine resp. a live OS on CD or DVD, -advise from a system person about the equivalent of Linux sg or FreeBSD CAM, -volunteers for testing of realistic use cases. - -We have a workable code base for burning CD and most single layer DVD. -The burn API is quite comprehensively documented and can be used to build a -presentable application. -We have a functional binary which emulates parts of cdrecord in order to -prove that usability, and in order to allow you to explore libburnia's scope -by help of existing cdrecord frontends. - -The project components (list subject to growth, hopefully): - -- libburn is the library by which preformatted data get onto optical media. - It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or - /dev/hdX (e.g. on kernel 2.6). - libburn is the foundation of our cdrecord emulation. Its code is - independent of cdrecord. Its DVD capabilities are learned from - studying the code of dvd+rw-tools and MMC-5 specs. No code but only - the pure SCSI knowledge has been taken from dvd+rw-tools, though. - -- libisofs is the library to pack up hard disk files and directories into a - ISO 9660 disk image. This may then be brought to media via libburn. - libisofs is to be the foundation of our upcoming mkisofs emulation. - -- cdrskin is a limited cdrecord compatibility wrapper for libburn. - Cdrecord is a powerful GPL'ed burn program included in Joerg - Schilling's cdrtools. cdrskin strives to be a second source for - the services traditionally provided by cdrecord. Additionally it - provides libburn's DVD capabilities, where only -sao is compatible - with cdrecord. - cdrskin does not contain any bytes copied from cdrecord's sources. - Many bytes have been copied from the message output of cdrecord - runs, though. - See cdrskin/README and man cdrskin/cdrskin.1 for more. - -- test is a collection of application gestures and examples given by the - authors of the library features. The main API example for libburn - is test/libburner.c . - Explore these examples if you look for inspiration. - -We plan to be a responsive upstream. Bear with us. We are still practicing. - - ------------------------------------------------------------------------------- -Project history as far as known to me: - -- Founded in 2002 as it seems. See mailing list archives - http://lists.freedesktop.org/archives/libburn/ - The site of this founder team is reachable and offers download of a - (somewhat outdated) tarball and from CVS : - http://icculus.org/burn/ - Copyright holders and most probably founders: - Derek Foreman and Ben Jansens. - -- I came to using libburn in 2005. Founded the cdrskin project and submitted - necessary patches which were accepted or implemented better. Except one - remaining patch which prevented cdrskin from using vanilla libburn from CVS. - The cdrskin project site is reachable and offers download of the heavily - patched (elsewise outdated) tarball under the name cdrskin-0.1.2 : - http://scdbackup.sourceforge.net/cdrskin_eng.html - It has meanwhile moved to use vanilla libburn.pykix.org , though. - Version 0.1.4 constitutes the first release of this kind. - -- In July 2006 our team mate Mario Danic announced a revival of libburn - which by about nearly everybody else was perceived as unfriendly fork. - Derek Foreman four days later posted a message which expressed his - discontent. - The situation first caused me to publically regret it and then - after i - got the opportunity to move in with cdrskin - gave me true reason to - personally apologize to Derek Foreman, Ben Jansens and the contibutors at - icculus.org/burn. Posted to both projects: - http://lists.freedesktop.org/archives/libburn/2006-August/000446.html - http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html - -- Mid August 2006 project cdrskin established a branch office in - libburn.pykix.org so that all maintainers of our tools have one single place - to get the current (at least slightely) usable coordinated versions of - everything. - Project cdrskin will live forth independendly for a while but it is committed - to stay in sync with libburn.pykix.org (or some successor, if ever). - cdrskin is also committed to support icculus.org/burn if the pending fork - is made reality by content changes in that project. It will cease to maintain - a patched version of icculus.org/burn though. Precondition for a new - release of cdrskin on base of icculus.org/burn would be the pending - "whitelist patch" therefore. - I would rather prefer if both projects find consense and merge, or at least - cooperate. I have not given up hope totally, yet. - I, personally, will honor any approach. - -- 2nd September 2006 the decision is made to strive for a consolidation of - copyright and a commitment to GPL in a reasonable and open minded way. - This is to avoid long term problems with code of unknown origin and - with finding consense among the not so clearly defined group of copyright - claimers and -holders. - libisofs is already claimed sole copyright Mario Danic. - cdrskin and libburner are already claimed sole copyright Thomas Schmitt. - Rewrites of other components will follow and concluded by claiming full - copyright within the group of libburn.pykix.org-copyright holders. - -- 16th September 2006 feature freeze for release of libburn-0.2.2 . - -- 20th September 2006 release of libburn-0.2.2 . - -- 26th October 2006 feature freeze for cdrskin-0.2.4 based on libburn-0.2.3 . - This version of cdrskin is much more cdrecord compatible in repect - to drive addressing and audio features. - -- 30th October 2006 release of cdrskin-0.2.4 . - -- 13th November 2006 splitting releases of libburn+cdrskin from libisofs. - -- 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has - become suitable for unaware frontends as long as they perform only the core - of cdrecord use cases (including open-ended input streams, audio, and - multi-session). - -- 28th November 2006 the umbrella project which encloses both, libisofs and - libburn, is now called libburnia. For the origin of this name, see - http://en.wikipedia.org/wiki/Liburnians . - -- 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope - is widened to a first class of DVD media: overwriteable single layer types - DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired - by dvd+rw-tools' "poor man" writing facility for this class of media. - Taking a bow towards Andy Polyakov. - -- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with - multi-session and with DAO. - -- 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer - DVD media. Code for double layer DVD+/-R is implemented but awaits a tester - yet. - -- 23th April 2007 version 0.3.6 follows the unanimous opinion of Linux kernel - people that one should not use /dev/sg on kernel 2.6. - -- 31st July 2007 version 0.3.8 marks the first anniversary of libburn revival. - We look back on improved stability, a substantially extended list of media - and write modes, and better protection against typical user mishaps. - -- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn - and an upcomming integrated application for manipulating and writing - ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs - by these enhancements: growing of overwriteable media and disk files. - Taking again a bow towards Andy Polyakov. - -- 26th Januar 2008 version 0.4.2 rectifies the version numbering so that we - reliably release libburn.so.4 as should have been done since libburn-0.3.2. - cdrskin now is by default linked dynamically and does a runtime check - to ensure not to be started with a libburn which is older than itself. - - ------------------------------------------------------------------------------- - - 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. To be exact: version 2 of that License. - - 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 - ------------------------------------------------------------------------------- -Clarification in my name and in the name of Mario Danic, upcoming copyright -holders on toplevel of libburnia. To be fully in effect after the remaining -other copyrighted code has been replaced by ours and by copyright-free -contributions of our friends: ------------------------------------------------------------------------------- - -We, the copyright holders, agree on the interpretation that -dynamical linking of our libraries constitutes "use of" and -not "derivation from" our work in the sense of GPL, provided -those libraries are compiled from our unaltered code. - -Thus you may link our libraries dynamically with applications -which are not under GPL. You may distribute our libraries and -application tools in binary form, if you fulfill the usual -condition of GPL to offer a copy of the source code -altered -or unaltered- under GPL. - -We ask you politely to use our work in open source spirit -and with the due reference to the entire open source community. - -If there should really arise the case where above clarification -does not suffice to fulfill a clear and neat request in open source -spirit that would otherwise be declined for mere formal reasons, -only in that case we will duely consider to issue a special license -covering only that special case. -It is the open source idea of responsible freedom which will be -decisive and you will have to prove that you exhausted all own -means to qualify for GPL. - -For now we are firmly committed to maintain one single license: GPL. - -signed: Mario Danic, Thomas Schmitt - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/Roadmap b/libisofs/tags/ForXorrisoZeroOneTwo/Roadmap deleted file mode 100644 index 926ecef6..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/Roadmap +++ /dev/null @@ -1,33 +0,0 @@ - ->>>>>>>>>> RELEASE 0.6.1 (development) >>>>>>>>>>>>>>>>>>>>> - -- Review error severities -OK - Prepare API for stability and compatibility check -- Documentation - ->>>>>>>>>> RELEASE 0.6.2 (stable) >>>>>>>>>>>>>>>>>>>>>>>>>> - -- Intensive testing and bug fixing - ->>>>>>>>>> RELEASE 0.6.3 (development) >>>>>>>>>>>>>>>>>>>>> - -- Improves to public tree - -> Expose node extended info. Always compile it. - (little memory cost) - -> Review builder / tree / node relation - -> Optimize storage of children in node? - -> Inode object? -- Expose Builder and Streams -- Implement filters: compression, encryption... -- Consider some kind of plugin system for Builders, Filesystems and Filters. -- ECMA-119, Joliet, and ISO-9660:1999 writers can share most of the code. - Create a new writer as a generalization of these. -- Update Java bindings - ->>>>>>>>>>> ...... - ->>>>>>>>>>> RELEASE 1.0.0 (stable) >>>>>>>>>>>>>>>>>>>>>>>>>> - -- UDF -- HFS - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/TODO b/libisofs/tags/ForXorrisoZeroOneTwo/TODO deleted file mode 100644 index bad313fc..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/TODO +++ /dev/null @@ -1,35 +0,0 @@ -FEATURES -======== - - -TODO -==== - -#00001 (node.h) -> consider adding new timestamps to IsoTreeNode -#00004 (libisofs.h) -> Add a get_mime_type() function. -#00005 (node.c) -> optimize iso_dir_iter_take. -#00006 (libisofs.h) -> define more replace values when adding a node to a dir -#00007 (libisofs.h) -> expose iso_tree_add_new_file -#00008 (data_dource.c) -> guard against partial reads -#00009 (ecma119_tree.c/h) -> add true support for harlinks and inode numbers -#00010 (buffer.c) -> optimize ring buffer -#00011 (ecma119.c) -> guard against bad path table usage with more than 65535 dirs -#00012 (fs_image.c) -> support follow symlinks on imafe filesystem -#00013 (fs_image.c) -> check for unsupported flags when reading a dir record -#00014 (fs_image.c) -> more sanity checks to ensure dir record info is valid -#00015 (fs_image.c) -> take care of CD-ROM XA discs when reading SP entry -#00016 (fs_image.c) -> handle non RR ER entries -#00017 (fs_image.c) -> take advantage of other atts of PVD -#00018 (fs_image.c) -> check if there are more entries in the boot catalog -#00019 (fs_image.c) -> set IsoImage attribs from Joliet SVD? -#00020 (fs_image.c) -> handle RR info in Joliet tree -#00021 (fs_image.c) -> handle RR info in ISO 9660:1999 tree -#00022 (joliet.c) -> support relaxed constraints in joliet filenames -#00024 (libisofs.h) -> option to convert names to lower case for iso reading -#00025 (libisofs.h) -> support for merging old image files -#00026 (libisofs.h) -> add support for "hidden" bootable images. -#00027 (iso1999.h) -> Follow ISO 9660:1999 specs when sorting files - -FIXME -===== - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/acinclude.m4 b/libisofs/tags/ForXorrisoZeroOneTwo/acinclude.m4 deleted file mode 100644 index 861847bb..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/acinclude.m4 +++ /dev/null @@ -1,22 +0,0 @@ -AC_DEFUN([TARGET_SHIZZLE], -[ - ARCH="" - - AC_MSG_CHECKING([target operating system]) - - case $target in - *-*-linux*) - ARCH=linux - LIBBURN_ARCH_LIBS= - ;; - *-*-freebsd*) - ARCH=freebsd - LIBBURN_ARCH_LIBS=-lcam - ;; - *) - AC_ERROR([You are attempting to compile for an unsupported platform]) - ;; - esac - - AC_MSG_RESULT([$ARCH]) -]) diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/bootstrap b/libisofs/tags/ForXorrisoZeroOneTwo/bootstrap deleted file mode 100755 index 86709bfc..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/bootstrap +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -x - -aclocal -libtoolize --copy --force -autoconf - -# ts A61101 : libburn is not prepared for config.h -# autoheader - -automake --foreign --add-missing --copy --include-deps diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/configure.ac b/libisofs/tags/ForXorrisoZeroOneTwo/configure.ac deleted file mode 100644 index 69b7dc5e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/configure.ac +++ /dev/null @@ -1,155 +0,0 @@ -AC_INIT([libisofs], [0.6.3], [http://libburnia-project.org]) -AC_PREREQ([2.50]) -dnl AC_CONFIG_HEADER([config.h]) - -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -AM_INIT_AUTOMAKE([subdir-objects]) - -dnl A61101 This breaks Linux build (makes 32 bit off_t) -dnl http://sourceware.org/autobook/autobook/autobook_96.html says -dnl one must include some config.h and this was a pitfall. -dnl So why dig the pit at all ? -dnl AM_CONFIG_HEADER(config.h) - -dnl -dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match -dnl -dnl CURRENT and AGE describe the binary compatibility interval of a -dnl dynamic library. -dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces -dnl -dnl The name of the library will be libisofs.so.$CURRENT-$AGE.$AGE.$REV -dnl In the terminology of this file: -dnl CURRENT = LT_CURRENT -dnl REV = LT_REVISION -dnl AGE = LT_AGE -dnl -dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now. -dnl -dnl SONAME of the emerging library is LT_CURRENT - LT_AGE. -dnl The linker will do no finer checks. Especially no age range check for -dnl the cdrskin binary. If SONAME matches, then the couple starts. -dnl -dnl Therefore a run time check is provided by libisofs function -dnl iso_lib_version(). It returns the major, minor and micro revision of the -dnl library. This means LIBISOFS_*_VERSION kept its second job which does not -dnl comply to the usual ways of configure.ac . I.e. now *officially* this is -dnl the source code release version as announced to the public. It has no -dnl conection to SONAME or libtool version numbering. -dnl It rather feeds the API function iso_lib_version(). -dnl -dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match. -dnl -LIBISOFS_MAJOR_VERSION=0 -LIBISOFS_MINOR_VERSION=6 -LIBISOFS_MICRO_VERSION=3 -LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION - -AC_SUBST(LIBISOFS_MAJOR_VERSION) -AC_SUBST(LIBISOFS_MINOR_VERSION) -AC_SUBST(LIBISOFS_MICRO_VERSION) -AC_SUBST(LIBISOFS_VERSION) - -dnl Libtool versioning -LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION -# SONAME = 6 - 0 = 6 . Library name = libisofs.6.0.0 -LT_CURRENT=6 -LT_REVISION=0 -LT_AGE=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_MSG_ERROR([Libisofs requires largefile support.]) -fi - -AC_PROG_LIBTOOL -AC_SUBST(LIBTOOL_DEPS) -LIBTOOL="$LIBTOOL --silent" - -AC_PROG_INSTALL - -AC_CHECK_HEADERS() - -dnl Use GNU extensions if available -AC_DEFINE(_GNU_SOURCE, 1) - -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 Check if non standard timegm() function is available -AC_CHECK_DECL([timegm], - [AC_DEFINE(HAVE_TIMEGM, 1, [Define this if timegm function is available])], - , - [#include ]) - -dnl Check if non standard eaccess() function is available -AC_CHECK_DECL([eaccess], - [AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])], - , - [#include ]) - -THREAD_LIBS=-lpthread -AC_SUBST(THREAD_LIBS) - -TARGET_SHIZZLE -AC_SUBST(ARCH) -AC_SUBST(LIBBURN_ARCH_LIBS) - -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="$CFLAGS -O3" - CFLAGS="$CFLAGS -fexpensive-optimizations" - fi - CFLAGS="$CFLAGS -DNDEBUG" -else - if test x$GCC = xyes; then - CFLAGS="$CFLAGS -g -pedantic -Wall" - fi - CFLAGS="$CFLAGS -DDEBUG" -fi - -dnl Verbose debug to make libisofs issue more debug messages -AC_ARG_ENABLE(verbose-debug, -[ --enable-verbose-debug Enable verbose debug messages [default=no]], - AC_DEFINE(LIBISOFS_VERBOSE_DEBUG, 1)) - - -AC_CONFIG_FILES([ - Makefile - doc/doxygen.conf - version.h - libisofs-1.pc - ]) -AC_OUTPUT diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat.c deleted file mode 100644 index a95eebc3..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "fsource.h" - -#include -#include - -/* - * Little test program to test filesystem implementations. - * Outputs file contents to stdout! - */ - -int main(int argc, char **argv) -{ - int res; - IsoFilesystem *fs; - IsoFileSource *file; - struct stat info; - - if (argc != 2) { - fprintf(stderr, "Usage: cat /path/to/file\n"); - return 1; - } - - /* create filesystem object */ - res = iso_local_filesystem_new(&fs); - if (res < 0) { - fprintf(stderr, "Can't get local fs object, err = %d\n", res); - return 1; - } - - res = fs->get_by_path(fs, argv[1], &file); - if (res < 0) { - fprintf(stderr, "Can't get file, err = %d\n", res); - return 1; - } - - res = iso_file_source_lstat(file, &info); - if (res < 0) { - fprintf(stderr, "Can't stat file, err = %d\n", res); - return 1; - } - - if (S_ISDIR(info.st_mode)) { - fprintf(stderr, "Path refers to a directory!!\n"); - return 1; - } else { - char buf[1024]; - res = iso_file_source_open(file); - if (res < 0) { - fprintf(stderr, "Can't open file, err = %d\n", res); - return 1; - } - while ((res = iso_file_source_read(file, buf, 1024)) > 0) { - fwrite(buf, 1, res, stdout); - } - if (res < 0) { - fprintf(stderr, "Error reading, err = %d\n", res); - return 1; - } - iso_file_source_close(file); - } - - iso_file_source_unref(file); - iso_filesystem_unref(fs); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat_buffer.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat_buffer.c deleted file mode 100644 index 74657ee2..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/cat_buffer.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "buffer.h" - -#include -#include -#include -#include -#include -#include -#include - -/* - * Little test program that reads a file and outputs it to stdout, using - * the libisofs ring buffer as intermediate memory - */ - -struct th_data -{ - IsoRingBuffer *rbuf; - char *path; -}; - -#define WRITE_CHUNK 2048 -#define READ_CHUNK 2048 - -static -void *write_function(void *arg) -{ - ssize_t bytes; - int res; - unsigned char tmp[WRITE_CHUNK]; - struct th_data *data = (struct th_data *) arg; - - int fd = open(data->path, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Writer thread error: Can't open file"); - iso_ring_buffer_writer_close(data->rbuf, 1); - pthread_exit(NULL); - } - - res = 1; - while ( (bytes = read(fd, tmp, WRITE_CHUNK)) > 0) { - res = iso_ring_buffer_write(data->rbuf, tmp, bytes); - if (res <= 0) { - break; - } - /* To test premature reader exit >>>>>>>>>>> - iso_ring_buffer_writer_close(data->rbuf); - pthread_exit(NULL); - <<<<<<<<<<<<<<<<<<<<<<<<< */ - // if (rand() > 2000000000) { - // fprintf(stderr, "Writer sleeping\n"); - // sleep(1); - // } - } - fprintf(stderr, "Writer finish: %d\n", res); - - close(fd); - iso_ring_buffer_writer_close(data->rbuf, 0); - pthread_exit(NULL); -} - -static -void *read_function(void *arg) -{ - unsigned char tmp[READ_CHUNK]; - int res = 1; - struct th_data *data = (struct th_data *) arg; - - while ( (res = iso_ring_buffer_read(data->rbuf, tmp, READ_CHUNK)) > 0) { - write(1, tmp, READ_CHUNK); - /* To test premature reader exit >>>>>>>>>>> - iso_ring_buffer_reader_close(data->rbuf); - pthread_exit(NULL); - <<<<<<<<<<<<<<<<<<<<<<<<< */ - // if (rand() > 2000000000) { - // fprintf(stderr, "Reader sleeping\n"); - // sleep(1); - // } - } - fprintf(stderr, "Reader finish: %d\n", res); - - iso_ring_buffer_reader_close(data->rbuf, 0); - - pthread_exit(NULL); -} - -int main(int argc, char **argv) -{ - int res; - struct th_data data; - pthread_t reader; - pthread_t writer; - - if (argc != 2) { - fprintf(stderr, "Usage: catbuffer /path/to/file\n"); - return 1; - } - - res = iso_ring_buffer_new(1024, &data.rbuf); - if (res < 0) { - fprintf(stderr, "Can't create buffer\n"); - return 1; - } - data.path = argv[1]; - - res = pthread_create(&writer, NULL, write_function, (void *) &data); - res = pthread_create(&reader, NULL, read_function, (void *) &data); - - pthread_join(writer, NULL); - pthread_join(reader, NULL); - - fprintf(stderr, "Buffer was %d times full and %d times empty.\n", - iso_ring_buffer_get_times_full(data.rbuf), - iso_ring_buffer_get_times_empty(data.rbuf)); - - free(data.rbuf); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/ecma119_tree.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/ecma119_tree.c deleted file mode 100644 index e1c4dbec..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/ecma119_tree.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Little program that imports a directory to iso image, generates the - * ecma119 low level tree and prints it. - * Note that this is not an API example, but a little program for test - * purposes. - */ - -#include "libisofs.h" -#include "ecma119.h" -#include "ecma119_tree.h" -#include "util.h" -#include "filesrc.h" -#include "node.h" -#include -#include -#include -#include -#include -#include - -static void -print_permissions(mode_t mode) -{ - char perm[10]; - - //TODO suid, sticky... - - perm[9] = '\0'; - perm[8] = mode & S_IXOTH ? 'x' : '-'; - perm[7] = mode & S_IWOTH ? 'w' : '-'; - perm[6] = mode & S_IROTH ? 'r' : '-'; - perm[5] = mode & S_IXGRP ? 'x' : '-'; - perm[4] = mode & S_IWGRP ? 'w' : '-'; - perm[3] = mode & S_IRGRP ? 'r' : '-'; - perm[2] = mode & S_IXUSR ? 'x' : '-'; - perm[1] = mode & S_IWUSR ? 'w' : '-'; - perm[0] = mode & S_IRUSR ? 'r' : '-'; - printf("[%s]",perm); -} - -static void -print_dir(Ecma119Node *dir, int level) -{ - int i; - char *sp = alloca(level * 2 + 1); - - for (i = 0; i < level * 2; i += 2) { - sp[i] = '|'; - sp[i+1] = ' '; - } - - sp[level * 2-1] = '-'; - sp[level * 2] = '\0'; - - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - - if (child->type == ECMA119_DIR) { - printf("%s+[D] ", sp); - print_permissions(iso_node_get_permissions(child->node)); - printf(" %s\n", child->iso_name); - print_dir(child, level+1); - } else if (child->type == ECMA119_FILE) { - printf("%s-[F] ", sp); - print_permissions(iso_node_get_permissions(child->node)); - printf(" %s {%p}\n", child->iso_name, (void*)child->info.file); - } else if (child->type == ECMA119_SYMLINK) { - printf("%s-[L] ", sp); - print_permissions(iso_node_get_permissions(child->node)); - printf(" %s -> %s\n", child->iso_name, - ((IsoSymlink*)child->node)->dest); - } else if (child->type == ECMA119_SPECIAL) { - printf("%s-[S] ", sp); - print_permissions(iso_node_get_permissions(child->node)); - printf(" %s\n", child->iso_name); - } else if (child->type == ECMA119_PLACEHOLDER) { - printf("%s-[RD] ", sp); - print_permissions(iso_node_get_permissions(child->node)); - printf(" %s\n", child->iso_name); - } else { - printf("%s-[????] ", sp); - } - } -} - -int main(int argc, char **argv) -{ - int result; - IsoImage *image; - Ecma119Image *ecma119; - - if (argc != 2) { - printf ("You need to specify a valid path\n"); - return 1; - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - result = iso_image_new("volume_id", &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - ecma119 = calloc(1, sizeof(Ecma119Image)); - iso_rbtree_new(iso_file_src_cmp, &(ecma119->files)); - ecma119->iso_level = 1; - ecma119->rockridge = 1; - ecma119->image = image; - ecma119->input_charset = strdup("UTF-8"); - - /* create low level tree */ - result = ecma119_tree_create(ecma119); - if (result < 0) { - printf ("Error creating ecma-119 tree: %d\n", result); - return 1; - } - - printf("================= ECMA-119 TREE =================\n"); - print_dir(ecma119->root, 0); - printf("\n\n"); - - ecma119_node_free(ecma119->root); - iso_rbtree_destroy(ecma119->files, iso_file_src_free); - free(ecma119->input_charset); - free(ecma119); - iso_image_unref(image); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso.c deleted file mode 100644 index f3783b08..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Little program to show how to create an iso image from a local - * directory. - */ - -#include "libisofs.h" -#include "libburn/libburn.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char * const optstring = "JRIL:b:hV:"; -extern char *optarg; -extern int optind; - -void usage(char **argv) -{ - printf("%s [OPTIONS] DIRECTORY OUTPUT\n", argv[0]); -} - -void help() -{ - printf( - "Options:\n" - " -J Add Joliet support\n" - " -R Add Rock Ridge support\n" - " -I Add ISO 9660:1999 support\n" - " -V label Volume Label\n" - " -L Set the ISO level (1 or 2)\n" - " -b file Specifies a boot image to add to image\n" - " -h Print this message\n" - ); -} - -int callback(IsoFileSource *src) -{ - char *path = iso_file_source_get_path(src); - printf("CALLBACK: %s\n", path); - free(path); - return 1; -} - -int main(int argc, char **argv) -{ - int result; - int c; - IsoImage *image; - struct burn_source *burn_src; - unsigned char buf[2048]; - FILE *fd; - IsoWriteOpts *opts; - char *volid = "VOLID"; - char *boot_img = NULL; - int rr = 0, j = 0, iso1999 = 0, level = 1; - - while ((c = getopt(argc, argv, optstring)) != -1) { - switch(c) { - case 'h': - usage(argv); - help(); - exit(0); - break; - case 'J': - j = 1; - break; - case 'R': - rr = 1; - break; - case 'I': - iso1999 = 1; - break; - case 'L': - level = atoi(optarg); - break; - case 'b': - boot_img = optarg; - break; - case 'V': - volid = optarg; - break; - case '?': - usage(argv); - exit(1); - break; - } - } - - if (argc < 2) { - printf ("Please pass directory from which to build ISO\n"); - usage(argv); - return 1; - } - if (argc < 3) { - printf ("Please supply output file\n"); - usage(argv); - return 1; - } - - fd = fopen(argv[optind+1], "w"); - if (!fd) { - err(1, "error opening output file"); - } - - result = iso_init(); - if (result < 0) { - printf ("Can't initialize libisofs\n"); - return 1; - } - iso_set_msgs_severities("NEVER", "ALL", ""); - - result = iso_image_new(volid, &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - iso_tree_set_follow_symlinks(image, 0); - iso_tree_set_ignore_hidden(image, 0); - iso_tree_set_ignore_special(image, 0); - iso_set_abort_severity("SORRY"); - /*iso_tree_set_report_callback(image, callback);*/ - - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[optind]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - if (boot_img) { - /* adds El-Torito boot info. Tunned for isolinux */ - ElToritoBootImage *bootimg; - result = iso_image_set_boot_image(image, boot_img, ELTORITO_NO_EMUL, - "/isolinux/boot.cat", &bootimg); - if (result < 0) { - printf ("Error adding boot image %d\n", result); - return 1; - } - el_torito_set_load_size(bootimg, 4); - el_torito_patch_isolinux_image(bootimg); - } - - result = iso_write_opts_new(&opts, 0); - if (result < 0) { - printf ("Cant create write opts, error %d\n", result); - return 1; - } - iso_write_opts_set_iso_level(opts, level); - iso_write_opts_set_rockridge(opts, rr); - iso_write_opts_set_joliet(opts, j); - iso_write_opts_set_iso1999(opts, iso1999); - - result = iso_image_create_burn_source(image, opts, &burn_src); - if (result < 0) { - printf ("Cant create image, error %d\n", result); - return 1; - } - - iso_write_opts_free(opts); - - while (burn_src->read_xt(burn_src, buf, 2048) == 2048) { - fwrite(buf, 1, 2048, fd); - } - fclose(fd); - burn_src->free_data(burn_src); - free(burn_src); - - iso_image_unref(image); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_cat.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_cat.c deleted file mode 100644 index 452d1b12..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_cat.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - - -#include -#include - -#include "libisofs.h" - -/* - * Little test program that extracts a file form a given ISO image. - * Outputs file contents to stdout! - */ - -int main(int argc, char **argv) -{ - int res; - IsoFilesystem *fs; - IsoFileSource *file; - struct stat info; - IsoDataSource *src; - IsoReadOpts *opts; - - if (argc != 3) { - fprintf(stderr, "Usage: isocat /path/to/image /path/to/file\n"); - return 1; - } - - res = iso_init(); - if (res < 0) { - fprintf(stderr, "Can't init libisofs\n"); - return 1; - } - - res = iso_data_source_new_from_file(argv[1], &src); - if (res < 0) { - fprintf(stderr, "Error creating data source\n"); - return 1; - } - - res = iso_read_opts_new(&opts, 0); - if (res < 0) { - fprintf(stderr, "Error creating read options\n"); - return 1; - } - res = iso_image_filesystem_new(src, opts, 1, &fs); - if (res < 0) { - fprintf(stderr, "Error creating filesystem\n"); - return 1; - } - iso_read_opts_free(opts); - - res = fs->get_by_path(fs, argv[2], &file); - if (res < 0) { - fprintf(stderr, "Can't get file, err = %d\n", res); - return 1; - } - - res = iso_file_source_lstat(file, &info); - if (res < 0) { - fprintf(stderr, "Can't stat file, err = %d\n", res); - return 1; - } - - if (S_ISDIR(info.st_mode)) { - fprintf(stderr, "Path refers to a directory!!\n"); - return 1; - } else { - char buf[1024]; - res = iso_file_source_open(file); - if (res < 0) { - fprintf(stderr, "Can't open file, err = %d\n", res); - return 1; - } - while ((res = iso_file_source_read(file, buf, 1024)) > 0) { - fwrite(buf, 1, res, stdout); - } - if (res < 0) { - fprintf(stderr, "Error reading, err = %d\n", res); - return 1; - } - iso_file_source_close(file); - } - - iso_file_source_unref(file); - iso_filesystem_unref(fs); - iso_data_source_unref(src); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_grow.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_grow.c deleted file mode 100644 index 951aec1b..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_grow.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Very simple program to show how to grow an iso image. - */ - -#include "libisofs.h" -#include "libburn/libburn.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -static IsoDataSource *libburn_data_source_new(struct burn_drive *d); - -void usage(char **argv) -{ - printf("%s DISC DIRECTORY\n", argv[0]); -} - -int main(int argc, char **argv) -{ - int result; - IsoImage *image; - IsoDataSource *src; - struct burn_source *burn_src; - struct burn_drive_info *drives; - struct burn_drive *drive; - unsigned char buf[32 * 2048]; - IsoWriteOpts *opts; - int ret = 0; - IsoReadImageFeatures *features; - uint32_t ms_block; - IsoReadOpts *ropts; - - if (argc < 3) { - usage(argv); - return 1; - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - - /* create the image context */ - result = iso_image_new("volume_id", &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - iso_tree_set_follow_symlinks(image, 0); - iso_tree_set_ignore_hidden(image, 0); - - if (!burn_initialize()) { - err(1, "Can't init libburn"); - } - burn_msgs_set_severities("NEVER", "SORRY", "libburner : "); - - if (burn_drive_scan_and_grab(&drives, argv[1], 0) != 1) { - err(1, "Can't open device. Are you sure it is a valid drive?\n"); - } - - drive = drives[0].drive; - -#ifdef ISO_GROW_CHECK_MEDIA - { - /* some check before going on */ - enum burn_disc_status state; - int pno; - char name[80]; - - state = burn_disc_get_status(drive); - burn_disc_get_profile(drive, &pno, name); - - /* - * my drives report BURN_DISC_BLANK on a DVD+RW with data. - * is that correct? - */ - if ( (pno != 0x1a) /*|| (state != BURN_DISC_FULL)*/ ) { - printf("You need to insert a DVD+RW with some data.\n"); - printf("Profile: %x, state: %d.\n", pno, state); - ret = 1; - goto exit_cleanup; - } - } -#endif - - /* create the data source to accesss previous image */ - src = libburn_data_source_new(drive); - if (src == NULL) { - printf("Can't create data source.\n"); - ret = 1; - goto exit_cleanup; - } - - /* import previous image */ - ret = iso_read_opts_new(&ropts, 0); - if (ret < 0) { - fprintf(stderr, "Error creating read options\n"); - return 1; - } - result = iso_image_import(image, src, ropts, &features); - iso_data_source_unref(src); - if (result < 0) { - printf ("Error importing previous session %d\n", result); - return 1; - } - iso_read_opts_free(ropts); - - iso_tree_set_replace_mode(image, ISO_REPLACE_IF_NEWER); - - /* add new dir */ - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - /* generate a multisession image with new contents */ - result = iso_write_opts_new(&opts, 1); - if (result < 0) { - printf("Cant create write opts, error %d\n", result); - return 1; - } - - /* round up to 32kb aligment = 16 block */ - ms_block = ((iso_read_image_features_get_size(features) + 15) / 16 ) * 16; - iso_write_opts_set_ms_block(opts, ms_block); - iso_write_opts_set_appendable(opts, 1); - iso_write_opts_set_overwrite_buf(opts, buf); - - iso_read_image_features_destroy(features); - - result = iso_image_create_burn_source(image, opts, &burn_src); - if (result < 0) { - printf("Cant create image, error %d\n", result); - return 1; - } - - iso_write_opts_free(opts); - - /* a. write the new image */ - printf("Adding new data...\n"); - { - struct burn_disc *target_disc; - struct burn_session *session; - struct burn_write_opts *burn_options; - struct burn_track *track; - struct burn_progress progress; - char reasons[BURN_REASONS_LEN]; - - target_disc = burn_disc_create(); - session = burn_session_create(); - burn_disc_add_session(target_disc, session, BURN_POS_END); - - track = burn_track_create(); - burn_track_set_source(track, burn_src); - burn_session_add_track(session, track, BURN_POS_END); - - burn_options = burn_write_opts_new(drive); - burn_drive_set_speed(drive, 0, 0); - burn_write_opts_set_underrun_proof(burn_options, 1); - - /* mmm, check for 32K alignment? */ - burn_write_opts_set_start_byte(burn_options, ms_block * 2048); - - if (burn_write_opts_auto_write_type(burn_options, target_disc, - reasons, 0) == BURN_WRITE_NONE) { - printf("Failed to find a suitable write mode:\n%s\n", reasons); - ret = 1; - goto exit_cleanup; - } - - /* ok, write the new track */ - burn_disc_write(burn_options, target_disc); - burn_write_opts_free(burn_options); - - while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) - usleep(1002); - - while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { - printf("Writing: sector %d of %d\n", progress.sector, progress.sectors); - sleep(1); - } - - } - - /* b. write the new vol desc */ - printf("Writing the new vol desc...\n"); - ret = burn_random_access_write(drive, 0, (char*)buf, 32*2048, 0); - if (ret != 1) { - printf("Ups, new vol desc write failed\n"); - } - - iso_image_unref(image); - -exit_cleanup:; - burn_drive_release(drives[0].drive, 0); - burn_finish(); - iso_finish(); - - exit(ret); -} - -static int -libburn_ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) -{ - struct burn_drive *d; - off_t data_count; - - d = (struct burn_drive*)src->data; - - if ( burn_read_data(d, (off_t) lba * (off_t) 2048, (char*)buffer, - 2048, &data_count, 0) < 0 ) { - return -1; /* error */ - } - - return 1; -} - -static -int libburn_ds_open(IsoDataSource *src) -{ - /* nothing to do, device is always opened */ - return 1; -} - -static -int libburn_ds_close(IsoDataSource *src) -{ - /* nothing to do, device is always opened */ - return 1; -} - -static void -libburn_ds_free_data(IsoDataSource *src) -{ - /* nothing to do */ -} - -static IsoDataSource * -libburn_data_source_new(struct burn_drive *d) -{ - IsoDataSource *ret; - - ret = malloc(sizeof(IsoDataSource)); - ret->version = 0; - ret->refcount = 1; - ret->read_block = libburn_ds_read_block; - ret->open = libburn_ds_open; - ret->close = libburn_ds_close; - ret->free_data = libburn_ds_free_data; - ret->data = d; - return ret; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_modify.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_modify.c deleted file mode 100644 index 85404ce4..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_modify.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Little program to show how to modify an iso image. - */ - -#include "libisofs.h" -#include "libburn/libburn.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -void usage(char **argv) -{ - printf("%s [OPTIONS] IMAGE DIRECTORY OUTPUT\n", argv[0]); -} - -int main(int argc, char **argv) -{ - int result; - IsoImage *image; - IsoDataSource *src; - struct burn_source *burn_src; - unsigned char buf[2048]; - FILE *fd; - IsoWriteOpts *opts; - IsoReadOpts *ropts; - - if (argc < 4) { - usage(argv); - return 1; - } - - fd = fopen(argv[3], "w"); - if (!fd) { - err(1, "error opening output file"); - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - - /* create the data source to accesss previous image */ - result = iso_data_source_new_from_file(argv[1], &src); - if (result < 0) { - printf ("Error creating data source\n"); - return 1; - } - - /* create the image context */ - result = iso_image_new("volume_id", &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - iso_tree_set_follow_symlinks(image, 0); - iso_tree_set_ignore_hidden(image, 0); - - /* import previous image */ - result = iso_read_opts_new(&ropts, 0); - if (result < 0) { - fprintf(stderr, "Error creating read options\n"); - return 1; - } - result = iso_image_import(image, src, ropts, NULL); - iso_read_opts_free(ropts); - iso_data_source_unref(src); - if (result < 0) { - printf ("Error importing previous session %d\n", result); - return 1; - } - - /* add new dir */ - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - /* generate a new image with both previous and added contents */ - result = iso_write_opts_new(&opts, 1); - if (result < 0) { - printf("Cant create write opts, error %d\n", result); - return 1; - } - /* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */ - - result = iso_image_create_burn_source(image, opts, &burn_src); - if (result < 0) { - printf ("Cant create image, error %d\n", result); - return 1; - } - - iso_write_opts_free(opts); - - while (burn_src->read_xt(burn_src, buf, 2048) == 2048) { - fwrite(buf, 1, 2048, fd); - } - fclose(fd); - burn_src->free_data(burn_src); - free(burn_src); - - iso_image_unref(image); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_ms.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_ms.c deleted file mode 100644 index 563c9d4d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_ms.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Little program to show how to create a multisession iso image. - */ - -#include "libisofs.h" -#include "libburn/libburn.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -void usage(char **argv) -{ - printf("%s LSS NWA DISC DIRECTORY OUTPUT\n", argv[0]); -} - -int main(int argc, char **argv) -{ - int result; - IsoImage *image; - IsoDataSource *src; - struct burn_source *burn_src; - unsigned char buf[2048]; - FILE *fd; - IsoWriteOpts *opts; - IsoReadOpts *ropts; - uint32_t ms_block; - - if (argc < 6) { - usage(argv); - return 1; - } - - fd = fopen(argv[5], "w"); - if (!fd) { - err(1, "error opening output file"); - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - - /* create the data source to accesss previous image */ - result = iso_data_source_new_from_file(argv[3], &src); - if (result < 0) { - printf ("Error creating data source\n"); - return 1; - } - - /* create the image context */ - result = iso_image_new("volume_id", &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - iso_tree_set_follow_symlinks(image, 0); - iso_tree_set_ignore_hidden(image, 0); - - /* import previous image */ - result = iso_read_opts_new(&ropts, 0); - if (result < 0) { - fprintf(stderr, "Error creating read options\n"); - return 1; - } - iso_read_opts_set_start_block(ropts, atoi(argv[1])); - result = iso_image_import(image, src, ropts, NULL); - iso_read_opts_free(ropts); - iso_data_source_unref(src); - if (result < 0) { - printf ("Error importing previous session %d\n", result); - return 1; - } - - /* add new dir */ - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - /* generate a multisession image with new contents */ - result = iso_write_opts_new(&opts, 1); - if (result < 0) { - printf("Cant create write opts, error %d\n", result); - return 1; - } - - /* round up to 32kb aligment = 16 block */ - ms_block = atoi(argv[2]); - iso_write_opts_set_ms_block(opts, ms_block); - iso_write_opts_set_appendable(opts, 1); - - result = iso_image_create_burn_source(image, opts, &burn_src); - if (result < 0) { - printf ("Cant create image, error %d\n", result); - return 1; - } - iso_write_opts_free(opts); - - while (burn_src->read_xt(burn_src, buf, 2048) == 2048) { - fwrite(buf, 1, 2048, fd); - } - fclose(fd); - burn_src->free_data(burn_src); - free(burn_src); - - iso_image_unref(image); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_read.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_read.c deleted file mode 100644 index de30717a..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/iso_read.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Little program to output the contents of an iso image. - */ - - -#include -#include -#include -#include - -#include "libisofs.h" - -static void -print_permissions(mode_t mode) -{ - char perm[10]; - - //TODO suid, sticky... - - perm[9] = '\0'; - perm[8] = mode & S_IXOTH ? 'x' : '-'; - perm[7] = mode & S_IWOTH ? 'w' : '-'; - perm[6] = mode & S_IROTH ? 'r' : '-'; - perm[5] = mode & S_IXGRP ? 'x' : '-'; - perm[4] = mode & S_IWGRP ? 'w' : '-'; - perm[3] = mode & S_IRGRP ? 'r' : '-'; - perm[2] = mode & S_IXUSR ? 'x' : '-'; - perm[1] = mode & S_IWUSR ? 'w' : '-'; - perm[0] = mode & S_IRUSR ? 'r' : '-'; - printf(" %s ",perm); -} - -static void -print_type(mode_t mode) -{ - switch(mode & S_IFMT) { - case S_IFSOCK: printf("[S] "); break; - case S_IFLNK: printf("[L] "); break; - case S_IFREG: printf("[R] "); break; - case S_IFBLK: printf("[B] "); break; - case S_IFDIR: printf("[D] "); break; - case S_IFIFO: printf("[F] "); break; - } -} - -static void -print_file_src(IsoFileSource *file) -{ - struct stat info; - char *name; - iso_file_source_lstat(file, &info); - print_type(info.st_mode); - print_permissions(info.st_mode); - //printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino); - name = iso_file_source_get_name(file); - printf(" %s", name); - free(name); - if (S_ISLNK(info.st_mode)) { - char buf[PATH_MAX]; - iso_file_source_readlink(file, buf, PATH_MAX); - printf(" -> %s\n", buf); - } - printf("\n"); -} - -static void -print_dir(IsoFileSource *dir, int level) -{ - int ret, i; - IsoFileSource *file; - struct stat info; - char *sp = alloca(level * 2 + 1); - - for (i = 0; i < level * 2; i += 2) { - sp[i] = '|'; - sp[i+1] = ' '; - } - - sp[level * 2-1] = '-'; - sp[level * 2] = '\0'; - - ret = iso_file_source_open(dir); - if (ret < 0) { - printf ("Can't open dir %d\n", ret); - } - while ((ret = iso_file_source_readdir(dir, &file)) == 1) { - printf("%s", sp); - print_file_src(file); - ret = iso_file_source_lstat(file, &info); - if (ret < 0) { - break; - } - if (S_ISDIR(info.st_mode)) { - print_dir(file, level + 1); - } - iso_file_source_unref(file); - } - iso_file_source_close(dir); - if (ret < 0) { - printf ("Can't print dir\n"); - } -} - -int main(int argc, char **argv) -{ - int result; - IsoImageFilesystem *fs; - IsoDataSource *src; - IsoFileSource *root; - IsoReadOpts *ropts; - - if (argc != 2) { - printf ("You need to specify a valid path\n"); - return 1; - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - - result = iso_data_source_new_from_file(argv[1], &src); - if (result < 0) { - printf ("Error creating data source\n"); - return 1; - } - - result = iso_read_opts_new(&ropts, 0); - if (result < 0) { - fprintf(stderr, "Error creating read options\n"); - return 1; - } - result = iso_image_filesystem_new(src, ropts, 1, &fs); - iso_read_opts_free(ropts); - if (result < 0) { - printf ("Error creating filesystem\n"); - return 1; - } - - printf("\nVOLUME INFORMATION\n"); - printf("==================\n\n"); - - printf("Vol. id: %s\n", iso_image_fs_get_volume_id(fs)); - printf("Publisher: %s\n", iso_image_fs_get_publisher_id(fs)); - printf("Data preparer: %s\n", iso_image_fs_get_data_preparer_id(fs)); - printf("System: %s\n", iso_image_fs_get_system_id(fs)); - printf("Application: %s\n", iso_image_fs_get_application_id(fs)); - printf("Copyright: %s\n", iso_image_fs_get_copyright_file_id(fs)); - printf("Abstract: %s\n", iso_image_fs_get_abstract_file_id(fs)); - printf("Biblio: %s\n", iso_image_fs_get_biblio_file_id(fs)); - - printf("\nDIRECTORY TREE\n"); - printf("==============\n"); - - result = fs->get_root(fs, &root); - if (result < 0) { - printf ("Can't get root %d\n", result); - return 1; - } - //print_file_src(root); - print_dir(root, 0); - iso_file_source_unref(root); - - fs->close(fs); - iso_filesystem_unref((IsoFilesystem*)fs); - iso_data_source_unref(src); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/lsl.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/lsl.c deleted file mode 100644 index 17659f75..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/lsl.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "fsource.h" - -#include -#include -#include - -/* - * Little test program to test filesystem implementations. - * - */ - -static void -print_permissions(mode_t mode) -{ - char perm[10]; - - //TODO suid, sticky... - - perm[9] = '\0'; - perm[8] = mode & S_IXOTH ? 'x' : '-'; - perm[7] = mode & S_IWOTH ? 'w' : '-'; - perm[6] = mode & S_IROTH ? 'r' : '-'; - perm[5] = mode & S_IXGRP ? 'x' : '-'; - perm[4] = mode & S_IWGRP ? 'w' : '-'; - perm[3] = mode & S_IRGRP ? 'r' : '-'; - perm[2] = mode & S_IXUSR ? 'x' : '-'; - perm[1] = mode & S_IWUSR ? 'w' : '-'; - perm[0] = mode & S_IRUSR ? 'r' : '-'; - printf(" %s ",perm); -} - -static void -print_type(mode_t mode) -{ - switch(mode & S_IFMT) { - case S_IFSOCK: printf("[S] "); break; - case S_IFLNK: printf("[L] "); break; - case S_IFREG: printf("[R] "); break; - case S_IFBLK: printf("[B] "); break; - case S_IFDIR: printf("[D] "); break; - case S_IFIFO: printf("[F] "); break; - } -} - -static void -print_file_src(IsoFileSource *file) -{ - struct stat info; - char *name; - iso_file_source_lstat(file, &info); - print_type(info.st_mode); - print_permissions(info.st_mode); - printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino); - name = iso_file_source_get_name(file); - printf(" %s", name); - free(name); - if (S_ISLNK(info.st_mode)) { - char buf[PATH_MAX]; - iso_file_source_readlink(file, buf, PATH_MAX); - printf(" -> %s\n", buf); - } - printf("\n"); -} - -int main(int argc, char **argv) -{ - int res; - IsoFilesystem *fs; - IsoFileSource *dir; - IsoFileSource *file; - struct stat info; - - if (argc != 2) { - fprintf(stderr, "Usage: lsl /path/to/file\n"); - return 1; - } - - /* create filesystem object */ - res = iso_local_filesystem_new(&fs); - if (res < 0) { - fprintf(stderr, "Can't get local fs object, err = %d\n", res); - return 1; - } - - res = fs->get_by_path(fs, argv[1], &dir); - if (res < 0) { - fprintf(stderr, "Can't get file, err = %d\n", res); - return 1; - } - - res = iso_file_source_lstat(dir, &info); - if (res < 0) { - fprintf(stderr, "Can't stat file, err = %d\n", res); - return 1; - } - - if (S_ISDIR(info.st_mode)) { - res = iso_file_source_open(dir); - if (res < 0) { - fprintf(stderr, "Can't open file, err = %d\n", res); - return 1; - } - - while (iso_file_source_readdir(dir, &file) == 1) { - print_file_src(file); - iso_file_source_unref(file); - } - - res = iso_file_source_close(dir); - if (res < 0) { - fprintf(stderr, "Can't close file, err = %d\n", res); - return 1; - } - } else { - print_file_src(dir); - } - - iso_file_source_unref(dir); - iso_filesystem_unref(fs); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/demo/tree.c b/libisofs/tags/ForXorrisoZeroOneTwo/demo/tree.c deleted file mode 100644 index 6dddbb99..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/demo/tree.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Little program that import a directory and prints the resulting iso tree. - */ - -#include "libisofs.h" -#include -#include -#include -#include -#include -#include - -static void -print_permissions(mode_t mode) -{ - char perm[10]; - - //TODO suid, sticky... - - perm[9] = '\0'; - perm[8] = mode & S_IXOTH ? 'x' : '-'; - perm[7] = mode & S_IWOTH ? 'w' : '-'; - perm[6] = mode & S_IROTH ? 'r' : '-'; - perm[5] = mode & S_IXGRP ? 'x' : '-'; - perm[4] = mode & S_IWGRP ? 'w' : '-'; - perm[3] = mode & S_IRGRP ? 'r' : '-'; - perm[2] = mode & S_IXUSR ? 'x' : '-'; - perm[1] = mode & S_IWUSR ? 'w' : '-'; - perm[0] = mode & S_IRUSR ? 'r' : '-'; - printf("[%s]",perm); -} - -static void -print_dir(IsoDir *dir, int level) -{ - int i; - IsoDirIter *iter; - IsoNode *node; - char *sp = alloca(level * 2 + 1); - - for (i = 0; i < level * 2; i += 2) { - sp[i] = '|'; - sp[i+1] = ' '; - } - - sp[level * 2-1] = '-'; - sp[level * 2] = '\0'; - - iso_dir_get_children(dir, &iter); - while (iso_dir_iter_next(iter, &node) == 1) { - - if (ISO_NODE_IS_DIR(node)) { - printf("%s+[D] ", sp); - print_permissions(iso_node_get_permissions(node)); - printf(" %s\n", iso_node_get_name(node)); - print_dir(ISO_DIR(node), level+1); - } else if (ISO_NODE_IS_FILE(node)) { - printf("%s-[F] ", sp); - print_permissions(iso_node_get_permissions(node)); - printf(" %s\n", iso_node_get_name(node) ); - } else if (ISO_NODE_IS_SYMLINK(node)) { - printf("%s-[L] ", sp); - print_permissions(iso_node_get_permissions(node)); - printf(" %s -> %s \n", iso_node_get_name(node), - iso_symlink_get_dest(ISO_SYMLINK(node)) ); - } else { - printf("%s-[C] ", sp); - print_permissions(iso_node_get_permissions(node)); - printf(" %s\n", iso_node_get_name(node) ); - } - } - iso_dir_iter_free(iter); -} - -int main(int argc, char **argv) -{ - int result; - IsoImage *image; - - if (argc != 2) { - printf ("You need to specify a valid path\n"); - return 1; - } - - iso_init(); - iso_set_msgs_severities("NEVER", "ALL", ""); - - result = iso_image_new("volume_id", &image); - if (result < 0) { - printf ("Error creating image\n"); - return 1; - } - - result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]); - if (result < 0) { - printf ("Error adding directory %d\n", result); - return 1; - } - - printf("================= IMAGE =================\n"); - print_dir(iso_image_get_root(image), 0); - printf("\n\n"); - - iso_image_unref(image); - iso_finish(); - return 0; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/Tutorial b/libisofs/tags/ForXorrisoZeroOneTwo/doc/Tutorial deleted file mode 100755 index 6de705bd..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/Tutorial +++ /dev/null @@ -1,506 +0,0 @@ -=============================================================================== - LIBISOFS DEVELOPMENT TUTORIAL -=============================================================================== - -Creation date: 2008-Jan-27 -Author: Vreixo Formoso -_______________________________________________________________________________ - -This is a little tutorial of how to use libisofs library for application -development. - -Contents: ---------- - -1. Introduction - 1.1 Library initialization - 1.2 Image context - 1.3 Error reporting -2. Creating an image - 2.1 Image tree manipulation - 2.2 Set the write options - 2.3 Obtaining a burn_source -3. Image growing and modification - 3.1 Growing vs Modification - 3.2 Image import - 3.3 Generating a new image -4. Bootable images -5. Advanced features - - -------------------------------------------------------------------------------- -1. Introduction -------------------------------------------------------------------------------- - -[TODO some lines about refcounts] - -------------------------------------------------------------------------------- -1.1. Library initialization - -Before any usage of the library, you have to call - - iso_init() - -in the same way, when you have finished using the library, you should call - - iso_finish() - -to free all resources reserved by the library. - -------------------------------------------------------------------------------- -1.2. Image context - -Libisofs is image-oriented, the core of libisofs usage is the IsoImage object. -Thus, the first you need to do is to get your own IsoImage object: - - IsoImage *my_image; - iso_image_new("NEW DISC", &my_image); - -An IsoImage is a context for image creation. It holds the files that will be -added to image, other related information and several options to customize -the behavior of libisofs when working with such Image. i.e., an IsoImage is -a context for libisofs operations. As such, you can work with several image -contexts at a time. - -------------------------------------------------------------------------------- -1.3. Error reporting - -In libisofs error reporting is done in two ways: with the return value of -the functions and with the message queue. - -Error codes are negative numbers, defined in "libisofs.h" header. An -error code is associated with a given severity, either "DEBUG", "UPDATE", -"NOTE", "HINT", "WARNING", "SORRY", "FAILURE" and "FATAL". For the meaning -of each severity take a look at private header "libiso_msgs.h". Errors -reported by function return value are always "FAILURE" or "FATAL". Other kind -of errors are only reported with the message queue. You can get the severity -of any error message with iso_error_get_severity() function. - -First of all, most libisofs functions return an integer. If such integer is -a negative number, it means the function has returned an error. The error code -and its severity is encoded in the return value (take a look at error codes in -libisofs.h header). - -Additionally, libisofs reports most of its errors in a message queue. Error -messages on that queue can be printed directly to stderr or programmatically -retrieved. First of all, you should set the severity threshold over which an -error is printed or enqueued, with function: - - iso_set_msgs_severities() - -Errors enqueued can be retrieved with function: - - iso_obtain_msgs() - -Together with the code error, a text message and its severity, this function -also returns the image id. This is an identifier that uniquely identifies a -given image context. You can get the identifier of each IsoImage with the - - iso_image_get_msg_id() - -and that way distinguish what image has issued the message. - - -------------------------------------------------------------------------------- -2. Creating an Image -------------------------------------------------------------------------------- - -An image is built from a set of files that you want to store together in an -ISO-9660 volume. We call the "iso tree" to the file hierarchy that will be -written to image. The image context, IsoImage, holds that tree, together with -configuration options and other properties of the image, that provide info -about the volume (such as the identifier, author, etc...). - -All configuration options and volume properties are set by its corresponding -setters (iso_image_set_volset_id(), iso_image_set_publisher_id()...) - -To create an image, you have to follow the following steps: - -* Obtain the image context. - See "1.2 Image context" for details of how to obtain the IsoImage. -* Set the desired properties -* Prepare the iso tree with the files you want to add to image. - See "2.1 Image tree manipulation" for details -* Select the options for image generation. - See "2.2 Set the write options" -* Get the burn_source used to actually write the image. - - -------------------------------------------------------------------------------- -2.1 Image tree manipulation - -libisofs maintains in memory a file tree (usually called the iso tree), that -represents the files and directories that will be written later to image. You -are allowed to make whatever changes you want to that tree, just like you do -to any "real" filesystem, before actually write it to image. - -Unlike other ISO-9660 mastering tools, you have full control over the file -hierarchy that will be written to image, via the libisofs API. You can add -new files, create any file in image, change its name, attributes, etc The iso -tree behaves just like any other POSIX filesystem. - -The root of the iso tree is created automatically when the IsoImage is -allocated, and you can't replace it. To get a reference to it you can use the -function: - - iso_image_get_root() - -* Iso tree objects - -Each file in the image or iso tree is represented by an IsoNode instance. In -the same way a POSIX filesystem has several file types (regular files, -directories, symlinks...), the IsoNode has several subtypes: - - IsoNode - | - --------------------------------- - | | | | - IsoDir IsoFile IsoSymlink IsoSpecial - -where - - - IsoDir represents a directory - - IsoFile represents a regular file - - IsoSymlink represents a symbolic linke - - IsoSpecial represents any other POSIX file, i.e. block and character - devices, FIFOs, sockets. - -You can obtain the concrete type of an IsoNode with the iso_node_get_type() -function. - -Many libisofs functions take or return an IsoNode. Many others, however, -require an specific type. You can safety cast any subtype to an IsoNode -object. In the same way, after ensuring you are dealing with the correct -subtype, you can downcast a given IsoNode to the specific subtype. - - IsoDir *dir; - IsoNode *node; - - node = (IsoNode*) dir; - - if (iso_node_get_type(node) == LIBISO_DIR) { - dir = (IsoDir*) node; - ... - } - -or with the provided macros: - - IsoDir *dir; - IsoNode *node; - - node = ISO_NODE(dir); - - if (ISO_NODE_IS_DIR(node)) { - dir = ISO_DIR(node); - ... - } - -* Adding files to the image - -Files can be added to the image or iso tree either as new files or as files -from the filesystem. - -In the first case, files are created directly on the image. They do not -correspond to any file in the filesystem. Provided functions are: - - - iso_tree_add_new_dir() - - iso_tree_add_new_symlink() - - iso_tree_add_new_special() - -On the other side, you can add local files to the image, either with the - - iso_tree_add_node() - -or with - - iso_tree_add_dir_rec(). - -The first is intended to add a single file, while the last can be used to add, -recursively, a full directory (see below for details). - -It is important to note that libisofs doesn't store any kind of link between -the IsoNode and the filesystem file it was created from. The above functions -just initialize a newly created IsoNode with the attributes of a given file in -the filesystem. After that, you can move the original file, change its -attributes or even delete it. The IsoNode in the image tree remains with the -original attributes. One exception to this rule are the contents of a regular -file. Libisofs does not make any copy of those contents until they're actually -written to image. Thus, you shouldn't modify, move or delete regular files -after adding them to the IsoImage. - - -* Recursive directory addition. - -One common use case is to add a local directory to the image. While this can -be done with iso_tree_add_node(), handling the addition of directory children -in the application, libisofs provides a function suitable for this case: - - iso_tree_add_dir_rec() - -that takes care of adding all files inside a directory, recursing on directory -children. By default, this function adds all children. However, it is usual -that you don't want really this. For example, you may want to exclude some -kind of files (backup files, application sockets,...). Libisofs provides -several functions to customize the behavior of that function: - - - iso_tree_set_follow_symlinks() - - iso_tree_set_ignore_hidden() - - iso_tree_set_ignore_special() - - iso_tree_add_exclude() - -* Operations on iso tree - -[TODO briefly explain how to add node, change attributes, ...] - -* Replace mode - -[TODO] - -------------------------------------------------------------------------------- -2.2 Set the write options - -Once you have prepared the iso tree, it is time to select the options for the -image writing. - -These options affect the characteristics of the filesystem to create in the -image, but also can control how libisofs generates the image. - -First of all you have to get an instance of IsoWriteOpts, with the function - - iso_write_opts_new() - -The several options available can be classified in: - -- Extensions to add to the ISO-9660 image: - - iso_write_opts_set_rockridge() - iso_write_opts_set_joliet() - iso_write_opts_set_iso1999() - -RockRidge is highly recommended, in fact you should use it in all image. Joliet -is needed if you want to use your images in Windows system. Nowadays, -ISO-9660:1999 is no much useful, so in most cases you don't want such -extension. - -- ISO-9660 options: - - iso_write_opts_set_iso_level() - iso_write_opts_set_omit_version_numbers() - iso_write_opts_set_allow_deep_paths() - iso_write_opts_set_allow_longer_paths() - iso_write_opts_set_max_37_char_filenames() - iso_write_opts_set_no_force_dots() - iso_write_opts_set_allow_lowercase() - iso_write_opts_set_allow_full_ascii() - -These control the options for the ISO-9660 filesystem. In most cases you won't -care about them, as it is the RockRidge or Joliet extensions what determine the -properties of the files once the image is mounted. - -- File attributes options - - iso_write_opts_set_replace_mode() - iso_write_opts_set_default_dir_mode() - iso_write_opts_set_default_file_mode() - iso_write_opts_set_default_uid() - iso_write_opts_set_default_gid() - iso_write_opts_set_replace_timestamps() - iso_write_opts_set_default_timestamp() - iso_write_opts_set_always_gmt() - -They allow to set default attributes for files in image, despite of the real -attributes of the file on the local filesystem. - -------------------------------------------------------------------------------- -2.3 Obtaining a burn_source - -Finally, you get the burn_source used to write the image with the function: - - iso_image_create_burn_source() - -The returned burn_source is suitable for using with libburn, to directly burn -the image to a disc. Alternatively, you can use burn_source read() to get -the image contents (for example, to write them to a file, pipe...). - -Before creating the burn_source, libisofs computes the size of the image, so -the get_size() function of the burn_source always returns the final image -size. It also starts a writing thread. All the operations needed to generate -the image are done by this thread, including read the original files contents. -The image is writing to a FIFO buffer, from which the burn_source will read. -The size of the buffer can be set in advanced with a property of the -IsoWriteOpts struct: - - iso_write_opts_set_fifo_size() - -You can get the state of the buffer in any moment, with the function: - - iso_ring_buffer_get_status() - -You can also cancel the writer thread at any time, with the cancel() function -of the burn_source. - - -------------------------------------------------------------------------------- -3. Image growing and modification -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -3.1 Growing vs Modification - -Libisofs is not restricted only to create new images. It can also be used to -modify existing images. It supports two kind of image modifications, that we -have called image growing and image modification: - -Image modification consists in generating a new image, based on the contents -of an existing image. In this mode, libisofs takes an image, the users modifies -its contents (adding new files, removing files, changing their names...), and -finally libisofs generates a completely new image. - -On the other side, image growing is similar, with the difference that the new -image is dependent on the other, i.e., it refers to files of the other image. -Thus, it can't be mounted without the old image. The purpose of this kind of -images is to increment or add files to a multisession disc. The new image only -contains the new files. Old files are just references to the old image blocks. - -The advantage of the growing approach is that the generated image is smaller, -as only the new files are written. This mode is suitable when you just want to -add some files to a very big image, or when dealing with write-once media, such -as CD-R. Both the time and space needed for the modification is much less than -with normal image modify. - -The main problem of growing is that the new image needs to be recorded together -with the old image, in order to be mountable. The total size of the image -(old + new) is bigger (even much bigger) than a completely new image. So, if -you plan to distribute an image on Internet, or burn it to a disc, generate a -completely new image is usually a better alternative. - -To be able to mount a grown image, the OS needs to now you have appended new -data to the original image. In multisession media (such as CD-R), the new data -is appended as a new session, so the OS can identify this and mount the image -propertly. However, when dealing with non-multisession media (such as DVD+RW) -or plain .iso files, the new data is just appended at the end of the old image, -and the OS has no way to know that the appended data is in fact a "new -session". The method introduced by Andy Polyakov in growisofs can be used in -those cases. It consists in overwrite the volume descriptors of the old image -with a new ones that refer to the newly appended contents. - -------------------------------------------------------------------------------- -3.2 Image import - -The first thing you need to do in order to modify or grow an image is to import -it, with the function: - - iso_image_import() - -It takes several arguments. - -First, the image context, an IsoImage previously obtained with iso_image_new(). -In most cases you will want to use an empty image. However, if you have already -added files to the image, they will be removed and replaced with the contents -of the image being imported. - -The second parameter is an IsoDataSource instance. It abstracts the original -image, and it is used by libisofs to access its contents. You are free to -implement your own data source to access image contents. However, libisofs has -a simple implementation suitable for reading images on the local filesystem, -that can be used for import both .iso files and inserted media, via the block -device and POSIX functions. You can get it with - - iso_data_source_new_from_file() - -The third parameter of iso_image_import() is a pointer to an IsoReadOpts -struct. It holds the options for image reading. You get it with: - - iso_read_opts_new() - -and after calling iso_image_import() you should free it with - - iso_read_opts_free() - -Some options are related to select what extensions to read. Default options -are suitable for most users. - - iso_read_opts_set_no_rockridge() - iso_read_opts_set_no_joliet() - iso_read_opts_set_no_iso1999() - iso_read_opts_set_preferjoliet() - -If RockRidge extensions are not present, many files attributes can't be -obtained. In those cases libisofs uses default values. You have options to -configure what default values to use. - - iso_read_opts_set_default_uid() - iso_read_opts_set_default_gid() - iso_read_opts_set_default_permissions() - -If the original image has been created in another system with a different -charset, you may want to use: - - iso_read_opts_set_input_charset() - -to specify the encoding of the file names on image. - -Finally, to import multisession images, you should tell libisofs that it must -read the last session. For that, you must set the block where the last session -starts: - - iso_read_opts_set_start_block() - -The last parameter for iso_image_import(), optional, is a pointer that will -be filled with a library-allocated IsoReadImageFeatures, that lets you access -some information about the image: size, extensions used,... - -[TODO: explain that iso_image_import uses dir rec options] - -------------------------------------------------------------------------------- -3.3 Generating a new image - -After importing the image, the old image tree gets loaded. You are free to -make any changes to it: add new files, remove files, change names or -attributes... Refer to "2.1 Image tree manipulation" for details. - -When it is ready, you can now create the new image. The process is the same as -explained in "2.2 Set the write options" and "2.3 Obtaining a burn_source". -However, there are some write options that should be taken into account. - -First of all, you must select whether you want to grow or modify the image -(read "3.1 Growing vs Modification" for details). You must call - - iso_write_opts_set_appendable() - -An appendable image leads to image growing, and a non-appendable image leads -to a completelly new image (modification). An appendable image will be appended -after the old image (in a new session, for example). Thus, in those cases, the -first block of the image is not 0. You should set the correct lba of the first -block with: - - iso_write_opts_set_ms_block() - -That is usually the "Next Writable Address" on a multisession media, and a -value slightly greater than the old image size on .iso files or DVD+RW media. -You can obtain the old image size with the iso_read_image_features_get_size() -function. - -In this last case (i.e., on a non multisession media), you will need to -overwrite the volume descriptors of the old image with the new ones. To do -this you need: - -- Allocate a buffer of at least 64 KiBs. -- Initialize it with the first 64 KiBs of the original image. -- Pass the buffer to libisofs with the iso_write_opts_set_overwrite_buf() - option. -- After appending the new image, you have to overwrite the first 64 KiBs of - the original image with the new content of the buffer. - - -------------------------------------------------------------------------------- -4. Bootable images -------------------------------------------------------------------------------- - - - -------------------------------------------------------------------------------- -5. Advanced features -------------------------------------------------------------------------------- - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/Wiki b/libisofs/tags/ForXorrisoZeroOneTwo/doc/Wiki deleted file mode 100755 index c9f6f8e1..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/Wiki +++ /dev/null @@ -1,32 +0,0 @@ -= libisofs = - -libisofs is a library to create an ISO-9660 filesystem, and supports extensions like RockRidge and Joliet. It is also a full featured ISO-9660 editor, allowing you to modify an ISO image or multisession disc, including file addition/removal, change of file names and attributes, and similar. - -The old libisofs.so.5 has been declarated deprecated and frozen, leaving it unmaintained. A full refactoring of the design has been done during the last months, and the next generation libisofs.so.6 of the library will be released in the following days. - -== Source Code == - -The code is maintained in a [http://bazaar-vcs.org/ Bazaar] repository at Launchpad (https://launchpad.net/libisofs/). You can download it with: - -{{{ -$ bzr branch lp:libisofs -}}} - - -To report any bug or suggest enchantments, [http://libburnia-project.org/register register] yourself and submit a new ticket. Bug and enchantments reports for nglibisofs can be found at http://libburnia-project.org/report/9. - -== Usage tutorial == - -Coming soon... For now check [http://codebrowse.launchpad.net/~mario-danic/libisofs/mainline/annotate/metalpain2002%40yahoo.es-20080201154704-xqyzc57vki97iv3y?file_id=tutorial-20080127170757-cwmomu7oz9eh7fcz-1 "doc/Tutorial"] in the source tree. - - -=== Applications === - -Comming soon: - -[http://libburnia-project.org/browser/libisoburn/trunk libisoburn]: - emulates ISO 9660 multi-session on overwriteable media, coordinates libisofs and libburn. - -[http://libburnia-project.org/browser/libisoburn/trunk/xorriso/xorriso_eng.html?format=raw xorriso]: - creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/1. Overview b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/1. Overview deleted file mode 100644 index e69de29b..00000000 diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/2. Features b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/2. Features deleted file mode 100644 index 89501e38..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/2. Features +++ /dev/null @@ -1,193 +0,0 @@ -FEATURES -======== - -Contents: - -2.0 Operations on image tree -2.1 ECMA-119 -2.2 Rock Ridge -2.3 Joliet -2.4 El-Torito -2.5 UDF -2.6 HFS/HFS+ -2.7 Others - - -=============================================================================== - -2.0 Operations on image tree ------------------------------ - -Basic: - - We HAVE TO Support addition of directories - - From filesystem - - From filesystem recursively - - New on image - - We HAVE TO support addition of files - - From local filesystem - - From previous/ms images - - We HAVE TO support addition of other POSIX file types - - From filesystem - - New on image - - Types: symlinks, block/char devices, fifos, sockets... - - We HAVE TO support modification of file names on image - - We HAVE TO support modification of POSIX attributes: - - Uid/Gid - - Permissions (we DON'T HAVE TO support full mode modification, - as we don't want a dir to be changed to a reg file!!) - - Timestamps - - We HAVE TO support deletion of nodes. - - We HAVE TO support iteration of directory tree. - - We WANT TO support direct getting (without iteration) of the number of - nodes in a directory. - -Extras: - - We WANT TO support on-the-fly modification of file contents, to - allow things like compression and encryption. - -Notes: many operations will need RR extensions to be actually reflected on -the image. - -=============================================================================== - -2.1 ECMA-119 ------------- - -Support for ECMA-119 (ISO-9660) specification. - -2.1.1 Creation --------------- - -We HAVE TO support creation of new images. - - General: - - We HAVE TO support single volume images - - We DON'T NEED TO support multiple volume images. - It seems multiple volume images are not used. - - We HAVE TO support bootable volumes (see 2.4 in this doc) - Conformance: - - We HAVE TO support Level 1 restrictions (ECMA-119 10.1) - - We HAVE TO support Level 2 restrictions (ECMA-119 10.2) - Single Section files have a theoric size limit of 4GB (data length - is a 32-bit number, see ECMA-119 9.1.4). However I think I have - read that only files up to 2GB are supported. - - We MAY support full Level 3 (ECMA-119 10.3) - Multiple file sections are useful to support files higher than - level 2 limit. However, it seems it's a feature not supported in - most O.S. nowadays, so it's not very useful. - - We DON'T WANT TO support files recording in interleaved mode - (ECMA-119 6.4.3) - It seems a feature that it's not used. - - We DON'T WANT TO support associated files (ECMA-119 6.5.4) - What is that? Is it used? - - We DON'T WANT TO support Volume Partitions (ECMA-119 8.6) - What is that? Is it used? - - We DON'T WANT TO support extended attribute records (ECMA-119 9.5) - It seems an unused feature. RR is a better alternative. - - We DON'T NEED TO support file versions other than 1. - Restrictions: - - We HAVE TO provide a way to relax iso restrictions related to - filenames, allowing: - - Higher filename length, up to 37 chars (ECMA-119 7.5.1/7.6.3) - - Omit version number (ECMA-119 7.5.1) - - Directory hierarchy deeper than 8 levels / 255 path length - (ECMA-119 6.8.2.1) - - More characters in filenames, not only d-characters - - -2.2.2 Reading -------------- - - General - - We HAVE TO support the reading of iso images - - We DON'T NEED TO support reading of features we don't support in - creation (see 2.2.1 above) - - We HAVE TO support reading arbitray file contents inside image - -2.2.3 Modification/growing --------------------------- - - General - - We HAVE TO support creation of new images from the contents of - an existing image - - We HAVE TO support multissession images - - We HAVE TO support growing of images - -=============================================================================== - -2.2 Rock Ridge --------------- - -- We HAVE TO support ALL Rock Ridge features, with these exceptions: - - We DON'T NEED TO support SF System User Entry (RRIP 4.1.7), used to - encode sparse files. - - We MIGHT support BACKUP timestamp (RRIP 4.1.6) -- We HAVE TO support any charset in RR filenames, and not only POSIX portable - filename character set (RRIP 3.4.1). Namely, UTF-8 SHOULD BE the default for - RR filenames. -- We MIGHT support Linux specific ZF extension, to allow transparent - compression. - -=============================================================================== - -2.3 Joliet ----------- - -- We HAVE TO support ALL Joliet features, with these exceptions: - - We DON'T KNOW what to do with UCS-2 conformance level 1 and 2 (scape - sequences '%\@' and '%\C'). What's this??????? - - We DON'T KNOW what to do with CD-XA extensions. - - -=============================================================================== - -2.4 El-Torito -------------- - -- We HAVE TO El-Torito standard with a single boot image. -- We MAY support multiple boot images and boot entry selection. - - El Torito standard is not very clear about how to do that. -- We HAVE TO support both emulation and not emulation mode. -- We HAVE TO support 80x86 platform. We MAY support Power PC and Mac platforms. -- We HAVE TO provide improved support for isolinux boot images, namely patching - features. -- We HAVE TO support El-Torito in ms images. - - -=============================================================================== - -2.5 UDF -------- - - - -=============================================================================== - -2.6 HFS/HFS+ ------------- - - - - - -=============================================================================== - -2.7 Others ----------- - -- We HAVE TO support sorting of file contents on image -- We HAVE TO support inode caching to prevent the same file to be written - several times into the image -- We DON'T NEED TO support TRANS.TBL files -- We DON'T NEED TO support padding of images - - Padding should be part of the burning process - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/3. Use Cases b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/3. Use Cases deleted file mode 100644 index e6e17f0f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/3. Use Cases +++ /dev/null @@ -1,193 +0,0 @@ -USE CASES FOR NG LIBISOFS -========================= - -3.1 General Operations -====================== - -3.1.1 Creation of a new image ------------------------------ - -Desc: Creation of a new ISO image from files on the local filesystem -Phases: - - User creates a new image context - - User get the root (empty) of the image - - User adds files to the image root (see 3.2.) - - User sets the options for the the new image (extension to use...) - - User gets a burn_source to write the image. - - The burn_source can be used by libburn to write the new image. - -3.1.2 Image growing (multisession) ----------------------------------- - -Desc: An existing image can be grown with new files. New content is added - incrementally. Suitable for multisession. Growing support for - overwritteable media. -Phases: - - Uses reads an existing image to get the image context. - - User get the root of the image - - User modifies the image tree (see 3.2.) - - User sets the options for the the new image (extension to use...) - A required option will be the nwa for the image. - Optionally it can pass a pointer to a 64K buffer, that will be filled - with suitable volume descriptors to be used with overwrieable media. - - User gets a burn_source to write the image. - - The burn_source can be used by libburn to write an image that should be - appended to the previous image. - - -3.1.3 Image modification ------------------------- - -Desc: Creation of a new image from the contents of a previous image. -Phases: - - Uses reads an existing image to get the image context. - - User get the root of the image - - User modifies the image tree (see 3.2.) - - User sets the options for the the new image (extension to use...) - - User gets a burn_source to write the image. - - The burn_source can be used by libburn to write the image to another - device or file. - -3.2 Tree operations -=================== - -3.2.1 Addition of contents --------------------------- - - All addition operations take a parent dir. The functions check that the - node name is unique among all children. Image context options determine - what to do if a file with such name already exist. - - 3.2.1.1 Directories - -------------------- - - Creation of new directories in image, given a parent dir. and a name. - Attributes are initialized to default values - - Addition of a dir from the filesystem, given a parent. - Dir contents are not added. Name and other attributes taken from - the dir on filesystem - - Recursive addition of a dir, given a parent. Directory contents are - recursivelly added to image. - - 3.2.1.2 Regular files - ---------------------- - - Addition of a local filesystem file. Name, attributes and contents to - be written taken from the filesystem file. - - Addition of files from the previous image. Files are automatically - added to the tree when the image is read. Name and attrbs taken from - previous image. When the image has no RR extensions, unavailable atts - are initialized to default values. The contents are only written to - img if we choose image modification. - - Addition of filtered files. Name and atts taken from the local - filesystem. A filter (see 3.3) is applied to the file contents before - written to image. - - Addition of splitted files. Like local filesystem files, but the file - is splitted in several files on a given size. Suitable for big (> 2GB) - files. Name of the splitted files automatically generated. - - 3.2.1.3 Symbolic links - ---------------------- - - Simbolic links are only written to image if RR extensions are enabled. - - - Addition of a simbolic link from local filesystem. Name, atts and - dest of a path are taken from the simbolic link. - - Addition of new link on image to a path. Name and dest specified, - the destination is specified as a path. Attributes initialized to - default values. - - Addition of new link on image to another node. Name and dest - specified, the dest is set to a node previously added to image. - When written, the destination path is computed as the relative path - from the link to the destination node. Attributes initialized to - default values. - - 3.2.1.4 Special files (block devices, fifos...) - ----------------------------------------------- - - Special files are only written to image if RR extensions are enabled. - - - Addition of special files from filesystem. - - Creation of new special files on image. - - -3.2.2 Modification of contents ------------------------------- - - 3.2.2.1 Deletion of nodes - ------------------------- - - - Any node can be deleted. When a dir is remove, all its contents - are also removed. - - 3.2.2.2 Move - ------------ - - - Any node can be move to another dir.. - - 3.2.2.3 Rename - -------------- - - - You can change the name of any node - - 3.2.2.4 Change of POSIX attributes - ---------------------------------- - - - Following POSIX atts can be changed: owner (uid/gid), permissions, - timestamps. - -3.2.3 Bootable information --------------------------- - - - Addition of a boot image to a volume. - - In most cases, the catalog and the boot image itself is added to the - iso tree. - - Alternatively, user can select to add a hidden images, i.e., images - that don't appear in the iso tree. - - Modification of boot image attributes: - - bootable flag - - load segment - - load size - - Automatic patching of isolinux images. User needs to set whether to apply - this. - - Reading of El-Torito info from multisession images. Modification of its - attributes. - - Removing of El-Torito images - - -3.2.4 Other operations ----------------------- - - 3.2.4.1 Set file sort weight - ----------------------------- - - - Any file can have a sort weight, that will determine the order in - which the files are written to image - - 3.2.4.2 Hidding of nodes - ------------------------ - - - Files can be hidden in the RR or Joliet tree - - -3.3 Filters -=========== - - [TODO] - - Support for: - - compression filter - - encryption filter - - external process filter - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/4. Design b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/4. Design deleted file mode 100644 index e69de29b..00000000 diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/5. Implementation b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/5. Implementation deleted file mode 100644 index e69de29b..00000000 diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/README b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/README deleted file mode 100644 index 75face44..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/README +++ /dev/null @@ -1,7 +0,0 @@ -Index -===== - -1. Overview -2. Features -3. Design -4. Implementation diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.png deleted file mode 100644 index a89203ee903b9abd36879bfe0d099c7f7d5f48eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25202 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 Wyv4nr=4OT5*VQsOUwGE>*8c&|P(C&Q diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.violet deleted file mode 100644 index c7e7fbf5..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/BuilderSec.violet +++ /dev/null @@ -1,821 +0,0 @@ - - - - - - - - fs:Filesystem - - - - - - 160.0 - 73.0 - - - - - - - - - - file:FileSource - - - - - - - - - - - 192.0 - 209.0 - - - - - - - - 274.0 - 202.0 - - - - - - - - User - - - - - - 34.86475730998367 - 0.0 - - - - - - - - - - - - - b:TNBuilder - - - - - - - - - - - - - - - - - - - - - - - ftn:FileTN - - - - - - - - - - - - - - - - fs:FileStream - - - - - - - - - - - - - - - - - - - - - d:DirTreeNode - - - - - - - - - - - - - - - - - - - - 66.86475730998367 - 80.0 - - - - - - - - 539.756828460011 - 126.0 - - - - - - - - 651.0 - 0.0 - - - - - - - - 683.0 - 305.0 - - - - - - - - 571.756828460011 - 328.0 - - - - - - - - 306.0 - 351.0 - - - - - - - - 331.97135964975513 - 374.0 - - - - - - - - 363.97135964975513 - 457.0 - - - - - - - - 418.8259109283281 - 480.0 - - - - - - - - 363.97135964975513 - 563.0 - - - - - - - - 1. User wants to add a file to a dir in the iso node - - - - - - 143.89406091532933 - 16.868736840587744 - - - - - - - - 2. It creates the source filesystem and the - custom builder - - - - - - 317.51829970572646 - 74.92004824517142 - - - - - - - - 570.819415201306 - 142.7048538003265 - 0.0 - 0.0 - - - - - - - - - 570.819415201306 - 142.7048538003265 - - - - - - - - 218.81410916050066 - 114.16388304026121 - 0.0 - 0.0 - - - - - - - - - 218.81410916050066 - 114.16388304026121 - - - - - - - - 3. It gets the file from the filesystem -and add it to parent dir - - - - - - 379.1320632384976 - 217.4323774110454 - - - - - - - - 327.03195662574825 - 218.46075295682857 - 0.0 - 0.0 - - - - - - - - - 327.03195662574825 - 218.46075295682857 - - - - - - - - 4. The dir delegates in the builder. -5. The builder stat's the source file. In - this example it's a reg. file - - - - - - 767.038589176755 - 206.92203801047344 - - - - - - - - 694.4969551615891 - 312.7614712457156 - 0.0 - 0.0 - - - - - - - - - 694.4969551615891 - 312.7614712457156 - - - - - - - - 314.9148790283507 - 359.23720542189034 - 0.0 - 0.0 - - - - - - - - - 314.9148790283507 - 359.23720542189034 - - - - - - - - 6. The conversion is not needed, so -the builder just creates a FileTreeNode - - - - - - 762.2817607167442 - 335.3564064307673 - - - - - - - - 522.2869299335649 - 399.9594286575042 - 0.0 - 0.0 - - - - - - - - - 522.2869299335649 - 399.9594286575042 - - - - - - - - 7. Sets the attributes from source - - - - - - 774.1738318667714 - 413.8440760209469 - - - - - - - - 8 ...and a FileStream to read contents - from the FileSource - - - - - - 762.2817607167442 - 478.0612602310938 - - - - - - - - 534.9181953038541 - 453.1845675071054 - 0.0 - 0.0 - - - - - - - - - 534.9181953038541 - 453.1845675071054 - - - - - - - - 482.368075796364 - 524.8261757327898 - 0.0 - 0.0 - - - - - - - - - 482.368075796364 - 524.8261757327898 - - - - - - - - 9. Finally, the FileTreeNode is added to - the parent dir, and returned to the user - - - - - - 757.5249322567332 - 556.5489298212734 - - - - - - - - 689.7401267015781 - 614.8200784564067 - 0.0 - 0.0 - - - - - - - - - 689.7401267015781 - 614.8200784564067 - - - - - - - - 363.97135964975513 - 656.0 - - - - - - - - 10. The user can change any attribute - on the FileTreeNode - - - - - - 735.3910524340093 - 659.0235200658623 - - - - - - - - 373.3523804664971 - 666.0945878777277 - 0.0 - 0.0 - - - - - - - - - 373.3523804664971 - 666.0945878777277 - - - - - - - «create» - - - - - - - - - «create» - - - - - - - - - - - - file - - - - - - - - - add_file(file,b) - - - - - - - - - create_file(file) - - - - - - - - - lstat() - - - - - - - - - S_IFREG - - - - - - - - - «create» - - - - - - - - - set attributes - - - - - - - - - - - - - - - - - ftn - - - - - - - - - «create» - - - - - - - - - set stream (fs) - - - - - - - - - - - - - - - - - ftn - - - - - - - - - «create» - - - - - - - - - get(path) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set_permission() - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet deleted file mode 100644 index 3dba303d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet +++ /dev/null @@ -1,884 +0,0 @@ - - - - - - - - get_root() -get_from_path(char *) - - - - - «interface» -Filesystem - - - - - - 159.04005306497305 - 489.4913761627291 - - - - - - - - MountedFilesytem - - - - - - 56.38849919058573 - 630.9884605487425 - - - - - - - - IsoImage - - - - - - 258.8562868808994 - 766.3563832139356 - - - - - - - - lstat() -read() -close() -open() -readdir() - - - - - «interface» -SourceFile - - - - - - 481.55979910778467 - 464.84194569982117 - - - - - - - - TarFile - - - - - - 176.58261638364775 - 701.0593878047844 - - - - - - - - read() -size() -open() -close() - - - - - «interface» -Stream - - - - - - 779.894860994415 - 340.36024540554786 - - - - - - - - FdStream - - - - - - 907.9433913981195 - 505.6600343909271 - - - - - - - - FileStream - - - - - - 646.2536512193697 - 514.5953286599063 - - - - - - - - TransformStream - - - - - - 774.6238447615127 - 513.9203093177954 - - - - - - - - create_file() -create_symlink() -create_dir() - - - - - «interface» -TreeNodeBuilder - - - - - - 469.51180397870456 - 119.92057094444797 - - - - - - - - TreeNode - - - - - - 777.5164467644091 - 137.7586776694888 - - - - - - - - File - - - - - - 776.3272396494064 - 235.11044131455145 - - - - - - - - Dir - - - - - - 899.7797731623193 - 242.40651557378732 - - - - - - - - Symlink - - - - - - 658.5957352641371 - 237.4888555445569 - - - - - - - - «interface» -FileBuilder - - - - - - 68.74900622278733 - 236.29964842955417 - - - - - - - - «interface» -DirBuilder - - - - - - 190.04813195306485 - 236.2996484295542 - - - - - - - - «interface» -SymlinkBuilder - - - - - - 304.21201499332614 - 236.29964842955417 - - - - - - - - POSIX inspired interface to files on different filesystems. -open/close act as a opendir/closedir if the file is a dir, -I think we don't need different function to open a dir. - - - - - - 154.8805850420814 - 333.9382491299707 - - - - - - - - "Sources" for file contents - - - - - - 587.0127806828101 - 358.755499461917 - - - - - - - - CutOutStream - - - - - - 845.6997102991108 - 605.2834046956852 - - - - - - - - FilterStream - - - - - - 721.2489168102784 - 605.2834046956852 - - - - - - - - «interface» -Filter - - - - - - 715.5920625607861 - 705.6925676241749 - - - - - - - - Used for arbitray streams, not related to -filesystem high-level idea. Also used for -files like fifos, that can't be added directly as -regulat files via de Builder, because its size is -unknown. The need to be added as new_files -on image - - - - - - 906.5108934811542 - 328.0975464705584 - - - - - - - - Create the user-specified TreeNode from the -user-specified source. If the source type differs the -TreeNode type the use wants to create, it makes -the needed conversion, if possible. Each builder -implementation can do different conversions. - - - - - - 654.7808793787427 - 20.610173055266337 - - - - - - - - Together with the SourceFile encapsulates the -access to a given filesystem and abstracts it to -a POSIX interface. - - - - - - 20.610173055266422 - 403.050865276332 - - - - - - - - The TreeNodeBuilder can be created with -the combination of different interfaces for -each factory method - - - - - - 149.90663761154804 - 57.982756057296896 - - - - - - - - MountedSrc - - - - - - 373.3523804664971 - 634.9818895055197 - - - - - - - - TarSrc - - - - - - 479.4183976444791 - 695.7930726875627 - - - - - - - - IsoSrc - - - - - - 578.4133470105959 - 773.574818618083 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{create}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/builder.violet.png deleted file mode 100644 index 6884fe9ab24b1af2531453fae6ce2c58e52402a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34098 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
oOVz;_72ai1A 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 - - - - - - - - - «interface» -BurnSource - - - - - - libburn - - - - - 600.0 - 50.0 - - - - - - - - 612.4370214406964 - 81.3237865499184 - - - - - - - - Ecma119Source - - - - - - 604.1172144213822 - 242.59825146055505 - - - - - - - - WriterState - - - - - - 861.1034292438676 - 244.31119796826698 - - - - - - - - FilesWriterSt - - - - - - 984.2531292100068 - 359.95094883087904 - - - - - - - - VolDescWriterSt - - - - - - 717.2457054234224 - 357.4185959653686 - - - - - - - - DirInfoWriterSt - - - - - - 854.6043620021998 - 355.85097462036043 - - - - - - - - Ecma119Image - - - - - - 392.3294860655768 - 240.39714472372754 - - - - - - - - The context data for image burn sources, contains -references to the tree, creation options... - - - - - - 261.45257180386454 - 85.80450046553075 - - - - - - - - Ecma119Node - - - - - - 291.8219414851778 - 612.806815288254 - - - - - - - - init() -write_voldesc() -write_dir_info() - - - - - «interface» -ImageWriter - - - - - - 401.9520048709197 - 344.8700633507891 - - - - - - - - JolietNode - - - - - - 409.0872475609359 - 614.8200784564067 - - - - - - - - FileRegistry - - - - - - 718.2810974616434 - 459.0339463910502 - - - - - - - - Ecma119Writer - - - - - - 273.51763645062584 - 489.95333138112096 - - - - - - - - JolietWriter - - - - - - 404.3304191009253 - 485.1965029211101 - - - - - - - - ElToritoWriter - - - - - - 512.5482665661723 - 485.19650292111 - - - - - - - - size : off_t -block : uint32_t - - - - - IsoFile - - - - - - 720.659511691649 - 568.4410009713001 - - - - - - - - «interface» -Stream - - - - - - 909.7434429770816 - 580.3330721213274 - - - - - - - - ImageWriter goal is to encapsulate the output -of image blocks related to one "specification", -i.e. we will have an implementation for ECMA-119/RR, -other for Joliet... - -Note that having different implementations for things that -need to be written in the same block has no utility, i.e. RR -and ECMA-119 must share its Writer implementation. - -Note also that while this provides considerable encapsulation -the provided abstraction is really partial: In the relation -with WriterState the encapsulation is quite good, each -concrete state know what method to call here (notice that -this interface is also quite coupled with state). However, -with respect to Ecma119Image the abstration only refers -to implementation, as the Ecma119Image needs to know -about the ImageWriter implementations. This can't be -avoided, as Ecma119Image has to be responsible of the -instantation in the correct order and following the user -needs. - - - - - - - - 2.3784142300054896 - 160.54296052536733 - - - - - - - - The files are registered into the file registry, that will take care -about the written of content. - - - - - - 286.59891471565567 - 708.7674405416217 - - - - - - - - Each state will invoque property method in each of -the ImageWriters. Some writers can return without -outputting anything. It is possible that when dealing -with UDF or other specification we would need new -states and methods in ImageWriter - - - - - - 765.8493820617523 - 132.001989765302 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/burn_source.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/burn_source.png deleted file mode 100644 index 5786ab29cc075491d6ee6f819d4624c1dede6ca2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35652 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 VL!|wOR^VH}q$T9UbDrwG{XaLw+CcyS diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet deleted file mode 100644 index b8a7d01c..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet +++ /dev/null @@ -1,552 +0,0 @@ - - - - - - - - Volume - - - - - - 479.2699858975891 - 226.94112549695433 - - - - - - - - block : uint32_t - - - - - ElToritoCatalog - - - - - - 472.58578643762684 - 344.73506473629425 - - - - - - - - bootable : bool -type : enum -partition_type : enum -load_seg : uint16 -load_size : uint16 -patch_isolinux : bool -block: uint32_t - - - - - BootImage - - - - - - 470.4142135623731 - 487.3919189857866 - - - - - - - - In a future we can support several boot -images - - - - - - 251.63542622468316 - 429.69343417595167 - - - - - - - - img : boolean - - - - - BootNode - - - - - - 193.07106781186545 - 334.49242404917493 - - - - - - - - - - TreeNode - - - - - - iso_tree - - - - - 180.0 - 40.0 - - - - - - - - 193.0 - 69.0 - - - - - - - - The img field is an implementation detail, used -to distinguish between the catalog node and the image -node. This is needed when the image is written. - - - - - - 57.81118318204312 - 584.0458146424488 - - - - - - - - The support for growing or modify El-Torito images -is really hard to implement. The reason: when the -image is hidden, we don't know its size, so the best we -can do is just refer to the old image. When modify, all -we can do may be wrong. - - - - - - 748.978906441031 - 574.8973495522459 - - - - - - - - The block in both Catalog and BootImage is needed -for multissession images - - - - - - 629.3242465083424 - 441.1316647878586 - - - - - - - - File - - - - - - 188.09040379562163 - 172.5340546095176 - - - - - - - - CatalogStream - - - - - - 851.105100475371 - 283.5127233261827 - - - - - - - - FileStream - - - - - - 743.4055403867466 - 284.4253525880894 - - - - - - - - TransformStream - - - - - - 958.5987801403015 - 279.8322618091961 - - - - - - - - «interface» -Stream - - - - - - 847.6728065449973 - 157.05765855361264 - - - - - - - - IsoLinuxPatch - - - - - - 968.73629022557 - 384.6660889654818 - - - - - - - - Generates the content of the catalog on-the-fly - - - - - - 517.6021638285529 - 107.48023074035522 - - - - - - - - To apply the needed patch to isolinux -images - - - - - - 923.4814562296309 - 509.1168824543143 - - - - - - - - - - - - - 1 image - - - - - - - - - - - - - - - - - - - - - - - 0..1 boot_cat - - - - - - - - - - - - - - - 0..1 node - - - - - - - - - - - - - - - - - - - - 0..1 node - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/eltorito.violet.png deleted file mode 100644 index adc195c25ed2dab2a308a7c84e068f0b5ba26ee5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24861 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 diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet deleted file mode 100644 index a3fa2268..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet +++ /dev/null @@ -1,748 +0,0 @@ - - - - - - - - volume_id : char* -publisher_id : char* -data_preparer_id : char* -system_id : char* -application_id : char* -copyright_file_id : char* -abstract_file_id : char* -biblio_file_id : char* - - - - - Volume - - - - - - 1160.4799402311673 - 240.649943764645 - - - - - - - - sort_weight : int -block : uint32_t - - - - - File - - - - - - 687.5479565719912 - 269.2931470368318 - - - - - - - - name : char * -attribs : struct stat -hidden : enum - - - - - TreeNode - - - - - - 706.83671056434 - 108.4726745515399 - - - - - - - - add(XXX) -remove(Node) -children() - - - - - Directory - - - - - - 986.1687535943008 - 267.29314703683184 - - - - - - - - dest : char* - - - - - Symlink - - - - - - 571.9364350336367 - 273.31078127658077 - - - - - - - - Special - - - - - - 813.0651280884073 - 272.20749521231266 - - - - - - - - name : char* - - - - - <<static>>new(id) -<<static>>read(src, opts) -create() -grow() - - - - - Image - - - - - - 1149.1980515339465 - 455.5218613006981 - - - - - - - - In addition to the dest as a path, it could -be a good idea to have a ref to tree node. -That way we can compute the dest on creation -time, and thus links to files on image are also valid -after moving or renaming those files - - - - - - 322.02220861890066 - 362.2044136147912 - - - - - - - - Image is a context for the creation of images. Its "static" -methods, new() and read() are used to create a new -image context, either from scratch or from an existing -image (for example, a ms disc). The methods create() and -grow() return an BurnSource suitable for libburn. -create() writes a full image, grow() only add to the image -the new files, thus it is suitable for a new session - - - - - - - 1212.7956394939486 - 697.0920982847697 - - - - - - - - Ecma119Source - - - - - - 1423.5617211564486 - 483.61244144432396 - - - - - - - - - - «interface» -BurnSource - - - - - - Libburn - - - - - 1420.0 - 280.0 - - - - - - - - 1431.4906533445824 - 311.35760744838467 - - - - - - - - Class diagram for the public tree. Note that getters and setters are not shown, -to improve readability. Note also that not all the attributes will have public getters -or/and setters. -El-Torito related information is shown in another diagram. -We don't show the several functions in Dir to manage the tree. - - - - - - 290.59037712396525 - 9.859316379054544 - - - - - - - - «interface» -DataSource - - - - - - 1192.781692587207 - 608.8954677283948 - - - - - - - - - - «interface» -Filters - - - - - - filters - - - - - 260.0 - 710.0 - - - - - - - - 265.45434264405947 - 743.9994422711634 - - - - - - - - TransformStream - - - - - - 486.9335577265969 - 640.636302316303 - - - - - - - - CutOutStream - - - - - - 555.9916340674516 - 750.220757440409 - - - - - - - - get_size() -read() -open() -close() -is_repeatable() - - - - - «interface» -Stream - - - - - - 688.5487814157467 - 437.25152600545294 - - - - - - - - FdStream - - - - - - 680.6673668471356 - 637.245696021424 - - - - - - - - FileStream - - - - - - 828.9404615480411 - 642.40096597045 - - - - - - - - FilteredStream - - - - - - 428.449880813367 - 747.5389646099015 - - - - - - - - «interface» -SourceFile - - - - - - 1000.6667341519202 - 639.0812755928229 - - - - - - - - For files, we need to know whethe they come -from a previous session. That's the purpose of -the block field - - - - - - 818.829652614022 - 414.36457377531684 - - - - - - - - - - - - - 1 volume - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {create} - - - - - - - - - - - - 0..1 - - - - - - - - - - - - - - - - - - * children - - - - - - - - - - - - - - - - - - 1 root - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 parent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 src - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/iso_tree.violet.png deleted file mode 100644 index d445b4fe0232237f34f353ecb3015f3e60866161..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38189 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 diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/nglibisofs.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/nglibisofs.violet deleted file mode 100644 index fd6a247f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/nglibisofs.violet +++ /dev/null @@ -1,1059 +0,0 @@ - - - - - - - - addFilter(Filter) - - - - - Image - - - - - - 1110.8240579870107 - 412.38305701571016 - - - - - - - - Volume - - - - - - 746.3823937606093 - 414.32909259072375 - - - - - - - - TreeNode - - - - - - 625.8940609153292 - 195.78347904495376 - - - - - - - - File - - - - - - 497.8940609153292 - 296.78347904495376 - - - - - - - - dest - - - - - Symlink - - - - - - 620.8940609153292 - 296.78347904495376 - - - - - - - - Directory - - - - - - 754.8940609153292 - 301.78347904495376 - - - - - - - - «interface» - -FileSource - - - - - - 567.7128002861876 - 674.7337520453865 - - - - - - - - FilterFileSource - - - - - - 404.71280028618764 - 774.7337520453866 - - - - - - - - «interface» -Filter - - - - - - 254.78439895092293 - 770.0234642237775 - - - - - - - - LocalFileSource - - - - - - 556.36965453568 - 774.2484706711477 - - - - - - - - PreviousImageSource - - - - - - 709.0702627569951 - 767.6450499937722 - - - - - - - - ExternalAppFilter - - - - - - 110.5229299160843 - 923.5005293319075 - - - - - - - - EncryptionFilter - - - - - - 239.49694258624206 - 916.3652866418913 - - - - - - - - CompressionFilter - - - - - - 371.4989323515441 - 917.5544937568939 - - - - - - - - SplittedFile - - - - - - 287.78812183065844 - 413.84407602094683 - - - - - - - - Special - - - - - - 386.0027189390628 - 302.28361365806154 - - - - - - - - DataSource - - - - - - 731.4111571155465 - 901.4839567978983 - - - - - - - - «interface» -BurnSource - - - - - - 1335.6119487863941 - 398.7730655710078 - - - - - - - - ... - - - - - - 1477.8641028983907 - 783.298732945339 - - - - - - - - PVDWriter - - - - - - 1198.964607961779 - 781.9555871948312 - - - - - - - - WriterState - - - - - - 1336.8762962072105 - 661.712946507712 - - - - - - - - - - Libburn - - - - - 1330.0 - 370.0 - - - - - - - - Ecma119Image - - - - - - 1095.4640655004926 - 540.6103494032706 - - - - - - - - Ecma119Source - - - - - - 1326.9200188086058 - 535.6052987693873 - - - - - - - - Ecma119Node - - - - - - 881.981844994835 - 577.6636135370297 - - - - - - - - DirectoryInfoWriter - - - - - - 1316.10674358551 - 783.9555871948312 - - - - - - - - LocalFile - - - - - - 396.0059692959062 - 407.89804044593336 - - - - - - - - FilteredFile - - - - - - 505.41302387615644 - 412.6548689059442 - - - - - - - - PrevImgFile - - - - - - 617.1984926864122 - 410.2764546759387 - - - - - - - - Ecma119File - - - - - - 743.3186217548513 - 674.795410727119 - - - - - - - - Ecma119Symlink - - - - - - 874.2922359743702 - 669.9419255760395 - - - - - - - - Ecma119Dir - - - - - - 1037.9535936976897 - 672.3203398060449 - - - - - - - - FileSourceRegistry - - - - - - 550.129075763134 - 551.543289325507 - - - - - - - - Base object for all interaction with user. -Represents a context for image creation -and manipulation. - - - - - - 1042.275395468971 - 308.29855659733465 - - - - - - - - Registry to ensure the same file is only -written once to the image - - - - - - 271.5290039756343 - 521.8448045156721 - - - - - - - - The context data for image burn sources, contains -references to the tree, creation options... - - - - - - 770.7463914933367 - 497.80317395532944 - - - - - - - - A filter to be applied to file contents. A single filter -can be used to several files. - - - - - - 151.32085117392114 - 668.9230150024738 - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * children - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 root - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [create] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet deleted file mode 100644 index d488940d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet +++ /dev/null @@ -1,492 +0,0 @@ - - - - - - - - TransformStream - - - - - - 374.71280028618764 - 246.7337520453866 - - - - - - - - get_size() -read() -open() -close() -is_repeatable() - - - - - «interface» -Stream - - - - - - 576.3280239753375 - 43.34897573453627 - - - - - - - - FileStream - - - - - - 741.9465965652432 - 246.8166228690261 - - - - - - - - - - CompressionFilter - - - - - - - - - EncryptionFilter - - - - - - - - - ExtAppFilter - - - - - - - - - filter(in, out) - - - - - «interface» -Filter - - - - - - Filters - - - - - 270.0 - 480.0 - - - - - - - - A Stream to read data from an abstract -file represented by a SourceFile - - - - - - 781.6101730552666 - 137.2161620284267 - - - - - - - - A stream to get data from an arbitrary file -descritor. size must be know in advance. - - - - - - 580.8730162779191 - 392.3137084989848 - - - - - - - - fd : int -size : off_t - - - - - FdStream - - - - - - 565.61818228198 - 253.24264068711926 - - - - - - - - 281.2426406871193 - 620.6274169979695 - - - - - - - - 429.51546936508925 - 624.9910026589843 - - - - - - - - 568.2426406871186 - 624.6274169979695 - - - - - - - - A Filter do a tranformation on a stream of data. -The main difference with TransformSources is that -a Filter can be applied to several sources. -NOTES: -- filter() method still to define -- A filter_changes_size() method can be useful - - - - - - - 724.6274169979696 - 510.3015151901651 - - - - - - - - FilteredStream - - - - - - 439.0 - 357.0 - - - - - - - - size : off_t -lba: off_t - - - - - CutOutStream - - - - - - 321.0 - 358.0 - - - - - - - - This can be implemented as a Filter, but -it has no sense to have the same cut out -filter to several sources, so this is a better -place. - - - - - - 67.0 - 276.0 - - - - - - - - A stream that applies some transformation -to the contents of another stream. - - - - - - 122.0 - 183.0 - - - - - - - - 437.57046683437824 - 509.23933115391503 - - - - - - - - «interface» -SourceFile - - - - - - 920.6530291048848 - 248.90158697766475 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet.png b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/UML/stream.violet.png deleted file mode 100644 index f5215a50ae42b31bb7da329d10df18921a868c7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21694 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/cookbook/ISO 9660-1999 b/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/cookbook/ISO 9660-1999 deleted file mode 100644 index 4b813b7b..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/devel/cookbook/ISO 9660-1999 +++ /dev/null @@ -1,119 +0,0 @@ -=============================================================================== - ISO/IEC 9660:1999 Cookbook -=============================================================================== - -Creation date: 2008-Jan-14 -Author: Vreixo Formoso -_______________________________________________________________________________ - -Contents: ---------- - -1. References -2. General -3. Features -4. Implementation -5. Known implementation bugs and specification ambiguities/problems - - -------------------------------------------------------------------------------- -1. References: - -ISO/IEC DIS 9660:1999(E) "Information processing. Volume and file structure of - CD­-ROM for Information Interchange" - - -------------------------------------------------------------------------------- -2. General - -ISO 9660:1999, also known as ISO-9660 version 2 is an update of the old -ISO 9660:1988 standard for writing data images for CD. - -In the same way Joliet does, it is based on a Secondary Volume Descriptor (that -is called Enhanced Volume Descriptor), that provides a second tree where the -new file information is recorded. - -------------------------------------------------------------------------------- -3. Features - -It makes some improvements with respect to ECMA-119, mainly related to relax -the constraints imposed by its predecessor. - -- It removes the limit to the deep of the directory hierarchy (6.8.2.1). -However, it still keep a limit to the path length, of 255 characters as in -ECMA-119. - -- File names don't need the version number (;1) anymore, and the "." and ";", -used as SEPARATORS for extension and version number, have no special meaning -now. - -- The file name max length is incremented to 207 bytes. - -- The file name is not restricted to d-characters. - -------------------------------------------------------------------------------- -4. Implementation - -ISO 9660:1999 is very similar to old ISO 9660:1988 (ECMA-119). It needs two -tree hierarchies: one, identified by the Primary Volume Descriptor, is recorded -in the same way that an ECMA-119 structure. - -The second structure is identified by a Enhanced Volume Descriptor (8.5). The -structure is exactly like defined in ECMA-119, with the exceptions named above. - -Thus, to write an ISO 9660:1999: - -- First 16 blocks are set to 0. -- Block 16 identifies a PVD (8.4), associated with a directory structure -written following ECMA-119. -- It is needed a Enhanced Volume descriptor to describe the additional -structure. It is much like a SVD, with version number set to 2 to identify -this new version. -- We can also write boot records (El-Torito) and additional SVD (Joliet). -- We write a Volume Descriptor Set Terminator (8.3) -- We write directory structure and path tables (L and M) for both ECMA-119 -tree and enhanced tree. Path table record and directory record format is -the same in both structures. However, ECMA-119 is constrained by the usual -restrictions. -- And write the contents of the files. - -Interchange levels 1, 2 and 3 are also defined. For PVD tree, they have the -same meaning as in ECMA-119. For EVD tree, in levels 1 and 2 files are -restricted to one file section (i.e., 4 GB filesize limit). In level 3 we can -have more than one section per file. Level 1 does not impose other -restrictions than that in the EVD tree. - -It seems that both El-Torito and Joliet can coexist in a ISO 9660:1999 image. -However, Joliet has no utility at all in this kind of images, as it has no -benefit over ISO 9660:1999, and it is more restrictive in filename length. - -------------------------------------------------------------------------------- -5. Known implementation bugs and specification ambiguities/problems - -- While the specification clearly states that the tree speficied by the Primary -Volume Descriptor should remain compatible with ISO-9660 (ECMA-119), i.e., it -should be constrained by ECMA-119 restrictions, some image generation -applications out there just make both Primary and Enhanced Volume Descriptors -to point to the same directory structure. That is a specification violation, as -for a) the directory hierarchy specified in the Primary Volume Descriptor -doesn't follow the restrictions specified in the specs, and b) the same -directories are part of two different hiearchies (6.8.3 "A directory shall not -be a part of more than one Directory Hierarchy."). -Thus, we should keep two trees as we do with Joliet. Or are there strong -reasons against this? - -- It's not very clear what characters are allowed for files and dir names. For -the tree identified in the Enhanced Volume Descriptor, it seems that a -"sequence of characters rather than d-characters or d1-characters" is allowed. -It also seems that the charset is determined by the escape sequence in the -EVD. Anyway, leaving escape sequence to 0 and use any user-specified sequence -(such as UTF-8) seems a good solution and is what many other applications do. -Linux correctly mounts the images in this case. - -- It is not clear if RR extensions are allowed in the tree identified by the -Enhanced Volume Descriptor. However, it seems not a good idea. With 207 bytes -filenames and XA extensions, there is no place for RR entries in the directory -records of the enhanced tree. In my opinion, RR extension should be attached to -the ECMA-119 tree that must also be written to image. - - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/doc/doxygen.conf.in b/libisofs/tags/ForXorrisoZeroOneTwo/doc/doxygen.conf.in deleted file mode 100644 index fe1864fe..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/doc/doxygen.conf.in +++ /dev/null @@ -1,1298 +0,0 @@ -# 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 DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = 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 - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# 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 = libisofs \ - doc - -# 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 = libisofs.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 HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# 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 - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# 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) - -HAVE_DOT = YES - -# 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/libisofs/tags/ForXorrisoZeroOneTwo/libisofs-1.pc.in b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs-1.pc.in deleted file mode 100644 index 4cf18c17..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs-1.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libisofs -Description: ISO9660 filesystem creation library -Version: @VERSION@ -Requires: -Libs: -L${libdir} -lisofs -Cflags: -I${includedir}/libisofs diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.c deleted file mode 100644 index c59bad13..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * Synchronized ring buffer, works with a writer thread and a read thread. - * - * TODO #00010 : optimize ring buffer - * - write/read at the end of buffer requires a second mutex_lock, even if - * there's enought space/data at the beginning - * - pre-buffer for writes < BLOCK_SIZE - * - */ - -#include "buffer.h" -#include "libburn/libburn.h" -#include "ecma119.h" - -#include -#include - -#ifndef MIN -# define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -struct iso_ring_buffer -{ - uint8_t *buf; - - /* - * Max number of bytes in buffer - */ - size_t cap; - - /* - * Number of bytes available. - */ - size_t size; - - /* position for reading and writing, offset from buf */ - size_t rpos; - size_t wpos; - - /* - * flags to report if read or writer threads ends execution - * 0 not finished, 1 finished ok, 2 finish with error - */ - unsigned int rend :2; - unsigned int wend :2; - - /* just for statistical purposes */ - unsigned int times_full; - unsigned int times_empty; - - pthread_mutex_t mutex; - pthread_cond_t empty; - pthread_cond_t full; -}; - -/** - * Create a new buffer. - * - * The created buffer should be freed with iso_ring_buffer_free() - * - * @param size - * Number of blocks in buffer. You should supply a number >= 32, otherwise - * size will be ignored and 32 will be used by default, which leads to a - * 64 KiB buffer. - * @return - * 1 success, < 0 error - */ -int iso_ring_buffer_new(size_t size, IsoRingBuffer **rbuf) -{ - IsoRingBuffer *buffer; - - if (rbuf == NULL) { - return ISO_NULL_POINTER; - } - - buffer = malloc(sizeof(IsoRingBuffer)); - if (buffer == NULL) { - return ISO_OUT_OF_MEM; - } - - buffer->cap = (size > 32 ? size : 32) * BLOCK_SIZE; - buffer->buf = malloc(buffer->cap); - if (buffer->buf == NULL) { - free(buffer); - return ISO_OUT_OF_MEM; - } - - buffer->size = 0; - buffer->wpos = 0; - buffer->rpos = 0; - - buffer->times_full = 0; - buffer->times_empty = 0; - - buffer->rend = buffer->wend = 0; - - /* init mutex and waiting queues */ - pthread_mutex_init(&buffer->mutex, NULL); - pthread_cond_init(&buffer->empty, NULL); - pthread_cond_init(&buffer->full, NULL); - - *rbuf = buffer; - return ISO_SUCCESS; -} - -void iso_ring_buffer_free(IsoRingBuffer *buf) -{ - if (buf == NULL) { - return; - } - free(buf->buf); - pthread_mutex_destroy(&buf->mutex); - pthread_cond_destroy(&buf->empty); - pthread_cond_destroy(&buf->full); - free(buf); -} - -/** - * Write count bytes into buffer. It blocks until all bytes where written or - * reader close the buffer. - * - * @param buf - * the buffer - * @param data - * pointer to a memory region of at least coun bytes, from which data - * will be read. - * @param - * Number of bytes to write - * @return - * 1 succes, 0 read finished, < 0 error - */ -int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count) -{ - size_t len; - int bytes_write = 0; - - if (buf == NULL || data == NULL) { - return ISO_NULL_POINTER; - } - - while (bytes_write < count) { - - pthread_mutex_lock(&buf->mutex); - - while (buf->size == buf->cap) { - - /* - * Note. There's only a writer, so we have no race conditions. - * Thus, the while(buf->size == buf->cap) is used here - * only to propertly detect the reader has been cancelled - */ - - if (buf->rend) { - /* the read procces has been finished */ - pthread_mutex_unlock(&buf->mutex); - return 0; - } - buf->times_full++; - /* wait until space available */ - pthread_cond_wait(&buf->full, &buf->mutex); - } - - len = MIN(count - bytes_write, buf->cap - buf->size); - if (buf->wpos + len > buf->cap) { - len = buf->cap - buf->wpos; - } - memcpy(buf->buf + buf->wpos, data + bytes_write, len); - buf->wpos = (buf->wpos + len) % (buf->cap); - bytes_write += len; - buf->size += len; - - /* wake up reader */ - pthread_cond_signal(&buf->empty); - pthread_mutex_unlock(&buf->mutex); - } - return ISO_SUCCESS; -} - -/** - * Read count bytes from the buffer into dest. It blocks until the desired - * bytes has been read. If the writer finishes before outputting enought - * bytes, 0 (EOF) is returned, the number of bytes already read remains - * unknown. - * - * @return - * 1 success, 0 EOF, < 0 error - */ -int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count) -{ - size_t len; - int bytes_read = 0; - - if (buf == NULL || dest == NULL) { - return ISO_NULL_POINTER; - } - - while (bytes_read < count) { - pthread_mutex_lock(&buf->mutex); - - while (buf->size == 0) { - /* - * Note. There's only a reader, so we have no race conditions. - * Thus, the while(buf->size == 0) is used here just to ensure - * a reader detects the EOF propertly if the writer has been - * canceled while the reader was waiting - */ - - if (buf->wend) { - /* the writer procces has been finished */ - pthread_mutex_unlock(&buf->mutex); - return 0; /* EOF */ - } - buf->times_empty++; - /* wait until data available */ - pthread_cond_wait(&buf->empty, &buf->mutex); - } - - len = MIN(count - bytes_read, buf->size); - if (buf->rpos + len > buf->cap) { - len = buf->cap - buf->rpos; - } - memcpy(dest + bytes_read, buf->buf + buf->rpos, len); - buf->rpos = (buf->rpos + len) % (buf->cap); - bytes_read += len; - buf->size -= len; - - /* wake up the writer */ - pthread_cond_signal(&buf->full); - pthread_mutex_unlock(&buf->mutex); - } - return ISO_SUCCESS; -} - -void iso_ring_buffer_writer_close(IsoRingBuffer *buf, int error) -{ - pthread_mutex_lock(&buf->mutex); - buf->wend = error ? 2 : 1; - - /* ensure no reader is waiting */ - pthread_cond_signal(&buf->empty); - pthread_mutex_unlock(&buf->mutex); -} - -void iso_ring_buffer_reader_close(IsoRingBuffer *buf, int error) -{ - pthread_mutex_lock(&buf->mutex); - - if (buf->rend) { - /* reader already closed */ - pthread_mutex_unlock(&buf->mutex); - return; - } - - buf->rend = error ? 2 : 1; - - /* ensure no writer is waiting */ - pthread_cond_signal(&buf->full); - pthread_mutex_unlock(&buf->mutex); -} - -/** - * Get the times the buffer was full. - */ -unsigned int iso_ring_buffer_get_times_full(IsoRingBuffer *buf) -{ - return buf->times_full; -} - -/** - * Get the times the buffer was empty. - */ -unsigned int iso_ring_buffer_get_times_empty(IsoRingBuffer *buf) -{ - return buf->times_empty; -} - - -/** - * Get the status of the buffer used by a burn_source. - * - * @param b - * A burn_source previously obtained with - * iso_image_create_burn_source(). - * @param size - * Will be filled with the total size of the buffer, in bytes - * @param free_bytes - * Will be filled with the bytes currently available in buffer - * @return - * < 0 error, > 0 state: - * 1="active" : input and consumption are active - * 2="ending" : input has ended without error - * 3="failing" : input had error and ended, - * 5="abandoned" : consumption has ended prematurely - * 6="ended" : consumption has ended without input error - * 7="aborted" : consumption has ended after input error - */ -int iso_ring_buffer_get_status(struct burn_source *b, size_t *size, - size_t *free_bytes) -{ - int ret; - IsoRingBuffer *buf; - if (b == NULL) { - return ISO_NULL_POINTER; - } - buf = ((Ecma119Image*)(b->data))->buffer; - - /* get mutex */ - pthread_mutex_lock(&buf->mutex); - if (size) { - *size = buf->cap; - } - if (free_bytes) { - *free_bytes = buf->cap - buf->size; - } - - ret = (buf->rend ? 4 : 0) + (buf->wend + 1); - - pthread_mutex_unlock(&buf->mutex); - return ret; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.h deleted file mode 100644 index c98e06cb..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/buffer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_BUFFER_H_ -#define LIBISO_BUFFER_H_ - -#include -#include - -#define BLOCK_SIZE 2048 - -typedef struct iso_ring_buffer IsoRingBuffer; - -/** - * Create a new buffer. - * - * The created buffer should be freed with iso_ring_buffer_free() - * - * @param size - * Number of blocks in buffer. You should supply a number >= 32, otherwise - * size will be ignored and 32 will be used by default, which leads to a - * 64 KiB buffer. - * @return - * 1 success, < 0 error - */ -int iso_ring_buffer_new(size_t size, IsoRingBuffer **rbuf); - -/** - * Free a given buffer - */ -void iso_ring_buffer_free(IsoRingBuffer *buf); - -/** - * Write count bytes into buffer. It blocks until all bytes where written or - * reader close the buffer. - * - * @param buf - * the buffer - * @param data - * pointer to a memory region of at least coun bytes, from which data - * will be read. - * @param - * Number of bytes to write - * @return - * 1 succes, 0 read finished, < 0 error - */ -int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count); - -/** - * Read count bytes from the buffer into dest. It blocks until the desired - * bytes has been read. If the writer finishes before outputting enought - * bytes, 0 (EOF) is returned, the number of bytes already read remains - * unknown. - * - * @return - * 1 success, 0 EOF, < 0 error - */ -int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count); - -/** - * Close the buffer (to be called by the writer). - * You have to explicity close the buffer when you don't have more data to - * write, otherwise reader will be waiting forever. - * - * @param error - * Writer has finished prematurely due to an error - */ -void iso_ring_buffer_writer_close(IsoRingBuffer *buf, int error); - -/** - * Close the buffer (to be called by the reader). - * If for any reason you don't want to read more data, you need to call this - * to let the writer thread finish. - * - * @param error - * Reader has finished prematurely due to an error - */ -void iso_ring_buffer_reader_close(IsoRingBuffer *buf, int error); - -/** - * Get the times the buffer was full. - */ -unsigned int iso_ring_buffer_get_times_full(IsoRingBuffer *buf); - -/** - * Get the times the buffer was empty. - */ -unsigned int iso_ring_buffer_get_times_empty(IsoRingBuffer *buf); - -#endif /*LIBISO_BUFFER_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.c deleted file mode 100644 index 9dbea875..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "builder.h" -#include "node.h" -#include "fsource.h" - -#include -#include -#include - -void iso_node_builder_ref(IsoNodeBuilder *builder) -{ - ++builder->refcount; -} - -void iso_node_builder_unref(IsoNodeBuilder *builder) -{ - if (--builder->refcount == 0) { - /* free private data */ - builder->free(builder); - free(builder); - } -} - -static -int default_create_file(IsoNodeBuilder *builder, IsoImage *image, - IsoFileSource *src, IsoFile **file) -{ - int ret; - struct stat info; - IsoStream *stream; - IsoFile *node; - char *name; - - if (builder == NULL || src == NULL || file == NULL) { - return ISO_NULL_POINTER; - } - - ret = iso_file_source_stat(src, &info); - if (ret < 0) { - return ret; - } - - /* this will fail if src is a dir, is not accessible... */ - ret = iso_file_source_stream_new(src, &stream); - if (ret < 0) { - return ret; - } - - name = iso_file_source_get_name(src); - ret = iso_node_new_file(name, stream, &node); - if (ret < 0) { - /* the stream has taken our ref to src, so we need to add one */ - iso_file_source_ref(src); - iso_stream_unref(stream); - free(name); - return ret; - } - - /* fill node fields */ - iso_node_set_permissions((IsoNode*)node, info.st_mode); - iso_node_set_uid((IsoNode*)node, info.st_uid); - iso_node_set_gid((IsoNode*)node, info.st_gid); - iso_node_set_atime((IsoNode*)node, info.st_atime); - iso_node_set_mtime((IsoNode*)node, info.st_mtime); - iso_node_set_ctime((IsoNode*)node, info.st_ctime); - iso_node_set_uid((IsoNode*)node, info.st_uid); - - *file = node; - return ISO_SUCCESS; -} - -static -int default_create_node(IsoNodeBuilder *builder, IsoImage *image, - IsoFileSource *src, IsoNode **node) -{ - int ret; - struct stat info; - IsoNode *new; - char *name; - - if (builder == NULL || src == NULL || node == NULL) { - return ISO_NULL_POINTER; - } - - /* get info about source */ - if (iso_tree_get_follow_symlinks(image)) { - ret = iso_file_source_stat(src, &info); - } else { - ret = iso_file_source_lstat(src, &info); - } - if (ret < 0) { - return ret; - } - - name = iso_file_source_get_name(src); - new = NULL; - - switch (info.st_mode & S_IFMT) { - case S_IFREG: - { - /* source is a regular file */ - IsoStream *stream; - IsoFile *file; - ret = iso_file_source_stream_new(src, &stream); - if (ret < 0) { - break; - } - /* take a ref to the src, as stream has taken our ref */ - iso_file_source_ref(src); - - /* create the file */ - ret = iso_node_new_file(name, stream, &file); - if (ret < 0) { - iso_stream_unref(stream); - } - new = (IsoNode*) file; - } - break; - case S_IFDIR: - { - /* source is a directory */ - IsoDir *dir; - ret = iso_node_new_dir(name, &dir); - new = (IsoNode*)dir; - } - break; - case S_IFLNK: - { - /* source is a symbolic link */ - char dest[PATH_MAX]; - IsoSymlink *link; - - ret = iso_file_source_readlink(src, dest, PATH_MAX); - if (ret < 0) { - break; - } - ret = iso_node_new_symlink(name, strdup(dest), &link); - new = (IsoNode*) link; - } - break; - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - { - /* source is an special file */ - IsoSpecial *special; - ret = iso_node_new_special(name, info.st_mode, info.st_rdev, - &special); - new = (IsoNode*) special; - } - break; - } - - if (ret < 0) { - free(name); - return ret; - } - - /* fill fields */ - iso_node_set_permissions(new, info.st_mode); - iso_node_set_uid(new, info.st_uid); - iso_node_set_gid(new, info.st_gid); - iso_node_set_atime(new, info.st_atime); - iso_node_set_mtime(new, info.st_mtime); - iso_node_set_ctime(new, info.st_ctime); - iso_node_set_uid(new, info.st_uid); - - *node = new; - return ISO_SUCCESS; -} - -static -void default_free(IsoNodeBuilder *builder) -{ - return; -} - -int iso_node_basic_builder_new(IsoNodeBuilder **builder) -{ - IsoNodeBuilder *b; - - if (builder == NULL) { - return ISO_NULL_POINTER; - } - - b = malloc(sizeof(IsoNodeBuilder)); - if (b == NULL) { - return ISO_OUT_OF_MEM; - } - - b->refcount = 1; - b->create_file_data = NULL; - b->create_node_data = NULL; - b->create_file = default_create_file; - b->create_node = default_create_node; - b->free = default_free; - - *builder = b; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.h deleted file mode 100644 index e0d3ff10..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/builder.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_BUILDER_H_ -#define LIBISO_BUILDER_H_ - -/* - * Definitions for IsoNode builders. - */ - -/* - * Some functions here will be moved to libisofs.h when we expose - * Builder. - */ - -#include "libisofs.h" -#include "fsource.h" - -typedef struct Iso_Node_Builder IsoNodeBuilder; - -struct Iso_Node_Builder -{ - - /** - * Create a new IsoFile from an IsoFileSource. Name, permissions - * and other attributes are taken from src, but a regular file will - * always be created, even if src is another kind of file. - * - * In that case, if the implementation can't do the conversion, it - * should fail propertly. - * - * On sucess, the ref. to src will be owned by file, so you musn't - * unref it. - * - * @return - * 1 on success, < 0 on error - */ - int (*create_file)(IsoNodeBuilder *builder, IsoImage *image, - IsoFileSource *src, IsoFile **file); - - /** - * Create a new IsoNode from a IsoFileSource. The type of the node to be - * created is determined from the type of the file source. Name, - * permissions and other attributes are taken from source file. - * - * Note that the src is never unref, so you need to free it. - * - * @return - * 1 on success, < 0 on error - */ - int (*create_node)(IsoNodeBuilder *builder, IsoImage *image, - IsoFileSource *src, IsoNode **node); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_node_builder_unref() instead. - */ - void (*free)(IsoNodeBuilder *builder); - - int refcount; - void *create_file_data; - void *create_node_data; -}; - -void iso_node_builder_ref(IsoNodeBuilder *builder); -void iso_node_builder_unref(IsoNodeBuilder *builder); - -/** - * Create a new basic builder ... - * - * @return - * 1 success, < 0 error - */ -int iso_node_basic_builder_new(IsoNodeBuilder **builder); - -#endif /*LIBISO_BUILDER_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/data_source.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/data_source.c deleted file mode 100644 index 4d7c3cc2..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/data_source.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include - -/** - * Private data for File IsoDataSource - */ -struct file_data_src -{ - char *path; - int fd; -}; - -/** - * Increments the reference counting of the given IsoDataSource. - */ -void iso_data_source_ref(IsoDataSource *src) -{ - src->refcount++; -} - -/** - * Decrements the reference counting of the given IsoDataSource, freeing it - * if refcount reach 0. - */ -void iso_data_source_unref(IsoDataSource *src) -{ - if (--src->refcount == 0) { - src->free_data(src); - free(src); - } -} - -static -int ds_open(IsoDataSource *src) -{ - int fd; - struct file_data_src *data; - - if (src == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (struct file_data_src*) src->data; - if (data->fd != -1) { - return ISO_FILE_ALREADY_OPENED; - } - - fd = open(data->path, O_RDONLY); - if (fd == -1) { - return ISO_FILE_ERROR; - } - - data->fd = fd; - return ISO_SUCCESS; -} - -static -int ds_close(IsoDataSource *src) -{ - int ret; - struct file_data_src *data; - - if (src == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (struct file_data_src*) src->data; - if (data->fd == -1) { - return ISO_FILE_NOT_OPENED; - } - - /* close can fail if fd is not valid, but that should never happen */ - ret = close(data->fd); - - /* in any case we mark file as closed */ - data->fd = -1; - return ret == 0 ? ISO_SUCCESS : ISO_FILE_ERROR; -} - -static int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) -{ - struct file_data_src *data; - - if (src == NULL || src->data == NULL || buffer == NULL) { - return ISO_NULL_POINTER; - } - - data = (struct file_data_src*) src->data; - if (data->fd == -1) { - return ISO_FILE_NOT_OPENED; - } - - /* goes to requested block */ - if (lseek(data->fd, (off_t)lba * (off_t)2048, SEEK_SET) == (off_t) -1) { - return ISO_FILE_SEEK_ERROR; - } - - /* TODO #00008 : guard against partial reads. */ - if (read(data->fd, buffer, 2048) != 2048) { - return ISO_FILE_READ_ERROR; - } - - return ISO_SUCCESS; -} - -static -void ds_free_data(IsoDataSource *src) -{ - struct file_data_src *data; - - data = (struct file_data_src*)src->data; - - /* close the file if needed */ - if (data->fd != -1) { - close(data->fd); - } - free(data->path); - free(data); -} - -/** - * Create a new IsoDataSource from a local file. This is suitable for - * accessing regular .iso images, or to acces drives via its block device - * and standard POSIX I/O calls. - * - * @param path - * The path of the file - * @param src - * Will be filled with the pointer to the newly created data source. - * @return - * 1 on success, < 0 on error. - */ -int iso_data_source_new_from_file(const char *path, IsoDataSource **src) -{ - int ret; - struct file_data_src *data; - IsoDataSource *ds; - - if (path == NULL || src == NULL) { - return ISO_NULL_POINTER; - } - - /* ensure we have read access to the file */ - ret = iso_eaccess(path); - if (ret < 0) { - return ret; - } - - data = malloc(sizeof(struct file_data_src)); - if (data == NULL) { - return ISO_OUT_OF_MEM; - } - - ds = malloc(sizeof(IsoDataSource)); - if (ds == NULL) { - free(data); - return ISO_OUT_OF_MEM; - } - - /* fill data fields */ - data->path = strdup(path); - if (data->path == NULL) { - free(data); - free(ds); - return ISO_OUT_OF_MEM; - } - - data->fd = -1; - ds->version = 0; - ds->refcount = 1; - ds->data = data; - - ds->open = ds_open; - ds->close = ds_close; - ds->read_block = ds_read_block; - ds->free_data = ds_free_data; - - *src = ds; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.c deleted file mode 100644 index e49ad8c0..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.c +++ /dev/null @@ -1,1579 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "ecma119.h" -#include "joliet.h" -#include "iso1999.h" -#include "eltorito.h" -#include "ecma119_tree.h" -#include "filesrc.h" -#include "image.h" -#include "writer.h" -#include "messages.h" -#include "rockridge.h" -#include "util.h" - -#include "libburn/libburn.h" - -#include -#include -#include -#include -#include - -/* - * TODO #00011 : guard against bad path table usage with more than 65535 dirs - * image with more than 65535 directories have path_table related problems - * due to 16 bits parent id. Note that this problem only affects to folders - * that are parent of another folder. - */ - -static -void ecma119_image_free(Ecma119Image *t) -{ - size_t i; - - ecma119_node_free(t->root); - iso_image_unref(t->image); - iso_rbtree_destroy(t->files, iso_file_src_free); - iso_ring_buffer_free(t->buffer); - - for (i = 0; i < t->nwriters; ++i) { - IsoImageWriter *writer = t->writers[i]; - writer->free_data(writer); - free(writer); - } - free(t->input_charset); - free(t->output_charset); - free(t->writers); - free(t); -} - -/** - * Check if we should add version number ";" to the given node name. - */ -static -int need_version_number(Ecma119Image *t, Ecma119Node *n) -{ - if (t->omit_version_numbers) { - return 0; - } - if (n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER) { - return 0; - } else { - return 1; - } -} - -/** - * Compute the size of a directory entry for a single node - */ -static -size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n) -{ - int ret = n->iso_name ? strlen(n->iso_name) + 33 : 34; - if (need_version_number(t, n)) { - ret += 2; /* take into account version numbers */ - } - if (ret % 2) - ret++; - return ret; -} - -/** - * Computes the total size of all directory entries of a single dir, - * acording to ECMA-119 6.8.1.1 - * - * This also take into account the size needed for RR entries and - * SUSP continuation areas (SUSP, 5.1). - * - * @param ce - * Will be filled with the size needed for Continuation Areas - * @return - * The size needed for all dir entries of the given dir, without - * taking into account the continuation areas. - */ -static -size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce) -{ - size_t i, len; - size_t ce_len = 0; - - /* size of "." and ".." entries */ - len = 34 + 34; - if (t->rockridge) { - len += rrip_calc_len(t, dir, 1, 255 - 34, &ce_len); - *ce += ce_len; - len += rrip_calc_len(t, dir, 2, 255 - 34, &ce_len); - *ce += ce_len; - } - - for (i = 0; i < dir->info.dir->nchildren; ++i) { - size_t remaining; - Ecma119Node *child = dir->info.dir->children[i]; - size_t dirent_len = calc_dirent_len(t, child); - if (t->rockridge) { - dirent_len += rrip_calc_len(t, child, 0, 255 - dirent_len, &ce_len); - *ce += ce_len; - } - remaining = BLOCK_SIZE - (len % BLOCK_SIZE); - if (dirent_len > remaining) { - /* child directory entry doesn't fit on block */ - len += remaining + dirent_len; - } else { - len += dirent_len; - } - } - - /* - * The size of a dir is always a multiple of block size, as we must add - * the size of the unused space after the last directory record - * (ECMA-119, 6.8.1.3) - */ - len = ROUND_UP(len, BLOCK_SIZE); - - /* cache the len */ - dir->info.dir->len = len; - return len; -} - -static -void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir) -{ - size_t i, len; - size_t ce_len = 0; - - t->ndirs++; - dir->info.dir->block = t->curblock; - len = calc_dir_size(t, dir, &ce_len); - t->curblock += DIV_UP(len, BLOCK_SIZE); - if (t->rockridge) { - t->curblock += DIV_UP(ce_len, BLOCK_SIZE); - } - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - if (child->type == ECMA119_DIR) { - calc_dir_pos(t, child); - } - } -} - -/** - * Compute the length of the path table, in bytes. - */ -static -uint32_t calc_path_table_size(Ecma119Node *dir) -{ - uint32_t size; - size_t i; - - /* size of path table for this entry */ - size = 8; - size += dir->iso_name ? strlen(dir->iso_name) : 1; - size += (size % 2); - - /* and recurse */ - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - if (child->type == ECMA119_DIR) { - size += calc_path_table_size(child); - } - } - return size; -} - -static -int ecma119_writer_compute_data_blocks(IsoImageWriter *writer) -{ - Ecma119Image *target; - uint32_t path_table_size; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - target = writer->target; - - /* compute position of directories */ - iso_msg_debug(target->image->id, "Computing position of dir structure"); - target->ndirs = 0; - calc_dir_pos(target, target->root); - - /* compute length of pathlist */ - iso_msg_debug(target->image->id, "Computing length of pathlist"); - path_table_size = calc_path_table_size(target->root); - - /* compute location for path tables */ - target->l_path_table_pos = target->curblock; - target->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - target->m_path_table_pos = target->curblock; - target->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - target->path_table_size = path_table_size; - - return ISO_SUCCESS; -} - -/** - * Write a single directory record (ECMA-119, 9.1) - * - * @param file_id - * if >= 0, we use it instead of the filename (for "." and ".." entries). - * @param len_fi - * Computed length of the file identifier. Total size of the directory - * entry will be len + 33 + padding if needed (ECMA-119, 9.1.12) - * @param info - * SUSP entries for the given directory record. It will be NULL for the - * root directory record in the PVD (ECMA-119, 8.4.18) (in order to - * distinguish it from the "." entry in the root directory) - */ -static -void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id, - uint8_t *buf, size_t len_fi, struct susp_info *info) -{ - uint32_t len; - uint32_t block; - uint8_t len_dr; /*< size of dir entry without SUSP fields */ - uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id - : (uint8_t*)node->iso_name; - - struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf; - - len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1); - - memcpy(rec->file_id, name, len_fi); - - if (need_version_number(t, node)) { - len_dr += 2; - rec->file_id[len_fi++] = ';'; - rec->file_id[len_fi++] = '1'; - } - - if (node->type == ECMA119_DIR) { - /* use the cached length */ - len = node->info.dir->len; - block = node->info.dir->block; - } else if (node->type == ECMA119_FILE) { - len = iso_file_src_get_size(node->info.file); - block = node->info.file->block; - } else { - /* - * for nodes other than files and dirs, we set both - * len and block to 0 - */ - len = 0; - block = 0; - } - - /* - * For ".." entry we need to write the parent info! - */ - if (file_id == 1 && node->parent) - node = node->parent; - - rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0); - iso_bb(rec->block, block, 4); - iso_bb(rec->length, len, 4); - iso_datetime_7(rec->recording_time, t->now, t->always_gmt); - rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0; - iso_bb(rec->vol_seq_number, 1, 2); - rec->len_fi[0] = len_fi; - - /* and finally write the SUSP fields */ - if (info != NULL) { - rrip_write_susp_fields(t, info, buf + len_dr); - } -} - -static -char *get_relaxed_vol_id(Ecma119Image *t, const char *name) -{ - int ret; - if (name == NULL) { - return NULL; - } - if (strcmp(t->input_charset, t->output_charset)) { - /* charset conversion needed */ - char *str; - ret = strconv(name, t->input_charset, t->output_charset, &str); - if (ret == ISO_SUCCESS) { - return str; - } - iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret, - "Charset conversion error. Can't convert %s from %s to %s", - name, t->input_charset, t->output_charset); - } - return strdup(name); -} - -/** - * Write the Primary Volume Descriptor (ECMA-119, 8.4) - */ -static -int ecma119_writer_write_vol_desc(IsoImageWriter *writer) -{ - IsoImage *image; - Ecma119Image *t; - struct ecma119_pri_vol_desc vol; - - char *vol_id, *pub_id, *data_id, *volset_id; - char *system_id, *application_id, *copyright_file_id; - char *abstract_file_id, *biblio_file_id; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - t = writer->target; - image = t->image; - - iso_msg_debug(image->id, "Write Primary Volume Descriptor"); - - memset(&vol, 0, sizeof(struct ecma119_pri_vol_desc)); - - if (t->relaxed_vol_atts) { - vol_id = get_relaxed_vol_id(t, image->volume_id); - volset_id = get_relaxed_vol_id(t, image->volset_id); - } else { - str2d_char(t->input_charset, image->volume_id, &vol_id); - str2d_char(t->input_charset, image->volset_id, &volset_id); - } - str2a_char(t->input_charset, image->publisher_id, &pub_id); - str2a_char(t->input_charset, image->data_preparer_id, &data_id); - str2a_char(t->input_charset, image->system_id, &system_id); - str2a_char(t->input_charset, image->application_id, &application_id); - str2d_char(t->input_charset, image->copyright_file_id, ©right_file_id); - str2d_char(t->input_charset, image->abstract_file_id, &abstract_file_id); - str2d_char(t->input_charset, image->biblio_file_id, &biblio_file_id); - - vol.vol_desc_type[0] = 1; - memcpy(vol.std_identifier, "CD001", 5); - vol.vol_desc_version[0] = 1; - strncpy_pad((char*)vol.system_id, system_id, 32); - strncpy_pad((char*)vol.volume_id, vol_id, 32); - iso_bb(vol.vol_space_size, t->vol_space_size, 4); - iso_bb(vol.vol_set_size, 1, 2); - iso_bb(vol.vol_seq_number, 1, 2); - iso_bb(vol.block_size, BLOCK_SIZE, 2); - iso_bb(vol.path_table_size, t->path_table_size, 4); - iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 4); - iso_msb(vol.m_path_table_pos, t->m_path_table_pos, 4); - - write_one_dir_record(t, t->root, 0, vol.root_dir_record, 1, NULL); - - strncpy_pad((char*)vol.vol_set_id, volset_id, 128); - strncpy_pad((char*)vol.publisher_id, pub_id, 128); - strncpy_pad((char*)vol.data_prep_id, data_id, 128); - - strncpy_pad((char*)vol.application_id, application_id, 128); - strncpy_pad((char*)vol.copyright_file_id, copyright_file_id, 37); - strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37); - strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37); - - iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt); - vol.file_structure_version[0] = 1; - - free(vol_id); - free(volset_id); - free(pub_id); - free(data_id); - free(system_id); - free(application_id); - free(copyright_file_id); - free(abstract_file_id); - free(biblio_file_id); - - /* Finally write the Volume Descriptor */ - return iso_write(t, &vol, sizeof(struct ecma119_pri_vol_desc)); -} - -static -int write_one_dir(Ecma119Image *t, Ecma119Node *dir) -{ - int ret; - uint8_t buffer[BLOCK_SIZE]; - size_t i; - size_t fi_len, len; - struct susp_info info; - - /* buf will point to current write position on buffer */ - uint8_t *buf = buffer; - - /* initialize buffer with 0s */ - memset(buffer, 0, BLOCK_SIZE); - - /* - * set susp_info to 0's, this way code for both plain ECMA-119 and - * RR is very similar - */ - memset(&info, 0, sizeof(struct susp_info)); - if (t->rockridge) { - /* initialize the ce_block, it might be needed */ - info.ce_block = dir->info.dir->block + DIV_UP(dir->info.dir->len, - BLOCK_SIZE); - } - - /* write the "." and ".." entries first */ - if (t->rockridge) { - ret = rrip_get_susp_fields(t, dir, 1, 255 - 32, &info); - if (ret < 0) { - return ret; - } - } - len = 34 + info.suf_len; - write_one_dir_record(t, dir, 0, buf, 1, &info); - buf += len; - - if (t->rockridge) { - ret = rrip_get_susp_fields(t, dir, 2, 255 - 32, &info); - if (ret < 0) { - return ret; - } - } - len = 34 + info.suf_len; - write_one_dir_record(t, dir, 1, buf, 1, &info); - buf += len; - - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - - /* compute len of directory entry */ - fi_len = strlen(child->iso_name); - len = fi_len + 33 + (fi_len % 2 ? 0 : 1); - if (need_version_number(t, child)) { - len += 2; - } - - /* get the SUSP fields if rockridge is enabled */ - if (t->rockridge) { - ret = rrip_get_susp_fields(t, child, 0, 255 - len, &info); - if (ret < 0) { - return ret; - } - len += info.suf_len; - } - - if ( (buf + len - buffer) > BLOCK_SIZE) { - /* dir doesn't fit in current block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - if (ret < 0) { - return ret; - } - memset(buffer, 0, BLOCK_SIZE); - buf = buffer; - } - /* write the directory entry in any case */ - write_one_dir_record(t, child, -1, buf, fi_len, &info); - buf += len; - } - - /* write the last block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - if (ret < 0) { - return ret; - } - - /* write the Continuation Area if needed */ - if (info.ce_len > 0) { - ret = rrip_write_ce_fields(t, &info); - } - - return ret; -} - -static -int write_dirs(Ecma119Image *t, Ecma119Node *root) -{ - int ret; - size_t i; - - /* write all directory entries for this dir */ - ret = write_one_dir(t, root); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < root->info.dir->nchildren; i++) { - Ecma119Node *child = root->info.dir->children[i]; - if (child->type == ECMA119_DIR) { - ret = write_dirs(t, child); - if (ret < 0) { - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type) -{ - size_t i, len; - uint8_t buf[64]; /* 64 is just a convenient size larger enought */ - struct ecma119_path_table_record *rec; - void (*write_int)(uint8_t*, uint32_t, int); - Ecma119Node *dir; - uint32_t path_table_size; - int parent = 0; - int ret= ISO_SUCCESS; - - path_table_size = 0; - write_int = l_type ? iso_lsb : iso_msb; - - for (i = 0; i < t->ndirs; i++) { - dir = pathlist[i]; - - /* find the index of the parent in the table */ - while ((i) && pathlist[parent] != dir->parent) { - parent++; - } - - /* write the Path Table Record (ECMA-119, 9.4) */ - memset(buf, 0, 64); - rec = (struct ecma119_path_table_record*) buf; - rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->iso_name) : 1; - rec->len_xa[0] = 0; - write_int(rec->block, dir->info.dir->block, 4); - write_int(rec->parent, parent + 1, 2); - if (dir->parent) { - memcpy(rec->dir_id, dir->iso_name, rec->len_di[0]); - } - len = 8 + rec->len_di[0] + (rec->len_di[0] % 2); - ret = iso_write(t, buf, len); - if (ret < 0) { - /* error */ - return ret; - } - path_table_size += len; - } - - /* we need to fill the last block with zeros */ - path_table_size %= BLOCK_SIZE; - if (path_table_size) { - uint8_t zeros[BLOCK_SIZE]; - len = BLOCK_SIZE - path_table_size; - memset(zeros, 0, len); - ret = iso_write(t, zeros, len); - } - return ret; -} - -static -int write_path_tables(Ecma119Image *t) -{ - int ret; - size_t i, j, cur; - Ecma119Node **pathlist; - - iso_msg_debug(t->image->id, "Writing ISO Path tables"); - - /* allocate temporal pathlist */ - pathlist = malloc(sizeof(void*) * t->ndirs); - if (pathlist == NULL) { - return ISO_OUT_OF_MEM; - } - pathlist[0] = t->root; - cur = 1; - - for (i = 0; i < t->ndirs; i++) { - Ecma119Node *dir = pathlist[i]; - for (j = 0; j < dir->info.dir->nchildren; j++) { - Ecma119Node *child = dir->info.dir->children[j]; - if (child->type == ECMA119_DIR) { - pathlist[cur++] = child; - } - } - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 1); - if (ret < 0) { - goto write_path_tables_exit; - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 0); - - write_path_tables_exit: ; - free(pathlist); - return ret; -} - -/** - * Write both the directory structure (ECMA-119, 6.8) and the L and M - * Path Tables (ECMA-119, 6.9). - */ -static -int ecma119_writer_write_data(IsoImageWriter *writer) -{ - int ret; - Ecma119Image *t; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - t = writer->target; - - /* first of all, we write the directory structure */ - ret = write_dirs(t, t->root); - if (ret < 0) { - return ret; - } - - /* and write the path tables */ - ret = write_path_tables(t); - - return ret; -} - -static -int ecma119_writer_free_data(IsoImageWriter *writer) -{ - /* nothing to do */ - return ISO_SUCCESS; -} - -int ecma119_writer_create(Ecma119Image *target) -{ - int ret; - IsoImageWriter *writer; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - writer->compute_data_blocks = ecma119_writer_compute_data_blocks; - writer->write_vol_desc = ecma119_writer_write_vol_desc; - writer->write_data = ecma119_writer_write_data; - writer->free_data = ecma119_writer_free_data; - writer->data = NULL; - writer->target = target; - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - - iso_msg_debug(target->image->id, "Creating low level ECMA-119 tree..."); - ret = ecma119_tree_create(target); - if (ret < 0) { - return ret; - } - - /* we need the volume descriptor */ - target->curblock++; - return ISO_SUCCESS; -} - -/** compute how many padding bytes are needed */ -static -int pad_writer_compute_data_blocks(IsoImageWriter *writer) -{ - Ecma119Image *target; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - target = writer->target; - if (target->curblock < 32) { - target->pad_blocks = 32 - target->curblock; - target->curblock = 32; - } - return ISO_SUCCESS; -} - -static -int pad_writer_write_vol_desc(IsoImageWriter *writer) -{ - /* nothing to do */ - return ISO_SUCCESS; -} -static -int pad_writer_write_data(IsoImageWriter *writer) -{ - int ret; - Ecma119Image *t; - uint32_t pad[BLOCK_SIZE]; - size_t i; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - t = writer->target; - - if (t->pad_blocks == 0) { - return ISO_SUCCESS; - } - - memset(pad, 0, BLOCK_SIZE); - for (i = 0; i < t->pad_blocks; ++i) { - ret = iso_write(t, pad, BLOCK_SIZE); - if (ret < 0) { - return ret; - } - } - - return ISO_SUCCESS; -} - -static -int pad_writer_free_data(IsoImageWriter *writer) -{ - /* nothing to do */ - return ISO_SUCCESS; -} - -static -int pad_writer_create(Ecma119Image *target) -{ - IsoImageWriter *writer; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - writer->compute_data_blocks = pad_writer_compute_data_blocks; - writer->write_vol_desc = pad_writer_write_vol_desc; - writer->write_data = pad_writer_write_data; - writer->free_data = pad_writer_free_data; - writer->data = NULL; - writer->target = target; - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - return ISO_SUCCESS; -} - -static -void *write_function(void *arg) -{ - int res; - size_t i; - uint8_t buf[BLOCK_SIZE]; - IsoImageWriter *writer; - - Ecma119Image *target = (Ecma119Image*)arg; - iso_msg_debug(target->image->id, "Starting image writing..."); - - target->bytes_written = (off_t) 0; - target->percent_written = 0; - - /* Write System Area, 16 blocks of zeros (ECMA-119, 6.2.1) */ - memset(buf, 0, BLOCK_SIZE); - for (i = 0; i < 16; ++i) { - res = iso_write(target, buf, BLOCK_SIZE); - if (res < 0) { - goto write_error; - } - } - - /* write volume descriptors, one per writer */ - iso_msg_debug(target->image->id, "Write volume descriptors"); - for (i = 0; i < target->nwriters; ++i) { - writer = target->writers[i]; - res = writer->write_vol_desc(writer); - if (res < 0) { - goto write_error; - } - } - - /* write Volume Descriptor Set Terminator (ECMA-119, 8.3) */ - { - struct ecma119_vol_desc_terminator *vol; - vol = (struct ecma119_vol_desc_terminator *) buf; - - vol->vol_desc_type[0] = 255; - memcpy(vol->std_identifier, "CD001", 5); - vol->vol_desc_version[0] = 1; - - res = iso_write(target, buf, BLOCK_SIZE); - if (res < 0) { - goto write_error; - } - } - - /* write data for each writer */ - for (i = 0; i < target->nwriters; ++i) { - writer = target->writers[i]; - res = writer->write_data(writer); - if (res < 0) { - goto write_error; - } - } - - iso_ring_buffer_writer_close(target->buffer, 0); - pthread_exit(NULL); - - write_error: ; - if (res == ISO_CANCELED) { - /* canceled */ - iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED, 0, NULL); - } else { - /* image write error */ - iso_msg_submit(target->image->id, ISO_WRITE_ERROR, res, - "Image write error"); - } - iso_ring_buffer_writer_close(target->buffer, 1); - pthread_exit(NULL); -} - -static -int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) -{ - int ret, i, voldesc_size, nwriters; - Ecma119Image *target; - - /* 1. Allocate target and copy opts there */ - target = calloc(1, sizeof(Ecma119Image)); - if (target == NULL) { - return ISO_OUT_OF_MEM; - } - - /* create the tree for file caching */ - ret = iso_rbtree_new(iso_file_src_cmp, &(target->files)); - if (ret < 0) { - free(target); - return ret; - } - - target->image = src; - iso_image_ref(src); - - target->iso_level = opts->level; - target->rockridge = opts->rockridge; - target->joliet = opts->joliet; - target->iso1999 = opts->iso1999; - target->always_gmt = opts->always_gmt; - target->ino = 0; - target->omit_version_numbers = opts->omit_version_numbers - | opts->max_37_char_filenames; - target->allow_deep_paths = opts->allow_deep_paths; - target->allow_longer_paths = opts->allow_longer_paths; - target->max_37_char_filenames = opts->max_37_char_filenames; - target->no_force_dots = opts->no_force_dots; - target->allow_lowercase = opts->allow_lowercase; - target->allow_full_ascii = opts->allow_full_ascii; - target->relaxed_vol_atts = opts->relaxed_vol_atts; - target->joliet_longer_paths = opts->joliet_longer_paths; - target->sort_files = opts->sort_files; - - target->replace_uid = opts->replace_uid ? 1 : 0; - target->replace_gid = opts->replace_gid ? 1 : 0; - target->replace_dir_mode = opts->replace_dir_mode ? 1 : 0; - target->replace_file_mode = opts->replace_file_mode ? 1 : 0; - - target->uid = opts->replace_uid == 2 ? opts->uid : 0; - target->gid = opts->replace_gid == 2 ? opts->gid : 0; - target->dir_mode = opts->replace_dir_mode == 2 ? opts->dir_mode : 0555; - target->file_mode = opts->replace_file_mode == 2 ? opts->file_mode : 0444; - - target->now = time(NULL); - target->ms_block = opts->ms_block; - target->appendable = opts->appendable; - - target->replace_timestamps = opts->replace_timestamps ? 1 : 0; - target->timestamp = opts->replace_timestamps == 2 ? - opts->timestamp : target->now; - - /* el-torito? */ - target->eltorito = (src->bootcat == NULL ? 0 : 1); - target->catalog = src->bootcat; - - /* default to locale charset */ - setlocale(LC_CTYPE, ""); - target->input_charset = strdup(nl_langinfo(CODESET)); - if (target->input_charset == NULL) { - iso_image_unref(src); - free(target); - return ISO_OUT_OF_MEM; - } - - if (opts->output_charset != NULL) { - target->output_charset = strdup(opts->output_charset); - } else { - target->output_charset = strdup(target->input_charset); - } - if (target->output_charset == NULL) { - iso_image_unref(src); - free(target); - return ISO_OUT_OF_MEM; - } - - /* - * 2. Based on those options, create needed writers: iso, joliet... - * Each writer inits its structures and stores needed info into - * target. - * If the writer needs an volume descriptor, it increments image - * current block. - * Finally, create Writer for files. - */ - target->curblock = target->ms_block + 16; - - /* the number of writers is dependent of the extensions */ - nwriters = 1 + 1 + 1; /* ECMA-119 + padding + files */ - - if (target->eltorito) { - nwriters++; - } - if (target->joliet) { - nwriters++; - } - if (target->iso1999) { - nwriters++; - } - - target->writers = malloc(nwriters * sizeof(void*)); - if (target->writers == NULL) { - iso_image_unref(src); - free(target); - return ISO_OUT_OF_MEM; - } - - /* create writer for ECMA-119 structure */ - ret = ecma119_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - - /* create writer for El-Torito */ - if (target->eltorito) { - ret = eltorito_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - } - - /* create writer for Joliet structure */ - if (target->joliet) { - ret = joliet_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - } - - /* create writer for ISO 9660:1999 structure */ - if (target->iso1999) { - ret = iso1999_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - } - - voldesc_size = target->curblock - target->ms_block - 16; - - /* Volume Descriptor Set Terminator */ - target->curblock++; - - /* - * Create the writer for possible padding to ensure that in case of image - * growing we can safety overwrite the first 64 KiB of image. - */ - ret = pad_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - - /* create writer for file contents */ - ret = iso_file_src_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - - /* - * 3. - * Call compute_data_blocks() in each Writer. - * That function computes the size needed by its structures and - * increments image current block propertly. - */ - for (i = 0; i < target->nwriters; ++i) { - IsoImageWriter *writer = target->writers[i]; - ret = writer->compute_data_blocks(writer); - if (ret < 0) { - goto target_cleanup; - } - } - - /* create the ring buffer */ - ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer); - if (ret < 0) { - goto target_cleanup; - } - - /* check if we need to provide a copy of volume descriptors */ - if (opts->overwrite) { - - /* - * Get a copy of the volume descriptors to be written in a DVD+RW - * disc - */ - - uint8_t *buf; - struct ecma119_vol_desc_terminator *vol; - IsoImageWriter *writer; - - /* - * In the PVM to be written in the 16th sector of the disc, we - * need to specify the full size. - */ - target->vol_space_size = target->curblock; - - /* write volume descriptor */ - for (i = 0; i < target->nwriters; ++i) { - writer = target->writers[i]; - ret = writer->write_vol_desc(writer); - if (ret < 0) { - iso_msg_debug(target->image->id, - "Error writing overwrite volume descriptors"); - goto target_cleanup; - } - } - - /* skip the first 16 blocks (system area) */ - buf = opts->overwrite + 16 * BLOCK_SIZE; - voldesc_size *= BLOCK_SIZE; - - /* copy the volume descriptors to the overwrite buffer... */ - ret = iso_ring_buffer_read(target->buffer, buf, voldesc_size); - if (ret < 0) { - iso_msg_debug(target->image->id, - "Error reading overwrite volume descriptors"); - goto target_cleanup; - } - - /* ...including the vol desc terminator */ - memset(buf + voldesc_size, 0, BLOCK_SIZE); - vol = (struct ecma119_vol_desc_terminator*) (buf + voldesc_size); - vol->vol_desc_type[0] = 255; - memcpy(vol->std_identifier, "CD001", 5); - vol->vol_desc_version[0] = 1; - } - - /* - * The volume space size is just the size of the last session, in - * case of ms images. - */ - target->vol_space_size = target->curblock - target->ms_block; - target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE; - - /* 4. Create and start writting thread */ - - /* ensure the thread is created joinable */ - pthread_attr_init(&(target->th_attr)); - pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE); - - ret = pthread_create(&(target->wthread), &(target->th_attr), - write_function, (void *) target); - if (ret != 0) { - iso_msg_submit(target->image->id, ISO_THREAD_ERROR, 0, - "Cannot create writer thread"); - ret = ISO_THREAD_ERROR; - goto target_cleanup; - } - - /* - * Notice that once we reach this point, target belongs to the writer - * thread and should not be modified until the writer thread finished. - * There're however, specific fields in target that can be accessed, or - * even modified by the read thread (look inside bs_* functions) - */ - - *img = target; - return ISO_SUCCESS; - - target_cleanup: ; - ecma119_image_free(target); - return ret; -} - -static int bs_read(struct burn_source *bs, unsigned char *buf, int size) -{ - int ret; - Ecma119Image *t = (Ecma119Image*)bs->data; - - ret = iso_ring_buffer_read(t->buffer, buf, size); - if (ret == ISO_SUCCESS) { - return size; - } else if (ret < 0) { - /* error */ - iso_msg_submit(t->image->id, ISO_BUF_READ_ERROR, ret, NULL); - return -1; - } else { - /* EOF */ - return 0; - } -} - -static off_t bs_get_size(struct burn_source *bs) -{ - Ecma119Image *target = (Ecma119Image*)bs->data; - return target->total_size; -} - -static void bs_free_data(struct burn_source *bs) -{ - int st; - Ecma119Image *target = (Ecma119Image*)bs->data; - - st = iso_ring_buffer_get_status(bs, NULL, NULL); - - /* was read already finished (i.e, canceled)? */ - if (st < 4) { - /* forces writer to stop if it is still running */ - iso_ring_buffer_reader_close(target->buffer, 0); - - /* wait until writer thread finishes */ - pthread_join(target->wthread, NULL); - iso_msg_debug(target->image->id, "Writer thread joined"); - } - - iso_msg_debug(target->image->id, - "Ring buffer was %d times full and %d times empty", - iso_ring_buffer_get_times_full(target->buffer), - iso_ring_buffer_get_times_empty(target->buffer)); - - /* now we can safety free target */ - ecma119_image_free(target); -} - -static -int bs_cancel(struct burn_source *bs) -{ - int st; - size_t cap, free; - Ecma119Image *target = (Ecma119Image*)bs->data; - - st = iso_ring_buffer_get_status(bs, &cap, &free); - - if (free == cap && (st == 2 || st == 3)) { - /* image was already consumed */ - iso_ring_buffer_reader_close(target->buffer, 0); - } else { - iso_msg_debug(target->image->id, "Reader thread being cancelled"); - - /* forces writer to stop if it is still running */ - iso_ring_buffer_reader_close(target->buffer, ISO_CANCELED); - } - - /* wait until writer thread finishes */ - pthread_join(target->wthread, NULL); - - iso_msg_debug(target->image->id, "Writer thread joined"); - return ISO_SUCCESS; -} - -static -int bs_set_size(struct burn_source *bs, off_t size) -{ - Ecma119Image *target = (Ecma119Image*)bs->data; - - /* - * just set the value to be returned by get_size. This is not used at - * all by libisofs, it is here just for helping libburn to correctly pad - * the image if needed. - */ - target->total_size = size; - return 1; -} - -int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts, - struct burn_source **burn_src) -{ - int ret; - struct burn_source *source; - Ecma119Image *target= NULL; - - if (image == NULL || opts == NULL || burn_src == NULL) { - return ISO_NULL_POINTER; - } - - source = calloc(1, sizeof(struct burn_source)); - if (source == NULL) { - return ISO_OUT_OF_MEM; - } - - ret = ecma119_image_new(image, opts, &target); - if (ret < 0) { - free(source); - return ret; - } - - source->refcount = 1; - source->version = 1; - source->read = NULL; - source->get_size = bs_get_size; - source->set_size = bs_set_size; - source->free_data = bs_free_data; - source->read_xt = bs_read; - source->cancel = bs_cancel; - source->data = target; - - *burn_src = source; - return ISO_SUCCESS; -} - -int iso_write(Ecma119Image *target, void *buf, size_t count) -{ - int ret; - - ret = iso_ring_buffer_write(target->buffer, buf, count); - if (ret == 0) { - /* reader cancelled */ - return ISO_CANCELED; - } - - /* total size is 0 when writing the overwrite buffer */ - if (ret > 0 && (target->total_size != (off_t) 0)){ - unsigned int kbw, kbt; - int percent; - - target->bytes_written += (off_t) count; - kbw = (unsigned int) (target->bytes_written >> 10); - kbt = (unsigned int) (target->total_size >> 10); - percent = (kbw * 100) / kbt; - - /* only report in 5% chunks */ - if (percent >= target->percent_written + 5) { - iso_msg_debug(target->image->id, "Processed %u of %u KB (%d %%)", - kbw, kbt, percent); - target->percent_written = percent; - } - } - - return ret; -} - -int iso_write_opts_new(IsoWriteOpts **opts, int profile) -{ - IsoWriteOpts *wopts; - - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (profile < 0 || profile > 2) { - return ISO_WRONG_ARG_VALUE; - } - - wopts = calloc(1, sizeof(IsoWriteOpts)); - if (wopts == NULL) { - return ISO_OUT_OF_MEM; - } - - switch (profile) { - case 0: - wopts->level = 1; - break; - case 1: - wopts->level = 2; - wopts->rockridge = 1; - break; - case 2: - wopts->level = 2; - wopts->rockridge = 1; - wopts->joliet = 1; - wopts->replace_dir_mode = 1; - wopts->replace_file_mode = 1; - wopts->replace_uid = 1; - wopts->replace_gid = 1; - wopts->replace_timestamps = 1; - wopts->always_gmt = 1; - break; - default: - /* should never happen */ - free(wopts); - return ISO_ASSERT_FAILURE; - break; - } - wopts->fifo_size = 1024; /* 2 MB buffer */ - wopts->sort_files = 1; /* file sorting is always good */ - - *opts = wopts; - return ISO_SUCCESS; -} - -void iso_write_opts_free(IsoWriteOpts *opts) -{ - if (opts == NULL) { - return; - } - - free(opts->output_charset); - free(opts); -} - -int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (level != 1 && level != 2) { - return ISO_WRONG_ARG_VALUE; - } - opts->level = level; - return ISO_SUCCESS; -} - -int iso_write_opts_set_rockridge(IsoWriteOpts *opts, int enable) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->rockridge = enable ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->joliet = enable ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->iso1999 = enable ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->omit_version_numbers = omit ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->allow_deep_paths = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->allow_longer_paths = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_max_37_char_filenames(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->max_37_char_filenames = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->no_force_dots = no ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->allow_lowercase = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->allow_full_ascii = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->relaxed_vol_atts = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->joliet_longer_paths = allow ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->sort_files = sort ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_replace_mode(IsoWriteOpts *opts, int dir_mode, - int file_mode, int uid, int gid) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (dir_mode < 0 || dir_mode > 2) { - return ISO_WRONG_ARG_VALUE; - } - if (file_mode < 0 || file_mode > 2) { - return ISO_WRONG_ARG_VALUE; - } - if (uid < 0 || uid > 2) { - return ISO_WRONG_ARG_VALUE; - } - if (gid < 0 || gid > 2) { - return ISO_WRONG_ARG_VALUE; - } - opts->replace_dir_mode = dir_mode; - opts->replace_file_mode = file_mode; - opts->replace_uid = uid; - opts->replace_gid = gid; - return ISO_SUCCESS; -} - -int iso_write_opts_set_default_dir_mode(IsoWriteOpts *opts, mode_t dir_mode) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->dir_mode = dir_mode; - return ISO_SUCCESS; -} - -int iso_write_opts_set_default_file_mode(IsoWriteOpts *opts, mode_t file_mode) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->file_mode = file_mode; - return ISO_SUCCESS; -} - -int iso_write_opts_set_default_uid(IsoWriteOpts *opts, uid_t uid) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->uid = uid; - return ISO_SUCCESS; -} - -int iso_write_opts_set_default_gid(IsoWriteOpts *opts, gid_t gid) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->gid = gid; - return ISO_SUCCESS; -} - -int iso_write_opts_set_replace_timestamps(IsoWriteOpts *opts, int replace) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (replace < 0 || replace > 2) { - return ISO_WRONG_ARG_VALUE; - } - opts->replace_timestamps = replace; - return ISO_SUCCESS; -} - -int iso_write_opts_set_default_timestamp(IsoWriteOpts *opts, time_t timestamp) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->timestamp = timestamp; - return ISO_SUCCESS; -} - -int iso_write_opts_set_always_gmt(IsoWriteOpts *opts, int gmt) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->always_gmt = gmt ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_output_charset(IsoWriteOpts *opts, const char *charset) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->output_charset = charset ? strdup(charset) : NULL; - return ISO_SUCCESS; -} - -int iso_write_opts_set_appendable(IsoWriteOpts *opts, int appendable) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->appendable = appendable ? 1 : 0; - return ISO_SUCCESS; -} - -int iso_write_opts_set_ms_block(IsoWriteOpts *opts, uint32_t ms_block) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->ms_block = ms_block; - return ISO_SUCCESS; -} - -int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->overwrite = overwrite; - return ISO_SUCCESS; -} - -int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (fifo_size < 32) { - return ISO_WRONG_ARG_VALUE; - } - opts->fifo_size = fifo_size; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.h deleted file mode 100644 index ffb16116..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119.h +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_ECMA119_H_ -#define LIBISO_ECMA119_H_ - -#include "libisofs.h" -#include "util.h" -#include "buffer.h" - -#include -#include - -#define BLOCK_SIZE 2048 - -/** - * Holds the options for the image generation. - */ -struct iso_write_opts { - - int level; /**< ISO level to write at. (ECMA-119, 10) */ - - /** Which extensions to support. */ - unsigned int rockridge :1; - unsigned int joliet :1; - unsigned int iso1999 :1; - - /* allways write timestamps in GMT */ - unsigned int always_gmt :1; - - /* - * Relaxed constraints. Setting any of these to 1 break the specifications, - * but it is supposed to work on most moderns systems. Use with caution. - */ - - /** - * Omit the version number (";1") at the end of the ISO-9660 identifiers. - * Version numbers are usually not used. - */ - unsigned int omit_version_numbers :1; - - /** - * Allow ISO-9660 directory hierarchy to be deeper than 8 levels. - */ - unsigned int allow_deep_paths :1; - - /** - * 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 - */ - unsigned int no_force_dots :1; - - /** - * 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; - - /** - * Allow all characters to be part of Volume and Volset identifiers on - * the Primary Volume Descriptor. This breaks ISO-9660 contraints, but - * should work on modern systems. - */ - unsigned int relaxed_vol_atts :1; - - /** - * Allow paths in the Joliet tree to have more than 240 characters. - */ - unsigned int joliet_longer_paths :1; - - /** If files should be sorted based on their weight. */ - unsigned int sort_files :1; - - /** - * 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 setted 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. */ - - /** - * 0 to use IsoNode timestamps, 1 to use recording time, 2 to use - * values from timestamp field. This has only meaning if RR extensions - * are enabled. - */ - unsigned int replace_timestamps :2; - time_t timestamp; - - /** - * Charset for the RR filenames that will be created. - * NULL to use default charset, the locale one. - */ - char *output_charset; - - /** - * This flags control the type of the image to create. Libisofs support - * two kind of images: stand-alone and appendable. - * - * A stand-alone image is an image that is valid alone, and that can be - * mounted by its own. This is the kind of image you will want to create - * in most cases. A stand-alone image can be burned in an empty CD or DVD, - * or write to an .iso file for future burning or distribution. - * - * On the other side, an appendable image is not self contained, it refers - * to serveral files that are stored outside the image. Its usage is for - * multisession discs, where you add data in a new session, while the - * previous session data can still be accessed. In those cases, the old - * data is not written again. Instead, the new image refers to it, and thus - * it's only valid when appended to the original. Note that in those cases - * the image will be written after the original, and thus you will want - * to use a ms_block greater than 0. - * - * Note that if you haven't import a previous image (by means of - * iso_image_import()), the image will always be a stand-alone image, as - * there is no previous data to refer to. - */ - unsigned int appendable : 1; - - /** - * Start block of the image. It is supposed to be the lba where the first - * block of the image will be written on disc. All references inside the - * ISO image will take this into account, thus providing a mountable image. - * - * For appendable images, that are written to a new session, you should - * pass here the lba of the next writable address on disc. - * - * In stand alone images this is usually 0. However, you may want to - * provide a different ms_block if you don't plan to burn the image in the - * first session on disc, such as in some CD-Extra disc whether the data - * image is written in a new session after some audio tracks. - */ - uint32_t ms_block; - - /** - * When not NULL, it should point to a buffer of at least 64KiB, where - * libisofs will write the contents that should be written at the beginning - * of a overwriteable media, to grow the image. The growing of an image is - * a way, used by first time in growisofs by Andy Polyakov, to allow the - * appending of new data to non-multisession media, such as DVD+RW, in the - * same way you append a new session to a multisession disc, i.e., without - * need to write again the contents of the previous image. - * - * Note that if you want this kind of image growing, you will also need to - * set appendable to "1" and provide a valid ms_block after the previous - * image. - * - * You should initialize the buffer either with 0s, or with the contents of - * the first blocks of the image you're growing. In most cases, 0 is good - * enought. - */ - uint8_t *overwrite; - - /** - * Size, in number of blocks, of the FIFO buffer used between the writer - * thread and the burn_source. You have to provide at least a 32 blocks - * buffer. - */ - size_t fifo_size; -}; - -typedef struct ecma119_image Ecma119Image; -typedef struct ecma119_node Ecma119Node; -typedef struct joliet_node JolietNode; -typedef struct iso1999_node Iso1999Node; -typedef struct Iso_File_Src IsoFileSrc; -typedef struct Iso_Image_Writer IsoImageWriter; - -struct ecma119_image -{ - IsoImage *image; - Ecma119Node *root; - - unsigned int iso_level :2; - - /* extensions */ - unsigned int rockridge :1; - unsigned int joliet :1; - unsigned int eltorito :1; - unsigned int iso1999 :1; - - /* allways write timestamps in GMT */ - unsigned int always_gmt :1; - - /* relaxed constraints */ - unsigned int omit_version_numbers :1; - unsigned int allow_deep_paths :1; - unsigned int allow_longer_paths :1; - unsigned int max_37_char_filenames :1; - unsigned int no_force_dots :1; - unsigned int allow_lowercase :1; - unsigned int allow_full_ascii :1; - - unsigned int relaxed_vol_atts : 1; - - /** Allow paths on Joliet tree to be larger than 240 bytes */ - unsigned int joliet_longer_paths :1; - - /* - * Mode replace. If one of these flags is set, the correspodent values are - * replaced with values below. - */ - unsigned int replace_uid :1; - unsigned int replace_gid :1; - unsigned int replace_file_mode :1; - unsigned int replace_dir_mode :1; - unsigned int replace_timestamps :1; - - uid_t uid; - gid_t gid; - mode_t file_mode; - mode_t dir_mode; - time_t timestamp; - - /** - * if sort files or not. Sorting is based of the weight of each file - */ - int sort_files; - - /** - * In the CD, each file must have an unique inode number. So each - * time we add a new file, this is incremented. - */ - ino_t ino; - - char *input_charset; - char *output_charset; - - unsigned int appendable : 1; - uint32_t ms_block; /**< start block for a ms image */ - time_t now; /**< Time at which writing began. */ - - /** Total size of the output. This only includes the current volume. */ - off_t total_size; - uint32_t vol_space_size; - - /* Bytes already written, just for progress notification */ - off_t bytes_written; - int percent_written; - - /* - * Block being processed, either during image writing or structure - * size calculation. - */ - uint32_t curblock; - - /* - * number of dirs in ECMA-119 tree, computed together with dir position, - * and needed for path table computation in a efficient way - */ - size_t ndirs; - uint32_t path_table_size; - uint32_t l_path_table_pos; - uint32_t m_path_table_pos; - - /* - * Joliet related information - */ - JolietNode *joliet_root; - size_t joliet_ndirs; - uint32_t joliet_path_table_size; - uint32_t joliet_l_path_table_pos; - uint32_t joliet_m_path_table_pos; - - /* - * ISO 9660:1999 related information - */ - Iso1999Node *iso1999_root; - size_t iso1999_ndirs; - uint32_t iso1999_path_table_size; - uint32_t iso1999_l_path_table_pos; - uint32_t iso1999_m_path_table_pos; - - /* - * El-Torito related information - */ - struct el_torito_boot_catalog *catalog; - IsoFileSrc *cat; /**< location of the boot catalog in the new image */ - IsoFileSrc *bootimg; /**< location of the boot image in the new image */ - - /* - * Number of pad blocks that we need to write. Padding blocks are blocks - * filled by 0s that we put between the directory structures and the file - * data. These padding blocks are added by libisofs to improve the handling - * of image growing. The idea is that the first blocks in the image are - * overwritten with the volume descriptors of the new image. These first - * blocks usually correspond to the volume descriptors and directory - * structure of the old image, and can be safety overwritten. However, - * with very small images they might correspond to valid data. To ensure - * this never happens, what we do is to add padding bytes, to ensure no - * file data is written in the first 64 KiB, that are the bytes we usually - * overwrite. - */ - uint32_t pad_blocks; - - size_t nwriters; - IsoImageWriter **writers; - - /* tree of files sources */ - IsoRBTree *files; - - /* Buffer for communication between burn_source and writer thread */ - IsoRingBuffer *buffer; - - /* writer thread descriptor */ - pthread_t wthread; - pthread_attr_t th_attr; -}; - -#define BP(a,b) [(b) - (a) + 1] - -/* ECMA-119, 8.4 */ -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); -}; - -/* ECMA-119, 8.5 */ -struct ecma119_sup_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 vol_flags 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 esc_sequences 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); -}; - -/* ECMA-119, 8.2 */ -struct ecma119_boot_rec_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 boot_sys_id BP(8, 39); - uint8_t boot_id BP(40, 71); - uint8_t boot_catalog BP(72, 75); - uint8_t unused BP(76, 2048); -}; - -/* ECMA-119, 9.1 */ -struct ecma119_dir_record -{ - uint8_t len_dr BP(1, 1); - uint8_t len_xa BP(2, 2); - uint8_t block BP(3, 10); - uint8_t length BP(11, 18); - uint8_t recording_time BP(19, 25); - uint8_t flags BP(26, 26); - uint8_t file_unit_size BP(27, 27); - uint8_t interleave_gap_size BP(28, 28); - uint8_t vol_seq_number BP(29, 32); - uint8_t len_fi BP(33, 33); - uint8_t file_id BP(34, 34); /* 34 to 33+len_fi */ - /* padding field (if len_fi is even) */ - /* system use (len_dr - len_su + 1 to len_dr) */ -}; - -/* ECMA-119, 9.4 */ -struct ecma119_path_table_record -{ - uint8_t len_di BP(1, 1); - uint8_t len_xa BP(2, 2); - uint8_t block BP(3, 6); - uint8_t parent BP(7, 8); - uint8_t dir_id BP(9, 9); /* 9 to 8+len_di */ - /* padding field (if len_di is odd) */ -}; - -/* ECMA-119, 8.3 */ -struct ecma119_vol_desc_terminator -{ - 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 reserved BP(8, 2048); -}; - -#endif /*LIBISO_ECMA119_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.c deleted file mode 100644 index 943fa0a4..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "ecma119_tree.h" -#include "ecma119.h" -#include "node.h" -#include "util.h" -#include "filesrc.h" -#include "messages.h" -#include "image.h" -#include "stream.h" -#include "eltorito.h" - -#include -#include -#include - -static -int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name) -{ - int ret, relaxed; - char *ascii_name; - char *isoname= NULL; - - if (iso->name == NULL) { - /* it is not necessarily an error, it can be the root */ - return ISO_SUCCESS; - } - - ret = str2ascii(img->input_charset, iso->name, &ascii_name); - if (ret < 0) { - iso_msg_submit(img->image->id, ret, 0, "Can't convert %s", iso->name); - return ret; - } - - if (img->allow_full_ascii) { - relaxed = 2; - } else { - relaxed = (int)img->allow_lowercase; - } - if (iso->type == LIBISO_DIR) { - if (img->max_37_char_filenames) { - isoname = iso_r_dirid(ascii_name, 37, relaxed); - } else if (img->iso_level == 1) { - if (relaxed) { - isoname = iso_r_dirid(ascii_name, 8, relaxed); - } else { - isoname = iso_1_dirid(ascii_name); - } - } else { - if (relaxed) { - isoname = iso_r_dirid(ascii_name, 8, relaxed); - } else { - isoname = iso_2_dirid(ascii_name); - } - } - } else { - if (img->max_37_char_filenames) { - isoname = iso_r_fileid(ascii_name, 36, relaxed, - img->no_force_dots ? 0 : 1); - } else if (img->iso_level == 1) { - if (relaxed) { - isoname = iso_r_fileid(ascii_name, 11, relaxed, - img->no_force_dots ? 0 : 1); - } else { - isoname = iso_1_fileid(ascii_name); - } - } else { - if (relaxed) { - isoname = iso_r_fileid(ascii_name, 30, relaxed, - img->no_force_dots ? 0 : 1); - } else { - isoname = iso_2_fileid(ascii_name); - } - } - } - free(ascii_name); - if (isoname != NULL) { - *name = isoname; - return ISO_SUCCESS; - } else { - /* - * only possible if mem error, as check for empty names is done - * in public tree - */ - return ISO_OUT_OF_MEM; - } -} - -static -int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node) -{ - Ecma119Node *ecma; - - ecma = calloc(1, sizeof(Ecma119Node)); - if (ecma == NULL) { - return ISO_OUT_OF_MEM; - } - - /* take a ref to the IsoNode */ - ecma->node = iso; - iso_node_ref(iso); - - /* TODO #00009 : add true support for harlinks and inode numbers */ - ecma->nlink = 1; - ecma->ino = ++img->ino; - - *node = ecma; - return ISO_SUCCESS; -} - -/** - * Create a new ECMA-119 node representing a directory from a iso directory - * node. - */ -static -int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node) -{ - int ret; - Ecma119Node **children; - struct ecma119_dir_info *dir_info; - - children = calloc(1, sizeof(void*) * iso->nchildren); - if (children == NULL) { - return ISO_OUT_OF_MEM; - } - - dir_info = calloc(1, sizeof(struct ecma119_dir_info)); - if (dir_info == NULL) { - free(children); - return ISO_OUT_OF_MEM; - } - - ret = create_ecma119_node(img, (IsoNode*)iso, node); - if (ret < 0) { - free(children); - free(dir_info); - return ret; - } - (*node)->type = ECMA119_DIR; - (*node)->info.dir = dir_info; - (*node)->info.dir->nchildren = 0; - (*node)->info.dir->children = children; - return ISO_SUCCESS; -} - -/** - * Create a new ECMA-119 node representing a regular file from a iso file - * node. - */ -static -int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node) -{ - int ret; - IsoFileSrc *src; - off_t size; - - size = iso_stream_get_size(iso->stream); - if (size > (off_t)0xffffffff) { - return iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0, - "File \"%s\" can't be added to image because " - "is greater than 4GB", iso->node.name); - } - - ret = iso_file_src_create(img, iso, &src); - if (ret < 0) { - return ret; - } - - ret = create_ecma119_node(img, (IsoNode*)iso, node); - if (ret < 0) { - /* - * the src doesn't need to be freed, it is free together with - * the Ecma119Image - */ - return ret; - } - (*node)->type = ECMA119_FILE; - (*node)->info.file = src; - - return ret; -} - -/** - * Create a new ECMA-119 node representing a regular file from an El-Torito - * boot catalog - */ -static -int create_boot_cat(Ecma119Image *img, IsoBoot *iso, Ecma119Node **node) -{ - int ret; - IsoFileSrc *src; - - ret = el_torito_catalog_file_src_create(img, &src); - if (ret < 0) { - return ret; - } - - ret = create_ecma119_node(img, (IsoNode*)iso, node); - if (ret < 0) { - /* - * the src doesn't need to be freed, it is free together with - * the Ecma119Image - */ - return ret; - } - (*node)->type = ECMA119_FILE; - (*node)->info.file = src; - - return ret; -} - -/** - * Create a new ECMA-119 node representing a symbolic link from a iso symlink - * node. - */ -static -int create_symlink(Ecma119Image *img, IsoSymlink *iso, Ecma119Node **node) -{ - int ret; - - ret = create_ecma119_node(img, (IsoNode*)iso, node); - if (ret < 0) { - return ret; - } - (*node)->type = ECMA119_SYMLINK; - return ISO_SUCCESS; -} - -/** - * Create a new ECMA-119 node representing a special file. - */ -static -int create_special(Ecma119Image *img, IsoSpecial *iso, Ecma119Node **node) -{ - int ret; - - ret = create_ecma119_node(img, (IsoNode*)iso, node); - if (ret < 0) { - return ret; - } - (*node)->type = ECMA119_SPECIAL; - return ISO_SUCCESS; -} - -void ecma119_node_free(Ecma119Node *node) -{ - if (node == NULL) { - return; - } - if (node->type == ECMA119_DIR) { - int i; - for (i = 0; i < node->info.dir->nchildren; i++) { - ecma119_node_free(node->info.dir->children[i]); - } - free(node->info.dir->children); - free(node->info.dir); - } - free(node->iso_name); - iso_node_unref(node->node); - free(node); -} - -/** - * - * @return - * 1 success, 0 node ignored, < 0 error - * - */ -static -int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, - int depth, int pathlen) -{ - int ret; - Ecma119Node *node; - int max_path; - char *iso_name= NULL; - - if (image == NULL || iso == NULL || tree == NULL) { - return ISO_NULL_POINTER; - } - - if (iso->hidden & LIBISO_HIDE_ON_RR) { - /* file will be ignored */ - return 0; - } - ret = get_iso_name(image, iso, &iso_name); - if (ret < 0) { - return ret; - } - max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0); - if (!image->rockridge) { - if ((iso->type == LIBISO_DIR && depth > 8) && !image->allow_deep_paths) { - free(iso_name); - return iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added, because directory depth " - "is greater than 8.", iso->name); - } else if (max_path > 255 && !image->allow_longer_paths) { - free(iso_name); - return iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added, because path length " - "is greater than 255 characters", iso->name); - } - } - - switch (iso->type) { - case LIBISO_FILE: - ret = create_file(image, (IsoFile*)iso, &node); - break; - case LIBISO_SYMLINK: - if (image->rockridge) { - ret = create_symlink(image, (IsoSymlink*)iso, &node); - } else { - /* symlinks are only supported when RR is enabled */ - ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0, - "File \"%s\" ignored. Symlinks need RockRidge extensions.", - iso->name); - } - break; - case LIBISO_SPECIAL: - if (image->rockridge) { - ret = create_special(image, (IsoSpecial*)iso, &node); - } else { - /* symlinks are only supported when RR is enabled */ - ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0, - "File \"%s\" ignored. Special files need RockRidge extensions.", - iso->name); - } - break; - case LIBISO_BOOT: - if (image->eltorito) { - ret = create_boot_cat(image, (IsoBoot*)iso, &node); - } else { - /* log and ignore */ - ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0, - "El-Torito catalog found on a image without El-Torito.", - iso->name); - } - break; - case LIBISO_DIR: - { - IsoNode *pos; - IsoDir *dir = (IsoDir*)iso; - ret = create_dir(image, dir, &node); - if (ret < 0) { - return ret; - } - pos = dir->children; - while (pos) { - int cret; - Ecma119Node *child; - cret = create_tree(image, pos, &child, depth + 1, max_path); - if (cret < 0) { - /* error */ - ecma119_node_free(node); - ret = cret; - break; - } else if (cret == ISO_SUCCESS) { - /* add child to this node */ - int nchildren = node->info.dir->nchildren++; - node->info.dir->children[nchildren] = child; - child->parent = node; - } - pos = pos->next; - } - } - break; - default: - /* should never happen */ - return ISO_ASSERT_FAILURE; - } - if (ret <= 0) { - free(iso_name); - return ret; - } - node->iso_name = iso_name; - *tree = node; - return ISO_SUCCESS; -} - -/** - * Compare the iso name of two ECMA-119 nodes - */ -static -int cmp_node_name(const void *f1, const void *f2) -{ - Ecma119Node *f = *((Ecma119Node**)f1); - Ecma119Node *g = *((Ecma119Node**)f2); - return strcmp(f->iso_name, g->iso_name); -} - -/** - * Sorts a the children of each directory in the ECMA-119 tree represented - * by \p root, acording to the order specified in ECMA-119, section 9.3. - */ -static -void sort_tree(Ecma119Node *root) -{ - size_t i; - - qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*), - cmp_node_name); - for (i = 0; i < root->info.dir->nchildren; i++) { - if (root->info.dir->children[i]->type == ECMA119_DIR) - sort_tree(root->info.dir->children[i]); - } -} - -/** - * Ensures that the ISO name of each children of the given dir is unique, - * changing some of them if needed. - * It also ensures that resulting filename is always <= than given - * max_name_len, including extension. If needed, the extension will be reduced, - * but never under 3 characters. - */ -static -int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, - int max_dir_len) -{ - int ret; - int i, nchildren; - Ecma119Node **children; - IsoHTable *table; - int need_sort = 0; - - nchildren = dir->info.dir->nchildren; - children = dir->info.dir->children; - - /* a hash table will temporary hold the names, for fast searching */ - ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash, - (compare_function_t)strcmp, &table); - if (ret < 0) { - return ret; - } - for (i = 0; i < nchildren; ++i) { - char *name = children[i]->iso_name; - ret = iso_htable_add(table, name, name); - if (ret < 0) { - goto mangle_cleanup; - } - } - - for (i = 0; i < nchildren; ++i) { - char *name, *ext; - char full_name[40]; - int max; /* computed max len for name, without extension */ - int j = i; - int digits = 1; /* characters to change per name */ - - /* first, find all child with same name */ - while (j + 1 < nchildren && !cmp_node_name(children + i, children + j - + 1)) { - ++j; - } - if (j == i) { - /* name is unique */ - continue; - } - - /* - * A max of 7 characters is good enought, it allows handling up to - * 9,999,999 files with same name. We can increment this to - * max_name_len, but the int_pow() function must then be modified - * to return a bigger integer. - */ - while (digits < 8) { - int ok, k; - char *dot; - int change = 0; /* number to be written */ - - /* copy name to buffer */ - strcpy(full_name, children[i]->iso_name); - - /* compute name and extension */ - dot = strrchr(full_name, '.'); - if (dot != NULL && children[i]->type != ECMA119_DIR) { - - /* - * File (not dir) with extension - * Note that we don't need to check for placeholders, as - * tree reparent happens later, so no placeholders can be - * here at this time. - */ - int extlen; - full_name[dot - full_name] = '\0'; - name = full_name; - ext = dot + 1; - - /* - * For iso level 1 we force ext len to be 3, as name - * can't grow on the extension space - */ - extlen = (max_file_len == 12) ? 3 : strlen(ext); - max = max_file_len - extlen - 1 - digits; - if (max <= 0) { - /* this can happen if extension is too long */ - if (extlen + max > 3) { - /* - * reduce extension len, to give name an extra char - * note that max is negative or 0 - */ - extlen = extlen + max - 1; - ext[extlen] = '\0'; - max = max_file_len - extlen - 1 - digits; - } else { - /* - * error, we don't support extensions < 3 - * This can't happen with current limit of digits. - */ - ret = ISO_ERROR; - goto mangle_cleanup; - } - } - /* ok, reduce name by digits */ - if (name + max < dot) { - name[max] = '\0'; - } - } else { - /* Directory, or file without extension */ - if (children[i]->type == ECMA119_DIR) { - max = max_dir_len - digits; - dot = NULL; /* dots have no meaning in dirs */ - } else { - max = max_file_len - digits; - } - name = full_name; - if (max < strlen(name)) { - name[max] = '\0'; - } - /* let ext be an empty string */ - ext = name + strlen(name); - } - - ok = 1; - /* change name of each file */ - for (k = i; k <= j; ++k) { - char tmp[40]; - char fmt[16]; - if (dot != NULL) { - sprintf(fmt, "%%s%%0%dd.%%s", digits); - } else { - sprintf(fmt, "%%s%%0%dd%%s", digits); - } - while (1) { - sprintf(tmp, fmt, name, change, ext); - ++change; - if (change > int_pow(10, digits)) { - ok = 0; - break; - } - if (!iso_htable_get(table, tmp, NULL)) { - /* the name is unique, so it can be used */ - break; - } - } - if (ok) { - char *new = strdup(tmp); - if (new == NULL) { - ret = ISO_OUT_OF_MEM; - goto mangle_cleanup; - } - iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"", - children[k]->iso_name, new); - - iso_htable_remove_ptr(table, children[k]->iso_name, NULL); - free(children[k]->iso_name); - children[k]->iso_name = new; - iso_htable_add(table, new, new); - - /* - * if we change a name we need to sort again children - * at the end - */ - need_sort = 1; - } else { - /* we need to increment digits */ - break; - } - } - if (ok) { - break; - } else { - ++digits; - } - } - if (digits == 8) { - ret = ISO_MANGLE_TOO_MUCH_FILES; - goto mangle_cleanup; - } - i = j; - } - - /* - * If needed, sort again the files inside dir - */ - if (need_sort) { - qsort(children, nchildren, sizeof(void*), cmp_node_name); - } - - ret = ISO_SUCCESS; - -mangle_cleanup : ; - iso_htable_destroy(table, NULL); - return ret; -} - -static -int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, - int max_dir_len) -{ - int ret; - size_t i; - - ret = mangle_single_dir(img, dir, max_file_len, max_dir_len); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < dir->info.dir->nchildren; ++i) { - if (dir->info.dir->children[i]->type == ECMA119_DIR) { - ret = mangle_dir(img, dir->info.dir->children[i], max_file_len, - max_dir_len); - if (ret < 0) { - /* error */ - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int mangle_tree(Ecma119Image *img, int recurse) -{ - int max_file, max_dir; - - if (img->max_37_char_filenames) { - max_file = max_dir = 37; - } else if (img->iso_level == 1) { - max_file = 12; /* 8 + 3 + 1 */ - max_dir = 8; - } else { - max_file = max_dir = 31; - } - if (recurse) { - return mangle_dir(img, img->root, max_file, max_dir); - } else { - return mangle_single_dir(img, img->root, max_file, max_dir); - } -} - -/** - * Create a new ECMA-119 node representing a placeholder for a relocated - * dir. - * - * See IEEE P1282, section 4.1.5 for details - */ -static -int create_placeholder(Ecma119Node *parent, Ecma119Node *real, - Ecma119Node **node) -{ - Ecma119Node *ret; - - ret = calloc(1, sizeof(Ecma119Node)); - if (ret == NULL) { - return ISO_OUT_OF_MEM; - } - - /* - * TODO - * If real is a dir, while placeholder is a file, ISO name restricctions - * are different, what to do? - */ - ret->iso_name = strdup(real->iso_name); - if (ret->iso_name == NULL) { - free(ret); - return ISO_OUT_OF_MEM; - } - - /* take a ref to the IsoNode */ - ret->node = real->node; - iso_node_ref(real->node); - ret->parent = parent; - ret->type = ECMA119_PLACEHOLDER; - ret->info.real_me = real; - ret->ino = real->ino; - ret->nlink = real->nlink; - - *node = ret; - return ISO_SUCCESS; -} - -static -size_t max_child_name_len(Ecma119Node *dir) -{ - size_t ret = 0, i; - for (i = 0; i < dir->info.dir->nchildren; i++) { - size_t len = strlen(dir->info.dir->children[i]->iso_name); - ret = MAX(ret, len); - } - return ret; -} - -/** - * Relocates a directory, as specified in Rock Ridge Specification - * (see IEEE P1282, section 4.1.5). This is needed when the number of levels - * on a directory hierarchy exceeds 8, or the length of a path is higher - * than 255 characters, as specified in ECMA-119, section 6.8.2.1 - */ -static -int reparent(Ecma119Node *child, Ecma119Node *parent) -{ - int ret; - size_t i; - Ecma119Node *placeholder; - - /* replace the child in the original parent with a placeholder */ - for (i = 0; i < child->parent->info.dir->nchildren; i++) { - if (child->parent->info.dir->children[i] == child) { - ret = create_placeholder(child->parent, child, &placeholder); - if (ret < 0) { - return ret; - } - child->parent->info.dir->children[i] = placeholder; - break; - } - } - - /* just for debug, this should never happen... */ - if (i == child->parent->info.dir->nchildren) { - return ISO_ASSERT_FAILURE; - } - - /* keep track of the real parent */ - child->info.dir->real_parent = child->parent; - - /* add the child to its new parent */ - child->parent = parent; - parent->info.dir->nchildren++; - parent->info.dir->children = realloc(parent->info.dir->children, - sizeof(void*) * parent->info.dir->nchildren); - parent->info.dir->children[parent->info.dir->nchildren - 1] = child; - return ISO_SUCCESS; -} - -/** - * Reorder the tree, if necessary, to ensure that - * - the depth is at most 8 - * - each path length is at most 255 characters - * This restriction is imposed by ECMA-119 specification (ECMA-119, 6.8.2.1). - * - * @param dir - * Dir we are currently processing - * @param level - * Level of the directory in the hierarchy - * @param pathlen - * Length of the path until dir, including it - * @return - * 1 success, < 0 error - */ -static -int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen) -{ - int ret; - size_t max_path; - - max_path = pathlen + 1 + max_child_name_len(dir); - - if (level > 8 || max_path > 255) { - ret = reparent(dir, img->root); - if (ret < 0) { - return ret; - } - - /* - * we are appended to the root's children now, so there is no - * need to recurse (the root will hit us again) - */ - } else { - size_t i; - - for (i = 0; i < dir->info.dir->nchildren; i++) { - Ecma119Node *child = dir->info.dir->children[i]; - if (child->type == ECMA119_DIR) { - int newpathlen = pathlen + 1 + strlen(child->iso_name); - ret = reorder_tree(img, child, level + 1, newpathlen); - if (ret < 0) { - return ret; - } - } - } - } - return ISO_SUCCESS; -} - -int ecma119_tree_create(Ecma119Image *img) -{ - int ret; - Ecma119Node *root; - - ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0); - if (ret <= 0) { - if (ret == 0) { - /* unexpected error, root ignored!! This can't happen */ - ret = ISO_ASSERT_FAILURE; - } - return ret; - } - img->root = root; - - iso_msg_debug(img->image->id, "Sorting the low level tree..."); - sort_tree(root); - - iso_msg_debug(img->image->id, "Mangling names..."); - ret = mangle_tree(img, 1); - if (ret < 0) { - return ret; - } - - if (img->rockridge && !img->allow_deep_paths) { - - /* reorder the tree, acording to RRIP, 4.1.5 */ - ret = reorder_tree(img, img->root, 1, 0); - if (ret < 0) { - return ret; - } - - /* - * and we need to remangle the root directory, as the function - * above could insert new directories into the root. - * Note that recurse = 0, as we don't need to recurse. - */ - ret = mangle_tree(img, 0); - if (ret < 0) { - return ret; - } - } - - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.h deleted file mode 100644 index 0cd05ee9..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/ecma119_tree.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_ECMA119_TREE_H_ -#define LIBISO_ECMA119_TREE_H_ - -#include "libisofs.h" -#include "ecma119.h" - -enum ecma119_node_type { - ECMA119_FILE, - ECMA119_DIR, - ECMA119_SYMLINK, - ECMA119_SPECIAL, - ECMA119_PLACEHOLDER -}; - -/** - * Struct with info about a node representing a directory - */ -struct ecma119_dir_info -{ - /* Block where the directory entries will be written on image */ - size_t block; - - size_t nchildren; - Ecma119Node **children; - - /* - * Size of the dir, i.e., sum of the lengths of all directory records. - * It is computed by calc_dir_size() [ecma119.c]. - * Note that this don't include the length of any SUSP Continuation - * Area needed by the dir, but it includes the size of the SUSP entries - * than fit in the directory records System Use Field. - */ - size_t len; - - /** - * Real parent if the dir has been reallocated. NULL otherwise. - */ - Ecma119Node *real_parent; -}; - -/** - * A node for a tree containing all the information necessary for writing - * an ISO9660 volume. - */ -struct ecma119_node -{ - /** - * Name in ASCII, conforming to selected ISO level. - * Version number is not include, it is added on the fly - */ - char *iso_name; - - Ecma119Node *parent; - - IsoNode *node; /*< reference to the iso node */ - - /* TODO #00009 : add true support for harlinks and inode numbers */ - ino_t ino; - nlink_t nlink; - - /**< file, symlink, special, directory or placeholder */ - enum ecma119_node_type type; - union - { - IsoFileSrc *file; - struct ecma119_dir_info *dir; - /** this field points to the relocated directory. */ - Ecma119Node *real_me; - } info; -}; - -/** - * - */ -int ecma119_tree_create(Ecma119Image *img); - -/** - * Free an Ecma119Node, and its children if node is a dir - */ -void ecma119_node_free(Ecma119Node *node); - -#endif /*LIBISO_ECMA119_TREE_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.c deleted file mode 100644 index 441b5c15..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.c +++ /dev/null @@ -1,908 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "eltorito.h" -#include "stream.h" -#include "fsource.h" -#include "filesrc.h" -#include "image.h" -#include "messages.h" -#include "writer.h" - -#include -#include - -/** - * This table should be written with accuracy values at offset - * 8 of boot image, when used ISOLINUX boot loader - */ -struct boot_info_table { - uint8_t bi_pvd BP(1, 4); /* LBA of primary volume descriptor */ - uint8_t bi_file BP(5, 8); /* LBA of boot file */ - uint8_t bi_length BP(9, 12); /* Length of boot file */ - uint8_t bi_csum BP(13, 16); /* Checksum of boot file */ - uint8_t bi_reserved BP(17, 56); /* Reserved */ -}; - -/** - * Structure for each one of the four entries in a partition table on a - * hard disk image. - */ -struct partition_desc { - uint8_t boot_ind; - uint8_t begin_chs[3]; - uint8_t type; - uint8_t end_chs[3]; - uint8_t start[4]; - uint8_t size[4]; -}; - -/** - * Structures for a Master Boot Record of a hard disk image. - */ -struct hard_disc_mbr { - uint8_t code_area[440]; - uint8_t opt_disk_sg[4]; - uint8_t pad[2]; - struct partition_desc partition[4]; - uint8_t sign1; - uint8_t sign2; -}; - -/** - * Sets the load segment for the initial boot image. This is only for - * no emulation boot images, and is a NOP for other image types. - */ -void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment) -{ - if (bootimg->type != ELTORITO_NO_EMUL) - return; - bootimg->load_seg = segment; -} - -/** - * Sets the number of sectors (512b) to be load at load segment during - * the initial boot procedure. This is only for no emulation boot images, - * and is a NOP for other image types. - */ -void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors) -{ - if (bootimg->type != ELTORITO_NO_EMUL) - return; - bootimg->load_size = sectors; -} - -/** - * Marks the specified boot image as not bootable - */ -void el_torito_set_no_bootable(ElToritoBootImage *bootimg) -{ - bootimg->bootable = 0; -} - -/** - * Specifies that this image needs to be patched. This involves the writting - * of a 56 bytes boot information table at offset 8 of the boot image file. - * The original boot image file won't be modified. - * This is needed for isolinux boot images. - */ -void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg) -{ - bootimg->isolinux = 1; -} - -static -int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot) -{ - IsoBoot *node; - IsoNode **pos; - time_t now; - - if (parent == NULL || name == NULL || boot == NULL) { - return ISO_NULL_POINTER; - } - if (boot) { - *boot = NULL; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - /* find place where to insert */ - pos = &(parent->children); - while (*pos != NULL && strcmp((*pos)->name, name) < 0) { - pos = &((*pos)->next); - } - if (*pos != NULL && !strcmp((*pos)->name, name)) { - /* a node with same name already exists */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - - node = calloc(1, sizeof(IsoBoot)); - if (node == NULL) { - return ISO_OUT_OF_MEM; - } - - node->node.refcount = 1; - node->node.type = LIBISO_BOOT; - node->node.name = strdup(name); - if (node->node.name == NULL) { - free(node); - return ISO_OUT_OF_MEM; - } - - /* atributes from parent */ - node->node.mode = S_IFREG | (parent->node.mode & 0444); - node->node.uid = parent->node.uid; - node->node.gid = parent->node.gid; - node->node.hidden = parent->node.hidden; - - /* current time */ - now = time(NULL); - node->node.atime = now; - node->node.ctime = now; - node->node.mtime = now; - - /* add to dir */ - node->node.parent = parent; - node->node.next = *pos; - *pos = (IsoNode*)node; - - if (boot) { - *boot = node; - } - return ++parent->nchildren; -} - - -static -int create_image(IsoImage *image, const char *image_path, - enum eltorito_boot_media_type type, - struct el_torito_boot_image **bootimg) -{ - int ret; - struct el_torito_boot_image *boot; - int boot_media_type = 0; - int load_sectors = 0; /* number of sector to load */ - unsigned char partition_type = 0; - IsoNode *imgfile; - IsoStream *stream; - - ret = iso_tree_path_to_node(image, image_path, &imgfile); - if (ret < 0) { - return ret; - } - if (ret == 0) { - return ISO_NODE_DOESNT_EXIST; - } - - if (imgfile->type != LIBISO_FILE) { - return ISO_BOOT_IMAGE_NOT_VALID; - } - - stream = ((IsoFile*)imgfile)->stream; - - /* we need to read the image at least two times */ - if (!iso_stream_is_repeatable(stream)) { - return ISO_BOOT_IMAGE_NOT_VALID; - } - - switch (type) { - case ELTORITO_FLOPPY_EMUL: - switch (iso_stream_get_size(stream)) { - case 1200 * 1024: - boot_media_type = 1; /* 1.2 meg diskette */ - break; - case 1440 * 1024: - boot_media_type = 2; /* 1.44 meg diskette */ - break; - case 2880 * 1024: - boot_media_type = 3; /* 2.88 meg diskette */ - break; - default: - iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, - "Invalid image size %d Kb. Must be one of 1.2, 1.44" - "or 2.88 Mb", iso_stream_get_size(stream) / 1024); - return ISO_BOOT_IMAGE_NOT_VALID; - break; - } - /* it seems that for floppy emulation we need to load - * a single sector (512b) */ - load_sectors = 1; - break; - case ELTORITO_HARD_DISC_EMUL: - { - size_t i; - struct hard_disc_mbr mbr; - int used_partition; - - /* read the MBR on disc and get the type of the partition */ - ret = iso_stream_open(stream); - if (ret < 0) { - iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, ret, - "Can't open image file."); - return ret; - } - ret = iso_stream_read(stream, &mbr, sizeof(mbr)); - iso_stream_close(stream); - if (ret != sizeof(mbr)) { - iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, - "Can't read MBR from image file."); - return ret < 0 ? ret : ISO_FILE_READ_ERROR; - } - - /* check valid MBR signature */ - if ( mbr.sign1 != 0x55 || mbr.sign2 != 0xAA ) { - iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, - "Invalid MBR. Wrong signature."); - return ISO_BOOT_IMAGE_NOT_VALID; - } - - /* ensure single partition */ - used_partition = -1; - for (i = 0; i < 4; ++i) { - if (mbr.partition[i].type != 0) { - /* it's an used partition */ - if (used_partition != -1) { - iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, - "Invalid MBR. At least 2 partitions: %d and " - "%d, are being used\n", used_partition, i); - return ISO_BOOT_IMAGE_NOT_VALID; - } else - used_partition = i; - } - } - partition_type = mbr.partition[used_partition].type; - } - boot_media_type = 4; - - /* only load the MBR */ - load_sectors = 1; - break; - case ELTORITO_NO_EMUL: - boot_media_type = 0; - break; - } - - boot = calloc(1, sizeof(struct el_torito_boot_image)); - if (boot == NULL) { - return ISO_OUT_OF_MEM; - } - boot->image = (IsoFile*)imgfile; - iso_node_ref(imgfile); /* get our ref */ - boot->bootable = 1; - boot->type = boot_media_type; - boot->load_size = load_sectors; - boot->partition_type = partition_type; - - if (bootimg) { - *bootimg = boot; - } - - return ISO_SUCCESS; -} - -int iso_image_set_boot_image(IsoImage *image, const char *image_path, - enum eltorito_boot_media_type type, - const char *catalog_path, - ElToritoBootImage **boot) -{ - int ret; - struct el_torito_boot_catalog *catalog; - ElToritoBootImage *boot_image= NULL; - IsoBoot *cat_node= NULL; - - if (image == NULL || image_path == NULL || catalog_path == NULL) { - return ISO_NULL_POINTER; - } - if (image->bootcat != NULL) { - return ISO_IMAGE_ALREADY_BOOTABLE; - } - - /* create the node for the catalog */ - { - IsoDir *parent; - char *catdir = NULL, *catname = NULL; - catdir = strdup(catalog_path); - if (catdir == NULL) { - return ISO_OUT_OF_MEM; - } - - /* get both the dir and the name */ - catname = strrchr(catdir, '/'); - if (catname == NULL) { - free(catdir); - return ISO_WRONG_ARG_VALUE; - } - if (catname == catdir) { - /* we are apending catalog to root node */ - parent = image->root; - } else { - IsoNode *p; - catname[0] = '\0'; - ret = iso_tree_path_to_node(image, catdir, &p); - if (ret <= 0) { - free(catdir); - return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST; - } - if (p->type != LIBISO_DIR) { - free(catdir); - return ISO_WRONG_ARG_VALUE; - } - parent = (IsoDir*)p; - } - catname++; - ret = iso_tree_add_boot_node(parent, catname, &cat_node); - free(catdir); - if (ret < 0) { - return ret; - } - } - - /* create the boot image */ - ret = create_image(image, image_path, type, &boot_image); - if (ret < 0) { - goto boot_image_cleanup; - } - - /* creates the catalog with the given image */ - catalog = malloc(sizeof(struct el_torito_boot_catalog)); - if (catalog == NULL) { - ret = ISO_OUT_OF_MEM; - goto boot_image_cleanup; - } - catalog->image = boot_image; - catalog->node = cat_node; - iso_node_ref((IsoNode*)cat_node); - image->bootcat = catalog; - - if (boot) { - *boot = boot_image; - } - - return ISO_SUCCESS; - -boot_image_cleanup:; - if (cat_node) { - iso_node_take((IsoNode*)cat_node); - iso_node_unref((IsoNode*)cat_node); - } - if (boot_image) { - iso_node_unref((IsoNode*)boot_image->image); - free(boot_image); - } - return ret; -} - -/** - * Get El-Torito boot image of an ISO image, if any. - * - * This can be useful, for example, to check if a volume read from a previous - * session or an existing image is bootable. It can also be useful to get - * the image and catalog tree nodes. An application would want those, for - * example, to prevent the user removing it. - * - * Both nodes are owned by libisofs and should not be freed. You can get your - * own ref with iso_node_ref(). You can can also check if the node is already - * on the tree by getting its parent (note that when reading El-Torito info - * from a previous image, the nodes might not be on the tree even if you haven't - * removed them). Remember that you'll need to get a new ref - * (with iso_node_ref()) before inserting them again to the tree, and probably - * you will also need to set the name or permissions. - * - * @param image - * The image from which to get the boot image. - * @param boot - * If not NULL, it will be filled with a pointer to the boot image, if - * any. That object is owned by the IsoImage and should not be freed by - * the user, nor dereferenced once the last reference to the IsoImage was - * disposed via iso_image_unref(). - * @param imgnode - * When not NULL, it will be filled with the image tree node. No extra ref - * is added, you can use iso_node_ref() to get one if you need it. - * @param catnode - * When not NULL, it will be filled with the catnode tree node. No extra - * ref is added, you can use iso_node_ref() to get one if you need it. - * @return - * 1 on success, 0 is the image is not bootable (i.e., it has no El-Torito - * image), < 0 error. - */ -int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot, - IsoFile **imgnode, IsoBoot **catnode) -{ - if (image == NULL) { - return ISO_NULL_POINTER; - } - if (image->bootcat == NULL) { - return 0; - } - - /* ok, image is bootable */ - if (boot) { - *boot = image->bootcat->image; - } - if (imgnode) { - *imgnode = image->bootcat->image->image; - } - if (catnode) { - *catnode = image->bootcat->node; - } - return ISO_SUCCESS; -} - -/** - * Removes the El-Torito bootable image. - * - * The IsoBoot node that acts as placeholder for the catalog is also removed - * for the image tree, if there. - * If the image is not bootable (don't have el-torito boot image) this function - * just returns. - */ -void iso_image_remove_boot_image(IsoImage *image) -{ - if (image == NULL || image->bootcat == NULL) - return; - - /* - * remove catalog node from its parent - * (the reference will be disposed next) - */ - iso_node_take((IsoNode*)image->bootcat->node); - - /* free boot catalog and image, including references to nodes */ - el_torito_boot_catalog_free(image->bootcat); - image->bootcat = NULL; -} - -void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat) -{ - struct el_torito_boot_image *image; - - if (cat == NULL) { - return; - } - - image = cat->image; - iso_node_unref((IsoNode*)image->image); - free(image); - iso_node_unref((IsoNode*)cat->node); - free(cat); -} - -/** - * Stream that generates the contents of a El-Torito catalog. - */ -struct catalog_stream -{ - Ecma119Image *target; - uint8_t buffer[BLOCK_SIZE]; - int offset; /* -1 if stream is not openned */ -}; - -static void -write_validation_entry(uint8_t *buf) -{ - size_t i; - int checksum; - - struct el_torito_validation_entry *ve = - (struct el_torito_validation_entry*)buf; - ve->header_id[0] = 1; - ve->platform_id[0] = 0; /* 0: 80x86, 1: PowerPC, 2: Mac */ - ve->key_byte1[0] = 0x55; - ve->key_byte2[0] = 0xAA; - - /* calculate the checksum, to ensure sum of all words is 0 */ - checksum = 0; - for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) { - checksum -= (int16_t) ((buf[i+1] << 8) | buf[i]); - } - iso_lsb(ve->checksum, checksum, 2); -} - -/** - * Write one section entry. - * Currently this is used only for default image (the only supported just now) - */ -static void -write_section_entry(uint8_t *buf, Ecma119Image *t) -{ - struct el_torito_boot_image *img; - struct el_torito_section_entry *se = - (struct el_torito_section_entry*)buf; - - img = t->catalog->image; - - se->boot_indicator[0] = img->bootable ? 0x88 : 0x00; - se->boot_media_type[0] = img->type; - iso_lsb(se->load_seg, img->load_seg, 2); - se->system_type[0] = img->partition_type; - iso_lsb(se->sec_count, img->load_size, 2); - iso_lsb(se->block, t->bootimg->block, 4); -} - -static -int catalog_open(IsoStream *stream) -{ - struct catalog_stream *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = stream->data; - - if (data->offset != -1) { - return ISO_FILE_ALREADY_OPENED; - } - - memset(data->buffer, 0, BLOCK_SIZE); - - /* fill the buffer with the catalog contents */ - write_validation_entry(data->buffer); - - /* write default entry */ - write_section_entry(data->buffer + 32, data->target); - - data->offset = 0; - return ISO_SUCCESS; -} - -static -int catalog_close(IsoStream *stream) -{ - struct catalog_stream *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = stream->data; - - if (data->offset == -1) { - return ISO_FILE_NOT_OPENED; - } - data->offset = -1; - return ISO_SUCCESS; -} - -static -off_t catalog_get_size(IsoStream *stream) -{ - return BLOCK_SIZE; -} - -static -int catalog_read(IsoStream *stream, void *buf, size_t count) -{ - size_t len; - struct catalog_stream *data; - if (stream == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - if (count == 0) { - return ISO_WRONG_ARG_VALUE; - } - data = stream->data; - - if (data->offset == -1) { - return ISO_FILE_NOT_OPENED; - } - - len = MIN(count, BLOCK_SIZE - data->offset); - memcpy(buf, data->buffer + data->offset, len); - return len; -} - -static -int catalog_is_repeatable(IsoStream *stream) -{ - return 1; -} - -/** - * fs_id will be the id reserved for El-Torito - * dev_id will be 0 for catalog, 1 for boot image (if needed) - * we leave ino_id for future use when we support multiple boot images - */ -static -void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id) -{ - *fs_id = ISO_ELTORITO_FS_ID; - *dev_id = 0; - *ino_id = 0; -} - -static -void catalog_free(IsoStream *stream) -{ - free(stream->data); -} - -IsoStreamIface catalog_stream_class = { - 0, - "boot", - catalog_open, - catalog_close, - catalog_get_size, - catalog_read, - catalog_is_repeatable, - catalog_get_id, - catalog_free -}; - -/** - * Create an IsoStream for writing El-Torito catalog for a given target. - */ -static -int catalog_stream_new(Ecma119Image *target, IsoStream **stream) -{ - IsoStream *str; - struct catalog_stream *data; - - if (target == NULL || stream == NULL || target->catalog == NULL) { - return ISO_NULL_POINTER; - } - - str = malloc(sizeof(IsoStream)); - if (str == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(struct catalog_stream)); - if (str == NULL) { - free(str); - return ISO_OUT_OF_MEM; - } - - /* fill data */ - data->target = target; - data->offset = -1; - - str->refcount = 1; - str->data = data; - str->class = &catalog_stream_class; - - *stream = str; - return ISO_SUCCESS; -} - -int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src) -{ - int ret; - IsoFileSrc *file; - IsoStream *stream; - - if (target == NULL || src == NULL || target->catalog == NULL) { - return ISO_OUT_OF_MEM; - } - - if (target->cat != NULL) { - /* catalog file src already created */ - *src = target->cat; - return ISO_SUCCESS; - } - - file = malloc(sizeof(IsoFileSrc)); - if (file == NULL) { - return ISO_OUT_OF_MEM; - } - - ret = catalog_stream_new(target, &stream); - if (ret < 0) { - free(file); - return ret; - } - - /* fill fields */ - file->prev_img = 0; /* TODO allow copy of old img catalog???? */ - file->block = 0; /* to be filled later */ - file->sort_weight = 1000; /* slightly high */ - file->stream = stream; - - ret = iso_file_src_add(target, file, src); - if (ret <= 0) { - iso_stream_unref(stream); - free(file); - } else { - target->cat = *src; - } - return ret; -} - -/******************* EL-TORITO WRITER *******************************/ - -static -int eltorito_writer_compute_data_blocks(IsoImageWriter *writer) -{ - /* nothing to do, the files are written by the file writer */ - return ISO_SUCCESS; -} - -/** - * Write the Boot Record Volume Descriptor (ECMA-119, 8.2) - */ -static -int eltorito_writer_write_vol_desc(IsoImageWriter *writer) -{ - Ecma119Image *t; - struct el_torito_boot_catalog *cat; - struct ecma119_boot_rec_vol_desc vol; - - if (writer == NULL) { - return ISO_NULL_POINTER; - } - - t = writer->target; - cat = t->catalog; - - iso_msg_debug(t->image->id, "Write El-Torito boot record"); - - memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc)); - vol.vol_desc_type[0] = 0; - memcpy(vol.std_identifier, "CD001", 5); - vol.vol_desc_version[0] = 1; - memcpy(vol.boot_sys_id, "EL TORITO SPECIFICATION", 23); - iso_lsb(vol.boot_catalog, t->cat->block, 4); - - return iso_write(t, &vol, sizeof(struct ecma119_boot_rec_vol_desc)); -} - -/** - * Patch an isolinux boot image. - * - * @return - * 1 on success, 0 error (but continue), < 0 error - */ -static -int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize) -{ - struct boot_info_table *info; - uint32_t checksum; - size_t offset; - - if (imgsize < 64) { - return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, - "Isolinux image too small. We won't patch it."); - } - - /* compute checksum, as the the sum of all 32 bit words in boot image - * from offset 64 */ - checksum = 0; - offset = (size_t) 64; - - while (offset <= imgsize - 4) { - checksum += iso_read_lsb(buf + offset, 4); - offset += 4; - } - if (offset != imgsize) { - /* file length not multiple of 4 */ - return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, - "Unexpected isolinux image length. Patch might not work."); - } - - /* patch boot info table */ - info = (struct boot_info_table*)(buf + 8); - /*memset(info, 0, sizeof(struct boot_info_table));*/ - iso_lsb(info->bi_pvd, t->ms_block + 16, 4); - iso_lsb(info->bi_file, t->bootimg->block, 4); - iso_lsb(info->bi_length, imgsize, 4); - iso_lsb(info->bi_csum, checksum, 4); - return ISO_SUCCESS; -} - -static -int eltorito_writer_write_data(IsoImageWriter *writer) -{ - /* - * We have nothing to write, but if we need to patch an isolinux image, - * this is a good place to do so. - */ - Ecma119Image *t; - int ret; - - if (writer == NULL) { - return ISO_NULL_POINTER; - } - - t = writer->target; - - if (t->catalog->image->isolinux) { - /* we need to patch the image */ - size_t size; - uint8_t *buf; - IsoStream *new = NULL; - IsoStream *original = t->bootimg->stream; - size = (size_t) iso_stream_get_size(original); - buf = malloc(size); - if (buf == NULL) { - return ISO_OUT_OF_MEM; - } - ret = iso_stream_open(original); - if (ret < 0) { - return ret; - } - ret = iso_stream_read(original, buf, size); - iso_stream_close(original); - if (ret != size) { - return (ret < 0) ? ret : ISO_FILE_READ_ERROR; - } - - /* ok, patch the read buffer */ - ret = patch_boot_image(buf, t, size); - if (ret < 0) { - return ret; - } - - /* replace the original stream with a memory stream that reads from - * the patched buffer */ - ret = iso_memory_stream_new(buf, size, &new); - if (ret < 0) { - return ret; - } - t->bootimg->stream = new; - iso_stream_unref(original); - } - return ISO_SUCCESS; -} - -static -int eltorito_writer_free_data(IsoImageWriter *writer) -{ - /* nothing to do */ - return ISO_SUCCESS; -} - -int eltorito_writer_create(Ecma119Image *target) -{ - int ret; - IsoImageWriter *writer; - IsoFile *bootimg; - IsoFileSrc *src; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - writer->compute_data_blocks = eltorito_writer_compute_data_blocks; - writer->write_vol_desc = eltorito_writer_write_vol_desc; - writer->write_data = eltorito_writer_write_data; - writer->free_data = eltorito_writer_free_data; - writer->data = NULL; - writer->target = target; - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - - /* - * get catalog and image file sources. - * Note that the catalog may be already added, when creating the low - * level ECMA-119 tree. - */ - if (target->cat == NULL) { - ret = el_torito_catalog_file_src_create(target, &src); - if (ret < 0) { - return ret; - } - } - bootimg = target->catalog->image->image; - ret = iso_file_src_create(target, bootimg, &src); - if (ret < 0) { - return ret; - } - target->bootimg = src; - - /* if we have selected to patch the image, it needs to be copied always */ - if (target->catalog->image->isolinux) { - src->prev_img = 0; - } - - /* we need the bootable volume descriptor */ - target->curblock++; - return ISO_SUCCESS; -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.h deleted file mode 100644 index 3c507997..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/eltorito.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/** - * Declare El-Torito related structures. - * References: - * "El Torito" Bootable CD-ROM Format Specification Version 1.0 (1995) - */ - -#ifndef LIBISO_ELTORITO_H -#define LIBISO_ELTORITO_H - -#include "ecma119.h" -#include "node.h" - -/** - * A node that acts as a placeholder for an El-Torito catalog. - */ -struct Iso_Boot -{ - IsoNode node; -}; - -struct el_torito_boot_catalog { - IsoBoot *node; /* node of the catalog */ - struct el_torito_boot_image *image; /* default boot image */ -}; - -struct el_torito_boot_image { - IsoFile *image; - - unsigned int bootable:1; /**< If the entry is bootable. */ - unsigned int isolinux:1; /**< If the image will be patched */ - unsigned char type; /**< The type of image */ - unsigned char partition_type; /**< type of partition for HD-emul images */ - short load_seg; /**< Load segment for the initial boot image. */ - short load_size; /**< Number of sectors to load. */ -}; - -/** El-Torito, 2.1 */ -struct el_torito_validation_entry { - uint8_t header_id BP(1, 1); - uint8_t platform_id BP(2, 2); - uint8_t reserved BP(3, 4); - uint8_t id_string BP(5, 28); - uint8_t checksum BP(29, 30); - uint8_t key_byte1 BP(31, 31); - uint8_t key_byte2 BP(32, 32); -}; - -/** El-Torito, 2.2 */ -struct el_torito_default_entry { - uint8_t boot_indicator BP(1, 1); - uint8_t boot_media_type BP(2, 2); - uint8_t load_seg BP(3, 4); - uint8_t system_type BP(5, 5); - uint8_t unused1 BP(6, 6); - uint8_t sec_count BP(7, 8); - uint8_t block BP(9, 12); - uint8_t unused2 BP(13, 32); -}; - -/** El-Torito, 2.3 */ -struct el_torito_section_header { - uint8_t header_indicator BP(1, 1); - uint8_t platform_id BP(2, 2); - uint8_t number BP(3, 4); - uint8_t character BP(5, 32); -}; - -/** El-Torito, 2.4 */ -struct el_torito_section_entry { - uint8_t boot_indicator BP(1, 1); - uint8_t boot_media_type BP(2, 2); - uint8_t load_seg BP(3, 4); - uint8_t system_type BP(5, 5); - uint8_t unused1 BP(6, 6); - uint8_t sec_count BP(7, 8); - uint8_t block BP(9, 12); - uint8_t selec_criteria BP(13, 13); - uint8_t vendor_sc BP(14, 32); -}; - -void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat); - -/** - * Create a IsoFileSrc for writing the el-torito catalog for the given - * target, and add it to target. If the target already has a src for the - * catalog, it just returns. - */ -int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src); - -/** - * Create a writer for el-torito information. - */ -int eltorito_writer_create(Ecma119Image *target); - -#endif /* LIBISO_ELTORITO_H */ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.c deleted file mode 100644 index 2c57ce53..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "filesrc.h" -#include "node.h" -#include "util.h" -#include "writer.h" -#include "messages.h" -#include "image.h" - -#include -#include -#include - -int iso_file_src_cmp(const void *n1, const void *n2) -{ - const IsoFileSrc *f1, *f2; - unsigned int fs_id1, fs_id2; - dev_t dev_id1, dev_id2; - ino_t ino_id1, ino_id2; - - f1 = (const IsoFileSrc *)n1; - f2 = (const IsoFileSrc *)n2; - - iso_stream_get_id(f1->stream, &fs_id1, &dev_id1, &ino_id1); - iso_stream_get_id(f2->stream, &fs_id2, &dev_id2, &ino_id2); - - if (fs_id1 < fs_id2) { - return -1; - } else if (fs_id1 > fs_id2) { - return 1; - } else { - /* files belong to the same fs */ - if (dev_id1 > dev_id2) { - return -1; - } else if (dev_id1 < dev_id2) { - return 1; - } else { - /* files belong to same device in same fs */ - return (ino_id1 < ino_id2) ? -1 : (ino_id1 > ino_id2) ? 1 : 0; - } - } -} - -int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src) -{ - int ret; - IsoFileSrc *fsrc; - unsigned int fs_id; - dev_t dev_id; - ino_t ino_id; - - if (img == NULL || file == NULL || src == NULL) { - return ISO_NULL_POINTER; - } - - iso_stream_get_id(file->stream, &fs_id, &dev_id, &ino_id); - - fsrc = malloc(sizeof(IsoFileSrc)); - if (fsrc == NULL) { - return ISO_OUT_OF_MEM; - } - - /* fill key and other atts */ - fsrc->prev_img = file->msblock ? 1 : 0; - fsrc->block = file->msblock; - fsrc->sort_weight = file->sort_weight; - fsrc->stream = file->stream; - - /* insert the filesrc in the tree */ - ret = iso_rbtree_insert(img->files, fsrc, (void**)src); - if (ret <= 0) { - free(fsrc); - return ret; - } - iso_stream_ref(fsrc->stream); - return ISO_SUCCESS; -} - -/** - * Add a given IsoFileSrc to the given image target. - * - * The IsoFileSrc will be cached in a tree to prevent the same file for - * being written several times to image. If you call again this function - * with a node that refers to the same source file, the previously - * created one will be returned. - * - * @param img - * The image where this file is to be written - * @param new - * The IsoFileSrc to add - * @param src - * Will be filled with a pointer to the IsoFileSrc really present in - * the tree. It could be different than new if the same file already - * exists in the tree. - * @return - * 1 on success, 0 if file already exists on tree, < 0 error - */ -int iso_file_src_add(Ecma119Image *img, IsoFileSrc *new, IsoFileSrc **src) -{ - int ret; - - if (img == NULL || new == NULL || src == NULL) { - return ISO_NULL_POINTER; - } - - /* insert the filesrc in the tree */ - ret = iso_rbtree_insert(img->files, new, (void**)src); - return ret; -} - -void iso_file_src_free(void *node) -{ - iso_stream_unref(((IsoFileSrc*)node)->stream); - free(node); -} - -off_t iso_file_src_get_size(IsoFileSrc *file) -{ - return iso_stream_get_size(file->stream); -} - -static int cmp_by_weight(const void *f1, const void *f2) -{ - IsoFileSrc *f = *((IsoFileSrc**)f1); - IsoFileSrc *g = *((IsoFileSrc**)f2); - /* higher weighted first */ - return g->sort_weight - f->sort_weight; -} - -static -int is_ms_file(void *arg) -{ - IsoFileSrc *f = (IsoFileSrc *)arg; - return f->prev_img ? 0 : 1; -} - -static -int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) -{ - size_t i, size; - Ecma119Image *t; - IsoFileSrc **filelist; - int (*inc_item)(void *); - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - t = writer->target; - - /* on appendable images, ms files shouldn't be included */ - if (t->appendable) { - inc_item = is_ms_file; - } else { - inc_item = NULL; - } - - /* store the filesrcs in a array */ - filelist = (IsoFileSrc**)iso_rbtree_to_array(t->files, inc_item, &size); - if (filelist == NULL) { - return ISO_OUT_OF_MEM; - } - - /* sort files by weight, if needed */ - if (t->sort_files) { - qsort(filelist, size, sizeof(void*), cmp_by_weight); - } - - /* fill block value */ - for (i = 0; i < size; ++i) { - IsoFileSrc *file = filelist[i]; - file->block = t->curblock; - t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE); - } - - /* the list is only needed by this writer, store locally */ - writer->data = filelist; - return ISO_SUCCESS; -} - -static -int filesrc_writer_write_vol_desc(IsoImageWriter *writer) -{ - /* nothing needed */ - return ISO_SUCCESS; -} - -/* open a file, i.e., its Stream */ -static inline -int filesrc_open(IsoFileSrc *file) -{ - return iso_stream_open(file->stream); -} - -static inline -int filesrc_close(IsoFileSrc *file) -{ - return iso_stream_close(file->stream); -} - -/** - * @return - * 1 ok, 0 EOF, < 0 error - */ -static -int filesrc_read(IsoFileSrc *file, char *buf, size_t count) -{ - size_t bytes = 0; - - /* loop to ensure the full buffer is filled */ - do { - ssize_t result; - result = iso_stream_read(file->stream, buf + bytes, count - bytes); - if (result < 0) { - /* fill buffer with 0s and return */ - memset(buf + bytes, 0, count - bytes); - return result; - } - if (result == 0) - break; - bytes += result; - } while (bytes < count); - - if (bytes < count) { - /* eof */ - memset(buf + bytes, 0, count - bytes); - return 0; - } else { - return 1; - } -} - -static -int filesrc_writer_write_data(IsoImageWriter *writer) -{ - int res; - size_t i, b; - Ecma119Image *t; - IsoFileSrc *file; - IsoFileSrc **filelist; - char name[PATH_MAX]; - char buffer[BLOCK_SIZE]; - - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - t = writer->target; - filelist = writer->data; - - iso_msg_debug(t->image->id, "Writing Files..."); - - i = 0; - while ((file = filelist[i++]) != NULL) { - - /* - * TODO WARNING - * when we allow files greater than 4GB, current DIV_UP implementation - * can overflow!! - */ - uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE); - - res = filesrc_open(file); - iso_stream_get_file_name(file->stream, name); - if (res < 0) { - /* - * UPS, very ugly error, the best we can do is just to write - * 0's to image - */ - iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0); - res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res, - "File \"%s\" can't be opened. Filling with 0s.", name); - if (res < 0) { - return res; /* aborted due to error severity */ - } - memset(buffer, 0, BLOCK_SIZE); - for (b = 0; b < nblocks; ++b) { - res = iso_write(t, buffer, BLOCK_SIZE); - if (res < 0) { - /* ko, writer error, we need to go out! */ - return res; - } - } - continue; - } else if (res > 1) { - iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0); - res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0, - "Size of file \"%s\" has changed. It will be %s", name, - (res == 2 ? "truncated" : "padded with 0's")); - if (res < 0) { - filesrc_close(file); - return res; /* aborted due to error severity */ - } - } -#ifdef LIBISOFS_VERBOSE_DEBUG - else { - iso_msg_debug(t->image->id, "Writing file %s", name); - } -#endif - - /* write file contents to image */ - for (b = 0; b < nblocks; ++b) { - int wres; - res = filesrc_read(file, buffer, BLOCK_SIZE); - if (res < 0) { - /* read error */ - break; - } - wres = iso_write(t, buffer, BLOCK_SIZE); - if (wres < 0) { - /* ko, writer error, we need to go out! */ - filesrc_close(file); - return wres; - } - } - - filesrc_close(file); - - if (b < nblocks) { - /* premature end of file, due to error or eof */ - iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0); - if (res < 0) { - /* error */ - res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res, - "Read error in file %s.", name); - } else { - /* eof */ - res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0, - "Premature end of file %s.", name); - } - - if (res < 0) { - return res; /* aborted due error severity */ - } - - /* fill with 0s */ - iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0, - "Filling with 0"); - memset(buffer, 0, BLOCK_SIZE); - while (b++ < nblocks) { - res = iso_write(t, buffer, BLOCK_SIZE); - if (res < 0) { - /* ko, writer error, we need to go out! */ - return res; - } - } - } - } - - return ISO_SUCCESS; -} - -static -int filesrc_writer_free_data(IsoImageWriter *writer) -{ - /* free the list of files (contents are free together with the tree) */ - free(writer->data); - return ISO_SUCCESS; -} - -int iso_file_src_writer_create(Ecma119Image *target) -{ - IsoImageWriter *writer; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - - writer->compute_data_blocks = filesrc_writer_compute_data_blocks; - writer->write_vol_desc = filesrc_writer_write_vol_desc; - writer->write_data = filesrc_writer_write_data; - writer->free_data = filesrc_writer_free_data; - writer->data = NULL; - writer->target = target; - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.h deleted file mode 100644 index 5a3c03c8..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filesrc.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_FILESRC_H_ -#define LIBISO_FILESRC_H_ - -#include "libisofs.h" -#include "stream.h" -#include "ecma119.h" - -#include - -struct Iso_File_Src -{ - unsigned int prev_img :1; /**< if the file comes from a previous image */ - uint32_t block; /**< Block where this file will be written on image */ - int sort_weight; - IsoStream *stream; -}; - -int iso_file_src_cmp(const void *n1, const void *n2); - -/** - * Create a new IsoFileSrc to get data from a specific IsoFile. - * - * The IsoFileSrc will be cached in a tree to prevent the same file for - * being written several times to image. If you call again this function - * with a node that refers to the same source file, the previously - * created one will be returned. No new IsoFileSrc is created in that case. - * - * @param img - * The image where this file is to be written - * @param file - * The IsoNode we want to write - * @param src - * Will be filled with a pointer to the IsoFileSrc - * @return - * 1 on success, < 0 on error - */ -int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src); - -/** - * Add a given IsoFileSrc to the given image target. - * - * The IsoFileSrc will be cached in a tree to prevent the same file for - * being written several times to image. If you call again this function - * with a node that refers to the same source file, the previously - * created one will be returned. - * - * @param img - * The image where this file is to be written - * @param new - * The IsoFileSrc to add - * @param src - * Will be filled with a pointer to the IsoFileSrc really present in - * the tree. It could be different than new if the same file already - * exists in the tree. - * @return - * 1 on success, 0 if file already exists on tree, < 0 error - */ -int iso_file_src_add(Ecma119Image *img, IsoFileSrc *new, IsoFileSrc **src); - -/** - * Free the IsoFileSrc especific data - */ -void iso_file_src_free(void *node); - -/** - * Get the size of the file this IsoFileSrc represents - */ -off_t iso_file_src_get_size(IsoFileSrc *file); - -/** - * Create a Writer for file contents. - * - * It takes care of written the files in the correct order. - */ -int iso_file_src_writer_create(Ecma119Image *target); - -#endif /*LIBISO_FILESRC_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.c deleted file mode 100644 index a7f2be69..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2008 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "filter.h" -#include "node.h" - - -void iso_filter_ref(FilterContext *filter) -{ - ++filter->refcount; -} - -void iso_filter_unref(FilterContext *filter) -{ - if (--filter->refcount == 0) { - filter->free(filter); - free(filter); - } -} - -int iso_file_add_filter(IsoFile *file, FilterContext *filter, int flag) -{ - int ret; - IsoStream *original, *filtered; - if (file == NULL || filter == NULL) { - return ISO_NULL_POINTER; - } - - original = file->stream; - - if (!iso_stream_is_repeatable(original)) { - /* TODO use custom error */ - return ISO_WRONG_ARG_VALUE; - } - - ret = filter->get_filter(filter, original, &filtered); - if (ret < 0) { - return ret; - } - iso_stream_unref(original); - file->stream = filtered; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.h deleted file mode 100644 index f711fe31..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filter.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2008 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_FILTER_H_ -#define LIBISO_FILTER_H_ - -/* - * Definitions of filters. - */ - -/* dev_id for stream identification */ -#define XOR_ENCRYPT_DEV_ID 1 - -typedef struct filter_context FilterContext; - -struct filter_context { - int version; /* reserved for future usage, set to 0 */ - int refcount; - - /** filter specific shared data */ - void *data; - - /** - * Factory method to create a filtered stream from another stream. - * - * @param original - * The original stream to be filtered. If the filter needs a ref to - * it (most cases), it should take a ref to it with iso_stream_ref(). - * @param filtered - * Will be filled with the filtered IsoStream (reference belongs to - * caller). - * @return - * 1 on success, < 0 on error - */ - int (*get_filter)(FilterContext *filter, IsoStream *original, - IsoStream **filtered); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_filter_unref() instead. - */ - void (*free)(FilterContext *filter); -}; - -/** - * - * @param flag - * Reserved for future usage, pass always 0 for now. - * TODO in a future a different value can mean filter caching, where - * the filter is applied once and the filtered file is stored in a temp - * dir. This prevent filter to be applied several times. - */ -int iso_file_add_filter(IsoFile *file, FilterContext *filter, int flag); - -void iso_filter_ref(FilterContext *filter); -void iso_filter_unref(FilterContext *filter); - -#endif /*LIBISO_FILTER_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filters/xor_encrypt.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filters/xor_encrypt.c deleted file mode 100644 index be83f725..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/filters/xor_encrypt.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2008 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "../libisofs.h" -#include "../filter.h" -#include "../fsource.h" - -/* - * A simple Filter implementation for example purposes. It encrypts a file - * by XORing each byte by a given key. - */ - -static ino_t xor_ino_id = 0; - -typedef struct -{ - IsoStream *orig; - uint8_t key; - ino_t id; -} XorEncryptStreamData; - -static -int xor_encrypt_stream_open(IsoStream *stream) -{ - XorEncryptStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = (XorEncryptStreamData*)stream->data; - return iso_stream_open(data->orig); -} - -static -int xor_encrypt_stream_close(IsoStream *stream) -{ - XorEncryptStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = stream->data; - return iso_stream_close(data->orig); -} - -static -off_t xor_encrypt_stream_get_size(IsoStream *stream) -{ - XorEncryptStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = stream->data; - return iso_stream_get_size(data->orig); -} - -static -int xor_encrypt_stream_read(IsoStream *stream, void *buf, size_t count) -{ - int ret, len; - XorEncryptStreamData *data; - uint8_t *buffer = buf; - - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = stream->data; - ret = iso_stream_read(data->orig, buf, count); - if (ret < 0) { - return ret; - } - - /* xor */ - for (len = 0; len < ret; ++len) { - buffer[len] = buffer[len] ^ data->key; - } - - return ret; -} - -static -int xor_encrypt_stream_is_repeatable(IsoStream *stream) -{ - /* the filter can't be created if underlying stream is not repeatable */ - return 1; -} - -static -void xor_encrypt_stream_get_id(IsoStream *stream, unsigned int *fs_id, - dev_t *dev_id, ino_t *ino_id) -{ - XorEncryptStreamData *data = stream->data; - *fs_id = ISO_FILTER_FS_ID; - *dev_id = XOR_ENCRYPT_DEV_ID; - *ino_id = data->id; -} - -static -void xor_encrypt_stream_free(IsoStream *stream) -{ - XorEncryptStreamData *data = stream->data; - iso_stream_unref(data->orig); - free(data); -} - -IsoStreamIface xor_encrypt_stream_class = { - 0, - "xorf", - xor_encrypt_stream_open, - xor_encrypt_stream_close, - xor_encrypt_stream_get_size, - xor_encrypt_stream_read, - xor_encrypt_stream_is_repeatable, - xor_encrypt_stream_get_id, - xor_encrypt_stream_free -}; - - -static -void xor_encrypt_filter_free(FilterContext *filter) -{ - free(filter->data); -} - -static -int xor_encrypt_filter_get_filter(FilterContext *filter, IsoStream *original, - IsoStream **filtered) -{ - IsoStream *str; - XorEncryptStreamData *data; - - if (filter == NULL || original == NULL || filtered == NULL) { - return ISO_NULL_POINTER; - } - - str = malloc(sizeof(IsoStream)); - if (str == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(XorEncryptStreamData)); - if (str == NULL) { - free(str); - return ISO_OUT_OF_MEM; - } - - /* fill data */ - data->key = *((uint8_t*)filter->data); - data->id = xor_ino_id++; - - /* get reference to the source */ - data->orig = original; - iso_stream_ref(original); - - str->refcount = 1; - str->data = data; - str->class = &xor_encrypt_stream_class; - - *filtered = str; - return ISO_SUCCESS; -} - -int create_xor_encrypt_filter(uint8_t key, FilterContext **filter) -{ - FilterContext *f; - uint8_t *data; - - f = calloc(1, sizeof(FilterContext)); - if (f == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(uint8_t)); - if (data == NULL) { - free(f); - return ISO_OUT_OF_MEM; - } - f->refcount = 1; - f->version = 0; - *data = key; - f->data = data; - f->free = xor_encrypt_filter_free; - f->get_filter = xor_encrypt_filter_get_filter; - - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/find.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/find.c deleted file mode 100644 index 797ef881..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/find.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 2008 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "node.h" - -#include -#include - -struct iso_find_condition -{ - /* - * Check whether the given node matches this condition. - * - * @param cond - * The condition to check - * @param node - * The node that should be checked - * @return - * 1 if the node matches the condition, 0 if not - */ - int (*matches)(IsoFindCondition *cond, IsoNode *node); - - /** - * Free condition specific data - */ - void (*free)(IsoFindCondition*); - - /** condition specific data */ - void *data; -}; - -struct find_iter_data -{ - IsoDirIter *iter; - IsoFindCondition *cond; -}; - -static -int find_iter_next(IsoDirIter *iter, IsoNode **node) -{ - int ret; - IsoNode *n; - struct find_iter_data *data = iter->data; - - while ((ret = iso_dir_iter_next(data->iter, &n)) == 1) { - if (data->cond->matches(data->cond, n)) { - *node = n; - break; - } - } - return ret; -} - -static -int find_iter_has_next(IsoDirIter *iter) -{ - struct find_iter_data *data = iter->data; - - /* - * FIXME wrong implementation!!!! the underlying iter may have more nodes, - * but they may not match find conditions - */ - return iso_dir_iter_has_next(data->iter); -} - -static -void find_iter_free(IsoDirIter *iter) -{ - struct find_iter_data *data = iter->data; - data->cond->free(data->cond); - free(data->cond); - iso_dir_iter_free(data->iter); - free(iter->data); -} - -static -int find_iter_take(IsoDirIter *iter) -{ - struct find_iter_data *data = iter->data; - return iso_dir_iter_take(data->iter); -} - -static -int find_iter_remove(IsoDirIter *iter) -{ - struct find_iter_data *data = iter->data; - return iso_dir_iter_remove(data->iter); -} - -void find_notify_child_taken(IsoDirIter *iter, IsoNode *node) -{ - /* nothing to do */ - return; -} - -static -struct iso_dir_iter_iface find_iter_class = { - find_iter_next, - find_iter_has_next, - find_iter_free, - find_iter_take, - find_iter_remove, - find_notify_child_taken -}; - -int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond, - IsoDirIter **iter) -{ - int ret; - IsoDirIter *children; - IsoDirIter *it; - struct find_iter_data *data; - - if (dir == NULL || cond == NULL || iter == NULL) { - return ISO_NULL_POINTER; - } - it = malloc(sizeof(IsoDirIter)); - if (it == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(struct find_iter_data)); - if (data == NULL) { - free(it); - return ISO_OUT_OF_MEM; - } - ret = iso_dir_get_children(dir, &children); - if (ret < 0) { - free(it); - free(data); - return ret; - } - - it->class = &find_iter_class; - it->dir = (IsoDir*)dir; - data->iter = children; - data->cond = cond; - it->data = data; - - if (iso_dir_iter_register(it) < 0) { - free(it); - return ISO_OUT_OF_MEM; - } - - *iter = it; - return ISO_SUCCESS; -} - -/*************** find by name wildcard condition *****************/ - -static -int cond_name_matches(IsoFindCondition *cond, IsoNode *node) -{ - char *pattern = (char*) cond->data; - int ret = fnmatch(pattern, node->name, 0); - return ret == 0 ? 1 : 0; -} - -static -void cond_name_free(IsoFindCondition *cond) -{ - free(cond->data); -} - -/** - * Create a new condition that checks if the node name matches the given - * wildcard. - * - * @param wildcard - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_name(const char *wildcard) -{ - IsoFindCondition *cond; - if (wildcard == NULL) { - return NULL; - } - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - cond->data = strdup(wildcard); - cond->free = cond_name_free; - cond->matches = cond_name_matches; - return cond; -} - -/*************** find by mode condition *****************/ - -static -int cond_mode_matches(IsoFindCondition *cond, IsoNode *node) -{ - mode_t *mask = (mode_t*) cond->data; - return node->mode & *mask ? 1 : 0; -} - -static -void cond_mode_free(IsoFindCondition *cond) -{ - free(cond->data); -} - -/** - * Create a new condition that checks the node mode against a mode mask. It - * can be used to check both file type and permissions. - * - * For example: - * - * iso_new_find_conditions_mode(S_IFREG) : search for regular files - * iso_new_find_conditions_mode(S_IFCHR | S_IWUSR) : search for character - * devices where owner has write permissions. - * - * @param mask - * Mode mask to AND against node mode. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_mode(mode_t mask) -{ - IsoFindCondition *cond; - mode_t *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(mode_t)); - if (data == NULL) { - free(cond); - return NULL; - } - *data = mask; - cond->data = data; - cond->free = cond_mode_free; - cond->matches = cond_mode_matches; - return cond; -} - -/*************** find by gid condition *****************/ - -static -int cond_gid_matches(IsoFindCondition *cond, IsoNode *node) -{ - gid_t *gid = (gid_t*) cond->data; - return node->gid == *gid ? 1 : 0; -} - -static -void cond_gid_free(IsoFindCondition *cond) -{ - free(cond->data); -} - -/** - * Create a new condition that checks the node gid. - * - * @param gid - * Desired Group Id. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_gid(gid_t gid) -{ - IsoFindCondition *cond; - gid_t *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(gid_t)); - if (data == NULL) { - free(cond); - return NULL; - } - *data = gid; - cond->data = data; - cond->free = cond_gid_free; - cond->matches = cond_gid_matches; - return cond; -} - -/*************** find by uid condition *****************/ - -static -int cond_uid_matches(IsoFindCondition *cond, IsoNode *node) -{ - uid_t *uid = (uid_t*) cond->data; - return node->uid == *uid ? 1 : 0; -} - -static -void cond_uid_free(IsoFindCondition *cond) -{ - free(cond->data); -} - -/** - * Create a new condition that checks the node uid. - * - * @param uid - * Desired User Id. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_uid(uid_t uid) -{ - IsoFindCondition *cond; - uid_t *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(uid_t)); - if (data == NULL) { - free(cond); - return NULL; - } - *data = uid; - cond->data = data; - cond->free = cond_uid_free; - cond->matches = cond_uid_matches; - return cond; -} - -/*************** find by timestamps condition *****************/ - -struct cond_times -{ - time_t time; - int what_time; /* 0 atime, 1 mtime, 2 ctime */ - enum iso_find_comparisons comparison; -}; - -static -int cond_time_matches(IsoFindCondition *cond, IsoNode *node) -{ - time_t node_time; - struct cond_times *data = cond->data; - - switch (data->what_time) { - case 0: node_time = node->atime; break; - case 1: node_time = node->mtime; break; - default: node_time = node->ctime; break; - } - - switch (data->comparison) { - case ISO_FIND_COND_GREATER: - return node_time > data->time ? 1 : 0; - case ISO_FIND_COND_GREATER_OR_EQUAL: - return node_time >= data->time ? 1 : 0; - case ISO_FIND_COND_EQUAL: - return node_time == data->time ? 1 : 0; - case ISO_FIND_COND_LESS: - return node_time < data->time ? 1 : 0; - case ISO_FIND_COND_LESS_OR_EQUAL: - return node_time <= data->time ? 1 : 0; - } - /* should never happen */ - return 0; -} - -static -void cond_time_free(IsoFindCondition *cond) -{ - free(cond->data); -} - -/** - * Create a new condition that checks the time of last access. - * - * @param time - * Time to compare against IsoNode atime. - * @param comparison - * Comparison to be done between IsoNode atime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_atime(time_t time, - enum iso_find_comparisons comparison) -{ - IsoFindCondition *cond; - struct cond_times *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(struct cond_times)); - if (data == NULL) { - free(cond); - return NULL; - } - data->time = time; - data->comparison = comparison; - data->what_time = 0; /* atime */ - cond->data = data; - cond->free = cond_time_free; - cond->matches = cond_time_matches; - return cond; -} - -/** - * Create a new condition that checks the time of last modification. - * - * @param time - * Time to compare against IsoNode mtime. - * @param comparison - * Comparison to be done between IsoNode mtime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_mtime(time_t time, - enum iso_find_comparisons comparison) -{ - IsoFindCondition *cond; - struct cond_times *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(struct cond_times)); - if (data == NULL) { - free(cond); - return NULL; - } - data->time = time; - data->comparison = comparison; - data->what_time = 1; /* mtime */ - cond->data = data; - cond->free = cond_time_free; - cond->matches = cond_time_matches; - return cond; -} - -/** - * Create a new condition that checks the time of last status change. - * - * @param time - * Time to compare against IsoNode ctime. - * @param comparison - * Comparison to be done between IsoNode ctime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_ctime(time_t time, - enum iso_find_comparisons comparison) -{ - IsoFindCondition *cond; - struct cond_times *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(struct cond_times)); - if (data == NULL) { - free(cond); - return NULL; - } - data->time = time; - data->comparison = comparison; - data->what_time = 2; /* ctime */ - cond->data = data; - cond->free = cond_time_free; - cond->matches = cond_time_matches; - return cond; -} - -/*************** logical operations on conditions *****************/ - -struct logical_binary_conditions { - IsoFindCondition *a; - IsoFindCondition *b; -}; - -static -void cond_logical_binary_free(IsoFindCondition *cond) -{ - struct logical_binary_conditions *data; - data = cond->data; - data->a->free(data->a); - free(data->a); - data->b->free(data->b); - free(data->b); - free(cond->data); -} - -static -int cond_logical_and_matches(IsoFindCondition *cond, IsoNode *node) -{ - struct logical_binary_conditions *data = cond->data; - return data->a->matches(data->a, node) && data->b->matches(data->b, node); -} - -/** - * Create a new condition that check if the two given conditions are - * valid. - * - * @param a - * @param b - * IsoFindCondition to compare - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_and(IsoFindCondition *a, - IsoFindCondition *b) -{ - IsoFindCondition *cond; - struct logical_binary_conditions *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(struct logical_binary_conditions)); - if (data == NULL) { - free(cond); - return NULL; - } - data->a = a; - data->b = b; - cond->data = data; - cond->free = cond_logical_binary_free; - cond->matches = cond_logical_and_matches; - return cond; -} - -static -int cond_logical_or_matches(IsoFindCondition *cond, IsoNode *node) -{ - struct logical_binary_conditions *data = cond->data; - return data->a->matches(data->a, node) || data->b->matches(data->b, node); -} - -/** - * Create a new condition that check if at least one the two given conditions - * is valid. - * - * @param a - * @param b - * IsoFindCondition to compare - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_or(IsoFindCondition *a, - IsoFindCondition *b) -{ - IsoFindCondition *cond; - struct logical_binary_conditions *data; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - data = malloc(sizeof(struct logical_binary_conditions)); - if (data == NULL) { - free(cond); - return NULL; - } - data->a = a; - data->b = b; - cond->data = data; - cond->free = cond_logical_binary_free; - cond->matches = cond_logical_or_matches; - return cond; -} - -static -void cond_not_free(IsoFindCondition *cond) -{ - IsoFindCondition *negate = cond->data; - negate->free(negate); - free(negate); -} - -static -int cond_not_matches(IsoFindCondition *cond, IsoNode *node) -{ - IsoFindCondition *negate = cond->data; - return !(negate->matches(negate, node)); -} - -/** - * Create a new condition that check if the given conditions is false. - * - * @param negate - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_not(IsoFindCondition *negate) -{ - IsoFindCondition *cond; - cond = malloc(sizeof(IsoFindCondition)); - if (cond == NULL) { - return NULL; - } - cond->data = negate; - cond->free = cond_not_free; - cond->matches = cond_not_matches; - return cond; -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_image.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_image.c deleted file mode 100644 index 8394cfda..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_image.c +++ /dev/null @@ -1,2642 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * Filesystem/FileSource implementation to access an ISO image, using an - * IsoDataSource to read image data. - */ - -#include "libisofs.h" -#include "ecma119.h" -#include "messages.h" -#include "rockridge.h" -#include "image.h" -#include "tree.h" -#include "eltorito.h" - -#include -#include -#include -#include -#include - - -/** - * Options for image reading. - * There are four kind of options: - * - Related to multisession support. - * In most cases, an image begins at LBA 0 of the data source. However, - * in multisession discs, the later image begins in the last session on - * disc. The block option can be used to specify the start of that last - * session. - * - Related to the tree that will be read. - * As default, when Rock Ridge extensions are present in the image, that - * will be used to get the tree. If RR extensions are not present, libisofs - * will use the Joliet extensions if available. Finally, the plain ISO-9660 - * tree is used if neither RR nor Joliet extensions are available. With - * norock, nojoliet, and preferjoliet options, you can change this - * default behavior. - * - Related to default POSIX attributes. - * When Rock Ridege extensions are not used, libisofs can't figure out what - * are the the permissions, uid or gid for the files. You should supply - * default values for that. - */ -struct iso_read_opts -{ - /** - * Block where the image begins, usually 0, can be different on a - * multisession disc. - */ - uint32_t block; - - 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 */ - - /** - * When both Joliet and RR extensions are present, the RR tree is used. - * If you prefer using Joliet, set this to 1. - */ - unsigned int preferjoliet : 1; - - uid_t uid; /**< Default uid when no RR */ - gid_t gid; /**< Default uid when no RR */ - mode_t dir_mode; /**< Default mode when no RR (only permissions) */ - mode_t file_mode; - /* TODO #00024 : option to convert names to lower case for iso reading */ - - /** - * Input charset for RR file names. NULL to use default locale charset. - */ - char *input_charset; -}; - -/** - * Return information for image. - * Both size, hasRR and hasJoliet will be filled by libisofs with suitable - * values. - */ -struct iso_read_image_features -{ - /** - * Will be filled with the size (in 2048 byte block) of the image, as - * reported in the PVM. - */ - uint32_t size; - - /** It will be set to 1 if RR extensions are present, to 0 if not. */ - unsigned int hasRR :1; - - /** It will be set to 1 if Joliet extensions are present, to 0 if not. */ - unsigned int hasJoliet :1; - - /** - * 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; -}; - -static int ifs_fs_open(IsoImageFilesystem *fs); -static int ifs_fs_close(IsoImageFilesystem *fs); -static int iso_file_source_new_ifs(IsoImageFilesystem *fs, - IsoFileSource *parent, struct ecma119_dir_record *record, - IsoFileSource **src); - -/** unique identifier for each image */ -unsigned int fs_dev_id = 0; - -/** - * Should the RR extensions be read? - */ -enum read_rr_ext { - RR_EXT_NO = 0, /*< Do not use RR extensions */ - RR_EXT_110 = 1, /*< RR extensions conforming version 1.10 */ - RR_EXT_112 = 2 /*< RR extensions conforming version 1.12 */ -}; - -/** - * Private data for the image IsoFilesystem - */ -typedef struct -{ - /** DataSource from where data will be read */ - IsoDataSource *src; - - /** unique id for the each image (filesystem instance) */ - unsigned int id; - - /** - * Counter of the times the filesystem has been openned still pending of - * close. It is used to keep track of when we need to actually open or - * close the IsoDataSource. - */ - unsigned int open_count; - - uid_t uid; /**< Default uid when no RR */ - gid_t gid; /**< Default uid when no RR */ - mode_t dir_mode; /**< Default mode when no RR (only permissions) */ - mode_t file_mode; - - int msgid; - - char *input_charset; /**< Input charset for RR names */ - char *local_charset; /**< For RR names, will be set to the locale one */ - - /** - * Will be filled with the block lba of the extend for the root directory - * of the hierarchy that will be read, either from the PVD (ISO, RR) or - * from the SVD (Joliet) - */ - uint32_t iso_root_block; - - /** - * Will be filled with the block lba of the extend for the root directory, - * as read from the PVM - */ - uint32_t pvd_root_block; - - /** - * Will be filled with the block lba of the extend for the root directory, - * as read from the SVD - */ - uint32_t svd_root_block; - - /** - * Will be filled with the block lba of the extend for the root directory, - * as read from the enhanced volume descriptor (ISO 9660:1999) - */ - uint32_t evd_root_block; - - /** - * If we need to read RR extensions. i.e., if the image contains RR - * extensions, and the user wants to read them. - */ - enum read_rr_ext rr; - - /** - * Bytes skipped within the System Use field of a directory record, before - * the beginning of the SUSP system user entries. See IEEE 1281, SUSP. 5.3. - */ - uint8_t len_skp; - - /* Volume attributes */ - char *volset_id; - char *volume_id; /**< Volume identifier. */ - char *publisher_id; /**< Volume publisher. */ - char *data_preparer_id; /**< Volume data preparer. */ - char *system_id; /**< Volume system identifier. */ - char *application_id; /**< Volume application id */ - char *copyright_file_id; - char *abstract_file_id; - char *biblio_file_id; - - /* extension information */ - - /** - * RR version being used in image. - * 0 no RR extension, 1 RRIP 1.10, 2 RRIP 1.12 - */ - enum read_rr_ext rr_version; - - /** If Joliet extensions are available on image */ - unsigned int joliet : 1; - - /** If ISO 9660:1999 is available on image */ - unsigned int iso1999 : 1; - - /** - * Number of blocks of the volume, as reported in the PVM. - */ - uint32_t nblocks; - - /* el-torito information */ - unsigned int eltorito : 1; /* is el-torito available */ - unsigned int bootable:1; /**< If the entry is bootable. */ - unsigned char type; /**< The type of image */ - unsigned char partition_type; /**< type of partition for HD-emul images */ - short load_seg; /**< Load segment for the initial boot image. */ - short load_size; /**< Number of sectors to load. */ - uint32_t imgblock; /**< Block for El-Torito boot image */ - uint32_t catblock; /**< Block for El-Torito catalog */ - -} _ImageFsData; - -typedef struct image_fs_data ImageFileSourceData; - -struct image_fs_data -{ - IsoImageFilesystem *fs; /**< reference to the image it belongs to */ - IsoFileSource *parent; /**< reference to the parent (NULL if root) */ - - struct stat info; /**< filled struct stat */ - char *name; /**< name of this file */ - - uint32_t block; /**< block of the extend */ - unsigned int opened : 2; /**< 0 not opened, 1 opened file, 2 opened dir */ - - /* info for content reading */ - struct - { - /** - * - For regular files, once opened it points to a temporary data - * buffer of 2048 bytes. - * - For dirs, once opened it points to a IsoFileSource* array with - * its children - * - For symlinks, it points to link destination - */ - void *content; - - /** - * - For regular files, number of bytes already read. - */ - off_t offset; - } data; -}; - -struct child_list -{ - IsoFileSource *file; - struct child_list *next; -}; - -void child_list_free(struct child_list *list) -{ - struct child_list *temp; - struct child_list *next = list; - while (next != NULL) { - temp = next->next; - iso_file_source_unref(next->file); - free(next); - next = temp; - } -} - -static -char* ifs_get_path(IsoFileSource *src) -{ - ImageFileSourceData *data; - data = src->data; - - if (data->parent == NULL) { - return strdup(""); - } else { - char *path = ifs_get_path(data->parent); - int pathlen = strlen(path); - path = realloc(path, pathlen + strlen(data->name) + 2); - path[pathlen] = '/'; - path[pathlen + 1] = '\0'; - return strcat(path, data->name); - } -} - -static -char* ifs_get_name(IsoFileSource *src) -{ - ImageFileSourceData *data; - data = src->data; - return data->name == NULL ? NULL : strdup(data->name); -} - -static -int ifs_lstat(IsoFileSource *src, struct stat *info) -{ - ImageFileSourceData *data; - - if (src == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - - data = src->data; - *info = data->info; - return ISO_SUCCESS; -} - -static -int ifs_stat(IsoFileSource *src, struct stat *info) -{ - ImageFileSourceData *data; - - if (src == NULL || info == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (ImageFileSourceData*)src->data; - - if (S_ISLNK(data->info.st_mode)) { - /* TODO #00012 : support follow symlinks on image filesystem */ - return ISO_FILE_BAD_PATH; - } - *info = data->info; - return ISO_SUCCESS; -} - -static -int ifs_access(IsoFileSource *src) -{ - /* we always have access, it is controlled by DataSource */ - return ISO_SUCCESS; -} - -/** - * Read all directory records in a directory, and creates an IsoFileSource for - * each of them, storing them in the data field of the IsoFileSource for the - * given dir. - */ -static -int read_dir(ImageFileSourceData *data) -{ - int ret; - uint32_t size; - uint32_t block; - IsoImageFilesystem *fs; - _ImageFsData *fsdata; - struct ecma119_dir_record *record; - uint8_t buffer[BLOCK_SIZE]; - IsoFileSource *child = NULL; - uint32_t pos = 0; - uint32_t tlen = 0; - - if (data == NULL) { - return ISO_NULL_POINTER; - } - - fs = data->fs; - fsdata = fs->data; - - block = data->block; - ret = fsdata->src->read_block(fsdata->src, block, buffer); - if (ret < 0) { - return ret; - } - - /* "." entry, get size of the dir and skip */ - record = (struct ecma119_dir_record *)(buffer + pos); - size = iso_read_bb(record->length, 4, NULL); - tlen += record->len_dr[0]; - pos += record->len_dr[0]; - - /* skip ".." */ - record = (struct ecma119_dir_record *)(buffer + pos); - tlen += record->len_dr[0]; - pos += record->len_dr[0]; - - while (tlen < size) { - - record = (struct ecma119_dir_record *)(buffer + pos); - if (pos == 2048 || record->len_dr[0] == 0) { - /* - * The directory entries are splitted in several blocks - * read next block - */ - ret = fsdata->src->read_block(fsdata->src, ++block, buffer); - if (ret < 0) { - return ret; - } - tlen += 2048 - pos; - pos = 0; - continue; - } - - /* - * What about ignoring files with existence flag? - * if (record->flags[0] & 0x01) - * continue; - */ - - /* - * For a extrange reason, mkisofs relocates directories under - * a RR_MOVED dir. It seems that it is only used for that purposes, - * and thus it should be removed from the iso tree before - * generating a new image with libisofs, that don't uses it. - */ - if (data->parent == NULL && record->len_fi[0] == 8 - && !strncmp((char*)record->file_id, "RR_MOVED", 8)) { - - iso_msg_debug(fsdata->msgid, "Skipping RR_MOVE entry."); - - tlen += record->len_dr[0]; - pos += record->len_dr[0]; - continue; - } - - /* - * We pass a NULL parent instead of dir, to prevent the circular - * reference from child to parent. - */ - ret = iso_file_source_new_ifs(fs, NULL, record, &child); - if (ret < 0) { - return ret; - } - - /* add to the child list */ - if (ret != 0) { - struct child_list *node; - node = malloc(sizeof(struct child_list)); - if (node == NULL) { - iso_file_source_unref(child); - return ISO_OUT_OF_MEM; - } - /* - * Note that we insert in reverse order. This leads to faster - * addition here, but also when adding to the tree, as insertion - * will be done, sorted, in the first position of the list. - */ - node->next = data->data.content; - node->file = child; - data->data.content = node; - } - - tlen += record->len_dr[0]; - pos += record->len_dr[0]; - } - - return ISO_SUCCESS; -} - -static -int ifs_open(IsoFileSource *src) -{ - int ret; - ImageFileSourceData *data; - - if (src == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - data = (ImageFileSourceData*)src->data; - - if (data->opened) { - return ISO_FILE_ALREADY_OPENED; - } - - if (S_ISDIR(data->info.st_mode)) { - /* ensure fs is openned */ - ret = data->fs->open(data->fs); - if (ret < 0) { - return ret; - } - - /* - * Cache all directory entries. - * This can waste more memory, but improves as disc is read in much more - * sequencially way, thus reducing jump between tracks on disc - */ - ret = read_dir(data); - data->fs->close(data->fs); - - if (ret < 0) { - /* free probably allocated children */ - child_list_free((struct child_list*)data->data.content); - } else { - data->opened = 2; - } - - return ret; - } else if (S_ISREG(data->info.st_mode)) { - /* ensure fs is openned */ - ret = data->fs->open(data->fs); - if (ret < 0) { - return ret; - } - data->data.content = malloc(BLOCK_SIZE); - if (data->data.content == NULL) { - return ISO_OUT_OF_MEM; - } - data->data.offset = 0; - data->opened = 1; - } else { - /* symlinks and special files inside image can't be openned */ - return ISO_FILE_ERROR; - } - return ISO_SUCCESS; -} - -static -int ifs_close(IsoFileSource *src) -{ - ImageFileSourceData *data; - - if (src == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - data = (ImageFileSourceData*)src->data; - - if (!data->opened) { - return ISO_FILE_NOT_OPENED; - } - - if (data->opened == 2) { - /* - * close a dir, free all pending pre-allocated children. - * not that we don't need to close the filesystem, it was already - * closed - */ - child_list_free((struct child_list*) data->data.content); - data->data.content = NULL; - data->opened = 0; - } else if (data->opened == 1) { - /* close regular file */ - free(data->data.content); - data->fs->close(data->fs); - data->data.content = NULL; - data->opened = 0; - } else { - /* TODO only dirs and files supported for now */ - return ISO_ERROR; - } - - return ISO_SUCCESS; -} - -/** - * Attempts to read up to count bytes from the given source into - * the buffer starting at buf. - * - * The file src must be open() before calling this, and close() when no - * more needed. Not valid for dirs. On symlinks it reads the destination - * file. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * ISO_FILE_IS_DIR - * ISO_OUT_OF_MEM - * ISO_INTERRUPTED - */ -static -int ifs_read(IsoFileSource *src, void *buf, size_t count) -{ - int ret; - ImageFileSourceData *data; - uint32_t read = 0; - - if (src == NULL || src->data == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - if (count == 0) { - return ISO_WRONG_ARG_VALUE; - } - data = (ImageFileSourceData*)src->data; - - if (!data->opened) { - return ISO_FILE_NOT_OPENED; - } else if (data->opened != 1) { - return ISO_FILE_IS_DIR; - } - - while (read < count && data->data.offset < data->info.st_size) { - size_t bytes; - uint8_t *orig; - - if (data->data.offset % BLOCK_SIZE == 0) { - /* we need to buffer next block */ - uint32_t block; - _ImageFsData *fsdata; - - if (data->data.offset >= data->info.st_size) { - /* EOF */ - break; - } - fsdata = data->fs->data; - block = data->block + (data->data.offset / BLOCK_SIZE); - ret = fsdata->src->read_block(fsdata->src, block, - data->data.content); - if (ret < 0) { - return ret; - } - } - - /* how much can I read */ - bytes = MIN(BLOCK_SIZE - (data->data.offset % BLOCK_SIZE), - count - read); - if (data->data.offset + (off_t)bytes > data->info.st_size) { - bytes = data->info.st_size - data->data.offset; - } - orig = data->data.content; - orig += data->data.offset % BLOCK_SIZE; - memcpy((uint8_t*)buf + read, orig, bytes); - read += bytes; - data->data.offset += (off_t)bytes; - } - return read; -} - -static -int ifs_readdir(IsoFileSource *src, IsoFileSource **child) -{ - ImageFileSourceData *data, *cdata; - struct child_list *children; - - if (src == NULL || src->data == NULL || child == NULL) { - return ISO_NULL_POINTER; - } - data = (ImageFileSourceData*)src->data; - - if (!data->opened) { - return ISO_FILE_NOT_OPENED; - } else if (data->opened != 2) { - return ISO_FILE_IS_NOT_DIR; - } - - /* return the first child and free it */ - if (data->data.content == NULL) { - return 0; /* EOF */ - } - - children = (struct child_list*)data->data.content; - *child = children->file; - cdata = (ImageFileSourceData*)(*child)->data; - - /* set the ref to the parent */ - cdata->parent = src; - iso_file_source_ref(src); - - /* free the first element of the list */ - data->data.content = children->next; - free(children); - - return ISO_SUCCESS; -} - -/** - * Read the destination of a symlink. You don't need to open the file - * to call this. - * - * @param buf - * allocated buffer of at least bufsiz bytes. - * The dest. will be copied there, and it will be NULL-terminated - * @param bufsiz - * characters to be copied. Destination link will be truncated if - * it is larger than given size. This include the \0 character. - * @return - * 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 - * ISO_FILE_IS_NOT_SYMLINK - * ISO_OUT_OF_MEM - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * - */ -static -int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz) -{ - char *dest; - size_t len; - ImageFileSourceData *data; - - if (src == NULL || buf == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - - if (bufsiz <= 0) { - return ISO_WRONG_ARG_VALUE; - } - - data = (ImageFileSourceData*)src->data; - - if (!S_ISLNK(data->info.st_mode)) { - return ISO_FILE_IS_NOT_SYMLINK; - } - - dest = (char*)data->data.content; - len = strlen(dest); - if (bufsiz <= len) { - len = bufsiz - 1; - } - - strncpy(buf, dest, len); - buf[len] = '\0'; - - return ISO_SUCCESS; -} - -static -IsoFilesystem* ifs_get_filesystem(IsoFileSource *src) -{ - ImageFileSourceData *data; - - if (src == NULL) { - return NULL; - } - - data = src->data; - return data->fs; -} - -static -void ifs_free(IsoFileSource *src) -{ - ImageFileSourceData *data; - - data = src->data; - - /* close the file if it is already openned */ - if (data->opened) { - src->class->close(src); - } - - /* free destination if it is a link */ - if (S_ISLNK(data->info.st_mode)) { - free(data->data.content); - } - iso_filesystem_unref(data->fs); - if (data->parent != NULL) { - iso_file_source_unref(data->parent); - } - free(data->name); - free(data); -} - -IsoFileSourceIface ifs_class = { - 0, /* version */ - ifs_get_path, - ifs_get_name, - ifs_lstat, - ifs_stat, - ifs_access, - ifs_open, - ifs_close, - ifs_read, - ifs_readdir, - ifs_readlink, - ifs_get_filesystem, - ifs_free -}; - -/** - * Read a file name from a directory record, doing the needed charset - * conversion - */ -static -char *get_name(_ImageFsData *fsdata, const char *str, size_t len) -{ - int ret; - char *name = NULL; - if (strcmp(fsdata->local_charset, fsdata->input_charset)) { - /* charset conversion needed */ - ret = strnconv(str, fsdata->input_charset, fsdata->local_charset, len, - &name); - if (ret == 1) { - return name; - } else { - ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, ret, - "Charset conversion error. Can't convert %s from %s to %s", - str, fsdata->input_charset, fsdata->local_charset); - if (ret < 0) { - return NULL; /* aborted */ - } - /* fallback */ - } - } - - /* we reach here when the charset conversion is not needed or has failed */ - - name = malloc(len + 1); - if (name == NULL) { - return NULL; - } - memcpy(name, str, len); - name[len] = '\0'; - return name; -} - -/** - * - * @return - * 1 success, 0 record ignored (not an error, can be a relocated dir), - * < 0 error - */ -static -int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, - struct ecma119_dir_record *record, - IsoFileSource **src) -{ - int ret; - struct stat atts; - time_t recorded; - _ImageFsData *fsdata; - IsoFileSource *ifsrc = NULL; - ImageFileSourceData *ifsdata = NULL; - - int namecont = 0; /* 1 if found a NM with CONTINUE flag */ - char *name = NULL; - - /* 1 if found a SL with CONTINUE flag, - * 2 if found a component with continue flag */ - int linkdestcont = 0; - char *linkdest = NULL; - - uint32_t relocated_dir = 0; - - if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) { - return ISO_NULL_POINTER; - } - - fsdata = (_ImageFsData*)fs->data; - - memset(&atts, 0, sizeof(struct stat)); - - /* - * First of all, check for unsupported ECMA-119 features - */ - - /* check for unsupported multiextend */ - if (record->flags[0] & 0x80) { - iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0, - "Unsupported image. This image makes use of Multi-Extend" - " features, that are not supported at this time. If you " - "need support for that, please request us this feature."); - return ISO_UNSUPPORTED_ECMA119; - } - - /* check for unsupported interleaved mode */ - if (record->file_unit_size[0] || record->interleave_gap_size[0]) { - iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0, - "Unsupported image. This image has at least one file recorded " - "in interleaved mode. We don't support this mode, as we think " - "it's not used. If you're reading this, then we're wrong :) " - "Please contact libisofs developers, so we can fix this."); - return ISO_UNSUPPORTED_ECMA119; - } - - /* - * Check for extended attributes, that are not supported. Note that even - * if we don't support them, it is easy to ignore them. - */ - if (record->len_xa[0]) { - iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0, - "Unsupported image. This image has at least one file with " - "Extended Attributes, that are not supported"); - return ISO_UNSUPPORTED_ECMA119; - } - - /* TODO #00013 : check for unsupported flags when reading a dir record */ - - /* - * The idea is to read all the RR entries (if we want to do that and RR - * extensions exist on image), storing the info we want from that. - * Then, we need some sanity checks. - * Finally, we select what kind of node it is, and set values properly. - */ - - if (fsdata->rr) { - struct susp_sys_user_entry *sue; - SuspIterator *iter; - - - iter = susp_iter_new(fsdata->src, record, fsdata->len_skp, - fsdata->msgid); - if (iter == NULL) { - return ISO_OUT_OF_MEM; - } - - while ((ret = susp_iter_next(iter, &sue)) > 0) { - - /* ignore entries from different version */ - if (sue->version[0] != 1) - continue; - - if (SUSP_SIG(sue, 'P', 'X')) { - ret = read_rr_PX(sue, &atts); - if (ret < 0) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, - "Invalid PX entry"); - } - } else if (SUSP_SIG(sue, 'T', 'F')) { - ret = read_rr_TF(sue, &atts); - if (ret < 0) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, - "Invalid TF entry"); - } - } else if (SUSP_SIG(sue, 'N', 'M')) { - if (name != NULL && namecont == 0) { - /* ups, RR standard violation */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0, - "New NM entry found without previous" - "CONTINUE flag. Ignored"); - continue; - } - ret = read_rr_NM(sue, &name, &namecont); - if (ret < 0) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, - "Invalid NM entry"); - } - } else if (SUSP_SIG(sue, 'S', 'L')) { - if (linkdest != NULL && linkdestcont == 0) { - /* ups, RR standard violation */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0, - "New SL entry found without previous" - "CONTINUE flag. Ignored"); - continue; - } - ret = read_rr_SL(sue, &linkdest, &linkdestcont); - if (ret < 0) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, - "Invalid SL entry"); - } - } else if (SUSP_SIG(sue, 'R', 'E')) { - /* - * this directory entry refers to a relocated directory. - * We simply ignore it, as it will be correctly handled - * when found the CL - */ - susp_iter_free(iter); - free(name); - return 0; /* it's not an error */ - } else if (SUSP_SIG(sue, 'C', 'L')) { - /* - * This entry is a placeholder for a relocated dir. - * We need to ignore other entries, with the exception of NM. - * Then we create a directory node that represents the - * relocated dir, and iterate over its children. - */ - relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL); - if (relocated_dir == 0) { - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "Invalid SL entry, no child location"); - break; - } - } else if (SUSP_SIG(sue, 'P', 'N')) { - ret = read_rr_PN(sue, &atts); - if (ret < 0) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret, - "Invalid PN entry"); - } - } else if (SUSP_SIG(sue, 'S', 'F')) { - ret = iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_RR, 0, - "Sparse files not supported."); - break; - } else if (SUSP_SIG(sue, 'R', 'R')) { - /* TODO I've seen this RR on mkisofs images. what's this? */ - continue; - } else if (SUSP_SIG(sue, 'S', 'P')) { - /* - * Ignore this, to prevent the hint message, if we are dealing - * with root node (SP is only valid in "." of root node) - */ - if (parent != NULL) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "SP entry found in a directory entry other " - "than '.' entry of root node"); - } - continue; - } else if (SUSP_SIG(sue, 'E', 'R')) { - /* - * Ignore this, to prevent the hint message, if we are dealing - * with root node (ER is only valid in "." of root node) - */ - if (parent != NULL) { - /* notify and continue */ - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "ER entry found in a directory entry other " - "than '.' entry of root node"); - } - continue; - } else { - ret = iso_msg_submit(fsdata->msgid, ISO_SUSP_UNHANDLED, 0, - "Unhandled SUSP entry %c%c.", sue->sig[0], sue->sig[1]); - } - } - - susp_iter_free(iter); - - /* check for RR problems */ - - if (ret < 0) { - /* error was already submitted above */ - iso_msg_debug(fsdata->msgid, "Error parsing RR entries"); - } else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) { - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "Mandatory " - "Rock Ridge PX entry is not present or it " - "contains invalid values."); - } else { - /* ensure both name and link dest are finished */ - if (namecont != 0) { - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "Incomplete RR name, last NM entry continues"); - } - if (linkdestcont != 0) { - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "Incomplete link destination, last SL entry continues"); - } - } - - if (ret < 0) { - free(name); - return ret; - } - - /* convert name to needed charset */ - if (strcmp(fsdata->input_charset, fsdata->local_charset) && name) { - /* we need to convert name charset */ - char *newname = NULL; - ret = strconv(name, fsdata->input_charset, fsdata->local_charset, - &newname); - if (ret < 0) { - /* its just a hint message */ - ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, - ret, "Charset conversion error. Can't " - "convert %s from %s to %s", name, - fsdata->input_charset, fsdata->local_charset); - free(newname); - if (ret < 0) { - free(name); - return ret; - } - } else { - free(name); - name = newname; - } - } - - /* convert link destination to needed charset */ - if (strcmp(fsdata->input_charset, fsdata->local_charset) && linkdest) { - /* we need to convert name charset */ - char *newlinkdest = NULL; - ret = strconv(linkdest, fsdata->input_charset, - fsdata->local_charset, &newlinkdest); - if (ret < 0) { - ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET, - ret, "Charset conversion error. Can't " - "convert %s from %s to %s", name, - fsdata->input_charset, fsdata->local_charset); - free(newlinkdest); - if (ret < 0) { - free(name); - return ret; - } - } else { - free(linkdest); - linkdest = newlinkdest; - } - } - - } else { - /* RR extensions are not read / used */ - atts.st_gid = fsdata->gid; - atts.st_uid = fsdata->uid; - if (record->flags[0] & 0x02) { - atts.st_mode = S_IFDIR | fsdata->dir_mode; - } else { - atts.st_mode = S_IFREG | fsdata->file_mode; - } - } - - /* - * if we haven't RR extensions, or no NM entry is present, - * we use the name in directory record - */ - if (!name) { - size_t len; - - if (record->len_fi[0] == 1 && record->file_id[0] == 0) { - /* "." entry, we can call this for root node, so... */ - if (!(atts.st_mode & S_IFDIR)) { - return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0, - "Wrong ISO file name. \".\" not dir"); - } - } else { - - name = get_name(fsdata, (char*)record->file_id, record->len_fi[0]); - if (name == NULL) { - return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0, - "Can't retrieve file name"); - } - - /* remove trailing version number */ - len = strlen(name); - if (len > 2 && name[len-2] == ';' && name[len-1] == '1') { - if (len > 3 && name[len-3] == '.') { - /* - * the "." is mandatory, so in most cases is included only - * for standard compliance - */ - name[len-3] = '\0'; - } else { - name[len-2] = '\0'; - } - } - } - } - - if (relocated_dir) { - - /* - * We are dealing with a placeholder for a relocated dir. - * Thus, we need to read attributes for this directory from the "." - * entry of the relocated dir. - */ - uint8_t buffer[BLOCK_SIZE]; - - ret = fsdata->src->read_block(fsdata->src, relocated_dir, buffer); - if (ret < 0) { - return ret; - } - - ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*) - buffer, src); - if (ret <= 0) { - return ret; - } - - /* but the real name is the name of the placeholder */ - ifsdata = (ImageFileSourceData*) (*src)->data; - ifsdata->name = name; - return ISO_SUCCESS; - } - - if (fsdata->rr != RR_EXT_112) { - /* - * Only RRIP 1.12 provides valid inode numbers. If not, it is not easy - * to generate those serial numbers, and we use extend block instead. - * It BREAKS POSIX SEMANTICS, but its suitable for our needs - */ - atts.st_ino = (ino_t) iso_read_bb(record->block, 4, NULL); - if (fsdata->rr == 0) { - atts.st_nlink = 1; - } - } - - /* - * if we haven't RR extensions, or a needed TF time stamp is not present, - * we use plain iso recording time - */ - recorded = iso_datetime_read_7(record->recording_time); - if (atts.st_atime == (time_t) 0) { - atts.st_atime = recorded; - } - if (atts.st_ctime == (time_t) 0) { - atts.st_ctime = recorded; - } - if (atts.st_mtime == (time_t) 0) { - atts.st_mtime = recorded; - } - - /* the size is read from iso directory record */ - atts.st_size = iso_read_bb(record->length, 4, NULL); - - /* Fill last entries */ - atts.st_dev = fsdata->id; - atts.st_blksize = BLOCK_SIZE; - atts.st_blocks = DIV_UP(atts.st_size, BLOCK_SIZE); - - /* TODO #00014 : more sanity checks to ensure dir record info is valid */ - if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) { - ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, - "Link without destination."); - free(name); - return ret; - } - - /* ok, we can now create the file source */ - ifsdata = calloc(1, sizeof(ImageFileSourceData)); - if (ifsdata == NULL) { - ret = ISO_OUT_OF_MEM; - goto ifs_cleanup; - } - ifsrc = calloc(1, sizeof(IsoFileSource)); - if (ifsrc == NULL) { - ret = ISO_OUT_OF_MEM; - goto ifs_cleanup; - } - - /* fill data */ - ifsdata->fs = fs; - iso_filesystem_ref(fs); - if (parent != NULL) { - ifsdata->parent = parent; - iso_file_source_ref(parent); - } - ifsdata->info = atts; - ifsdata->name = name; - ifsdata->block = iso_read_bb(record->block, 4, NULL); - - if (S_ISLNK(atts.st_mode)) { - ifsdata->data.content = linkdest; - } - - ifsrc->class = &ifs_class; - ifsrc->data = ifsdata; - ifsrc->refcount = 1; - - *src = ifsrc; - return ISO_SUCCESS; - -ifs_cleanup: ; - free(name); - free(linkdest); - free(ifsdata); - free(ifsrc); - return ret; -} - -static -int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root) -{ - int ret; - _ImageFsData *data; - uint8_t buffer[BLOCK_SIZE]; - - if (fs == NULL || fs->data == NULL || root == NULL) { - return ISO_NULL_POINTER; - } - - data = (_ImageFsData*)fs->data; - - /* open the filesystem */ - ret = ifs_fs_open((IsoImageFilesystem*)fs); - if (ret < 0) { - return ret; - } - - /* read extend for root record */ - ret = data->src->read_block(data->src, data->iso_root_block, buffer); - if (ret < 0) { - ifs_fs_close((IsoImageFilesystem*)fs); - return ret; - } - - /* get root attributes from "." entry */ - ret = iso_file_source_new_ifs((IsoImageFilesystem*)fs, NULL, - (struct ecma119_dir_record*) buffer, root); - - ifs_fs_close((IsoImageFilesystem*)fs); - return ret; -} - -/** - * Find a file inside a node. - * - * @param file - * it is not modified if requested file is not found - * @return - * 1 success, 0 not found, < 0 error - */ -static -int ifs_get_file(IsoFileSource *dir, const char *name, IsoFileSource **file) -{ - int ret; - IsoFileSource *src; - - ret = iso_file_source_open(dir); - if (ret < 0) { - return ret; - } - while ((ret = iso_file_source_readdir(dir, &src)) == 1) { - char *fname = iso_file_source_get_name(src); - if (!strcmp(name, fname)) { - free(fname); - *file = src; - ret = ISO_SUCCESS; - break; - } - free(fname); - iso_file_source_unref(src); - } - iso_file_source_close(dir); - return ret; -} - -static -int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file) -{ - int ret; - _ImageFsData *data; - IsoFileSource *src; - char *ptr, *brk_info, *component; - - if (fs == NULL || fs->data == NULL || path == NULL || file == NULL) { - return ISO_NULL_POINTER; - } - - if (path[0] != '/') { - /* only absolute paths supported */ - return ISO_FILE_BAD_PATH; - } - - data = (_ImageFsData*)fs->data; - - /* open the filesystem */ - ret = ifs_fs_open((IsoImageFilesystem*)fs); - if (ret < 0) { - return ret; - } - - ret = ifs_get_root(fs, &src); - if (ret < 0) { - return ret; - } - if (!strcmp(path, "/")) { - /* we are looking for root */ - *file = src; - ret = ISO_SUCCESS; - goto get_path_exit; - } - - ptr = strdup(path); - if (ptr == NULL) { - iso_file_source_unref(src); - ret = ISO_OUT_OF_MEM; - goto get_path_exit; - } - - component = strtok_r(ptr, "/", &brk_info); - while (component) { - IsoFileSource *child = NULL; - - ImageFileSourceData *fdata; - fdata = src->data; - if (!S_ISDIR(fdata->info.st_mode)) { - ret = ISO_FILE_BAD_PATH; - break; - } - - ret = ifs_get_file(src, component, &child); - iso_file_source_unref(src); - if (ret <= 0) { - break; - } - - src = child; - component = strtok_r(NULL, "/", &brk_info); - } - - free(ptr); - if (ret < 0) { - iso_file_source_unref(src); - } else if (ret == 0) { - ret = ISO_FILE_DOESNT_EXIST; - } else { - *file = src; - } - - get_path_exit:; - ifs_fs_close((IsoImageFilesystem*)fs); - return ret; -} - -unsigned int ifs_get_id(IsoFilesystem *fs) -{ - return ISO_IMAGE_FS_ID; -} - -static -int ifs_fs_open(IsoImageFilesystem *fs) -{ - _ImageFsData *data; - - if (fs == NULL || fs->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (_ImageFsData*)fs->data; - - if (data->open_count == 0) { - /* we need to actually open the data source */ - int res = data->src->open(data->src); - if (res < 0) { - return res; - } - } - ++data->open_count; - return ISO_SUCCESS; -} - -static -int ifs_fs_close(IsoImageFilesystem *fs) -{ - _ImageFsData *data; - - if (fs == NULL || fs->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (_ImageFsData*)fs->data; - - if (--data->open_count == 0) { - /* we need to actually close the data source */ - return data->src->close(data->src); - } - return ISO_SUCCESS; -} - -static -void ifs_fs_free(IsoFilesystem *fs) -{ - IsoImageFilesystem *ifs; - _ImageFsData *data; - - ifs = (IsoImageFilesystem*)fs; - data = (_ImageFsData*) fs->data; - - /* close data source if already openned */ - if (data->open_count > 0) { - data->src->close(data->src); - } - - /* free our ref to datasource */ - iso_data_source_unref(data->src); - - /* free volume atts */ - free(data->volset_id); - free(data->volume_id); - free(data->publisher_id); - free(data->data_preparer_id); - free(data->system_id); - free(data->application_id); - free(data->copyright_file_id); - free(data->abstract_file_id); - free(data->biblio_file_id); - - free(data->input_charset); - free(data->local_charset); - free(data); -} - -/** - * Read the SUSP system user entries of the "." entry of the root directory, - * indentifying when Rock Ridge extensions are being used. - * - * @return - * 1 success, 0 ignored, < 0 error - */ -static -int read_root_susp_entries(_ImageFsData *data, uint32_t block) -{ - int ret; - unsigned char buffer[2048]; - struct ecma119_dir_record *record; - struct susp_sys_user_entry *sue; - SuspIterator *iter; - - ret = data->src->read_block(data->src, block, buffer); - if (ret < 0) { - return ret; - } - - /* record will be the "." directory entry for the root record */ - record = (struct ecma119_dir_record *)buffer; - - /* - * TODO #00015 : take care of CD-ROM XA discs when reading SP entry - * SUSP specification claims that for CD-ROM XA the SP entry - * is not at position BP 1, but at BP 15. Is that used? - * In that case, we need to set info->len_skp to 15!! - */ - - iter = susp_iter_new(data->src, record, data->len_skp, data->msgid); - if (iter == NULL) { - return ISO_OUT_OF_MEM; - } - - /* first entry must be an SP system use entry */ - ret = susp_iter_next(iter, &sue); - if (ret < 0) { - /* error */ - susp_iter_free(iter); - return ret; - } else if (ret == 0 || !SUSP_SIG(sue, 'S', 'P') ) { - iso_msg_debug(data->msgid, "SUSP/RR is not being used."); - susp_iter_free(iter); - return ISO_SUCCESS; - } - - /* it is a SP system use entry */ - if (sue->version[0] != 1 || sue->data.SP.be[0] != 0xBE - || sue->data.SP.ef[0] != 0xEF) { - - susp_iter_free(iter); - return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0, - "SUSP SP system use entry seems to be wrong. " - "Ignoring Rock Ridge Extensions."); - } - - iso_msg_debug(data->msgid, "SUSP/RR is being used."); - - /* - * The LEN_SKP field, defined in IEEE 1281, SUSP. 5.3, specifies the - * number of bytes to be skipped within each System Use field. - * I think this will be always 0, but given that support this standard - * feature is easy... - */ - data->len_skp = sue->data.SP.len_skp[0]; - - /* - * Ok, now search for ER entry. - * Just notice that the attributes for root dir are read elsewhere. - * - * TODO #00016 : handle non RR ER entries - * - * if several ER are present, we need to identify the position of - * what refers to RR, and then look for corresponding ES entry in - * each directory record. I have not implemented this (it's not used, - * no?), but if we finally need it, it can be easily implemented in - * the iterator, transparently for the rest of the code. - */ - while ((ret = susp_iter_next(iter, &sue)) > 0) { - - /* ignore entries from different version */ - if (sue->version[0] != 1) - continue; - - if (SUSP_SIG(sue, 'E', 'R')) { - - if (data->rr_version) { - ret = iso_msg_submit(data->msgid, ISO_SUSP_MULTIPLE_ER, 0, - "More than one ER has found. This is not supported. " - "It will be ignored, but can cause problems. " - "Please notify us about this."); - if (ret < 0) { - break; - } - } - - /* - * it seems that Rock Ridge can be identified with any - * of the following - */ - if ( sue->data.ER.len_id[0] == 10 && - !strncmp((char*)sue->data.ER.ext_id, "RRIP_1991A", 10) ) { - - iso_msg_debug(data->msgid, - "Suitable Rock Ridge ER found. Version 1.10."); - data->rr_version = RR_EXT_110; - - } else if ( (sue->data.ER.len_id[0] == 10 && - !strncmp((char*)sue->data.ER.ext_id, "IEEE_P1282", 10)) - || (sue->data.ER.len_id[0] == 9 && - !strncmp((char*)sue->data.ER.ext_id, "IEEE_1282", 9)) ) { - - iso_msg_debug(data->msgid, - "Suitable Rock Ridge ER found. Version 1.12."); - data->rr_version = RR_EXT_112; - } else { - ret = iso_msg_submit(data->msgid, ISO_SUSP_MULTIPLE_ER, 0, - "Not Rock Ridge ER found.\n" - "That will be ignored, but can cause problems in " - "image reading. Please notify us about this"); - if (ret < 0) { - break; - } - } - } - } - - susp_iter_free(iter); - - if (ret < 0) { - return ret; - } - - return ISO_SUCCESS; -} - -static -int read_pvm(_ImageFsData *data, uint32_t block) -{ - int ret; - struct ecma119_pri_vol_desc *pvm; - struct ecma119_dir_record *rootdr; - uint8_t buffer[BLOCK_SIZE]; - - /* read PVM */ - ret = data->src->read_block(data->src, block, buffer); - if (ret < 0) { - return ret; - } - - pvm = (struct ecma119_pri_vol_desc *)buffer; - - /* sanity checks */ - if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 - || strncmp((char*)pvm->std_identifier, "CD001", 5) - || pvm->file_structure_version[0] != 1) { - - return ISO_WRONG_PVD; - } - - /* ok, it is a valid PVD */ - - /* fill volume attributes */ - /* TODO take care of input charset */ - data->volset_id = strcopy((char*)pvm->vol_set_id, 128); - data->volume_id = strcopy((char*)pvm->volume_id, 32); - data->publisher_id = strcopy((char*)pvm->publisher_id, 128); - data->data_preparer_id = strcopy((char*)pvm->data_prep_id, 128); - data->system_id = strcopy((char*)pvm->system_id, 32); - data->application_id = strcopy((char*)pvm->application_id, 128); - data->copyright_file_id = strcopy((char*)pvm->copyright_file_id, 37); - data->abstract_file_id = strcopy((char*)pvm->abstract_file_id, 37); - data->biblio_file_id = strcopy((char*)pvm->bibliographic_file_id, 37); - - data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL); - - rootdr = (struct ecma119_dir_record*) pvm->root_dir_record; - data->pvd_root_block = iso_read_bb(rootdr->block, 4, NULL); - - /* - * TODO #00017 : take advantage of other atts of PVD - * PVD has other things that could be interesting, but that don't have a - * member in IsoImage, such as creation date. In a multisession disc, we - * could keep the creation date and update the modification date, for - * example. - */ - - return ISO_SUCCESS; -} - -/** - * @return - * 1 success, 0 ignored, < 0 error - */ -static -int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block) -{ - int ret; - struct el_torito_validation_entry *ve; - struct el_torito_default_entry *entry; - unsigned char buffer[BLOCK_SIZE]; - - ret = data->src->read_block(data->src, block, buffer); - if (ret < 0) { - return ret; - } - - ve = (struct el_torito_validation_entry*)buffer; - - /* check if it is a valid catalog (TODO: check also the checksum)*/ - if ( (ve->header_id[0] != 1) || (ve->key_byte1[0] != 0x55) - || (ve->key_byte2[0] != 0xAA) ) { - - return iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0, - "Wrong or damaged El-Torito Catalog. El-Torito info " - "will be ignored."); - } - - /* check for a valid platform */ - if (ve->platform_id[0] != 0) { - return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0, - "Unsupported El-Torito platform. Only 80x86 is " - "supported. El-Torito info will be ignored."); - } - - /* ok, once we are here we assume it is a valid catalog */ - - /* parse the default entry */ - entry = (struct el_torito_default_entry *)(buffer + 32); - - data->eltorito = 1; - data->bootable = entry->boot_indicator[0] ? 1 : 0; - data->type = entry->boot_media_type[0]; - data->partition_type = entry->system_type[0]; - data->load_seg = iso_read_lsb(entry->load_seg, 2); - data->load_size = iso_read_lsb(entry->sec_count, 2); - data->imgblock = iso_read_lsb(entry->block, 4); - - /* TODO #00018 : check if there are more entries in the boot catalog */ - - return ISO_SUCCESS; -} - -int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, - int msgid, IsoImageFilesystem **fs) -{ - int ret; - uint32_t block; - IsoImageFilesystem *ifs; - _ImageFsData *data; - uint8_t buffer[BLOCK_SIZE]; - - if (src == NULL || opts == NULL || fs == NULL) { - return ISO_NULL_POINTER; - } - - data = calloc(1, sizeof(_ImageFsData)); - if (data == NULL) { - return ISO_OUT_OF_MEM; - } - - ifs = calloc(1, sizeof(IsoImageFilesystem)); - if (ifs == NULL) { - free(data); - return ISO_OUT_OF_MEM; - } - - /* get our ref to IsoDataSource */ - data->src = src; - iso_data_source_ref(src); - data->open_count = 0; - - /* get an id for the filesystem */ - data->id = ++fs_dev_id; - - /* fill data from opts */ - data->gid = opts->gid; - data->uid = opts->uid; - data->file_mode = opts->file_mode & ~S_IFMT; - data->dir_mode = opts->dir_mode & ~S_IFMT; - data->msgid = msgid; - - setlocale(LC_CTYPE, ""); - data->local_charset = strdup(nl_langinfo(CODESET)); - if (data->local_charset == NULL) { - ret = ISO_OUT_OF_MEM; - goto fs_cleanup; - } - - strncpy(ifs->type, "iso ", 4); - ifs->data = data; - ifs->refcount = 1; - ifs->version = 0; - ifs->get_root = ifs_get_root; - ifs->get_by_path = ifs_get_by_path; - ifs->get_id = ifs_get_id; - ifs->open = ifs_fs_open; - ifs->close = ifs_fs_close; - ifs->free = ifs_fs_free; - - /* read Volume Descriptors and ensure it is a valid image */ - - /* 1. first, open the filesystem */ - ifs_fs_open(ifs); - - /* 2. read primary volume description */ - ret = read_pvm(data, opts->block + 16); - if (ret < 0) { - goto fs_cleanup; - } - - /* 3. read next volume descriptors */ - block = opts->block + 17; - do { - ret = src->read_block(src, block, buffer); - if (ret < 0) { - /* cleanup and exit */ - goto fs_cleanup; - } - switch (buffer[0]) { - case 0: - /* boot record */ - { - struct ecma119_boot_rec_vol_desc *vol; - vol = (struct ecma119_boot_rec_vol_desc*)buffer; - - /* some sanity checks */ - if (strncmp((char*)vol->std_identifier, "CD001", 5) - || vol->vol_desc_version[0] != 1 - || strncmp((char*)vol->boot_sys_id, - "EL TORITO SPECIFICATION", 23)) { - - ret = iso_msg_submit(data->msgid, - ISO_UNSUPPORTED_EL_TORITO, 0, - "Unsupported Boot Vol. Desc. Only El-Torito " - "Specification, Version 1.0 Volume " - "Descriptors are supported. Ignoring boot info"); - if (ret < 0) { - goto fs_cleanup; - } - break; - } - data->catblock = iso_read_lsb(vol->boot_catalog, 4); - ret = read_el_torito_boot_catalog(data, data->catblock); - if (ret < 0) { - goto fs_cleanup; - } - } - break; - case 2: - /* suplementary volume descritor */ - { - struct ecma119_sup_vol_desc *sup; - struct ecma119_dir_record *root; - - sup = (struct ecma119_sup_vol_desc*)buffer; - if (sup->esc_sequences[0] == 0x25 && - sup->esc_sequences[1] == 0x2F && - (sup->esc_sequences[2] == 0x40 || - sup->esc_sequences[2] == 0x43 || - sup->esc_sequences[2] == 0x45) ) { - - /* it's a Joliet Sup. Vol. Desc. */ - iso_msg_debug(data->msgid, "Found Joliet extensions"); - data->joliet = 1; - root = (struct ecma119_dir_record*)sup->root_dir_record; - data->svd_root_block = iso_read_bb(root->block, 4, NULL); - /* TODO #00019 : set IsoImage attribs from Joliet SVD? */ - /* TODO #00020 : handle RR info in Joliet tree */ - } else if (sup->vol_desc_version[0] == 2) { - /* - * It is an Enhanced Volume Descriptor, image is an - * ISO 9660:1999 - */ - iso_msg_debug(data->msgid, "Found ISO 9660:1999"); - data->iso1999 = 1; - root = (struct ecma119_dir_record*)sup->root_dir_record; - data->evd_root_block = iso_read_bb(root->block, 4, NULL); - /* TODO #00021 : handle RR info in ISO 9660:1999 tree */ - } else { - ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0, - "Unsupported Sup. Vol. Desc found."); - if (ret < 0) { - goto fs_cleanup; - } - } - } - break; - case 255: - /* - * volume set terminator - * ignore, as it's checked in loop end condition - */ - break; - default: - ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0, - "Ignoring Volume descriptor %x.", buffer[0]); - if (ret < 0) { - goto fs_cleanup; - } - break; - } - block++; - } while (buffer[0] != 255); - - /* 4. check if RR extensions are being used */ - ret = read_root_susp_entries(data, data->pvd_root_block); - if (ret < 0) { - goto fs_cleanup; - } - - /* user doesn't want to read RR extensions */ - if (opts->norock) { - data->rr = RR_EXT_NO; - } else { - data->rr = data->rr_version; - } - - /* select what tree to read */ - if (data->rr) { - /* RR extensions are available */ - if (!opts->nojoliet && opts->preferjoliet && data->joliet) { - /* if user prefers joliet, that is used */ - iso_msg_debug(data->msgid, "Reading Joliet extensions."); - data->input_charset = strdup("UCS-2BE"); - data->rr = RR_EXT_NO; - data->iso_root_block = data->svd_root_block; - } else { - /* RR will be used */ - iso_msg_debug(data->msgid, "Reading Rock Ridge extensions."); - data->iso_root_block = data->pvd_root_block; - } - } else { - /* RR extensions are not available */ - if (!opts->nojoliet && data->joliet) { - /* joliet will be used */ - iso_msg_debug(data->msgid, "Reading Joliet extensions."); - data->input_charset = strdup("UCS-2BE"); - data->iso_root_block = data->svd_root_block; - } else if (!opts->noiso1999 && data->iso1999) { - /* we will read ISO 9660:1999 */ - iso_msg_debug(data->msgid, "Reading ISO-9660:1999 tree."); - data->iso_root_block = data->evd_root_block; - } else { - /* default to plain iso */ - iso_msg_debug(data->msgid, "Reading plain ISO-9660 tree."); - data->iso_root_block = data->pvd_root_block; - data->input_charset = strdup("ASCII"); - } - } - - if (data->input_charset == NULL) { - if (opts->input_charset != NULL) { - data->input_charset = strdup(opts->input_charset); - } else { - data->input_charset = strdup(data->local_charset); - } - } - if (data->input_charset == NULL) { - ret = ISO_OUT_OF_MEM; - goto fs_cleanup; - } - - /* and finally return. Note that we keep the DataSource opened */ - - *fs = ifs; - return ISO_SUCCESS; - - fs_cleanup: ; - ifs_fs_free(ifs); - free(ifs); - return ret; -} - -static -int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image, - IsoFileSource *src, IsoNode **node) -{ - int ret; - struct stat info; - IsoNode *new; - char *name; - ImageFileSourceData *data; - - if (builder == NULL || src == NULL || node == NULL || src->data == NULL) { - return ISO_NULL_POINTER; - } - - data = (ImageFileSourceData*)src->data; - - name = iso_file_source_get_name(src); - - /* get info about source */ - ret = iso_file_source_lstat(src, &info); - if (ret < 0) { - return ret; - } - - new = NULL; - switch (info.st_mode & S_IFMT) { - case S_IFREG: - { - /* source is a regular file */ - _ImageFsData *fsdata = data->fs->data; - - if (fsdata->eltorito && data->block == fsdata->catblock) { - - if (image->bootcat->node != NULL) { - ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0, - "More than one catalog node has been found. " - "We can continue, but that could lead to " - "problems"); - if (ret < 0) { - return ret; - } - iso_node_unref((IsoNode*)image->bootcat->node); - } - - /* we create a placeholder for the catalog instead of - * a regular file */ - new = calloc(1, sizeof(IsoBoot)); - if (new == NULL) { - ret = ISO_OUT_OF_MEM; - free(name); - return ret; - } - - /* and set the image node */ - image->bootcat->node = (IsoBoot*)new; - new->type = LIBISO_BOOT; - new->refcount = 1; - } else { - IsoStream *stream; - IsoFile *file; - - ret = iso_file_source_stream_new(src, &stream); - if (ret < 0) { - free(name); - return ret; - } - /* take a ref to the src, as stream has taken our ref */ - iso_file_source_ref(src); - - file = calloc(1, sizeof(IsoFile)); - if (file == NULL) { - free(name); - iso_stream_unref(stream); - return ISO_OUT_OF_MEM; - } - - /* the msblock is taken from the image */ - file->msblock = data->block; - - /* - * and we set the sort weight based on the block on image, to - * improve performance on image modifying. - */ - file->sort_weight = INT_MAX - data->block; - - file->stream = stream; - file->node.type = LIBISO_FILE; - new = (IsoNode*) file; - new->refcount = 0; - - if (fsdata->eltorito && data->block == fsdata->imgblock) { - /* it is boot image node */ - if (image->bootcat->image->image != NULL) { - ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0, - "More than one image node has been found."); - if (ret < 0) { - free(name); - iso_stream_unref(stream); - return ret; - } - } else { - /* and set the image node */ - image->bootcat->image->image = file; - new->refcount++; - } - } - } - } - break; - case S_IFDIR: - { - /* source is a directory */ - new = calloc(1, sizeof(IsoDir)); - if (new == NULL) { - free(name); - return ISO_OUT_OF_MEM; - } - new->type = LIBISO_DIR; - new->refcount = 0; - } - break; - case S_IFLNK: - { - /* source is a symbolic link */ - char dest[PATH_MAX]; - IsoSymlink *link; - - ret = iso_file_source_readlink(src, dest, PATH_MAX); - if (ret < 0) { - free(name); - return ret; - } - link = malloc(sizeof(IsoSymlink)); - if (link == NULL) { - free(name); - return ISO_OUT_OF_MEM; - } - link->dest = strdup(dest); - link->node.type = LIBISO_SYMLINK; - new = (IsoNode*) link; - new->refcount = 0; - } - break; - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - { - /* source is an special file */ - IsoSpecial *special; - special = malloc(sizeof(IsoSpecial)); - if (special == NULL) { - free(name); - return ISO_OUT_OF_MEM; - } - special->dev = info.st_rdev; - special->node.type = LIBISO_SPECIAL; - new = (IsoNode*) special; - new->refcount = 0; - } - break; - } - - /* fill fields */ - new->refcount++; - new->name = name; - new->mode = info.st_mode; - new->uid = info.st_uid; - new->gid = info.st_gid; - new->atime = info.st_atime; - new->mtime = info.st_mtime; - new->ctime = info.st_ctime; - - new->hidden = 0; - - new->parent = NULL; - new->next = NULL; - - *node = new; - return ISO_SUCCESS; -} - -/** - * Create a new builder, that is exactly a copy of an old builder, but where - * create_node() function has been replaced by image_builder_create_node. - */ -static -int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder) -{ - IsoNodeBuilder *b; - - if (builder == NULL) { - return ISO_NULL_POINTER; - } - - b = malloc(sizeof(IsoNodeBuilder)); - if (b == NULL) { - return ISO_OUT_OF_MEM; - } - - b->refcount = 1; - b->create_file_data = old->create_file_data; - b->create_node_data = old->create_node_data; - b->create_file = old->create_file; - b->create_node = image_builder_create_node; - b->free = old->free; - - *builder = b; - return ISO_SUCCESS; -} - -/** - * Create a file source to access the El-Torito boot image, when it is not - * accessible from the ISO filesystem. - */ -static -int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src) -{ - int ret; - struct stat atts; - _ImageFsData *fsdata; - IsoFileSource *ifsrc = NULL; - ImageFileSourceData *ifsdata = NULL; - - if (fs == NULL || fs->data == NULL || src == NULL) { - return ISO_NULL_POINTER; - } - - fsdata = (_ImageFsData*)fs->data; - - memset(&atts, 0, sizeof(struct stat)); - atts.st_mode = S_IFREG; - atts.st_ino = fsdata->imgblock; /* not the best solution, but... */ - atts.st_nlink = 1; - - /* - * this is the greater problem. We don't know the size. For now, we - * just use a single block of data. In a future, maybe we could figure out - * a better idea. Another alternative is to use several blocks, that way - * is less probable that we throw out valid data. - */ - atts.st_size = (off_t)BLOCK_SIZE; - - /* Fill last entries */ - atts.st_dev = fsdata->id; - atts.st_blksize = BLOCK_SIZE; - atts.st_blocks = DIV_UP(atts.st_size, BLOCK_SIZE); - - /* ok, we can now create the file source */ - ifsdata = calloc(1, sizeof(ImageFileSourceData)); - if (ifsdata == NULL) { - ret = ISO_OUT_OF_MEM; - goto boot_fs_cleanup; - } - ifsrc = calloc(1, sizeof(IsoFileSource)); - if (ifsrc == NULL) { - ret = ISO_OUT_OF_MEM; - goto boot_fs_cleanup; - } - - /* fill data */ - ifsdata->fs = fs; - iso_filesystem_ref(fs); - ifsdata->parent = NULL; - ifsdata->info = atts; - ifsdata->name = NULL; - ifsdata->block = fsdata->imgblock; - - ifsrc->class = &ifs_class; - ifsrc->data = ifsdata; - ifsrc->refcount = 1; - - *src = ifsrc; - return ISO_SUCCESS; - -boot_fs_cleanup: ; - free(ifsdata); - free(ifsrc); - return ret; -} - - -int iso_image_import(IsoImage *image, IsoDataSource *src, - struct iso_read_opts *opts, - IsoReadImageFeatures **features) -{ - int ret; - IsoImageFilesystem *fs; - IsoFilesystem *fsback; - IsoNodeBuilder *blback; - IsoDir *oldroot; - IsoFileSource *newroot; - _ImageFsData *data; - struct el_torito_boot_catalog *oldbootcat; - - if (image == NULL || src == NULL || opts == NULL) { - return ISO_NULL_POINTER; - } - - ret = iso_image_filesystem_new(src, opts, image->id, &fs); - if (ret < 0) { - return ret; - } - data = fs->data; - - /* get root from filesystem */ - ret = fs->get_root(fs, &newroot); - if (ret < 0) { - return ret; - } - - /* backup image filesystem, builder and root */ - fsback = image->fs; - blback = image->builder; - oldroot = image->root; - oldbootcat = image->bootcat; /* could be NULL */ - - image->bootcat = NULL; - - /* create new builder */ - ret = iso_image_builder_new(blback, &image->builder); - if (ret < 0) { - goto import_revert; - } - - image->fs = fs; - - /* create new root, and set root attributes from source */ - ret = iso_node_new_root(&image->root); - if (ret < 0) { - goto import_revert; - } - { - struct stat info; - - /* I know this will not fail */ - iso_file_source_lstat(newroot, &info); - image->root->node.mode = info.st_mode; - image->root->node.uid = info.st_uid; - image->root->node.gid = info.st_gid; - image->root->node.atime = info.st_atime; - image->root->node.mtime = info.st_mtime; - image->root->node.ctime = info.st_ctime; - } - - /* if old image has el-torito, add a new catalog */ - if (data->eltorito) { - struct el_torito_boot_catalog *catalog; - ElToritoBootImage *boot_image= NULL; - - boot_image = calloc(1, sizeof(ElToritoBootImage)); - if (boot_image == NULL) { - ret = ISO_OUT_OF_MEM; - goto import_revert; - } - boot_image->bootable = data->bootable; - boot_image->type = data->type; - boot_image->partition_type = data->partition_type; - boot_image->load_seg = data->load_seg; - boot_image->load_size = data->load_size; - - catalog = calloc(1, sizeof(struct el_torito_boot_catalog)); - if (catalog == NULL) { - ret = ISO_OUT_OF_MEM; - goto import_revert; - } - catalog->image = boot_image; - image->bootcat = catalog; - } - - /* recursively add image */ - ret = iso_add_dir_src_rec(image, image->root, newroot); - - /* error during recursive image addition? */ - if (ret < 0) { - iso_node_builder_unref(image->builder); - goto import_revert; - } - - if (data->eltorito) { - /* if catalog and image nodes were not filled, we create them here */ - if (image->bootcat->image->image == NULL) { - IsoFileSource *src; - IsoNode *node; - ret = create_boot_img_filesrc(fs, &src); - if (ret < 0) { - iso_node_builder_unref(image->builder); - goto import_revert; - } - ret = image_builder_create_node(image->builder, image, src, &node); - if (ret < 0) { - iso_node_builder_unref(image->builder); - goto import_revert; - } - image->bootcat->image->image = (IsoFile*)node; - - /* warn about hidden images */ - iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0, - "Found hidden El-Torito image. Its size could not " - "be figure out, so image modify or boot image " - "patching may lead to bad results."); - } - if (image->bootcat->node == NULL) { - IsoNode *node = calloc(1, sizeof(IsoBoot)); - if (node == NULL) { - ret = ISO_OUT_OF_MEM; - goto import_revert; - } - node->type = LIBISO_BOOT; - node->mode = S_IFREG; - node->refcount = 1; - image->bootcat->node = (IsoBoot*)node; - } - } - - iso_node_builder_unref(image->builder); - - /* free old root */ - iso_node_unref((IsoNode*)oldroot); - - /* free old boot catalog */ - el_torito_boot_catalog_free(oldbootcat); - - /* set volume attributes */ - iso_image_set_volset_id(image, data->volset_id); - iso_image_set_volume_id(image, data->volume_id); - iso_image_set_publisher_id(image, data->publisher_id); - iso_image_set_data_preparer_id(image, data->data_preparer_id); - iso_image_set_system_id(image, data->system_id); - iso_image_set_application_id(image, data->application_id); - iso_image_set_copyright_file_id(image, data->copyright_file_id); - iso_image_set_abstract_file_id(image, data->abstract_file_id); - iso_image_set_biblio_file_id(image, data->biblio_file_id); - - if (features != NULL) { - *features = malloc(sizeof(IsoReadImageFeatures)); - if (*features == NULL) { - ret = ISO_OUT_OF_MEM; - goto import_cleanup; - } - (*features)->hasJoliet = data->joliet; - (*features)->hasRR = data->rr_version != 0; - (*features)->hasIso1999 = data->iso1999; - (*features)->hasElTorito = data->eltorito; - (*features)->size = data->nblocks; - } - - ret = ISO_SUCCESS; - goto import_cleanup; - - import_revert:; - - iso_node_unref((IsoNode*)image->root); - el_torito_boot_catalog_free(image->bootcat); - image->root = oldroot; - image->fs = fsback; - image->bootcat = oldbootcat; - - import_cleanup:; - - /* recover backed fs and builder */ - image->fs = fsback; - image->builder = blback; - - iso_file_source_unref(newroot); - fs->close(fs); - iso_filesystem_unref(fs); - - return ret; -} - -const char *iso_image_fs_get_volset_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->volset_id; -} - -const char *iso_image_fs_get_volume_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->volume_id; -} - -const char *iso_image_fs_get_publisher_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->publisher_id; -} - -const char *iso_image_fs_get_data_preparer_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->data_preparer_id; -} - -const char *iso_image_fs_get_system_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->system_id; -} - -const char *iso_image_fs_get_application_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->application_id; -} - -const char *iso_image_fs_get_copyright_file_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->copyright_file_id; -} - -const char *iso_image_fs_get_abstract_file_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data; - data = (_ImageFsData*) fs->data; - return data->abstract_file_id; -} - -const char *iso_image_fs_get_biblio_file_id(IsoImageFilesystem *fs) -{ - _ImageFsData *data = (_ImageFsData*) fs->data; - return data->biblio_file_id; -} - -int iso_read_opts_new(IsoReadOpts **opts, int profile) -{ - IsoReadOpts *ropts; - - if (opts == NULL) { - return ISO_NULL_POINTER; - } - if (profile != 0) { - return ISO_WRONG_ARG_VALUE; - } - - ropts = calloc(1, sizeof(IsoReadOpts)); - if (ropts == NULL) { - return ISO_OUT_OF_MEM; - } - - ropts->file_mode = 0444; - ropts->dir_mode = 0555; - *opts = ropts; - return ISO_SUCCESS; -} - -void iso_read_opts_free(IsoReadOpts *opts) -{ - if (opts == NULL) { - return; - } - - free(opts->input_charset); - free(opts); -} - -int iso_read_opts_set_start_block(IsoReadOpts *opts, uint32_t block) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->block = block; - return ISO_SUCCESS; -} - -int iso_read_opts_set_no_rockridge(IsoReadOpts *opts, int norr) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->norock = norr ? 1 :0; - return ISO_SUCCESS; -} - -int iso_read_opts_set_no_joliet(IsoReadOpts *opts, int nojoliet) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->nojoliet = nojoliet ? 1 :0; - return ISO_SUCCESS; -} - -int iso_read_opts_set_no_iso1999(IsoReadOpts *opts, int noiso1999) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->noiso1999 = noiso1999 ? 1 :0; - return ISO_SUCCESS; -} - -int iso_read_opts_set_preferjoliet(IsoReadOpts *opts, int preferjoliet) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->preferjoliet = preferjoliet ? 1 :0; - return ISO_SUCCESS; -} - -int iso_read_opts_set_default_uid(IsoReadOpts *opts, uid_t uid) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->uid = uid; - return ISO_SUCCESS; -} - -int iso_read_opts_set_default_gid(IsoReadOpts *opts, gid_t gid) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->gid = gid; - return ISO_SUCCESS; -} - -int iso_read_opts_set_default_permissions(IsoReadOpts *opts, mode_t file_perm, - mode_t dir_perm) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->file_mode = file_perm; - opts->dir_mode = dir_perm; - return ISO_SUCCESS; -} - -int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset) -{ - if (opts == NULL) { - return ISO_NULL_POINTER; - } - opts->input_charset = charset ? strdup(charset) : NULL; - return ISO_SUCCESS; -} - -/** - * Destroy an IsoReadImageFeatures object obtained with iso_image_import. - */ -void iso_read_image_features_destroy(IsoReadImageFeatures *f) -{ - if (f) { - free(f); - } -} - -/** - * Get the size (in 2048 byte block) of the image, as reported in the PVM. - */ -uint32_t iso_read_image_features_get_size(IsoReadImageFeatures *f) -{ - return f->size; -} - -/** - * Whether RockRidge extensions are present in the image imported. - */ -int iso_read_image_features_has_rockridge(IsoReadImageFeatures *f) -{ - return f->hasRR; -} - -/** - * Whether Joliet extensions are present in the image imported. - */ -int iso_read_image_features_has_joliet(IsoReadImageFeatures *f) -{ - return f->hasJoliet; -} - -/** - * Whether the image is recorded according to ISO 9660:1999, i.e. it has - * a version 2 Enhanced Volume Descriptor. - */ -int iso_read_image_features_has_iso1999(IsoReadImageFeatures *f) -{ - return f->hasIso1999; -} - -/** - * Whether El-Torito boot record is present present in the image imported. - */ -int iso_read_image_features_has_eltorito(IsoReadImageFeatures *f) -{ - return f->hasElTorito; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_local.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_local.c deleted file mode 100644 index bf37337f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fs_local.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * Filesystem/FileSource implementation to access the local filesystem. - */ - -#include "fsource.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static -int iso_file_source_new_lfs(IsoFileSource *parent, const char *name, - IsoFileSource **src); - -/* - * We can share a local filesystem object, as it has no private atts. - */ -IsoFilesystem *lfs= NULL; - -typedef struct -{ - /** reference to the parent (if root it points to itself) */ - IsoFileSource *parent; - char *name; - unsigned int openned :2; /* 0: not openned, 1: file, 2:dir */ - union - { - int fd; - DIR *dir; - } info; -} _LocalFsFileSource; - -static -char* lfs_get_path(IsoFileSource *src) -{ - _LocalFsFileSource *data; - data = src->data; - - if (data->parent == src) { - return strdup("/"); - } else { - char *path = lfs_get_path(data->parent); - int pathlen = strlen(path); - path = realloc(path, pathlen + strlen(data->name) + 2); - if (pathlen != 1) { - /* pathlen can only be 1 for root */ - path[pathlen] = '/'; - path[pathlen + 1] = '\0'; - } - return strcat(path, data->name); - } -} - -static -char* lfs_get_name(IsoFileSource *src) -{ - _LocalFsFileSource *data; - data = src->data; - return strdup(data->name); -} - -static -int lfs_lstat(IsoFileSource *src, struct stat *info) -{ - _LocalFsFileSource *data; - char *path; - - if (src == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - data = src->data; - path = lfs_get_path(src); - - if (lstat(path, info) != 0) { - int err; - - /* error, choose an appropriate return code */ - switch (errno) { - case EACCES: - err = ISO_FILE_ACCESS_DENIED; - break; - case ENOTDIR: - case ENAMETOOLONG: - case ELOOP: - err = ISO_FILE_BAD_PATH; - break; - case ENOENT: - err = ISO_FILE_DOESNT_EXIST; - break; - case EFAULT: - case ENOMEM: - err = ISO_OUT_OF_MEM; - break; - default: - err = ISO_FILE_ERROR; - break; - } - return err; - } - free(path); - return ISO_SUCCESS; -} - -static -int lfs_stat(IsoFileSource *src, struct stat *info) -{ - _LocalFsFileSource *data; - char *path; - - if (src == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - data = src->data; - path = lfs_get_path(src); - - if (stat(path, info) != 0) { - int err; - - /* error, choose an appropriate return code */ - switch (errno) { - case EACCES: - err = ISO_FILE_ACCESS_DENIED; - break; - case ENOTDIR: - case ENAMETOOLONG: - case ELOOP: - err = ISO_FILE_BAD_PATH; - break; - case ENOENT: - err = ISO_FILE_DOESNT_EXIST; - break; - case EFAULT: - case ENOMEM: - err = ISO_OUT_OF_MEM; - break; - default: - err = ISO_FILE_ERROR; - break; - } - return err; - } - free(path); - return ISO_SUCCESS; -} - -static -int lfs_access(IsoFileSource *src) -{ - int ret; - _LocalFsFileSource *data; - char *path; - - if (src == NULL) { - return ISO_NULL_POINTER; - } - data = src->data; - path = lfs_get_path(src); - - ret = iso_eaccess(path); - free(path); - return ret; -} - -static -int lfs_open(IsoFileSource *src) -{ - int err; - struct stat info; - _LocalFsFileSource *data; - char *path; - - if (src == NULL) { - return ISO_NULL_POINTER; - } - - data = src->data; - if (data->openned) { - return ISO_FILE_ALREADY_OPENED; - } - - /* is a file or a dir ? */ - err = lfs_stat(src, &info); - if (err < 0) { - return err; - } - - path = lfs_get_path(src); - if (S_ISDIR(info.st_mode)) { - data->info.dir = opendir(path); - data->openned = data->info.dir ? 2 : 0; - } else { - data->info.fd = open(path, O_RDONLY); - data->openned = data->info.fd != -1 ? 1 : 0; - } - free(path); - - /* - * check for possible errors, note that many of possible ones are - * parsed in the lstat call above - */ - if (data->openned == 0) { - switch (errno) { - case EACCES: - err = ISO_FILE_ACCESS_DENIED; - break; - case EFAULT: - case ENOMEM: - err = ISO_OUT_OF_MEM; - break; - default: - err = ISO_FILE_ERROR; - break; - } - return err; - } - - return ISO_SUCCESS; -} - -static -int lfs_close(IsoFileSource *src) -{ - int ret; - _LocalFsFileSource *data; - - if (src == NULL) { - return ISO_NULL_POINTER; - } - - data = src->data; - switch (data->openned) { - case 1: /* not dir */ - ret = close(data->info.fd) == 0 ? ISO_SUCCESS : ISO_FILE_ERROR; - break; - case 2: /* directory */ - ret = closedir(data->info.dir) == 0 ? ISO_SUCCESS : ISO_FILE_ERROR; - break; - default: - ret = ISO_FILE_NOT_OPENED; - break; - } - if (ret == ISO_SUCCESS) { - data->openned = 0; - } - return ret; -} - -static -int lfs_read(IsoFileSource *src, void *buf, size_t count) -{ - _LocalFsFileSource *data; - - if (src == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - if (count == 0) { - return ISO_WRONG_ARG_VALUE; - } - - data = src->data; - switch (data->openned) { - case 1: /* not dir */ - { - int ret; - ret = read(data->info.fd, buf, count); - if (ret < 0) { - /* error on read */ - switch (errno) { - case EINTR: - ret = ISO_INTERRUPTED; - break; - case EFAULT: - ret = ISO_OUT_OF_MEM; - break; - case EIO: - ret = ISO_FILE_READ_ERROR; - break; - default: - ret = ISO_FILE_ERROR; - break; - } - } - return ret; - } - case 2: /* directory */ - return ISO_FILE_IS_DIR; - default: - return ISO_FILE_NOT_OPENED; - } -} - -static -int lfs_readdir(IsoFileSource *src, IsoFileSource **child) -{ - _LocalFsFileSource *data; - - if (src == NULL || child == NULL) { - return ISO_NULL_POINTER; - } - - data = src->data; - switch (data->openned) { - case 1: /* not dir */ - return ISO_FILE_IS_NOT_DIR; - case 2: /* directory */ - { - struct dirent *entry; - int ret; - - /* while to skip "." and ".." dirs */ - while (1) { - entry = readdir(data->info.dir); - if (entry == NULL) { - if (errno == EBADF) - return ISO_FILE_ERROR; - else - return 0; /* EOF */ - } - if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { - break; - } - } - - /* create the new FileSrc */ - ret = iso_file_source_new_lfs(src, entry->d_name, child); - return ret; - } - default: - return ISO_FILE_NOT_OPENED; - } -} - -static -int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz) -{ - int size; - _LocalFsFileSource *data; - char *path; - - if (src == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - - if (bufsiz <= 0) { - return ISO_WRONG_ARG_VALUE; - } - - data = src->data; - path = lfs_get_path(src); - - /* - * invoke readlink, with bufsiz -1 to reserve an space for - * the NULL character - */ - size = readlink(path, buf, bufsiz - 1); - free(path); - if (size < 0) { - /* error */ - switch (errno) { - case EACCES: - return ISO_FILE_ACCESS_DENIED; - case ENOTDIR: - case ENAMETOOLONG: - case ELOOP: - return ISO_FILE_BAD_PATH; - case ENOENT: - return ISO_FILE_DOESNT_EXIST; - case EINVAL: - return ISO_FILE_IS_NOT_SYMLINK; - case EFAULT: - case ENOMEM: - return ISO_OUT_OF_MEM; - default: - return ISO_FILE_ERROR; - } - } - - /* NULL-terminate the buf */ - buf[size] = '\0'; - return ISO_SUCCESS; -} - -static -IsoFilesystem* lfs_get_filesystem(IsoFileSource *src) -{ - return src == NULL ? NULL : lfs; -} - -static -void lfs_free(IsoFileSource *src) -{ - _LocalFsFileSource *data; - - data = src->data; - - /* close the file if it is already openned */ - if (data->openned) { - src->class->close(src); - } - if (data->parent != src) { - iso_file_source_unref(data->parent); - } - free(data->name); - free(data); - iso_filesystem_unref(lfs); -} - -IsoFileSourceIface lfs_class = { - 0, /* version */ - lfs_get_path, - lfs_get_name, - lfs_lstat, - lfs_stat, - lfs_access, - lfs_open, - lfs_close, - lfs_read, - lfs_readdir, - lfs_readlink, - lfs_get_filesystem, - lfs_free -}; - -/** - * - * @return - * 1 success, < 0 error - */ -static -int iso_file_source_new_lfs(IsoFileSource *parent, const char *name, - IsoFileSource **src) -{ - IsoFileSource *lfs_src; - _LocalFsFileSource *data; - - if (src == NULL) { - return ISO_NULL_POINTER; - } - - if (lfs == NULL) { - /* this should never happen */ - return ISO_ASSERT_FAILURE; - } - - /* allocate memory */ - data = malloc(sizeof(_LocalFsFileSource)); - if (data == NULL) { - return ISO_OUT_OF_MEM; - } - lfs_src = malloc(sizeof(IsoFileSource)); - if (lfs_src == NULL) { - free(data); - return ISO_OUT_OF_MEM; - } - - /* fill struct */ - data->name = name ? strdup(name) : NULL; - data->openned = 0; - if (parent) { - data->parent = parent; - iso_file_source_ref(parent); - } else { - data->parent = lfs_src; - } - - lfs_src->refcount = 1; - lfs_src->data = data; - lfs_src->class = &lfs_class; - - /* take a ref to local filesystem */ - iso_filesystem_ref(lfs); - - /* return */ - *src = lfs_src; - return ISO_SUCCESS; -} - -static -int lfs_get_root(IsoFilesystem *fs, IsoFileSource **root) -{ - if (fs == NULL || root == NULL) { - return ISO_NULL_POINTER; - } - return iso_file_source_new_lfs(NULL, NULL, root); -} - -static -int lfs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file) -{ - int ret; - IsoFileSource *src; - struct stat info; - char *ptr, *brk_info, *component; - - if (fs == NULL || path == NULL || file == NULL) { - return ISO_NULL_POINTER; - } - - /* - * first of all check that it is a valid path. - */ - if (lstat(path, &info) != 0) { - int err; - - /* error, choose an appropriate return code */ - switch (errno) { - case EACCES: - err = ISO_FILE_ACCESS_DENIED; - break; - case ENOTDIR: - case ENAMETOOLONG: - case ELOOP: - err = ISO_FILE_BAD_PATH; - break; - case ENOENT: - err = ISO_FILE_DOESNT_EXIST; - break; - case EFAULT: - case ENOMEM: - err = ISO_OUT_OF_MEM; - break; - default: - err = ISO_FILE_ERROR; - break; - } - return err; - } - - /* ok, path is valid. create the file source */ - ret = lfs_get_root(fs, &src); - if (ret < 0) { - return ret; - } - if (!strcmp(path, "/")) { - /* we are looking for root */ - *file = src; - return ISO_SUCCESS; - } - - ptr = strdup(path); - if (ptr == NULL) { - iso_file_source_unref(src); - return ISO_OUT_OF_MEM; - } - - component = strtok_r(ptr, "/", &brk_info); - while (component) { - IsoFileSource *child = NULL; - if (!strcmp(component, ".")) { - child = src; - } else if (!strcmp(component, "..")) { - child = ((_LocalFsFileSource*)src->data)->parent; - iso_file_source_ref(child); - iso_file_source_unref(src); - } else { - ret = iso_file_source_new_lfs(src, component, &child); - iso_file_source_unref(src); - if (ret < 0) { - break; - } - } - - src = child; - component = strtok_r(NULL, "/", &brk_info); - } - - free(ptr); - if (ret > 0) { - *file = src; - } - return ret; -} - -static -unsigned int lfs_get_id(IsoFilesystem *fs) -{ - return ISO_LOCAL_FS_ID; -} - -static -int lfs_fs_open(IsoFilesystem *fs) -{ - /* open() operation is not needed */ - return ISO_SUCCESS; -} - -static -int lfs_fs_close(IsoFilesystem *fs) -{ - /* close() operation is not needed */ - return ISO_SUCCESS; -} - -static -void lfs_fs_free(IsoFilesystem *fs) -{ - lfs = NULL; -} - -int iso_local_filesystem_new(IsoFilesystem **fs) -{ - if (fs == NULL) { - return ISO_NULL_POINTER; - } - - if (lfs != NULL) { - /* just take a new ref */ - iso_filesystem_ref(lfs); - } else { - - lfs = malloc(sizeof(IsoFilesystem)); - if (lfs == NULL) { - return ISO_OUT_OF_MEM; - } - - /* fill struct */ - strncpy(lfs->type, "file", 4); - lfs->refcount = 1; - lfs->version = 0; - lfs->data = NULL; /* we don't need private data */ - lfs->get_root = lfs_get_root; - lfs->get_by_path = lfs_get_by_path; - lfs->get_id = lfs_get_id; - lfs->open = lfs_fs_open; - lfs->close = lfs_fs_close; - lfs->free = lfs_fs_free; - } - *fs = lfs; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.c deleted file mode 100644 index b6e5c5f6..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "fsource.h" -#include - -/** - * Values belong 1000 are reserved for libisofs usage - */ -unsigned int iso_fs_global_id = 1000; - -void iso_file_source_ref(IsoFileSource *src) -{ - ++src->refcount; -} - -void iso_file_source_unref(IsoFileSource *src) -{ - if (--src->refcount == 0) { - src->class->free(src); - free(src); - } -} - -void iso_filesystem_ref(IsoFilesystem *fs) -{ - ++fs->refcount; -} - -void iso_filesystem_unref(IsoFilesystem *fs) -{ - if (--fs->refcount == 0) { - fs->free(fs); - free(fs); - } -} - -/* - * this are just helpers to invoque methods in class - */ - -inline -char* iso_file_source_get_path(IsoFileSource *src) -{ - return src->class->get_path(src); -} - -inline -char* iso_file_source_get_name(IsoFileSource *src) -{ - return src->class->get_name(src); -} - -inline -int iso_file_source_lstat(IsoFileSource *src, struct stat *info) -{ - return src->class->lstat(src, info); -} - -inline -int iso_file_source_access(IsoFileSource *src) -{ - return src->class->access(src); -} - -inline -int iso_file_source_stat(IsoFileSource *src, struct stat *info) -{ - return src->class->stat(src, info); -} - -inline -int iso_file_source_open(IsoFileSource *src) -{ - return src->class->open(src); -} - -inline -int iso_file_source_close(IsoFileSource *src) -{ - return src->class->close(src); -} - -inline -int iso_file_source_read(IsoFileSource *src, void *buf, size_t count) -{ - return src->class->read(src, buf, count); -} - -inline -int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child) -{ - return src->class->readdir(src, child); -} - -inline -int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz) -{ - return src->class->readlink(src, buf, bufsiz); -} - -inline -IsoFilesystem* iso_file_source_get_filesystem(IsoFileSource *src) -{ - return src->class->get_filesystem(src); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.h deleted file mode 100644 index 1ee8b185..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/fsource.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_FSOURCE_H_ -#define LIBISO_FSOURCE_H_ - -/* - * Definitions for the file sources. Most functions/structures related with - * this were moved to libisofs.h. - */ - -#include "libisofs.h" - -#define ISO_LOCAL_FS_ID 1 -#define ISO_IMAGE_FS_ID 2 -#define ISO_ELTORITO_FS_ID 3 -#define ISO_MEM_FS_ID 4 -#define ISO_FILTER_FS_ID 5 - -/** - * Create a new IsoFilesystem to deal with local filesystem. - * - * @return - * 1 sucess, < 0 error - */ -int iso_local_filesystem_new(IsoFilesystem **fs); - -#endif /*LIBISO_FSOURCE_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.c deleted file mode 100644 index 4539ac9d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "image.h" -#include "node.h" -#include "messages.h" -#include "eltorito.h" - -#include -#include - -/** - * Create a new image, empty. - * - * The image will be owned by you and should be unref() when no more needed. - * - * @param name - * Name of the image. This will be used as volset_id and volume_id. - * @param image - * Location where the image pointer will be stored. - * @return - * 1 sucess, < 0 error - */ -int iso_image_new(const char *name, IsoImage **image) -{ - int res; - IsoImage *img; - - if (image == NULL) { - return ISO_NULL_POINTER; - } - - img = calloc(1, sizeof(IsoImage)); - if (img == NULL) { - return ISO_OUT_OF_MEM; - } - - /* local filesystem will be used by default */ - res = iso_local_filesystem_new(&(img->fs)); - if (res < 0) { - free(img); - return ISO_OUT_OF_MEM; - } - - /* use basic builder as default */ - res = iso_node_basic_builder_new(&(img->builder)); - if (res < 0) { - iso_filesystem_unref(img->fs); - free(img); - return ISO_OUT_OF_MEM; - } - - /* fill image fields */ - res = iso_node_new_root(&img->root); - if (res < 0) { - iso_node_builder_unref(img->builder); - iso_filesystem_unref(img->fs); - free(img); - return res; - } - img->refcount = 1; - img->id = iso_message_id++; - - if (name != NULL) { - img->volset_id = strdup(name); - img->volume_id = strdup(name); - } - *image = img; - return ISO_SUCCESS; -} - -/** - * Increments the reference counting of the given image. - */ -void iso_image_ref(IsoImage *image) -{ - ++image->refcount; -} - -/** - * Decrements the reference couting of the given image. - * If it reaches 0, the image is free, together with its tree nodes (whether - * their refcount reach 0 too, of course). - */ -void iso_image_unref(IsoImage *image) -{ - if (--image->refcount == 0) { - int nexcl; - - /* we need to free the image */ - if (image->user_data_free != NULL) { - /* free attached data */ - image->user_data_free(image->user_data); - } - - for (nexcl = 0; nexcl < image->nexcludes; ++nexcl) { - free(image->excludes[nexcl]); - } - free(image->excludes); - - iso_node_unref((IsoNode*)image->root); - iso_node_builder_unref(image->builder); - iso_filesystem_unref(image->fs); - el_torito_boot_catalog_free(image->bootcat); - free(image->volset_id); - free(image->volume_id); - free(image->publisher_id); - free(image->data_preparer_id); - free(image->system_id); - free(image->application_id); - free(image->copyright_file_id); - free(image->abstract_file_id); - free(image->biblio_file_id); - free(image); - } -} - -/** - * Attach user defined data to the image. Use this if your application needs - * to store addition info together with the IsoImage. If the image already - * has data attached, the old data will be freed. - * - * @param data - * Pointer to application defined data that will be attached to the - * image. You can pass NULL to remove any already attached data. - * @param give_up - * Function that will be called when the image does not need the data - * any more. It receives the data pointer as an argumente, and eventually - * causes data to be free. It can be NULL if you don't need it. - */ -int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*)) -{ - if (image == NULL || (data != NULL && free == NULL)) { - return ISO_NULL_POINTER; - } - - if (image->user_data != NULL) { - /* free previously attached data */ - if (image->user_data_free) { - image->user_data_free(image->user_data); - } - image->user_data = NULL; - image->user_data_free = NULL; - } - - if (data != NULL) { - image->user_data = data; - image->user_data_free = give_up; - } - return ISO_SUCCESS; -} - -/** - * The the data previously attached with iso_image_attach_data() - */ -void *iso_image_get_attached_data(IsoImage *image) -{ - return image->user_data; -} - -IsoDir *iso_image_get_root(const IsoImage *image) -{ - return image->root; -} - -void iso_image_set_volset_id(IsoImage *image, const char *volset_id) -{ - free(image->volset_id); - image->volset_id = strdup(volset_id); -} - -const char *iso_image_get_volset_id(const IsoImage *image) -{ - return image->volset_id; -} - -void iso_image_set_volume_id(IsoImage *image, const char *volume_id) -{ - free(image->volume_id); - image->volume_id = strdup(volume_id); -} - -const char *iso_image_get_volume_id(const IsoImage *image) -{ - return image->volume_id; -} - -void iso_image_set_publisher_id(IsoImage *image, const char *publisher_id) -{ - free(image->publisher_id); - image->publisher_id = strdup(publisher_id); -} - -const char *iso_image_get_publisher_id(const IsoImage *image) -{ - return image->publisher_id; -} - -void iso_image_set_data_preparer_id(IsoImage *image, - const char *data_preparer_id) -{ - free(image->data_preparer_id); - image->data_preparer_id = strdup(data_preparer_id); -} - -const char *iso_image_get_data_preparer_id(const IsoImage *image) -{ - return image->data_preparer_id; -} - -void iso_image_set_system_id(IsoImage *image, const char *system_id) -{ - free(image->system_id); - image->system_id = strdup(system_id); -} - -const char *iso_image_get_system_id(const IsoImage *image) -{ - return image->system_id; -} - -void iso_image_set_application_id(IsoImage *image, const char *application_id) -{ - free(image->application_id); - image->application_id = strdup(application_id); -} - -const char *iso_image_get_application_id(const IsoImage *image) -{ - return image->application_id; -} - -void iso_image_set_copyright_file_id(IsoImage *image, - const char *copyright_file_id) -{ - free(image->copyright_file_id); - image->copyright_file_id = strdup(copyright_file_id); -} - -const char *iso_image_get_copyright_file_id(const IsoImage *image) -{ - return image->copyright_file_id; -} - -void iso_image_set_abstract_file_id(IsoImage *image, - const char *abstract_file_id) -{ - free(image->abstract_file_id); - image->abstract_file_id = strdup(abstract_file_id); -} - -const char *iso_image_get_abstract_file_id(const IsoImage *image) -{ - return image->abstract_file_id; -} - -void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id) -{ - free(image->biblio_file_id); - image->biblio_file_id = strdup(biblio_file_id); -} - -const char *iso_image_get_biblio_file_id(const IsoImage *image) -{ - return image->biblio_file_id; -} - -int iso_image_get_msg_id(IsoImage *image) -{ - return image->id; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.h deleted file mode 100644 index b86aca1e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/image.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_IMAGE_H_ -#define LIBISO_IMAGE_H_ - -#include "libisofs.h" -#include "node.h" -#include "fsource.h" -#include "builder.h" - -/* - * Image is a context for image manipulation. - * Global objects such as the message_queues must belogn to that - * context. Thus we will have, for example, a msg queue per image, - * so images are completelly independent and can be managed together. - * (Usefull, for example, in Multiple-Document-Interface GUI apps. - * [The stuff we have in init belongs really to image!] - */ - -struct Iso_Image -{ - - int refcount; - - IsoDir *root; - - char *volset_id; - - char *volume_id; /**< Volume identifier. */ - char *publisher_id; /**< Volume publisher. */ - char *data_preparer_id; /**< Volume data preparer. */ - char *system_id; /**< Volume system identifier. */ - char *application_id; /**< Volume application id */ - char *copyright_file_id; - char *abstract_file_id; - char *biblio_file_id; - - /* el-torito boot catalog */ - struct el_torito_boot_catalog *bootcat; - - /* image identifier, for message origin identifier */ - int id; - - /** - * Default filesystem to use when adding files to the image tree. - */ - IsoFilesystem *fs; - - /* - * Default builder to use when adding files to the image tree. - */ - IsoNodeBuilder *builder; - - /** - * Whether to follow symlinks or just add them as symlinks - */ - unsigned int follow_symlinks : 1; - - /** - * Whether to skip hidden files - */ - unsigned int ignore_hidden : 1; - - /** - * Flags that determine what special files should be ignore. It is a - * bitmask: - * bit0: ignore FIFOs - * bit1: ignore Sockets - * bit2: ignore char devices - * bit3: ignore block devices - */ - int ignore_special; - - /** - * Files to exclude. Wildcard support is included. - */ - char** excludes; - int nexcludes; - - /** - * if the dir already contains a node with the same name, whether to - * replace or not the old node with the new. - */ - enum iso_replace_mode replace; - - /* TODO - enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node); - */ - - /** - * When this is not NULL, it is a pointer to a function that will - * be called just before a file will be added. You can control where - * the file will be in fact added or ignored. - * - * @return - * 1 add, 0 ignore, < 0 cancel - */ - int (*report)(IsoImage *image, IsoFileSource *src); - - /** - * User supplied data - */ - void *user_data; - void (*user_data_free)(void *ptr); -}; - -#endif /*LIBISO_IMAGE_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.c deleted file mode 100644 index 827d5ad6..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "iso1999.h" -#include "messages.h" -#include "writer.h" -#include "image.h" -#include "filesrc.h" -#include "eltorito.h" - -#include -#include -#include - -static -int get_iso1999_name(Ecma119Image *t, const char *str, char **fname) -{ - int ret; - char *name; - - if (fname == NULL) { - return ISO_ASSERT_FAILURE; - } - - if (str == NULL) { - /* not an error, can be root node */ - *fname = NULL; - return ISO_SUCCESS; - } - - if (!strcmp(t->input_charset, t->output_charset)) { - /* no conversion needed */ - name = strdup(str); - } else { - ret = strconv(str, t->input_charset, t->output_charset, &name); - if (ret < 0) { - ret = iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret, - "Charset conversion error. Can't convert %s from %s to %s", - str, t->input_charset, t->output_charset); - if (ret < 0) { - return ret; /* aborted */ - } - - /* use the original name, it's the best we can do */ - name = strdup(str); - } - } - - /* ISO 9660:1999 7.5.1 */ - if (strlen(name) > 207) { - name[207] = '\0'; - } - - *fname = name; - - return ISO_SUCCESS; -} - -static -void iso1999_node_free(Iso1999Node *node) -{ - if (node == NULL) { - return; - } - if (node->type == ISO1999_DIR) { - int i; - for (i = 0; i < node->info.dir->nchildren; i++) { - iso1999_node_free(node->info.dir->children[i]); - } - free(node->info.dir->children); - free(node->info.dir); - } - iso_node_unref(node->node); - free(node->name); - free(node); -} - -/** - * Create a low level ISO 9660:1999 node - * @return - * 1 success, 0 ignored, < 0 error - */ -static -int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node) -{ - int ret; - Iso1999Node *n; - - n = calloc(1, sizeof(Iso1999Node)); - if (n == NULL) { - return ISO_OUT_OF_MEM; - } - - if (iso->type == LIBISO_DIR) { - IsoDir *dir = (IsoDir*) iso; - n->info.dir = calloc(1, sizeof(struct iso1999_dir_info)); - if (n->info.dir == NULL) { - free(n); - return ISO_OUT_OF_MEM; - } - n->info.dir->children = calloc(sizeof(void*), dir->nchildren); - if (n->info.dir->children == NULL) { - free(n->info.dir); - free(n); - return ISO_OUT_OF_MEM; - } - n->type = ISO1999_DIR; - } else if (iso->type == LIBISO_FILE) { - /* it's a file */ - off_t size; - IsoFileSrc *src; - IsoFile *file = (IsoFile*) iso; - - size = iso_stream_get_size(file->stream); - if (size > (off_t)0xffffffff) { - free(n); - return iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0, - "File \"%s\" can't be added to image because is " - "greater than 4GB", iso->name); - return 0; - } - - ret = iso_file_src_create(t, file, &src); - if (ret < 0) { - free(n); - return ret; - } - n->info.file = src; - n->type = ISO1999_FILE; - } else if (iso->type == LIBISO_BOOT) { - /* it's a el-torito boot catalog, that we write as a file */ - IsoFileSrc *src; - - ret = el_torito_catalog_file_src_create(t, &src); - if (ret < 0) { - free(n); - return ret; - } - n->info.file = src; - n->type = ISO1999_FILE; - } else { - /* should never happen */ - free(n); - return ISO_ASSERT_FAILURE; - } - - /* take a ref to the IsoNode */ - n->node = iso; - iso_node_ref(iso); - - *node = n; - return ISO_SUCCESS; -} - -/** - * Create the low level ISO 9660:1999 tree from the high level ISO tree. - * - * @return - * 1 success, 0 file ignored, < 0 error - */ -static -int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen) -{ - int ret, max_path; - Iso1999Node *node = NULL; - char *iso_name = NULL; - - if (t == NULL || iso == NULL || tree == NULL) { - return ISO_NULL_POINTER; - } - - if (iso->hidden & LIBISO_HIDE_ON_1999) { - /* file will be ignored */ - return 0; - } - ret = get_iso1999_name(t, iso->name, &iso_name); - if (ret < 0) { - return ret; - } - - max_path = pathlen + 1 + (iso_name ? strlen(iso_name): 0); - if (!t->allow_longer_paths && max_path > 255) { - free(iso_name); - return iso_msg_submit(t->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added to ISO 9660:1999 tree, " - "because its path length is larger than 255", iso->name); - } - - switch (iso->type) { - case LIBISO_FILE: - ret = create_node(t, iso, &node); - break; - case LIBISO_DIR: - { - IsoNode *pos; - IsoDir *dir = (IsoDir*)iso; - ret = create_node(t, iso, &node); - if (ret < 0) { - free(iso_name); - return ret; - } - pos = dir->children; - while (pos) { - int cret; - Iso1999Node *child; - cret = create_tree(t, pos, &child, max_path); - if (cret < 0) { - /* error */ - iso1999_node_free(node); - ret = cret; - break; - } else if (cret == ISO_SUCCESS) { - /* add child to this node */ - int nchildren = node->info.dir->nchildren++; - node->info.dir->children[nchildren] = child; - child->parent = node; - } - pos = pos->next; - } - } - break; - case LIBISO_BOOT: - if (t->eltorito) { - ret = create_node(t, iso, &node); - } else { - /* log and ignore */ - ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0, - "El-Torito catalog found on a image without El-Torito.", - iso->name); - } - break; - case LIBISO_SYMLINK: - case LIBISO_SPECIAL: - ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0, - "Can't add %s to ISO 9660:1999 tree. This kind of files " - "can only be added to a Rock Ridget tree. Skipping.", - iso->name); - break; - default: - /* should never happen */ - return ISO_ASSERT_FAILURE; - } - if (ret <= 0) { - free(iso_name); - return ret; - } - node->name = iso_name; - *tree = node; - return ISO_SUCCESS; -} - -static int -cmp_node(const void *f1, const void *f2) -{ - Iso1999Node *f = *((Iso1999Node**)f1); - Iso1999Node *g = *((Iso1999Node**)f2); - - /** - * TODO #00027 Follow ISO 9660:1999 specs when sorting files - * strcmp do not does exactly what ISO 9660:1999, 9.3, as characters - * < 0x20 " " are allowed, so name len must be taken into accout - */ - return strcmp(f->name, g->name); -} - -/** - * Sort the entries inside an ISO 9660:1999 directory, according to - * ISO 9660:1999, 9.3 - */ -static -void sort_tree(Iso1999Node *root) -{ - size_t i; - - qsort(root->info.dir->children, root->info.dir->nchildren, - sizeof(void*), cmp_node); - for (i = 0; i < root->info.dir->nchildren; i++) { - Iso1999Node *child = root->info.dir->children[i]; - if (child->type == ISO1999_DIR) - sort_tree(child); - } -} - -static -int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir) -{ - int ret; - int i, nchildren; - Iso1999Node **children; - IsoHTable *table; - int need_sort = 0; - - nchildren = dir->info.dir->nchildren; - children = dir->info.dir->children; - - /* a hash table will temporary hold the names, for fast searching */ - ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash, - (compare_function_t)strcmp, &table); - if (ret < 0) { - return ret; - } - for (i = 0; i < nchildren; ++i) { - char *name = children[i]->name; - ret = iso_htable_add(table, name, name); - if (ret < 0) { - goto mangle_cleanup; - } - } - - for (i = 0; i < nchildren; ++i) { - char *name, *ext; - char full_name[208]; - int max; /* computed max len for name, without extension */ - int j = i; - int digits = 1; /* characters to change per name */ - - /* first, find all child with same name */ - while (j + 1 < nchildren && - !cmp_node(children + i, children + j + 1)) { - ++j; - } - if (j == i) { - /* name is unique */ - continue; - } - - /* - * A max of 7 characters is good enought, it allows handling up to - * 9,999,999 files with same name. - */ - while (digits < 8) { - int ok, k; - char *dot; - int change = 0; /* number to be written */ - - /* copy name to buffer */ - strcpy(full_name, children[i]->name); - - /* compute name and extension */ - dot = strrchr(full_name, '.'); - if (dot != NULL && children[i]->type != ISO1999_DIR) { - - /* - * File (not dir) with extension. - */ - int extlen; - full_name[dot - full_name] = '\0'; - name = full_name; - ext = dot + 1; - - extlen = strlen(ext); - max = 207 - extlen - 1 - digits; - if (max <= 0) { - /* this can happen if extension is too long */ - if (extlen + max > 3) { - /* - * reduce extension len, to give name an extra char - * note that max is negative or 0 - */ - extlen = extlen + max - 1; - ext[extlen] = '\0'; - max = 207 - extlen - 1 - digits; - } else { - /* - * error, we don't support extensions < 3 - * This can't happen with current limit of digits. - */ - ret = ISO_ERROR; - goto mangle_cleanup; - } - } - /* ok, reduce name by digits */ - if (name + max < dot) { - name[max] = '\0'; - } - } else { - /* Directory, or file without extension */ - if (children[i]->type == ISO1999_DIR) { - dot = NULL; /* dots have no meaning in dirs */ - } - max = 207 - digits; - name = full_name; - if (max < strlen(name)) { - name[max] = '\0'; - } - /* let ext be an empty string */ - ext = name + strlen(name); - } - - ok = 1; - /* change name of each file */ - for (k = i; k <= j; ++k) { - char tmp[208]; - char fmt[16]; - if (dot != NULL) { - sprintf(fmt, "%%s%%0%dd.%%s", digits); - } else { - sprintf(fmt, "%%s%%0%dd%%s", digits); - } - while (1) { - sprintf(tmp, fmt, name, change, ext); - ++change; - if (change > int_pow(10, digits)) { - ok = 0; - break; - } - if (!iso_htable_get(table, tmp, NULL)) { - /* the name is unique, so it can be used */ - break; - } - } - if (ok) { - char *new = strdup(tmp); - if (new == NULL) { - ret = ISO_OUT_OF_MEM; - goto mangle_cleanup; - } - iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"", - children[k]->name, new); - - iso_htable_remove_ptr(table, children[k]->name, NULL); - free(children[k]->name); - children[k]->name = new; - iso_htable_add(table, new, new); - - /* - * if we change a name we need to sort again children - * at the end - */ - need_sort = 1; - } else { - /* we need to increment digits */ - break; - } - } - if (ok) { - break; - } else { - ++digits; - } - } - if (digits == 8) { - ret = ISO_MANGLE_TOO_MUCH_FILES; - goto mangle_cleanup; - } - i = j; - } - - /* - * If needed, sort again the files inside dir - */ - if (need_sort) { - qsort(children, nchildren, sizeof(void*), cmp_node); - } - - ret = ISO_SUCCESS; - -mangle_cleanup : ; - iso_htable_destroy(table, NULL); - return ret; -} - -static -int mangle_tree(Ecma119Image *t, Iso1999Node *dir) -{ - int ret; - size_t i; - - ret = mangle_single_dir(t, dir); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < dir->info.dir->nchildren; ++i) { - if (dir->info.dir->children[i]->type == ISO1999_DIR) { - ret = mangle_tree(t, dir->info.dir->children[i]); - if (ret < 0) { - /* error */ - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int iso1999_tree_create(Ecma119Image *t) -{ - int ret; - Iso1999Node *root; - - if (t == NULL) { - return ISO_NULL_POINTER; - } - - ret = create_tree(t, (IsoNode*)t->image->root, &root, 0); - if (ret <= 0) { - if (ret == 0) { - /* unexpected error, root ignored!! This can't happen */ - ret = ISO_ASSERT_FAILURE; - } - return ret; - } - - /* the ISO 9660:1999 tree is stored in Ecma119Image target */ - t->iso1999_root = root; - - iso_msg_debug(t->image->id, "Sorting the ISO 9660:1999 tree..."); - sort_tree(root); - - iso_msg_debug(t->image->id, "Mangling ISO 9660:1999 names..."); - ret = mangle_tree(t, t->iso1999_root); - if (ret < 0) { - return ret; - } - - return ISO_SUCCESS; -} - -/** - * Compute the size of a directory entry for a single node - */ -static -size_t calc_dirent_len(Ecma119Image *t, Iso1999Node *n) -{ - int ret = n->name ? strlen(n->name) + 33 : 34; - if (ret % 2) - ret++; - return ret; -} - -/** - * Computes the total size of all directory entries of a single dir, as - * stated in ISO 9660:1999, 6.8.1.3 - */ -static -size_t calc_dir_size(Ecma119Image *t, Iso1999Node *dir) -{ - size_t i, len; - - /* size of "." and ".." entries */ - len = 34 + 34; - - for (i = 0; i < dir->info.dir->nchildren; ++i) { - size_t remaining; - Iso1999Node *child = dir->info.dir->children[i]; - size_t dirent_len = calc_dirent_len(t, child); - remaining = BLOCK_SIZE - (len % BLOCK_SIZE); - if (dirent_len > remaining) { - /* child directory entry doesn't fit on block */ - len += remaining + dirent_len; - } else { - len += dirent_len; - } - } - - /* - * The size of a dir is always a multiple of block size, as we must add - * the size of the unused space after the last directory record - * (ISO 9660:1999, 6.8.1.3) - */ - len = ROUND_UP(len, BLOCK_SIZE); - - /* cache the len */ - dir->info.dir->len = len; - return len; -} - -static -void calc_dir_pos(Ecma119Image *t, Iso1999Node *dir) -{ - size_t i, len; - - t->iso1999_ndirs++; - dir->info.dir->block = t->curblock; - len = calc_dir_size(t, dir); - t->curblock += DIV_UP(len, BLOCK_SIZE); - for (i = 0; i < dir->info.dir->nchildren; i++) { - Iso1999Node *child = dir->info.dir->children[i]; - if (child->type == ISO1999_DIR) { - calc_dir_pos(t, child); - } - } -} - -/** - * Compute the length of the path table (ISO 9660:1999, 6.9), in bytes. - */ -static -uint32_t calc_path_table_size(Iso1999Node *dir) -{ - uint32_t size; - size_t i; - - /* size of path table for this entry */ - size = 8; - size += dir->name ? strlen(dir->name) : 2; - size += (size % 2); - - /* and recurse */ - for (i = 0; i < dir->info.dir->nchildren; i++) { - Iso1999Node *child = dir->info.dir->children[i]; - if (child->type == ISO1999_DIR) { - size += calc_path_table_size(child); - } - } - return size; -} - -static -int iso1999_writer_compute_data_blocks(IsoImageWriter *writer) -{ - Ecma119Image *t; - uint32_t path_table_size; - - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - t = writer->target; - - /* compute position of directories */ - iso_msg_debug(t->image->id, - "Computing position of ISO 9660:1999 dir structure"); - t->iso1999_ndirs = 0; - calc_dir_pos(t, t->iso1999_root); - - /* compute length of pathlist */ - iso_msg_debug(t->image->id, "Computing length of ISO 9660:1999 pathlist"); - path_table_size = calc_path_table_size(t->iso1999_root); - - /* compute location for path tables */ - t->iso1999_l_path_table_pos = t->curblock; - t->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - t->iso1999_m_path_table_pos = t->curblock; - t->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - t->iso1999_path_table_size = path_table_size; - - return ISO_SUCCESS; -} - -/** - * Write a single directory record (ISO 9660:1999, 9.1). - * - * @param file_id - * if >= 0, we use it instead of the filename (for "." and ".." entries). - * @param len_fi - * Computed length of the file identifier. - */ -static -void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id, - uint8_t *buf, size_t len_fi) -{ - uint32_t len; - uint32_t block; - uint8_t len_dr; /*< size of dir entry */ - uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id - : (uint8_t*)node->name; - - struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf; - - len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1); - - memcpy(rec->file_id, name, len_fi); - - if (node->type == ISO1999_DIR) { - /* use the cached length */ - len = node->info.dir->len; - block = node->info.dir->block; - } else if (node->type == ISO1999_FILE) { - len = iso_file_src_get_size(node->info.file); - block = node->info.file->block; - } else { - /* - * for nodes other than files and dirs, we set both - * len and block to 0 - */ - len = 0; - block = 0; - } - - /* - * For ".." entry we need to write the parent info! - */ - if (file_id == 1 && node->parent) - node = node->parent; - - rec->len_dr[0] = len_dr; - iso_bb(rec->block, block, 4); - iso_bb(rec->length, len, 4); - iso_datetime_7(rec->recording_time, t->now, t->always_gmt); - rec->flags[0] = (node->type == ISO1999_DIR) ? 2 : 0; - iso_bb(rec->vol_seq_number, 1, 2); - rec->len_fi[0] = len_fi; -} - -/** - * Write the enhanced volume descriptor (ISO/IEC 9660:1999, 8.5) - */ -static -int iso1999_writer_write_vol_desc(IsoImageWriter *writer) -{ - IsoImage *image; - Ecma119Image *t; - - /* The enhanced volume descriptor is like the sup vol desc */ - struct ecma119_sup_vol_desc vol; - - char *vol_id = NULL, *pub_id = NULL, *data_id = NULL; - char *volset_id = NULL, *system_id = NULL, *application_id = NULL; - char *copyright_file_id = NULL, *abstract_file_id = NULL; - char *biblio_file_id = NULL; - - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - t = writer->target; - image = t->image; - - iso_msg_debug(image->id, "Write Enhanced Vol Desc (ISO 9660:1999)"); - - memset(&vol, 0, sizeof(struct ecma119_sup_vol_desc)); - - get_iso1999_name(t, image->volume_id, &vol_id); - str2a_char(t->input_charset, image->publisher_id, &pub_id); - str2a_char(t->input_charset, image->data_preparer_id, &data_id); - get_iso1999_name(t, image->volset_id, &volset_id); - - str2a_char(t->input_charset, image->system_id, &system_id); - str2a_char(t->input_charset, image->application_id, &application_id); - get_iso1999_name(t, image->copyright_file_id, ©right_file_id); - get_iso1999_name(t, image->abstract_file_id, &abstract_file_id); - get_iso1999_name(t, image->biblio_file_id, &biblio_file_id); - - vol.vol_desc_type[0] = 2; - memcpy(vol.std_identifier, "CD001", 5); - - /* descriptor version is 2 (ISO/IEC 9660:1999, 8.5.2) */ - vol.vol_desc_version[0] = 2; - strncpy_pad((char*)vol.volume_id, vol_id, 32); - - iso_bb(vol.vol_space_size, t->vol_space_size, 4); - iso_bb(vol.vol_set_size, 1, 2); - iso_bb(vol.vol_seq_number, 1, 2); - iso_bb(vol.block_size, BLOCK_SIZE, 2); - iso_bb(vol.path_table_size, t->iso1999_path_table_size, 4); - iso_lsb(vol.l_path_table_pos, t->iso1999_l_path_table_pos, 4); - iso_msb(vol.m_path_table_pos, t->iso1999_m_path_table_pos, 4); - - write_one_dir_record(t, t->iso1999_root, 0, vol.root_dir_record, 1); - - strncpy_pad((char*)vol.vol_set_id, volset_id, 128); - strncpy_pad((char*)vol.publisher_id, pub_id, 128); - strncpy_pad((char*)vol.data_prep_id, data_id, 128); - - strncpy_pad((char*)vol.system_id, system_id, 32); - - strncpy_pad((char*)vol.application_id, application_id, 128); - strncpy_pad((char*)vol.copyright_file_id, copyright_file_id, 37); - strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37); - strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37); - - iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt); - vol.file_structure_version[0] = 1; - - free(vol_id); - free(volset_id); - free(pub_id); - free(data_id); - free(system_id); - free(application_id); - free(copyright_file_id); - free(abstract_file_id); - free(biblio_file_id); - - /* Finally write the Volume Descriptor */ - return iso_write(t, &vol, sizeof(struct ecma119_sup_vol_desc)); -} - -static -int write_one_dir(Ecma119Image *t, Iso1999Node *dir) -{ - int ret; - uint8_t buffer[BLOCK_SIZE]; - size_t i; - size_t fi_len, len; - - /* buf will point to current write position on buffer */ - uint8_t *buf = buffer; - - /* initialize buffer with 0s */ - memset(buffer, 0, BLOCK_SIZE); - - /* write the "." and ".." entries first */ - write_one_dir_record(t, dir, 0, buf, 1); - buf += 34; - write_one_dir_record(t, dir, 1, buf, 1); - buf += 34; - - for (i = 0; i < dir->info.dir->nchildren; i++) { - Iso1999Node *child = dir->info.dir->children[i]; - - /* compute len of directory entry */ - fi_len = strlen(child->name); - len = fi_len + 33 + (fi_len % 2 ? 0 : 1); - - if ( (buf + len - buffer) > BLOCK_SIZE) { - /* dir doesn't fit in current block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - if (ret < 0) { - return ret; - } - memset(buffer, 0, BLOCK_SIZE); - buf = buffer; - } - /* write the directory entry in any case */ - write_one_dir_record(t, child, -1, buf, fi_len); - buf += len; - } - - /* write the last block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - return ret; -} - -static -int write_dirs(Ecma119Image *t, Iso1999Node *root) -{ - int ret; - size_t i; - - /* write all directory entries for this dir */ - ret = write_one_dir(t, root); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < root->info.dir->nchildren; i++) { - Iso1999Node *child = root->info.dir->children[i]; - if (child->type == ISO1999_DIR) { - ret = write_dirs(t, child); - if (ret < 0) { - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type) -{ - size_t i, len; - uint8_t buf[256]; /* 256 is just a convenient size larger enought */ - struct ecma119_path_table_record *rec; - void (*write_int)(uint8_t*, uint32_t, int); - Iso1999Node *dir; - uint32_t path_table_size; - int parent = 0; - int ret= ISO_SUCCESS; - - path_table_size = 0; - write_int = l_type ? iso_lsb : iso_msb; - - for (i = 0; i < t->iso1999_ndirs; i++) { - dir = pathlist[i]; - - /* find the index of the parent in the table */ - while ((i) && pathlist[parent] != dir->parent) { - parent++; - } - - /* write the Path Table Record (ECMA-119, 9.4) */ - memset(buf, 0, 256); - rec = (struct ecma119_path_table_record*) buf; - rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->name) : 1; - rec->len_xa[0] = 0; - write_int(rec->block, dir->info.dir->block, 4); - write_int(rec->parent, parent + 1, 2); - if (dir->parent) { - memcpy(rec->dir_id, dir->name, rec->len_di[0]); - } - len = 8 + rec->len_di[0] + (rec->len_di[0] % 2); - ret = iso_write(t, buf, len); - if (ret < 0) { - /* error */ - return ret; - } - path_table_size += len; - } - - /* we need to fill the last block with zeros */ - path_table_size %= BLOCK_SIZE; - if (path_table_size) { - uint8_t zeros[BLOCK_SIZE]; - len = BLOCK_SIZE - path_table_size; - memset(zeros, 0, len); - ret = iso_write(t, zeros, len); - } - return ret; -} - -static -int write_path_tables(Ecma119Image *t) -{ - int ret; - size_t i, j, cur; - Iso1999Node **pathlist; - - iso_msg_debug(t->image->id, "Writing ISO 9660:1999 Path tables"); - - /* allocate temporal pathlist */ - pathlist = malloc(sizeof(void*) * t->iso1999_ndirs); - if (pathlist == NULL) { - return ISO_OUT_OF_MEM; - } - pathlist[0] = t->iso1999_root; - cur = 1; - - for (i = 0; i < t->iso1999_ndirs; i++) { - Iso1999Node *dir = pathlist[i]; - for (j = 0; j < dir->info.dir->nchildren; j++) { - Iso1999Node *child = dir->info.dir->children[j]; - if (child->type == ISO1999_DIR) { - pathlist[cur++] = child; - } - } - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 1); - if (ret < 0) { - goto write_path_tables_exit; - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 0); - - write_path_tables_exit: ; - free(pathlist); - return ret; -} - -static -int iso1999_writer_write_data(IsoImageWriter *writer) -{ - int ret; - Ecma119Image *t; - - if (writer == NULL) { - return ISO_NULL_POINTER; - } - t = writer->target; - - /* first of all, we write the directory structure */ - ret = write_dirs(t, t->iso1999_root); - if (ret < 0) { - return ret; - } - - /* and write the path tables */ - ret = write_path_tables(t); - - return ret; -} - -static -int iso1999_writer_free_data(IsoImageWriter *writer) -{ - /* free the ISO 9660:1999 tree */ - Ecma119Image *t = writer->target; - iso1999_node_free(t->iso1999_root); - return ISO_SUCCESS; -} - -int iso1999_writer_create(Ecma119Image *target) -{ - int ret; - IsoImageWriter *writer; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - writer->compute_data_blocks = iso1999_writer_compute_data_blocks; - writer->write_vol_desc = iso1999_writer_write_vol_desc; - writer->write_data = iso1999_writer_write_data; - writer->free_data = iso1999_writer_free_data; - writer->data = NULL; - writer->target = target; - - iso_msg_debug(target->image->id, - "Creating low level ISO 9660:1999 tree..."); - ret = iso1999_tree_create(target); - if (ret < 0) { - return ret; - } - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - - /* we need the volume descriptor */ - target->curblock++; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.h deleted file mode 100644 index 5c986e7d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/iso1999.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/** - * Structures related to ISO/IEC 9660:1999, that is version 2 of ISO-9660 - * "See doc/devel/cookbook/ISO 9660-1999" and - * ISO/IEC DIS 9660:1999(E) "Information processing. Volume and file structure - * of CD­-ROM for Information Interchange" - * for further details. - */ - -#ifndef LIBISO_ISO1999_H -#define LIBISO_ISO1999_H - -#include "libisofs.h" -#include "ecma119.h" - -enum iso1999_node_type { - ISO1999_FILE, - ISO1999_DIR -}; - -struct iso1999_dir_info { - Iso1999Node **children; - size_t nchildren; - size_t len; - size_t block; -}; - -struct iso1999_node -{ - char *name; /**< Name chosen output charset. */ - - Iso1999Node *parent; - - IsoNode *node; /*< reference to the iso node */ - - enum iso1999_node_type type; - union { - IsoFileSrc *file; - struct iso1999_dir_info *dir; - } info; -}; - -/** - * Create a IsoWriter to deal with ISO 9660:1999 estructures, and add it to - * the given target. - * - * @return - * 1 on success, < 0 on error - */ -int iso1999_writer_create(Ecma119Image *target); - -#endif /* LIBISO_ISO1999_H */ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.c deleted file mode 100644 index 0b86f031..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.c +++ /dev/null @@ -1,1081 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "joliet.h" -#include "messages.h" -#include "writer.h" -#include "image.h" -#include "filesrc.h" -#include "eltorito.h" - -#include -#include -#include - -static -int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name) -{ - int ret; - uint16_t *ucs_name; - uint16_t *jname = NULL; - - if (iso->name == NULL) { - /* it is not necessarily an error, it can be the root */ - return ISO_SUCCESS; - } - - ret = str2ucs(t->input_charset, iso->name, &ucs_name); - if (ret < 0) { - iso_msg_debug(t->image->id, "Can't convert %s", iso->name); - return ret; - } - - /* TODO #00022 : support relaxed constraints in joliet filenames */ - if (iso->type == LIBISO_DIR) { - jname = iso_j_dir_id(ucs_name); - } else { - jname = iso_j_file_id(ucs_name); - } - free(ucs_name); - if (jname != NULL) { - *name = jname; - return ISO_SUCCESS; - } else { - /* - * only possible if mem error, as check for empty names is done - * in public tree - */ - return ISO_OUT_OF_MEM; - } -} - -static -void joliet_node_free(JolietNode *node) -{ - if (node == NULL) { - return; - } - if (node->type == JOLIET_DIR) { - int i; - for (i = 0; i < node->info.dir->nchildren; i++) { - joliet_node_free(node->info.dir->children[i]); - } - free(node->info.dir->children); - free(node->info.dir); - } - iso_node_unref(node->node); - free(node->name); - free(node); -} - -/** - * Create a low level Joliet node - * @return - * 1 success, 0 ignored, < 0 error - */ -static -int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node) -{ - int ret; - JolietNode *joliet; - - joliet = calloc(1, sizeof(JolietNode)); - if (joliet == NULL) { - return ISO_OUT_OF_MEM; - } - - if (iso->type == LIBISO_DIR) { - IsoDir *dir = (IsoDir*) iso; - joliet->info.dir = calloc(1, sizeof(struct joliet_dir_info)); - if (joliet->info.dir == NULL) { - free(joliet); - return ISO_OUT_OF_MEM; - } - joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren); - if (joliet->info.dir->children == NULL) { - free(joliet->info.dir); - free(joliet); - return ISO_OUT_OF_MEM; - } - joliet->type = JOLIET_DIR; - } else if (iso->type == LIBISO_FILE) { - /* it's a file */ - off_t size; - IsoFileSrc *src; - IsoFile *file = (IsoFile*) iso; - - size = iso_stream_get_size(file->stream); - if (size > (off_t)0xffffffff) { - free(joliet); - return iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0, - "File \"%s\" can't be added to image because is " - "greater than 4GB", iso->name); - } - - ret = iso_file_src_create(t, file, &src); - if (ret < 0) { - free(joliet); - return ret; - } - joliet->info.file = src; - joliet->type = JOLIET_FILE; - } else if (iso->type == LIBISO_BOOT) { - /* it's a el-torito boot catalog, that we write as a file */ - IsoFileSrc *src; - - ret = el_torito_catalog_file_src_create(t, &src); - if (ret < 0) { - free(joliet); - return ret; - } - joliet->info.file = src; - joliet->type = JOLIET_FILE; - } else { - /* should never happen */ - free(joliet); - return ISO_ASSERT_FAILURE; - } - - /* take a ref to the IsoNode */ - joliet->node = iso; - iso_node_ref(iso); - - *node = joliet; - return ISO_SUCCESS; -} - -/** - * Create the low level Joliet tree from the high level ISO tree. - * - * @return - * 1 success, 0 file ignored, < 0 error - */ -static -int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen) -{ - int ret, max_path; - JolietNode *node = NULL; - uint16_t *jname = NULL; - - if (t == NULL || iso == NULL || tree == NULL) { - return ISO_NULL_POINTER; - } - - if (iso->hidden & LIBISO_HIDE_ON_JOLIET) { - /* file will be ignored */ - return 0; - } - ret = get_joliet_name(t, iso, &jname); - if (ret < 0) { - return ret; - } - max_path = pathlen + 1 + (jname ? ucslen(jname) * 2 : 0); - if (!t->joliet_longer_paths && max_path > 240) { - free(jname); - /* - * Wow!! Joliet is even more restrictive than plain ISO-9660, - * that allows up to 255 bytes!! - */ - return iso_msg_submit(t->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added to Joliet tree, because " - "its path length is larger than 240", iso->name); - } - - switch (iso->type) { - case LIBISO_FILE: - ret = create_node(t, iso, &node); - break; - case LIBISO_DIR: - { - IsoNode *pos; - IsoDir *dir = (IsoDir*)iso; - ret = create_node(t, iso, &node); - if (ret < 0) { - free(jname); - return ret; - } - pos = dir->children; - while (pos) { - int cret; - JolietNode *child; - cret = create_tree(t, pos, &child, max_path); - if (cret < 0) { - /* error */ - joliet_node_free(node); - ret = cret; - break; - } else if (cret == ISO_SUCCESS) { - /* add child to this node */ - int nchildren = node->info.dir->nchildren++; - node->info.dir->children[nchildren] = child; - child->parent = node; - } - pos = pos->next; - } - } - break; - case LIBISO_BOOT: - if (t->eltorito) { - ret = create_node(t, iso, &node); - } else { - /* log and ignore */ - ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0, - "El-Torito catalog found on a image without El-Torito.", - iso->name); - } - break; - case LIBISO_SYMLINK: - case LIBISO_SPECIAL: - ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0, - "Can't add %s to Joliet tree. This kind of files can only" - " be added to a Rock Ridget tree. Skipping.", iso->name); - break; - default: - /* should never happen */ - return ISO_ASSERT_FAILURE; - } - if (ret <= 0) { - free(jname); - return ret; - } - node->name = jname; - *tree = node; - return ISO_SUCCESS; -} - -static int -cmp_node(const void *f1, const void *f2) -{ - JolietNode *f = *((JolietNode**)f1); - JolietNode *g = *((JolietNode**)f2); - return ucscmp(f->name, g->name); -} - -static -void sort_tree(JolietNode *root) -{ - size_t i; - - qsort(root->info.dir->children, root->info.dir->nchildren, - sizeof(void*), cmp_node); - for (i = 0; i < root->info.dir->nchildren; i++) { - JolietNode *child = root->info.dir->children[i]; - if (child->type == JOLIET_DIR) - sort_tree(child); - } -} - -static -int cmp_node_name(const void *f1, const void *f2) -{ - JolietNode *f = *((JolietNode**)f1); - JolietNode *g = *((JolietNode**)f2); - return ucscmp(f->name, g->name); -} - -static -int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits, - int number, uint16_t *ext) -{ - int ret, pos; - uint16_t *ucsnumber; - char fmt[16]; - char *nstr = alloca(digits + 1); - - sprintf(fmt, "%%0%dd", digits); - sprintf(nstr, fmt, number); - - ret = str2ucs("ASCII", nstr, &ucsnumber); - if (ret < 0) { - return ret; - } - - /* copy name */ - pos = ucslen(src); - ucsncpy(dest, src, pos); - - /* copy number */ - ucsncpy(dest + pos, ucsnumber, digits); - pos += digits; - - if (ext[0] != (uint16_t)0) { - size_t extlen = ucslen(ext); - dest[pos++] = (uint16_t)0x2E00; /* '.' in big endian UCS */ - ucsncpy(dest + pos, ext, extlen); - pos += extlen; - } - dest[pos] = (uint16_t)0; - free(ucsnumber); - return ISO_SUCCESS; -} - -static -int mangle_single_dir(Ecma119Image *t, JolietNode *dir) -{ - int ret; - int i, nchildren; - JolietNode **children; - IsoHTable *table; - int need_sort = 0; - - nchildren = dir->info.dir->nchildren; - children = dir->info.dir->children; - - /* a hash table will temporary hold the names, for fast searching */ - ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash, - (compare_function_t)ucscmp, &table); - if (ret < 0) { - return ret; - } - for (i = 0; i < nchildren; ++i) { - uint16_t *name = children[i]->name; - ret = iso_htable_add(table, name, name); - if (ret < 0) { - goto mangle_cleanup; - } - } - - for (i = 0; i < nchildren; ++i) { - uint16_t *name, *ext; - uint16_t full_name[66]; - int max; /* computed max len for name, without extension */ - int j = i; - int digits = 1; /* characters to change per name */ - - /* first, find all child with same name */ - while (j + 1 < nchildren && - !cmp_node_name(children + i, children + j + 1)) { - ++j; - } - if (j == i) { - /* name is unique */ - continue; - } - - /* - * A max of 7 characters is good enought, it allows handling up to - * 9,999,999 files with same name. - */ - while (digits < 8) { - int ok, k; - uint16_t *dot; - int change = 0; /* number to be written */ - - /* copy name to buffer */ - ucscpy(full_name, children[i]->name); - - /* compute name and extension */ - dot = ucsrchr(full_name, '.'); - if (dot != NULL && children[i]->type != JOLIET_DIR) { - - /* - * File (not dir) with extension - */ - int extlen; - full_name[dot - full_name] = 0; - name = full_name; - ext = dot + 1; - - extlen = ucslen(ext); - max = 65 - extlen - 1 - digits; - if (max <= 0) { - /* this can happen if extension is too long */ - if (extlen + max > 3) { - /* - * reduce extension len, to give name an extra char - * note that max is negative or 0 - */ - extlen = extlen + max - 1; - ext[extlen] = 0; - max = 66 - extlen - 1 - digits; - } else { - /* - * error, we don't support extensions < 3 - * This can't happen with current limit of digits. - */ - ret = ISO_ERROR; - goto mangle_cleanup; - } - } - /* ok, reduce name by digits */ - if (name + max < dot) { - name[max] = 0; - } - } else { - /* Directory, or file without extension */ - if (children[i]->type == JOLIET_DIR) { - max = 65 - digits; - dot = NULL; /* dots have no meaning in dirs */ - } else { - max = 65 - digits; - } - name = full_name; - if (max < ucslen(name)) { - name[max] = 0; - } - /* let ext be an empty string */ - ext = name + ucslen(name); - } - - ok = 1; - /* change name of each file */ - for (k = i; k <= j; ++k) { - uint16_t tmp[66]; - while (1) { - ret = joliet_create_mangled_name(tmp, name, digits, - change, ext); - if (ret < 0) { - goto mangle_cleanup; - } - ++change; - if (change > int_pow(10, digits)) { - ok = 0; - break; - } - if (!iso_htable_get(table, tmp, NULL)) { - /* the name is unique, so it can be used */ - break; - } - } - if (ok) { - uint16_t *new = ucsdup(tmp); - if (new == NULL) { - ret = ISO_OUT_OF_MEM; - goto mangle_cleanup; - } - - iso_htable_remove_ptr(table, children[k]->name, NULL); - free(children[k]->name); - children[k]->name = new; - iso_htable_add(table, new, new); - - /* - * if we change a name we need to sort again children - * at the end - */ - need_sort = 1; - } else { - /* we need to increment digits */ - break; - } - } - if (ok) { - break; - } else { - ++digits; - } - } - if (digits == 8) { - ret = ISO_MANGLE_TOO_MUCH_FILES; - goto mangle_cleanup; - } - i = j; - } - - /* - * If needed, sort again the files inside dir - */ - if (need_sort) { - qsort(children, nchildren, sizeof(void*), cmp_node_name); - } - - ret = ISO_SUCCESS; - -mangle_cleanup : ; - iso_htable_destroy(table, NULL); - return ret; -} - -static -int mangle_tree(Ecma119Image *t, JolietNode *dir) -{ - int ret; - size_t i; - - ret = mangle_single_dir(t, dir); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < dir->info.dir->nchildren; ++i) { - if (dir->info.dir->children[i]->type == JOLIET_DIR) { - ret = mangle_tree(t, dir->info.dir->children[i]); - if (ret < 0) { - /* error */ - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int joliet_tree_create(Ecma119Image *t) -{ - int ret; - JolietNode *root; - - if (t == NULL) { - return ISO_NULL_POINTER; - } - - ret = create_tree(t, (IsoNode*)t->image->root, &root, 0); - if (ret <= 0) { - if (ret == 0) { - /* unexpected error, root ignored!! This can't happen */ - ret = ISO_ASSERT_FAILURE; - } - return ret; - } - - /* the Joliet tree is stored in Ecma119Image target */ - t->joliet_root = root; - - iso_msg_debug(t->image->id, "Sorting the Joliet tree..."); - sort_tree(root); - - iso_msg_debug(t->image->id, "Mangling Joliet names..."); - ret = mangle_tree(t, t->joliet_root); - if (ret < 0) { - return ret; - } - - return ISO_SUCCESS; -} - -/** - * Compute the size of a directory entry for a single node - */ -static -size_t calc_dirent_len(Ecma119Image *t, JolietNode *n) -{ - /* note than name len is always even, so we always need the pad byte */ - int ret = n->name ? ucslen(n->name) * 2 + 34 : 34; - if (n->type == JOLIET_FILE && !t->omit_version_numbers) { - /* take into account version numbers */ - ret += 4; - } - return ret; -} - -/** - * Computes the total size of all directory entries of a single joliet dir. - * This is like ECMA-119 6.8.1.1, but taking care that names are stored in - * UCS. - */ -static -size_t calc_dir_size(Ecma119Image *t, JolietNode *dir) -{ - size_t i, len; - - /* size of "." and ".." entries */ - len = 34 + 34; - - for (i = 0; i < dir->info.dir->nchildren; ++i) { - size_t remaining; - JolietNode *child = dir->info.dir->children[i]; - size_t dirent_len = calc_dirent_len(t, child); - remaining = BLOCK_SIZE - (len % BLOCK_SIZE); - if (dirent_len > remaining) { - /* child directory entry doesn't fit on block */ - len += remaining + dirent_len; - } else { - len += dirent_len; - } - } - - /* - * The size of a dir is always a multiple of block size, as we must add - * the size of the unused space after the last directory record - * (ECMA-119, 6.8.1.3) - */ - len = ROUND_UP(len, BLOCK_SIZE); - - /* cache the len */ - dir->info.dir->len = len; - return len; -} - -static -void calc_dir_pos(Ecma119Image *t, JolietNode *dir) -{ - size_t i, len; - - t->joliet_ndirs++; - dir->info.dir->block = t->curblock; - len = calc_dir_size(t, dir); - t->curblock += DIV_UP(len, BLOCK_SIZE); - for (i = 0; i < dir->info.dir->nchildren; i++) { - JolietNode *child = dir->info.dir->children[i]; - if (child->type == JOLIET_DIR) { - calc_dir_pos(t, child); - } - } -} - -/** - * Compute the length of the joliet path table, in bytes. - */ -static -uint32_t calc_path_table_size(JolietNode *dir) -{ - uint32_t size; - size_t i; - - /* size of path table for this entry */ - size = 8; - size += dir->name ? ucslen(dir->name) * 2 : 2; - - /* and recurse */ - for (i = 0; i < dir->info.dir->nchildren; i++) { - JolietNode *child = dir->info.dir->children[i]; - if (child->type == JOLIET_DIR) { - size += calc_path_table_size(child); - } - } - return size; -} - -static -int joliet_writer_compute_data_blocks(IsoImageWriter *writer) -{ - Ecma119Image *t; - uint32_t path_table_size; - - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - t = writer->target; - - /* compute position of directories */ - iso_msg_debug(t->image->id, "Computing position of Joliet dir structure"); - t->joliet_ndirs = 0; - calc_dir_pos(t, t->joliet_root); - - /* compute length of pathlist */ - iso_msg_debug(t->image->id, "Computing length of Joliet pathlist"); - path_table_size = calc_path_table_size(t->joliet_root); - - /* compute location for path tables */ - t->joliet_l_path_table_pos = t->curblock; - t->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - t->joliet_m_path_table_pos = t->curblock; - t->curblock += DIV_UP(path_table_size, BLOCK_SIZE); - t->joliet_path_table_size = path_table_size; - - return ISO_SUCCESS; -} - -/** - * Write a single directory record for Joliet. It is like (ECMA-119, 9.1), - * but file identifier is stored in UCS. - * - * @param file_id - * if >= 0, we use it instead of the filename (for "." and ".." entries). - * @param len_fi - * Computed length of the file identifier. Total size of the directory - * entry will be len + 34 (ECMA-119, 9.1.12), as padding is always needed - */ -static -void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id, - uint8_t *buf, size_t len_fi) -{ - uint32_t len; - uint32_t block; - uint8_t len_dr; /*< size of dir entry */ - uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id - : (uint8_t*)node->name; - - struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf; - - len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1); - - memcpy(rec->file_id, name, len_fi); - - if (node->type == JOLIET_FILE && !t->omit_version_numbers) { - len_dr += 4; - rec->file_id[len_fi++] = 0; - rec->file_id[len_fi++] = ';'; - rec->file_id[len_fi++] = 0; - rec->file_id[len_fi++] = '1'; - } - - if (node->type == JOLIET_DIR) { - /* use the cached length */ - len = node->info.dir->len; - block = node->info.dir->block; - } else if (node->type == JOLIET_FILE) { - len = iso_file_src_get_size(node->info.file); - block = node->info.file->block; - } else { - /* - * for nodes other than files and dirs, we set both - * len and block to 0 - */ - len = 0; - block = 0; - } - - /* - * For ".." entry we need to write the parent info! - */ - if (file_id == 1 && node->parent) - node = node->parent; - - rec->len_dr[0] = len_dr; - iso_bb(rec->block, block, 4); - iso_bb(rec->length, len, 4); - iso_datetime_7(rec->recording_time, t->now, t->always_gmt); - rec->flags[0] = (node->type == JOLIET_DIR) ? 2 : 0; - iso_bb(rec->vol_seq_number, 1, 2); - rec->len_fi[0] = len_fi; -} - -/** - * Copy up to \p max characters from \p src to \p dest. If \p src has less than - * \p max characters, we pad dest with " " characters. - */ -static -void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max) -{ - char *cdest, *csrc; - size_t len, i; - - cdest = (char*)dest; - csrc = (char*)src; - - if (src != NULL) { - len = MIN(ucslen(src) * 2, max); - } else { - len = 0; - } - - for (i = 0; i < len; ++i) - cdest[i] = csrc[i]; - - for (i = len; i < max; i += 2) { - cdest[i] = '\0'; - cdest[i + 1] = ' '; - } -} - -static -int joliet_writer_write_vol_desc(IsoImageWriter *writer) -{ - IsoImage *image; - Ecma119Image *t; - struct ecma119_sup_vol_desc vol; - - uint16_t *vol_id = NULL, *pub_id = NULL, *data_id = NULL; - uint16_t *volset_id = NULL, *system_id = NULL, *application_id = NULL; - uint16_t *copyright_file_id = NULL, *abstract_file_id = NULL; - uint16_t *biblio_file_id = NULL; - - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - t = writer->target; - image = t->image; - - iso_msg_debug(image->id, "Write SVD for Joliet"); - - memset(&vol, 0, sizeof(struct ecma119_sup_vol_desc)); - - str2ucs(t->input_charset, image->volume_id, &vol_id); - str2ucs(t->input_charset, image->publisher_id, &pub_id); - str2ucs(t->input_charset, image->data_preparer_id, &data_id); - str2ucs(t->input_charset, image->volset_id, &volset_id); - - str2ucs(t->input_charset, image->system_id, &system_id); - str2ucs(t->input_charset, image->application_id, &application_id); - str2ucs(t->input_charset, image->copyright_file_id, ©right_file_id); - str2ucs(t->input_charset, image->abstract_file_id, &abstract_file_id); - str2ucs(t->input_charset, image->biblio_file_id, &biblio_file_id); - - vol.vol_desc_type[0] = 2; - memcpy(vol.std_identifier, "CD001", 5); - vol.vol_desc_version[0] = 1; - ucsncpy_pad((uint16_t*)vol.volume_id, vol_id, 32); - - /* make use of UCS-2 Level 3 */ - memcpy(vol.esc_sequences, "%/E", 3); - - iso_bb(vol.vol_space_size, t->vol_space_size, 4); - iso_bb(vol.vol_set_size, 1, 2); - iso_bb(vol.vol_seq_number, 1, 2); - iso_bb(vol.block_size, BLOCK_SIZE, 2); - iso_bb(vol.path_table_size, t->joliet_path_table_size, 4); - iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4); - iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4); - - write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1); - - ucsncpy_pad((uint16_t*)vol.vol_set_id, volset_id, 128); - ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128); - ucsncpy_pad((uint16_t*)vol.data_prep_id, data_id, 128); - - ucsncpy_pad((uint16_t*)vol.system_id, system_id, 32); - - ucsncpy_pad((uint16_t*)vol.application_id, application_id, 128); - ucsncpy_pad((uint16_t*)vol.copyright_file_id, copyright_file_id, 37); - ucsncpy_pad((uint16_t*)vol.abstract_file_id, abstract_file_id, 37); - ucsncpy_pad((uint16_t*)vol.bibliographic_file_id, biblio_file_id, 37); - - iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt); - iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt); - vol.file_structure_version[0] = 1; - - free(vol_id); - free(volset_id); - free(pub_id); - free(data_id); - free(system_id); - free(application_id); - free(copyright_file_id); - free(abstract_file_id); - free(biblio_file_id); - - /* Finally write the Volume Descriptor */ - return iso_write(t, &vol, sizeof(struct ecma119_sup_vol_desc)); -} - -static -int write_one_dir(Ecma119Image *t, JolietNode *dir) -{ - int ret; - uint8_t buffer[BLOCK_SIZE]; - size_t i; - size_t fi_len, len; - - /* buf will point to current write position on buffer */ - uint8_t *buf = buffer; - - /* initialize buffer with 0s */ - memset(buffer, 0, BLOCK_SIZE); - - /* write the "." and ".." entries first */ - write_one_dir_record(t, dir, 0, buf, 1); - buf += 34; - write_one_dir_record(t, dir, 1, buf, 1); - buf += 34; - - for (i = 0; i < dir->info.dir->nchildren; i++) { - JolietNode *child = dir->info.dir->children[i]; - - /* compute len of directory entry */ - fi_len = ucslen(child->name) * 2; - len = fi_len + 34; - if (child->type == JOLIET_FILE && !t->omit_version_numbers) { - len += 4; - } - - if ( (buf + len - buffer) > BLOCK_SIZE) { - /* dir doesn't fit in current block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - if (ret < 0) { - return ret; - } - memset(buffer, 0, BLOCK_SIZE); - buf = buffer; - } - /* write the directory entry in any case */ - write_one_dir_record(t, child, -1, buf, fi_len); - buf += len; - } - - /* write the last block */ - ret = iso_write(t, buffer, BLOCK_SIZE); - return ret; -} - -static -int write_dirs(Ecma119Image *t, JolietNode *root) -{ - int ret; - size_t i; - - /* write all directory entries for this dir */ - ret = write_one_dir(t, root); - if (ret < 0) { - return ret; - } - - /* recurse */ - for (i = 0; i < root->info.dir->nchildren; i++) { - JolietNode *child = root->info.dir->children[i]; - if (child->type == JOLIET_DIR) { - ret = write_dirs(t, child); - if (ret < 0) { - return ret; - } - } - } - return ISO_SUCCESS; -} - -static -int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type) -{ - size_t i, len; - uint8_t buf[256]; /* 256 is just a convenient size larger enought */ - struct ecma119_path_table_record *rec; - void (*write_int)(uint8_t*, uint32_t, int); - JolietNode *dir; - uint32_t path_table_size; - int parent = 0; - int ret= ISO_SUCCESS; - - path_table_size = 0; - write_int = l_type ? iso_lsb : iso_msb; - - for (i = 0; i < t->joliet_ndirs; i++) { - dir = pathlist[i]; - - /* find the index of the parent in the table */ - while ((i) && pathlist[parent] != dir->parent) { - parent++; - } - - /* write the Path Table Record (ECMA-119, 9.4) */ - memset(buf, 0, 256); - rec = (struct ecma119_path_table_record*) buf; - rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1; - rec->len_xa[0] = 0; - write_int(rec->block, dir->info.dir->block, 4); - write_int(rec->parent, parent + 1, 2); - if (dir->parent) { - memcpy(rec->dir_id, dir->name, rec->len_di[0]); - } - len = 8 + rec->len_di[0] + (rec->len_di[0] % 2); - ret = iso_write(t, buf, len); - if (ret < 0) { - /* error */ - return ret; - } - path_table_size += len; - } - - /* we need to fill the last block with zeros */ - path_table_size %= BLOCK_SIZE; - if (path_table_size) { - uint8_t zeros[BLOCK_SIZE]; - len = BLOCK_SIZE - path_table_size; - memset(zeros, 0, len); - ret = iso_write(t, zeros, len); - } - return ret; -} - -static -int write_path_tables(Ecma119Image *t) -{ - int ret; - size_t i, j, cur; - JolietNode **pathlist; - - iso_msg_debug(t->image->id, "Writing Joliet Path tables"); - - /* allocate temporal pathlist */ - pathlist = malloc(sizeof(void*) * t->joliet_ndirs); - if (pathlist == NULL) { - return ISO_OUT_OF_MEM; - } - pathlist[0] = t->joliet_root; - cur = 1; - - for (i = 0; i < t->joliet_ndirs; i++) { - JolietNode *dir = pathlist[i]; - for (j = 0; j < dir->info.dir->nchildren; j++) { - JolietNode *child = dir->info.dir->children[j]; - if (child->type == JOLIET_DIR) { - pathlist[cur++] = child; - } - } - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 1); - if (ret < 0) { - goto write_path_tables_exit; - } - - /* Write L Path Table */ - ret = write_path_table(t, pathlist, 0); - - write_path_tables_exit: ; - free(pathlist); - return ret; -} - -static -int joliet_writer_write_data(IsoImageWriter *writer) -{ - int ret; - Ecma119Image *t; - - if (writer == NULL) { - return ISO_NULL_POINTER; - } - t = writer->target; - - /* first of all, we write the directory structure */ - ret = write_dirs(t, t->joliet_root); - if (ret < 0) { - return ret; - } - - /* and write the path tables */ - ret = write_path_tables(t); - - return ret; -} - -static -int joliet_writer_free_data(IsoImageWriter *writer) -{ - /* free the Joliet tree */ - Ecma119Image *t = writer->target; - joliet_node_free(t->joliet_root); - return ISO_SUCCESS; -} - -int joliet_writer_create(Ecma119Image *target) -{ - int ret; - IsoImageWriter *writer; - - writer = malloc(sizeof(IsoImageWriter)); - if (writer == NULL) { - return ISO_OUT_OF_MEM; - } - - writer->compute_data_blocks = joliet_writer_compute_data_blocks; - writer->write_vol_desc = joliet_writer_write_vol_desc; - writer->write_data = joliet_writer_write_data; - writer->free_data = joliet_writer_free_data; - writer->data = NULL; - writer->target = target; - - iso_msg_debug(target->image->id, "Creating low level Joliet tree..."); - ret = joliet_tree_create(target); - if (ret < 0) { - return ret; - } - - /* add this writer to image */ - target->writers[target->nwriters++] = writer; - - /* we need the volume descriptor */ - target->curblock++; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.h deleted file mode 100644 index a2db1890..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/joliet.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/** - * Declare Joliet related structures. - */ - -#ifndef LIBISO_JOLIET_H -#define LIBISO_JOLIET_H - -#include "libisofs.h" -#include "ecma119.h" - -enum joliet_node_type { - JOLIET_FILE, - JOLIET_DIR -}; - -struct joliet_dir_info { - JolietNode **children; - size_t nchildren; - size_t len; - size_t block; -}; - -struct joliet_node -{ - uint16_t *name; /**< Name in UCS-2BE. */ - - JolietNode *parent; - - IsoNode *node; /*< reference to the iso node */ - - enum joliet_node_type type; - union { - IsoFileSrc *file; - struct joliet_dir_info *dir; - } info; -}; - -/** - * Create a IsoWriter to deal with Joliet estructures, and add it to the given - * target. - * - * @return - * 1 on success, < 0 on error - */ -int joliet_writer_create(Ecma119Image *target); - -#endif /* LIBISO_JOLIET_H */ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.c deleted file mode 100644 index 6a60429d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.c +++ /dev/null @@ -1,439 +0,0 @@ - -/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008) - Message handling facility of libisofs. - Copyright (C) 2006 - 2008 Thomas Schmitt , - provided under GPL version 2 -*/ - -#include -#include -#include -#include -#include -#include -#include - -/* Only this single source module is entitled to do this */ -#define LIBISO_MSGS_H_INTERNAL 1 - -/* All participants in the messaging system must do this */ -#include "libiso_msgs.h" - - -/* ----------------------------- libiso_msgs_item ------------------------- */ - - -static int libiso_msgs_item_new(struct libiso_msgs_item **item, - struct libiso_msgs_item *link, int flag) -{ - int ret; - struct libiso_msgs_item *o; - struct timeval tv; - struct timezone tz; - - (*item)= o= - (struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item)); - if(o==NULL) - return(-1); - o->timestamp= 0.0; - ret= gettimeofday(&tv,&tz); - if(ret==0) - o->timestamp= tv.tv_sec+0.000001*tv.tv_usec; - o->process_id= getpid(); - o->origin= -1; - o->severity= LIBISO_MSGS_SEV_ALL; - o->priority= LIBISO_MSGS_PRIO_ZERO; - o->error_code= 0; - o->msg_text= NULL; - o->os_errno= 0; - o->prev= link; - o->next= NULL; - if(link!=NULL) { - if(link->next!=NULL) { - link->next->prev= o; - o->next= link->next; - } - link->next= o; - } - return(1); -} - - -/** Detaches item from its queue and eventually readjusts start, end pointers - of the queue */ -int libiso_msgs_item_unlink(struct libiso_msgs_item *o, - struct libiso_msgs_item **chain_start, - struct libiso_msgs_item **chain_end, int flag) -{ - if(o->prev!=NULL) - o->prev->next= o->next; - if(o->next!=NULL) - o->next->prev= o->prev; - if(chain_start!=NULL) - if(*chain_start == o) - *chain_start= o->next; - if(chain_end!=NULL) - if(*chain_end == o) - *chain_end= o->prev; - o->next= o->prev= NULL; - return(1); -} - - -int libiso_msgs_item_destroy(struct libiso_msgs_item **item, - int flag) -{ - struct libiso_msgs_item *o; - - o= *item; - if(o==NULL) - return(0); - libiso_msgs_item_unlink(o,NULL,NULL,0); - if(o->msg_text!=NULL) - free((char *) o->msg_text); - free((char *) o); - *item= NULL; - return(1); -} - - -int libiso_msgs_item_get_msg(struct libiso_msgs_item *item, - int *error_code, char **msg_text, int *os_errno, - int flag) -{ - *error_code= item->error_code; - *msg_text= item->msg_text; - *os_errno= item->os_errno; - return(1); -} - - -int libiso_msgs_item_get_origin(struct libiso_msgs_item *item, - double *timestamp, pid_t *process_id, int *origin, - int flag) -{ - *timestamp= item->timestamp; - *process_id= item->process_id; - *origin= item->origin; - return(1); -} - - -int libiso_msgs_item_get_rank(struct libiso_msgs_item *item, - int *severity, int *priority, int flag) -{ - *severity= item->severity; - *priority= item->priority; - return(1); -} - - -/* ------------------------------- libiso_msgs ---------------------------- */ - - -int libiso_msgs_new(struct libiso_msgs **m, int flag) -{ - struct libiso_msgs *o; - - (*m)= o= (struct libiso_msgs *) malloc(sizeof(struct libiso_msgs)); - if(o==NULL) - return(-1); - o->refcount= 1; - o->oldest= NULL; - o->youngest= NULL; - o->count= 0; - o->queue_severity= LIBISO_MSGS_SEV_ALL; - o->print_severity= LIBISO_MSGS_SEV_NEVER; - strcpy(o->print_id,"libiso: "); - -#ifndef LIBISO_MSGS_SINGLE_THREADED - pthread_mutex_init(&(o->lock_mutex),NULL); -#endif - - return(1); -} - - -static int libiso_msgs_lock(struct libiso_msgs *m, int flag) -{ - -#ifndef LIBISO_MSGS_SINGLE_THREADED - int ret; - - ret= pthread_mutex_lock(&(m->lock_mutex)); - if(ret!=0) - return(0); -#endif - - return(1); -} - - -static int libiso_msgs_unlock(struct libiso_msgs *m, int flag) -{ - -#ifndef LIBISO_MSGS_SINGLE_THREADED - int ret; - - ret= pthread_mutex_unlock(&(m->lock_mutex)); - if(ret!=0) - return(0); -#endif - - return(1); -} - - -int libiso_msgs_destroy(struct libiso_msgs **m, int flag) -{ - struct libiso_msgs *o; - struct libiso_msgs_item *item, *next_item; - - o= *m; - if(o==NULL) - return(0); - if(o->refcount > 1) { - if(libiso_msgs_lock(*m,0)<=0) - return(-1); - o->refcount--; - libiso_msgs_unlock(*m,0); - *m= NULL; - return(1); - } - -#ifndef LIBISO_MSGS_SINGLE_THREADED - if(pthread_mutex_destroy(&(o->lock_mutex))!=0) { - pthread_mutex_unlock(&(o->lock_mutex)); - pthread_mutex_destroy(&(o->lock_mutex)); - } -#endif - - for(item= o->oldest; item!=NULL; item= next_item) { - next_item= item->next; - libiso_msgs_item_destroy(&item,0); - } - free((char *) o); - *m= NULL; - return(1); -} - - -int libiso_msgs_refer(struct libiso_msgs **pt, struct libiso_msgs *m, int flag) -{ - if(libiso_msgs_lock(m,0)<=0) - return(0); - m->refcount++; - *pt= m; - libiso_msgs_unlock(m,0); - return(1); -} - - -int libiso_msgs_set_severities(struct libiso_msgs *m, int queue_severity, - int print_severity, char *print_id, int flag) -{ - if(libiso_msgs_lock(m,0)<=0) - return(0); - m->queue_severity= queue_severity; - m->print_severity= print_severity; - strncpy(m->print_id,print_id,80); - m->print_id[80]= 0; - libiso_msgs_unlock(m,0); - return(1); -} - - -int libiso_msgs__text_to_sev(char *severity_name, int *severity, - int flag) -{ - if(strncmp(severity_name,"NEVER",5)==0) - *severity= LIBISO_MSGS_SEV_NEVER; - else if(strncmp(severity_name,"ABORT",5)==0) - *severity= LIBISO_MSGS_SEV_ABORT; - else if(strncmp(severity_name,"FATAL",5)==0) - *severity= LIBISO_MSGS_SEV_FATAL; - else if(strncmp(severity_name,"FAILURE",7)==0) - *severity= LIBISO_MSGS_SEV_FAILURE; - else if(strncmp(severity_name,"MISHAP",6)==0) - *severity= LIBISO_MSGS_SEV_MISHAP; - else if(strncmp(severity_name,"SORRY",5)==0) - *severity= LIBISO_MSGS_SEV_SORRY; - else if(strncmp(severity_name,"WARNING",7)==0) - *severity= LIBISO_MSGS_SEV_WARNING; - else if(strncmp(severity_name,"HINT",4)==0) - *severity= LIBISO_MSGS_SEV_HINT; - else if(strncmp(severity_name,"NOTE",4)==0) - *severity= LIBISO_MSGS_SEV_NOTE; - else if(strncmp(severity_name,"UPDATE",6)==0) - *severity= LIBISO_MSGS_SEV_UPDATE; - else if(strncmp(severity_name,"DEBUG",5)==0) - *severity= LIBISO_MSGS_SEV_DEBUG; - else if(strncmp(severity_name,"ERRFILE",7)==0) - *severity= LIBISO_MSGS_SEV_ERRFILE; - else if(strncmp(severity_name,"ALL",3)==0) - *severity= LIBISO_MSGS_SEV_ALL; - else { - *severity= LIBISO_MSGS_SEV_ALL; - return(0); - } - return(1); -} - - -int libiso_msgs__sev_to_text(int severity, char **severity_name, - int flag) -{ - if(flag&1) { - *severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL"; - return(1); - } - *severity_name= ""; - if(severity>=LIBISO_MSGS_SEV_NEVER) - *severity_name= "NEVER"; - else if(severity>=LIBISO_MSGS_SEV_ABORT) - *severity_name= "ABORT"; - else if(severity>=LIBISO_MSGS_SEV_FATAL) - *severity_name= "FATAL"; - else if(severity>=LIBISO_MSGS_SEV_FAILURE) - *severity_name= "FAILURE"; - else if(severity>=LIBISO_MSGS_SEV_MISHAP) - *severity_name= "MISHAP"; - else if(severity>=LIBISO_MSGS_SEV_SORRY) - *severity_name= "SORRY"; - else if(severity>=LIBISO_MSGS_SEV_WARNING) - *severity_name= "WARNING"; - else if(severity>=LIBISO_MSGS_SEV_HINT) - *severity_name= "HINT"; - else if(severity>=LIBISO_MSGS_SEV_NOTE) - *severity_name= "NOTE"; - else if(severity>=LIBISO_MSGS_SEV_UPDATE) - *severity_name= "UPDATE"; - else if(severity>=LIBISO_MSGS_SEV_DEBUG) - *severity_name= "DEBUG"; - else if(severity>=LIBISO_MSGS_SEV_ERRFILE) - *severity_name= "ERRFILE"; - else if(severity>=LIBISO_MSGS_SEV_ALL) - *severity_name= "ALL"; - else { - *severity_name= ""; - return(0); - } - return(1); -} - - -int libiso_msgs_submit(struct libiso_msgs *m, int origin, int error_code, - int severity, int priority, char *msg_text, - int os_errno, int flag) -{ - int ret; - char *textpt,*sev_name,sev_text[81]; - struct libiso_msgs_item *item= NULL; - - if(severity >= m->print_severity) { - if(msg_text==NULL) - textpt= ""; - else - textpt= msg_text; - sev_text[0]= 0; - ret= libiso_msgs__sev_to_text(severity,&sev_name,0); - if(ret>0) - sprintf(sev_text,"%s : ",sev_name); - - fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt); - if(os_errno!=0) { - ret= libiso_msgs_lock(m,0); - if(ret<=0) - return(-1); - fprintf(stderr,"%s( Most recent system error: %d '%s' )\n", - m->print_id,os_errno,strerror(os_errno)); - libiso_msgs_unlock(m,0); - } - - } - if(severity < m->queue_severity) - return(0); - - ret= libiso_msgs_lock(m,0); - if(ret<=0) - return(-1); - ret= libiso_msgs_item_new(&item,m->youngest,0); - if(ret<=0) - goto failed; - item->origin= origin; - item->error_code= error_code; - item->severity= severity; - item->priority= priority; - if(msg_text!=NULL) { - item->msg_text= malloc(strlen(msg_text)+1); - if(item->msg_text==NULL) - goto failed; - strcpy(item->msg_text,msg_text); - } - item->os_errno= os_errno; - if(m->oldest==NULL) - m->oldest= item; - m->youngest= item; - m->count++; - libiso_msgs_unlock(m,0); - -/* -fprintf(stderr,"libiso_experimental: message submitted to queue (now %d)\n", - m->count); -*/ - - return(1); -failed:; - libiso_msgs_item_destroy(&item,0); - libiso_msgs_unlock(m,0); - return(-1); -} - - -int libiso_msgs_obtain(struct libiso_msgs *m, struct libiso_msgs_item **item, - int severity, int priority, int flag) -{ - int ret; - struct libiso_msgs_item *im, *next_im= NULL; - - *item= NULL; - ret= libiso_msgs_lock(m,0); - if(ret<=0) - return(-1); - for(im= m->oldest; im!=NULL; im= next_im) { - for(; im!=NULL; im= next_im) { - next_im= im->next; - if(im->severity>=severity) - break; - libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); - libiso_msgs_item_destroy(&im,0); /* severity too low: delete */ - } - if(im==NULL) - break; - if(im->priority>=priority) - break; - } - if(im==NULL) - {ret= 0; goto ex;} - libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); - *item= im; - ret= 1; -ex:; - libiso_msgs_unlock(m,0); - return(ret); -} - - -int libiso_msgs_destroy_item(struct libiso_msgs *m, - struct libiso_msgs_item **item, int flag) -{ - int ret; - - ret= libiso_msgs_lock(m,0); - if(ret<=0) - return(-1); - ret= libiso_msgs_item_destroy(item,0); - libiso_msgs_unlock(m,0); - return(ret); -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.h deleted file mode 100644 index 17e8f9e5..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libiso_msgs.h +++ /dev/null @@ -1,682 +0,0 @@ - -/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008) - Message handling facility of libisofs. - Copyright (C) 2006-2008 Thomas Schmitt , - provided under GPL version 2 -*/ - - -/* - *Never* set this macro outside libiso_msgs.c ! - The entrails of the message handling facility are not to be seen by - the other library components or the applications. -*/ -#ifdef LIBISO_MSGS_H_INTERNAL - - -#ifndef LIBISO_MSGS_SINGLE_THREADED -#include -#endif - - -struct libiso_msgs_item { - - double timestamp; - pid_t process_id; - int origin; - - int severity; - int priority; - - /* Apply for your developer's error code range at - libburn-hackers@pykix.org - Report introduced codes in the list below. */ - int error_code; - - char *msg_text; - int os_errno; - - struct libiso_msgs_item *prev,*next; - -}; - - -struct libiso_msgs { - - int refcount; - - struct libiso_msgs_item *oldest; - struct libiso_msgs_item *youngest; - int count; - - int queue_severity; - int print_severity; - char print_id[81]; - -#ifndef LIBISO_MSGS_SINGLE_THREADED - pthread_mutex_t lock_mutex; -#endif - - -}; - -#endif /* LIBISO_MSGS_H_INTERNAL */ - - -#ifndef LIBISO_MSGS_H_INCLUDED -#define LIBISO_MSGS_H_INCLUDED 1 - - -#ifndef LIBISO_MSGS_H_INTERNAL - - - /* Architectural aspects */ -/* - libdax_msgs is designed to serve in libraries which want to offer their - applications a way to control the output of library messages. It shall be - incorporated by an owner, i.e. a software entity which encloses the code - of the .c file. - - Owner of libdax_msgs is libburn. A fully compatible variant named libiso_msgs - is owned by libisofs and can get generated by a script of the libburn - project: libburn/libiso_msgs_to_xyz_msgs.sh . - - Reason: One cannot link two owners of the same variant together because - both would offer the same functions to the linker. For that situation one - has to create a compatible variant as it is done for libisofs. - - Compatible variants may get plugged together by call combinations like - burn_set_messenger(iso_get_messenger()); - A new variant would demand a _set_messenger() function if it has to work - with libisofs. If only libburn is planned as link partner then a simple - _get_messenger() does suffice. - Take care to shutdown libburn before its provider of the *_msgs object - gets shut down. - -*/ - - /* Public Opaque Handles */ - -/** A pointer to this is a opaque handle to a message handling facility */ -struct libiso_msgs; - -/** A pointer to this is a opaque handle to a single message item */ -struct libiso_msgs_item; - -#endif /* ! LIBISO_MSGS_H_INTERNAL */ - - - /* Public Macros */ - - -/* Registered Severities */ - -/* It is well advisable to let applications select severities via strings and - forwarded functions libiso_msgs__text_to_sev(), libiso_msgs__sev_to_text(). - These macros are for use by the owner of libiso_msgs. -*/ - -/** Use this to get messages of any severity. Do not use for submitting. -*/ -#define LIBISO_MSGS_SEV_ALL 0x00000000 - - -/** Messages of this severity shall transport plain disk file paths - whenever an event of severity SORRY or above is related with an - individual disk file. - No message text shall be added to the file path. The ERRFILE message - shall be issued before the human readable message which carries the - true event severity. That message should contain the file path so it - can be found by strstr(message, path)!=NULL. - The error code shall be the same as with the human readable message. -*/ -#define LIBISO_MSGS_SEV_ERRFILE 0x08000000 - - -/** Debugging messages not to be visible to normal users by default -*/ -#define LIBISO_MSGS_SEV_DEBUG 0x10000000 - -/** Update of a progress report about long running actions -*/ -#define LIBISO_MSGS_SEV_UPDATE 0x20000000 - -/** Not so usual events which were gracefully handled -*/ -#define LIBISO_MSGS_SEV_NOTE 0x30000000 - -/** Possibilities to achieve a better result -*/ -#define LIBISO_MSGS_SEV_HINT 0x40000000 - -/** Warnings about problems which could not be handled optimally -*/ -#define LIBISO_MSGS_SEV_WARNING 0x50000000 - - -/** Non-fatal error messages indicating that parts of an action failed but - processing may go on if one accepts deviations from the desired result. - - SORRY may also be the severity for incidents which are severe enough - for FAILURE but happen within already started irrevocable actions, - like ISO image generation. A precondition for such a severity ease is - that the action can be continued after the incident. - See below MISHAP for what xorriso would need instead of this kind of SORRY - and generates for itself in case of libisofs image generation. - - E.g.: A pattern yields no result. - A speed setting cannot be made. - A libisofs input file is inaccessible during image generation. - - After SORRY a function should try to go on if that makes any sense - and if no threshold prescribes abort on SORRY. The function should - nevertheless indicate some failure in its return value. - It should - but it does not have to. -*/ -#define LIBISO_MSGS_SEV_SORRY 0x60000000 - - -/** A FAILURE (see below) which can be tolerated during long lasting - operations just because they cannot simply be stopped or revoked. - - xorriso converts libisofs SORRY messages issued during image generation - into MISHAP messages in order to allow its evaluators to distinguish - image generation problems from minor image composition problems. - E.g.: - A libisofs input file is inaccessible during image generation. - - After a MISHAP a function should behave like after SORRY. -*/ -#define LIBISO_MSGS_SEV_MISHAP 0x64000000 - - -/** Non-fatal error indicating that an important part of an action failed and - that only a new setup of preconditions will give hope for sufficient - success. - - E.g.: No media is inserted in the output drive. - No write mode can be found for inserted media. - A libisofs input file is inaccessible during grafting. - - After FAILURE a function should end with a return value indicating failure. - It is at the discretion of the function whether it ends immediately in any - case or whether it tries to go on if the eventual threshold allows. -*/ -#define LIBISO_MSGS_SEV_FAILURE 0x68000000 - - -/** An error message which puts the whole operation of the program in question - - E.g.: Not enough memory for essential temporary objects. - Irregular errors from resources. - Programming errors (soft assert). - - After FATAL a function should end very soon with a return value - indicating severe failure. -*/ -#define LIBISO_MSGS_SEV_FATAL 0x70000000 - - -/** A message from an abort handler which will finally finish libburn -*/ -#define LIBISO_MSGS_SEV_ABORT 0x71000000 - -/** A severity to exclude resp. discard any possible message. - Do not use this severity for submitting. -*/ -#define LIBISO_MSGS_SEV_NEVER 0x7fffffff - - -/* Registered Priorities */ - -/* Priorities are to be selected by the programmers and not by the user. */ - -#define LIBISO_MSGS_PRIO_ZERO 0x00000000 -#define LIBISO_MSGS_PRIO_LOW 0x10000000 -#define LIBISO_MSGS_PRIO_MEDIUM 0x20000000 -#define LIBISO_MSGS_PRIO_HIGH 0x30000000 -#define LIBISO_MSGS_PRIO_TOP 0x7ffffffe - -/* Do not use this priority for submitting */ -#define LIBISO_MSGS_PRIO_NEVER 0x7fffffff - - -/* Origin numbers of libburn drives may range from 0 to 1048575 */ -#define LIBISO_MSGS_ORIGIN_DRIVE_BASE 0 -#define LIBISO_MSGS_ORIGIN_DRIVE_TOP 0xfffff - -/* Origin numbers of libisofs images may range from 1048575 to 2097152 */ -#define LIBISO_MSGS_ORIGIN_IMAGE_BASE 0x100000 -#define LIBISO_MSGS_ORIGIN_IMAGE_TOP 0x1fffff - - - - /* Public Functions */ - - /* Calls initiated from inside the direct owner (e.g. from libburn) */ - - -/** Create new empty message handling facility with queue and issue a first - official reference to it. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -int libiso_msgs_new(struct libiso_msgs **m, int flag); - - -/** Destroy a message handling facility and all its eventual messages. - The submitted pointer gets set to NULL. - Actually only the last destroy call of all offical references to the object - will really dispose it. All others just decrement the reference counter. - Call this function only with official reference pointers obtained by - libiso_msgs_new() or libiso_msgs_refer(), and only once per such pointer. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL, -1 for fatal error -*/ -int libiso_msgs_destroy(struct libiso_msgs **m, int flag); - - -/** Create an official reference to an existing libiso_msgs object. The - references keep the object alive at least until it is released by - a matching number of destroy calls. So each reference MUST be revoked - by exactly one call to libiso_msgs_destroy(). - @param pt The pointer to be set and registered - @param m A pointer to the existing object - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for failure -*/ -int libiso_msgs_refer(struct libiso_msgs **pt, struct libiso_msgs *o, int flag); - - -/** Submit a message to a message handling facility. - @param origin program specific identification number of the originator of - a message. E.g. drive number. Programs should have an own - range of origin numbers. See above LIBISO_MSGS_ORIGIN_*_BASE - Use -1 if no number is known. - @param error_code Unique error code. Use only registered codes. See below. - The same unique error_code may be issued at different - occasions but those should be equivalent out of the view - of a libiso_msgs application. (E.g. "cannot open ATA drive" - versus "cannot open SCSI drive" would be equivalent.) - @param severity The LIBISO_MSGS_SEV_* of the event. - @param priority The LIBISO_MSGS_PRIO_* number of the event. - @param msg_text Printable and human readable message text. - @param os_errno Eventual error code from operating system (0 if none) - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on rejection, <0 for severe errors -*/ -int libiso_msgs_submit(struct libiso_msgs *m, int origin, int error_code, - int severity, int priority, char *msg_text, - int os_errno, int flag); - - - - /* Calls from applications (to be forwarded by direct owner) */ - - -/** Convert a registered severity number into a severity name - @param flag Bitfield for control purposes: - bit0= list all severity names in a newline separated string - @return >0 success, <=0 failure -*/ -int libiso_msgs__sev_to_text(int severity, char **severity_name, - int flag); - - -/** Convert a severity name into a severity number, - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -int libiso_msgs__text_to_sev(char *severity_name, int *severity, - int flag); - - -/** Set minimum severity for messages to be queued (default - LIBISO_MSGS_SEV_ALL) and for messages to be printed directly to stderr - (default LIBISO_MSGS_SEV_NEVER). - @param print_id A text of at most 80 characters to be printed before - any eventually printed message (default is "libiso: "). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return always 1 for now -*/ -int libiso_msgs_set_severities(struct libiso_msgs *m, int queue_severity, - int print_severity, char *print_id, int flag); - - -/** Obtain a message item that has at least the given severity and priority. - Usually all older messages of lower severity are discarded then. If no - item of sufficient severity was found, all others are discarded from the - queue. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 if a matching item was found, 0 if not, <0 for severe errors -*/ -int libiso_msgs_obtain(struct libiso_msgs *m, struct libiso_msgs_item **item, - int severity, int priority, int flag); - - -/** Destroy a message item obtained by libiso_msgs_obtain(). The submitted - pointer gets set to NULL. - Caution: Copy eventually obtained msg_text before destroying the item, - if you want to use it further. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL, <0 for severe errors -*/ -int libiso_msgs_destroy_item(struct libiso_msgs *m, - struct libiso_msgs_item **item, int flag); - - -/** Obtain from a message item the three application oriented components as - submitted with the originating call of libiso_msgs_submit(). - Caution: msg_text becomes a pointer into item, not a copy. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libiso_msgs_item_get_msg(struct libiso_msgs_item *item, - int *error_code, char **msg_text, int *os_errno, - int flag); - - -/** Obtain from a message item the submitter identification submitted - with the originating call of libiso_msgs_submit(). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libiso_msgs_item_get_origin(struct libiso_msgs_item *item, - double *timestamp, pid_t *process_id, int *origin, - int flag); - - -/** Obtain from a message item severity and priority as submitted - with the originating call of libiso_msgs_submit(). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libiso_msgs_item_get_rank(struct libiso_msgs_item *item, - int *severity, int *priority, int flag); - - -#ifdef LIDBAX_MSGS_________________ - - - /* Registered Error Codes */ - - -Format: error_code (LIBISO_MSGS_SEV_*,LIBISO_MSGS_PRIO_*) = explanation -If no severity or priority are fixely associated, use "(,)". - ------------------------------------------------------------------------------- -Range "libiso_msgs" : 0x00000000 to 0x0000ffff - - 0x00000000 (ALL,ZERO) = Initial setting in new libiso_msgs_item - 0x00000001 (DEBUG,ZERO) = Test error message - 0x00000002 (DEBUG,ZERO) = Debugging message - 0x00000003 (FATAL,HIGH) = Out of virtual memory - - ------------------------------------------------------------------------------- -Range "elmom" : 0x00010000 to 0x0001ffff - - - ------------------------------------------------------------------------------- -Range "scdbackup" : 0x00020000 to 0x0002ffff - - Acessing and defending drives: - - 0x00020001 (SORRY,LOW) = Cannot open busy device - 0x00020002 (SORRY,HIGH) = Encountered error when closing drive - 0x00020003 (SORRY,HIGH) = Could not grab drive - 0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling - 0x00020005 (SORRY,HIGH) = Failed to open device - 0x00020006 (FATAL,HIGH) = Too many scsi siblings - 0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings - 0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock - 0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist - - General library operations: - - 0x00020101 (WARNING,HIGH) = Cannot find given worker item - 0x00020102 (SORRY,HIGH) = A drive operation is still going on - 0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on - 0x00020104 (SORRY,HIGH) = NULL pointer caught - 0x00020105 (SORRY,HIGH) = Drive is already released - 0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close - 0x00020107 (WARNING,HIGH) = A drive is still busy on shutdown of library - 0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry - 0x00020108 (FATAL,HIGH) = Could not allocate new drive object - 0x00020109 (FATAL,HIGH) = Library not running - 0x0002010a (FATAL,HIGH) = Unsuitable track mode - 0x0002010b (FATAL,HIGH) = Burn run failed - 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive - 0x0002010d (DEBUG,HIGH) = Could not inquire TOC - 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive - 0x0002010f (DEBUG,HIGH) = SCSI error condition on command - 0x00020110 (FATAL,HIGH) = Persistent drive address too long - 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object - 0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type - 0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet - 0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data - 0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value - 0x00020116 (FATAL,HIGH) = Track mode has unusable value - 0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use - 0x00020118 (DEBUG,HIGH) = Closing track - 0x00020119 (DEBUG,HIGH) = Closing session - 0x0002011a (NOTE,HIGH) = Padding up track to minimum size - 0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive - 0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive - 0x0002011d (FATAL,HIGH) = SCSI error on write - 0x0002011e (SORRY,HIGH) = Unsuitable media detected - 0x0002011f (SORRY,HIGH) = Burning is restricted to a single track - 0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored - 0x00020121 (FATAL,HIGH) = Write preparation setup failed - 0x00020122 (FATAL,HIGH) = SCSI error on format_unit - 0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type - 0x00020124 (SORRY,HIGH) = SCSI error on set_streaming - 0x00020125 (SORRY,HIGH) = Write start address not supported - 0x00020126 (SORRY,HIGH) = Write start address not properly aligned - 0x00020127 (NOTE,HIGH) = Write start address is ... - 0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance - 0x00020129 (SORRY,HIGH) = Will not format media type - 0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities - 0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job - 0x0002012c (SORRY,HIGH) = Too many logical tracks recorded - 0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses - 0x0002012e (NOTE,HIGH) = Activated track default size - 0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session - 0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking - 0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive - 0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn - 0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode - 0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO - 0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO - 0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track - 0x00020137 (HINT,HIGH) = TAO would be possible - 0x00020138 (FATAL,HIGH) = Cannot reserve track - 0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable - 0x0002013a (FATAL,HIGH) = No suitable media detected - 0x0002013b (DEBUG,HIGH) = SCSI command indicates host or driver error - 0x0002013c (SORRY,HIGH) = Malformed capabilities page 2Ah received - 0x0002013d (DEBUG,LOW) = Waiting for free buffer space takes long time - 0x0002013e (SORRY,HIGH) = Timeout with waiting for free buffer. Now disabled - 0x0002013f (DEBUG,LOW) = Reporting total time spent with waiting for buffer - 0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access - 0x00020141 (SORRY,HIGH) = Write data count not properly aligned - 0x00020142 (FATAL,HIGH) = Drive is not grabbed on random access write - 0x00020143 (SORRY,HIGH) = Read start address not properly aligned - 0x00020144 (SORRY,HIGH) = SCSI error on read - 0x00020145 (FATAL,HIGH) = Drive is busy on attempt to read data - 0x00020146 (FATAL,HIGH) = Drive is a virtual placeholder - 0x00020147 (SORRY,HIGH) = Cannot address start byte - 0x00020148 (SORRY,HIGH) = Cannot write desired amount of data - 0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive - 0x0002014a (SORRY,HIGH) = Cannot read desired amount of data - 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned - 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function - 0x0002014d (SORRY,HIGH) = Asynchromous SCSI error - 0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command - 0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time - 0x00020151 (FATAL,HIGH) = Read attempt on write-only drive - 0x00020152 (FATAL,HIGH) = Cannot start fifo thread - 0x00020153 (SORRY,HIGH) = Read error on fifo input - 0x00020154 (NOTE,HIGH) = Forwarded input error ends output - 0x00020155 (SORRY,HIGH) = Desired fifo buffer too large - 0x00020156 (SORRY,HIGH) = Desired fifo buffer too small - 0x00020157 (FATAL,HIGH) = burn_source is not a fifo object - 0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions - 0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data - - libiso_audioxtr: - 0x00020200 (SORRY,HIGH) = Cannot open audio source file - 0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format - 0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data - - - ------------------------------------------------------------------------------- -Range "vreixo" : 0x00030000 to 0x0003ffff - - 0x0003ffff (FAILURE,HIGH) = Operation canceled - 0x0003fffe (FATAL,HIGH) = Unknown or unexpected fatal error - 0x0003fffd (FAILURE,HIGH) = Unknown or unexpected error - 0x0003fffc (FATAL,HIGH) = Internal programming error - 0x0003fffb (FAILURE,HIGH) = NULL pointer where NULL not allowed - 0x0003fffa (FATAL,HIGH) = Memory allocation error - 0x0003fff9 (FATAL,HIGH) = Interrupted by a signal - 0x0003fff8 (FAILURE,HIGH) = Invalid parameter value - 0x0003fff7 (FATAL,HIGH) = Cannot create a needed thread - 0x0003fff6 (FAILURE,HIGH) = Write error - 0x0003fff5 (FAILURE,HIGH) = Buffer read error - 0x0003ffc0 (FAILURE,HIGH) = Trying to add a node already added to another dir - 0x0003ffbf (FAILURE,HIGH) = Node with same name already exist - 0x0003ffbe (FAILURE,HIGH) = Trying to remove a node that was not added to dir - 0x0003ffbd (FAILURE,HIGH) = A requested node does not exist - 0x0003ffbc (FAILURE,HIGH) = Image already bootable - 0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image - 0x0003ff80 (FAILURE,HIGH) = Error on file operation - 0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file - 0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed - 0x0003ff7d (FAILURE,HIGH) = Incorrect path to file - 0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem - 0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned - 0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected - 0x0003ff79 (FAILURE,HIGH) = File read error - 0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected - 0x0003ff77 (FAILURE,HIGH) = Not symlink used where a symlink is expected - 0x0003ff76 (FAILURE,HIGH) = Cannot seek to specified location - 0x0003ff75 (HINT,MEDIUM) = File not supported in ECMA-119 tree and ignored - 0x0003ff74 (HINT,MEDIUM) = File bigger than supported by used standard - 0x0003ff73 (MISHAP,HIGH) = File read error during image creation - 0x0003ff72 (HINT,MEDIUM) = Cannot convert filename to requested charset - 0x0003ff71 (SORRY,HIGH) = File cannot be added to the tree - 0x0003ff70 (HINT,MEDIUM) = File path breaks specification constraints - 0x0003ff00 (FAILURE,HIGH) = Charset conversion error - 0x0003feff (FAILURE,HIGH) = Too much files to mangle - 0x0003fec0 (FAILURE,HIGH) = Wrong or damaged Primary Volume Descriptor - 0x0003febf (SORRY,HIGH) = Wrong or damaged RR entry - 0x0003febe (SORRY,HIGH) = Unsupported RR feature - 0x0003febd (FAILURE,HIGH) = Wrong or damaged ECMA-119 - 0x0003febc (FAILURE,HIGH) = Unsupported ECMA-119 feature - 0x0003febb (SORRY,HIGH) = Wrong or damaged El-Torito catalog - 0x0003feba (SORRY,HIGH) = Unsupported El-Torito feature - 0x0003feb9 (SORRY,HIGH) = Cannot patch isolinux boot image - 0x0003feb8 (SORRY,HIGH) = Unsupported SUSP feature - 0x0003feb7 (WARNING,HIGH) = Error on a RR entry that can be ignored - 0x0003feb6 (HINT,MEDIUM) = Error on a RR entry that can be ignored - 0x0003feb5 (WARNING,HIGH) = Multiple ER SUSP entries found - 0x0003feb4 (HINT,MEDIUM) = Unsupported volume descriptor found - 0x0003feb3 (WARNING,HIGH) = El-Torito related warning - 0x0003feb2 (MISHAP,HIGH) = Image write cancelled - 0x0003feb1 (WARNING,HIGH) = El-Torito image is hidden - -Outdated codes which may not be re-used for other purposes than -re-instating them, if ever: - -X 0x00031001 (SORRY,HIGH) = Cannot read file (ignored) -X 0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled) -X 0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image -X 0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored -X 0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image -X 0x00031003 (SORRY,HIGH) = Cannot read previous image file -X 0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored -X 0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry -X 0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found -X 0x00030111 (SORRY,HIGH) = Unsupported RR feature -X 0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry -X 0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored -X 0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog -X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature -X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image -X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image -X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without -X enought info about it -X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree - - ------------------------------------------------------------------------------- -Range "application" : 0x00040000 to 0x0004ffff - - 0x00040000 (ABORT,HIGH) : Application supplied message - 0x00040001 (FATAL,HIGH) : Application supplied message - 0x00040002 (SORRY,HIGH) : Application supplied message - 0x00040003 (WARNING,HIGH) : Application supplied message - 0x00040004 (HINT,HIGH) : Application supplied message - 0x00040005 (NOTE,HIGH) : Application supplied message - 0x00040006 (UPDATE,HIGH) : Application supplied message - 0x00040007 (DEBUG,HIGH) : Application supplied message - 0x00040008 (*,HIGH) : Application supplied message - - ------------------------------------------------------------------------------- -Range "libisofs-xorriso" : 0x00050000 to 0x0005ffff - -This is an alternative representation of libisofs.so.6 error codes in xorriso. -If values returned by iso_error_get_code() do not fit into 0x30000 to 0x3ffff -then they get truncated to 16 bit and mapped into this range. -(This should never need to happen, of course.) - ------------------------------------------------------------------------------- -Range "libisoburn" : 0x00060000 to 0x00006ffff - - 0x00060000 (*,*) : Message which shall be attributed to libisoburn - - >>> the messages of libisoburn need to be registered individually - - ------------------------------------------------------------------------------- - -#endif /* LIDBAX_MSGS_________________ */ - - - -#ifdef LIBISO_MSGS_H_INTERNAL - - /* Internal Functions */ - - -/** Lock before doing side effect operations on m */ -static int libiso_msgs_lock(struct libiso_msgs *m, int flag); - -/** Unlock after effect operations on m are done */ -static int libiso_msgs_unlock(struct libiso_msgs *m, int flag); - - -/** Create new empty message item. - @param link Previous item in queue - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -static int libiso_msgs_item_new(struct libiso_msgs_item **item, - struct libiso_msgs_item *link, int flag); - -/** Destroy a message item obtained by libiso_msgs_obtain(). The submitted - pointer gets set to NULL. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL -*/ -static int libiso_msgs_item_destroy(struct libiso_msgs_item **item, int flag); - - -#endif /* LIBISO_MSGS_H_INTERNAL */ - - -#endif /* ! LIBISO_MSGS_H_INCLUDED */ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libisofs.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libisofs.h deleted file mode 100644 index a5bd199b..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/libisofs.h +++ /dev/null @@ -1,3644 +0,0 @@ -/* - * Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_LIBISOFS_H_ -#define LIBISO_LIBISOFS_H_ - -#include -#include -#include - -struct burn_source; - -/** - * Context for image creation. It holds the files that will be added to image, - * and several options to control libisofs behavior. - * - * @since 0.6.2 - */ -typedef struct Iso_Image IsoImage; - -/* - * A node in the iso tree, i.e. a file that will be written to image. - * - * It can represent any kind of files. When needed, you can get the type with - * iso_node_get_type() and cast it to the appropiate subtype. Useful macros - * are provided, see below. - * - * @since 0.6.2 - */ -typedef struct Iso_Node IsoNode; - -/** - * A directory in the iso tree. It is an special type of IsoNode and can be - * casted to it in any case. - * - * @since 0.6.2 - */ -typedef struct Iso_Dir IsoDir; - -/** - * A symbolic link in the iso tree. It is an special type of IsoNode and can be - * casted to it in any case. - * - * @since 0.6.2 - */ -typedef struct Iso_Symlink IsoSymlink; - -/** - * A regular file in the iso tree. It is an special type of IsoNode and can be - * casted to it in any case. - * - * @since 0.6.2 - */ -typedef struct Iso_File IsoFile; - -/** - * An special file in the iso tree. This is used to represent any POSIX file - * other that regular files, directories or symlinks, i.e.: socket, block and - * character devices, and fifos. - * It is an special type of IsoNode and can be casted to it in any case. - * - * @since 0.6.2 - */ -typedef struct Iso_Special IsoSpecial; - -/** - * The type of an IsoNode. - * - * When an user gets an IsoNode from an image, (s)he can use - * iso_node_get_type() to get the current type of the node, and then - * cast to the appropriate subtype. For example: - * - * ... - * IsoNode *node; - * res = iso_dir_iter_next(iter, &node); - * if (res == 1 && iso_node_get_type(node) == LIBISO_DIR) { - * IsoDir *dir = (IsoDir *)node; - * ... - * } - * - * @since 0.6.2 - */ -enum IsoNodeType { - LIBISO_DIR, - LIBISO_FILE, - LIBISO_SYMLINK, - LIBISO_SPECIAL, - LIBISO_BOOT -}; - -/* macros to check node type */ -#define ISO_NODE_IS_DIR(n) (iso_node_get_type(n) == LIBISO_DIR) -#define ISO_NODE_IS_FILE(n) (iso_node_get_type(n) == LIBISO_FILE) -#define ISO_NODE_IS_SYMLINK(n) (iso_node_get_type(n) == LIBISO_SYMLINK) -#define ISO_NODE_IS_SPECIAL(n) (iso_node_get_type(n) == LIBISO_SPECIAL) -#define ISO_NODE_IS_BOOTCAT(n) (iso_node_get_type(n) == LIBISO_BOOT) - -/* macros for safe downcasting */ -#define ISO_DIR(n) ((IsoDir*)(ISO_NODE_IS_DIR(n) ? n : NULL)) -#define ISO_FILE(n) ((IsoFile*)(ISO_NODE_IS_FILE(n) ? n : NULL)) -#define ISO_SYMLINK(n) ((IsoSymlink*)(ISO_NODE_IS_SYMLINK(n) ? n : NULL)) -#define ISO_SPECIAL(n) ((IsoSpecial*)(ISO_NODE_IS_SPECIAL(n) ? n : NULL)) - -#define ISO_NODE(n) ((IsoNode*)n) - -/** - * Context for iterate on directory children. - * @see iso_dir_get_children() - * - * @since 0.6.2 - */ -typedef struct Iso_Dir_Iter IsoDirIter; - -/** - * It represents an El-Torito boot image. - * - * @since 0.6.2 - */ -typedef struct el_torito_boot_image ElToritoBootImage; - -/** - * An special type of IsoNode that acts as a placeholder for an El-Torito - * boot catalog. Once written, it will appear as a regular file. - * - * @since 0.6.2 - */ -typedef struct Iso_Boot IsoBoot; - -/** - * Flag used to hide a file in the RR/ISO or Joliet tree. - * - * @see iso_node_set_hidden - * @since 0.6.2 - */ -enum IsoHideNodeFlag { - /** Hide the node in the ECMA-119 / RR tree */ - LIBISO_HIDE_ON_RR = 1 << 0, - /** Hide the node in the Joliet tree, if Joliet extension are enabled */ - LIBISO_HIDE_ON_JOLIET = 1 << 1, - /** Hide the node in the ISO-9660:1999 tree, if that format is enabled */ - LIBISO_HIDE_ON_1999 = 1 << 2 -}; - -/** - * El-Torito bootable image type. - * - * @since 0.6.2 - */ -enum eltorito_boot_media_type { - ELTORITO_FLOPPY_EMUL, - ELTORITO_HARD_DISC_EMUL, - ELTORITO_NO_EMUL -}; - -/** - * Replace mode used when addding a node to a file. - * This controls how libisofs will act when you tried to add to a dir a file - * with the same name that an existing file. - * - * @since 0.6.2 - */ -enum iso_replace_mode { - /** - * Never replace an existing node, and instead fail with - * ISO_NODE_NAME_NOT_UNIQUE. - */ - ISO_REPLACE_NEVER, - /** - * Always replace the old node with the new. - */ - ISO_REPLACE_ALWAYS, - /** - * Replace with the new node if it is the same file type - */ - ISO_REPLACE_IF_SAME_TYPE, - /** - * Replace with the new node if it is the same file type and its ctime - * is newer than the old one. - */ - ISO_REPLACE_IF_SAME_TYPE_AND_NEWER, - /** - * Replace with the new node if its ctime is newer than the old one. - */ - ISO_REPLACE_IF_NEWER - /* - * TODO #00006 define more values - * -if both are dirs, add contents (and what to do with conflicts?) - */ -}; - -/** - * Options for image written. - * @see iso_write_opts_new() - * @since 0.6.2 - */ -typedef struct iso_write_opts IsoWriteOpts; - -/** - * Options for image reading or import. - * @see iso_read_opts_new() - * @since 0.6.2 - */ -typedef struct iso_read_opts IsoReadOpts; - -/** - * Source for image reading. - * - * @see struct iso_data_source - * @since 0.6.2 - */ -typedef struct iso_data_source IsoDataSource; - -/** - * Data source used by libisofs for reading an existing image. - * - * It offers homogeneous read access to arbitrary blocks to different sources - * for images, such as .iso files, CD/DVD drives, etc... - * - * To create a multisession image, libisofs needs a IsoDataSource, that the - * user must provide. The function iso_data_source_new_from_file() constructs - * an IsoDataSource that uses POSIX I/O functions to access data. You can use - * it with regular .iso images, and also with block devices that represent a - * drive. - * - * @since 0.6.2 - */ -struct iso_data_source -{ - - /* reserved for future usage, set to 0 */ - int version; - - /** - * Reference count for the data source. Should be 1 when a new source - * is created. Don't access it directly, but with iso_data_source_ref() - * and iso_data_source_unref() functions. - */ - unsigned int refcount; - - /** - * Opens the given source. You must open() the source before any attempt - * to read data from it. The open is the right place for grabbing the - * underlying resources. - * - * @return - * 1 if success, < 0 on error - */ - int (*open)(IsoDataSource *src); - - /** - * Close a given source, freeing all system resources previously grabbed in - * open(). - * - * @return - * 1 if success, < 0 on error - */ - int (*close)(IsoDataSource *src); - - /** - * Read an arbitrary block (2048 bytes) of data from the source. - * - * @param lba - * Block to be read. - * @param buffer - * Buffer where the data will be written. It should have at least - * 2048 bytes. - * @return - * 1 if success, < 0 on error - */ - int (*read_block)(IsoDataSource *src, uint32_t lba, uint8_t *buffer); - - /** - * Clean up the source specific data. Never call this directly, it is - * automatically called by iso_data_source_unref() when refcount reach - * 0. - */ - void (*free_data)(IsoDataSource *); - - /** Source specific data */ - void *data; -}; - -/** - * Return information for image. This is optionally allocated by libisofs, - * as a way to inform user about the features of an existing image, such as - * extensions present, size, ... - * - * @see iso_image_import() - * @since 0.6.2 - */ -typedef struct iso_read_image_features IsoReadImageFeatures; - -/** - * POSIX abstraction for source files. - * - * @see struct iso_file_source - * @since 0.6.2 - */ -typedef struct iso_file_source IsoFileSource; - -/** - * Abstract for source filesystems. - * - * @see struct iso_filesystem - * @since 0.6.2 - */ -typedef struct iso_filesystem IsoFilesystem; - -/** - * Interface that defines the operations (methods) available for an - * IsoFileSource. - * - * @see struct IsoFileSource_Iface - * @since 0.6.2 - */ -typedef struct IsoFileSource_Iface IsoFileSourceIface; - -/** - * IsoFilesystem implementation to deal with ISO images, and to offer a way to - * access specific information of the image, such as several volume attributes, - * extensions being used, El-Torito artifacts... - * - * @since 0.6.2 - */ -typedef IsoFilesystem IsoImageFilesystem; - -/** - * See IsoFilesystem->get_id() for info about this. - * @since 0.6.2 - */ -extern unsigned int iso_fs_global_id; - -/** - * An IsoFilesystem is a handler for a source of files, or a "filesystem". - * That is defined as a set of files that are organized in a hierarchical - * structure. - * - * A filesystem allows libisofs to access files from several sources in - * an homogeneous way, thus abstracting the underlying operations needed to - * access and read file contents. Note that this doesn't need to be tied - * to the disc filesystem used in the partition being accessed. For example, - * we have an IsoFilesystem implementation to access any mounted filesystem, - * using standard Linux functions. It is also legal, of course, to implement - * an IsoFilesystem to deal with a specific filesystem over raw partitions. - * That is what we do, for example, to access an ISO Image. - * - * Each file inside an IsoFilesystem is represented as an IsoFileSource object, - * that defines POSIX-like interface for accessing files. - * - * @since 0.6.2 - */ -struct iso_filesystem -{ - /** - * Type of filesystem. - * "file" -> local filesystem - * "iso " -> iso image filesystem - */ - char type[4]; - - /* reserved for future usage, set to 0 */ - int version; - - /** - * Get the root of a filesystem. - * - * @return - * 1 on success, < 0 on error - */ - int (*get_root)(IsoFilesystem *fs, IsoFileSource **root); - - /** - * Retrieve a file from its absolute path inside the filesystem. - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*get_by_path)(IsoFilesystem *fs, const char *path, - IsoFileSource **file); - - /** - * Get filesystem identifier. - * - * If the filesystem is able to generate correct values of the st_dev - * and st_ino fields for the struct stat of each file, this should - * return an unique number, greater than 0. - * - * To get a identifier for your filesystem implementation you should - * use iso_fs_global_id, incrementing it by one each time. - * - * Otherwise, if you can't ensure values in the struct stat are valid, - * this should return 0. - */ - unsigned int (*get_id)(IsoFilesystem *fs); - - /** - * Opens the filesystem for several read operations. Calling this funcion - * is not needed at all, each time that the underlying system resource - * needs to be accessed, it is openned propertly. - * However, if you plan to execute several operations on the filesystem, - * it is a good idea to open it previously, to prevent several open/close - * operations to occur. - * - * @return 1 on success, < 0 on error - */ - int (*open)(IsoFilesystem *fs); - - /** - * Close the filesystem, thus freeing all system resources. You should - * call this function if you have previously open() it. - * Note that you can open()/close() a filesystem several times. - * - * @return 1 on success, < 0 on error - */ - int (*close)(IsoFilesystem *fs); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_filesystem_unref() instead. - */ - void (*free)(IsoFilesystem *fs); - - /* internal usage, do never access them directly */ - unsigned int refcount; - void *data; -}; - -/** - * Interface definition for an IsoFileSource. Defines the POSIX-like function - * to access files and abstract underlying source. - * - * @since 0.6.2 - */ -struct IsoFileSource_Iface -{ - /* reserved for future usage, set to 0 */ - int version; - - /** - * Get the path, relative to the filesystem this file source belongs to. - * - * @return - * the path of the FileSource inside the filesystem, it should be - * freed when no more needed. - */ - char* (*get_path)(IsoFileSource *src); - - /** - * Get the name of the file, with the dir component of the path. - * - * @return - * the name of the file, it should be freed when no more needed. - */ - char* (*get_name)(IsoFileSource *src); - - /** - * Get information about the file. It is equivalent to lstat(2). - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*lstat)(IsoFileSource *src, struct stat *info); - - /** - * Get information about the file. If the file is a symlink, the info - * returned refers to the destination. It is equivalent to stat(2). - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*stat)(IsoFileSource *src, struct stat *info); - - /** - * Check if the process has access to read file contents. Note that this - * is not necessarily related with (l)stat functions. For example, in a - * filesystem implementation to deal with an ISO image, if the user has - * read access to the image it will be able to read all files inside it, - * despite of the particular permission of each file in the RR tree, that - * are what the above functions return. - * - * @return - * 1 if process has read access, < 0 on error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*access)(IsoFileSource *src); - - /** - * Opens the source. - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ALREADY_OPENED - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*open)(IsoFileSource *src); - - /** - * Close a previuously openned file - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - */ - int (*close)(IsoFileSource *src); - - /** - * Attempts to read up to count bytes from the given source into - * the buffer starting at buf. - * - * The file src must be open() before calling this, and close() when no - * more needed. Not valid for dirs. On symlinks it reads the destination - * file. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * ISO_WRONG_ARG_VALUE -> if count == 0 - * ISO_FILE_IS_DIR - * ISO_OUT_OF_MEM - * ISO_INTERRUPTED - */ - int (*read)(IsoFileSource *src, void *buf, size_t count); - - /** - * Read a directory. - * - * Each call to this function will return a new children, until we reach - * the end of file (i.e, no more children), in that case it returns 0. - * - * The dir must be open() before calling this, and close() when no more - * needed. Only valid for dirs. - * - * Note that "." and ".." children MUST NOT BE returned. - * - * @param child - * pointer to be filled with the given child. Undefined on error or OEF - * @return - * 1 on success, 0 if EOF (no more children), < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * ISO_FILE_IS_NOT_DIR - * ISO_OUT_OF_MEM - */ - int (*readdir)(IsoFileSource *src, IsoFileSource **child); - - /** - * Read the destination of a symlink. You don't need to open the file - * to call this. - * - * @param buf - * allocated buffer of at least bufsiz bytes. - * The dest. will be copied there, and it will be NULL-terminated - * @param bufsiz - * characters to be copied. Destination link will be truncated if - * it is larger than given size. This include the \0 character. - * @return - * 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 - * ISO_FILE_IS_NOT_SYMLINK - * ISO_OUT_OF_MEM - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * - */ - int (*readlink)(IsoFileSource *src, char *buf, size_t bufsiz); - - /** - * Get the filesystem for this source. No extra ref is added, so you - * musn't unref the IsoFilesystem. - * - * @return - * The filesystem, NULL on error - */ - IsoFilesystem* (*get_filesystem)(IsoFileSource *src); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_file_source_unref() instead. - */ - void (*free)(IsoFileSource *src); - - /* - * TODO #00004 Add a get_mime_type() function. - * This can be useful for GUI apps, to choose the icon of the file - */ -}; - -/** - * An IsoFile Source is a POSIX abstraction of a file. - * - * @since 0.6.2 - */ -struct iso_file_source -{ - const IsoFileSourceIface *class; - int refcount; - void *data; -}; - -/** - * Representation of file contents. It is an stream of bytes, functionally - * like a pipe. - * - * @since 0.6.4 - */ -typedef struct iso_stream IsoStream; - -/** - * Interface that defines the operations (methods) available for an - * IsoStream. - * - * @see struct IsoStream_Iface - * @since 0.6.4 - */ -typedef struct IsoStream_Iface IsoStreamIface; - -/** - * Serial number to be used when you can't get a valid id for a Stream by other - * means. If you use this, both fs_id and dev_id should be set to 0. - * This must be incremented each time you get a reference to it. - * - * @see IsoStreamIface->get_id() - * @since 0.6.4 - */ -extern ino_t serial_id; - -/** - * Interface definition for IsoStream methods. - * - * @since 0.6.4 - */ -struct IsoStream_Iface -{ - /* reserved for future usage, set to 0 */ - int version; - - /** - * Type of Stream. - * "fsrc" -> Read from file source - * "mem " -> Read from memory - * "boot" -> Boot catalog - * "user" -> User supplied stream - */ - char type[4]; - - /** - * Opens the stream. - * - * @return - * 1 on success, 2 file greater than expected, 3 file smaller than - * expected, < 0 on error - */ - int (*open)(IsoStream *stream); - - /** - * Close the Stream. - * @return 1 on success, < 0 on error - */ - int (*close)(IsoStream *stream); - - /** - * Get the size (in bytes) of the stream. This function should always - * return the same size, even if the underlying source size changes. - */ - off_t (*get_size)(IsoStream *stream); - - /** - * Attempts to read up to count bytes from the given stream into - * the buffer starting at buf. - * - * The stream must be open() before calling this, and close() when no - * more needed. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - */ - int (*read)(IsoStream *stream, void *buf, size_t count); - - /** - * Whether this IsoStream can be read several times, with the same results. - * For example, a regular file is repeatable, you can read it as many - * times as you want. However, a pipe isn't. - * - * This function doesn't take into account if the file has been modified - * between the two reads. - * - * @return - * 1 if stream is repeatable, 0 if not, < 0 on error - */ - int (*is_repeatable)(IsoStream *stream); - - /** - * Get an unique identifier for the IsoStream. - */ - void (*get_id)(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_stream_unref() instead. - */ - void (*free)(IsoStream *stream); -}; - -/** - * Representation of file contents as a stream of bytes. - * - * @since 0.6.4 - */ -struct iso_stream -{ - IsoStreamIface *class; - int refcount; - void *data; -}; - -/** - * Initialize libisofs. You must call this before any usage of the library. - * @return 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_init(); - -/** - * Finalize libisofs. - * - * @since 0.6.2 - */ -void iso_finish(); - -/** - * Create a new image, empty. - * - * The image will be owned by you and should be unref() when no more needed. - * - * @param name - * Name of the image. This will be used as volset_id and volume_id. - * @param image - * Location where the image pointer will be stored. - * @return - * 1 sucess, < 0 error - * - * @since 0.6.2 - */ -int iso_image_new(const char *name, IsoImage **image); - - -/** - * The following two functions three macros are utilities to help ensuring - * version match of application, compile time header, and runtime library. - */ -/** - * Get version of the libisofs library at runtime. - * - * @since 0.6.2 - */ -void iso_lib_version(int *major, int *minor, int *micro); - -/** - * Check at runtime if the library is ABI compatible with the given version. - * - * @return - * 1 lib is compatible, 0 is not. - * - * @since 0.6.2 - */ -int iso_lib_is_compatible(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 - * compile time. - * They must show the same values as these symbols in ./configure.ac - * LIBISOFS_MAJOR_VERSION=... - * LIBISOFS_MINOR_VERSION=... - * LIBISOFS_MICRO_VERSION=... - * Note to anybody who does own work inside libisofs: - * Any change of configure.ac or libisofs.h has to keep up this equality ! - * - * Before usage of these macros on your code, please read the usage discussion - * below. - * - * @since 0.6.2 - */ -#define iso_lib_header_version_major 0 -#define iso_lib_header_version_minor 6 -#define iso_lib_header_version_micro 3 - -/** - * 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 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 iso_lib_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. - */ - - -/** - * Creates an IsoWriteOpts for writing an image. You should set the options - * desired with the correspondent setters. - * - * Options by default are determined by the selected profile. Fifo size is set - * by default to 2 MB. - * - * @param opts - * Pointer to the location where the newly created IsoWriteOpts will be - * stored. You should free it with iso_write_opts_free() when no more - * needed. - * @param profile - * Default profile for image creation. For now the following values are - * defined: - * ---> 0 [BASIC] - * No extensions are enabled, and ISO level is set to 1. Only suitable - * for usage for very old and limited systems (like MS-DOS), or by a - * start point from which to set your custom options. - * ---> 1 [BACKUP] - * POSIX compatibility for backup. Simple settings, ISO level is set to - * 2 and RR extensions are enabled. Useful for backup purposes. - * ---> 2 [DISTRIBUTION] - * Setting for information distribution. Both RR and Joliet are enabled - * to maximize compatibility with most systems. Permissions are set to - * default values, and timestamps to the time of recording. - * @return - * 1 success, < 0 error - * - * @since 0.6.2 - */ -int iso_write_opts_new(IsoWriteOpts **opts, int profile); - -/** - * Free an IsoWriteOpts previously allocated with iso_write_opts_new(). - * - * @since 0.6.2 - */ -void iso_write_opts_free(IsoWriteOpts *opts); - -/** - * Set the ISO-9960 level to write at. - * - * @param level - * -> 1 for higher compatibility with old systems. With this level - * filenames are restricted to 8.3 characters. - * -> 2 to allow up to 31 filename characters. - * @return - * 1 success, < 0 error - * - * @since 0.6.2 - */ -int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level); - -/** - * Whether to use or not Rock Ridge extensions. - * - * This are standard extensions to ECMA-119, intended to add POSIX filesystem - * features to ECMA-119 images. Thus, usage of this flag is highly recommended - * for images used on GNU/Linux systems. With the usage of RR extension, the - * resulting image will have long filenames (up to 255 characters), deeper - * directory structure, POSIX permissions and owner info on files and - * directories, support for symbolic links or special files... All that - * attributes can be modified/setted with the appropiate function. - * - * @param enable - * 1 to enable RR extension, 0 to not add them - * @return - * 1 success, < 0 error - * - * @since 0.6.2 - */ -int iso_write_opts_set_rockridge(IsoWriteOpts *opts, int enable); - -/** - * Whether to add the non-standard Joliet extension to the image. - * - * This extensions are heavily used in Microsoft Windows systems, so if you - * plan to use your disc on such a system you should add this extension. - * Usage of Joliet supplies longer filesystem length (up to 64 unicode - * characters), and deeper directory structure. - * - * @param enable - * 1 to enable Joliet extension, 0 to not add them - * @return - * 1 success, < 0 error - * - * @since 0.6.2 - */ -int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable); - -/** - * Whether to use newer ISO-9660:1999 version. - * - * This is the second version of ISO-9660. It allows longer filenames and has - * less restrictions than old ISO-9660. However, nobody is using it so there - * are no much reasons to enable this. - * - * @since 0.6.2 - */ -int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable); - -/** - * Omit the version number (";1") at the end of the ISO-9660 identifiers. - * This breaks ECMA-119 specification, but version numbers are usually not - * used, so it should work on most systems. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit); - -/** - * Allow ISO-9660 directory hierarchy to be deeper than 8 levels. - * This breaks ECMA-119 specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow); - -/** - * Allow path in the ISO-9660 tree to have more than 255 characters. - * This breaks ECMA-119 specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow); - -/** - * 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. - * This breaks ECMA-119 specification and could lead to buffer overflow - * problems on old systems. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_max_37_char_filenames(IsoWriteOpts *opts, int allow); - -/** - * 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. - * This breaks ECMA-119 specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no); - -/** - * Allow lowercase characters in ISO-9660 filenames. By default, only - * uppercase characters, numbers and a few other characters are allowed. - * This breaks ECMA-119 specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow); - -/** - * Allow all ASCII characters to be appear on an ISO-9660 filename. Note - * that "/" and "\0" characters are never allowed, even in RR names. - * This breaks ECMA-119 specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow); - -/** - * Allow all characters to be part of Volume and Volset identifiers on - * the Primary Volume Descriptor. This breaks ISO-9660 contraints, but - * should work on modern systems. - * - * @since 0.6.2 - */ -int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow); - -/** - * Allow paths in the Joliet tree to have more than 240 characters. - * This breaks Joliet specification. Use with caution. - * - * @since 0.6.2 - */ -int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow); - -/** - * Whether to sort files based on their weight. - * - * @see iso_node_set_sort_weight - * @since 0.6.2 - */ -int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort); - -/** - * Whether to set 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 setted 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 by the functioins - * below. Note that for mode attributes, only the permissions are set, the - * file type remains unchanged. - * - * @see iso_write_opts_set_default_dir_mode - * @see iso_write_opts_set_default_file_mode - * @see iso_write_opts_set_default_uid - * @see iso_write_opts_set_default_gid - * @since 0.6.2 - */ -int iso_write_opts_set_replace_mode(IsoWriteOpts *opts, int dir_mode, - int file_mode, int uid, int gid); - -/** - * Set the mode to use on dirs when you set the replace_mode of dirs to 2. - * - * @see iso_write_opts_set_replace_mode - * @since 0.6.2 - */ -int iso_write_opts_set_default_dir_mode(IsoWriteOpts *opts, mode_t dir_mode); - -/** - * Set the mode to use on files when you set the replace_mode of files to 2. - * - * @see iso_write_opts_set_replace_mode - * @since 0.6.2 - */ -int iso_write_opts_set_default_file_mode(IsoWriteOpts *opts, mode_t file_mode); - -/** - * Set the uid to use when you set the replace_uid to 2. - * - * @see iso_write_opts_set_replace_mode - * @since 0.6.2 - */ -int iso_write_opts_set_default_uid(IsoWriteOpts *opts, uid_t uid); - -/** - * Set the gid to use when you set the replace_gid to 2. - * - * @see iso_write_opts_set_replace_mode - * @since 0.6.2 - */ -int iso_write_opts_set_default_gid(IsoWriteOpts *opts, gid_t gid); - -/** - * 0 to use IsoNode timestamps, 1 to use recording time, 2 to use - * values from timestamp field. This has only meaning if RR extensions - * are enabled. - * - * @see iso_write_opts_set_default_timestamp - * @since 0.6.2 - */ -int iso_write_opts_set_replace_timestamps(IsoWriteOpts *opts, int replace); - -/** - * Set the timestamp to use when you set the replace_timestamps to 2. - * - * @see iso_write_opts_set_replace_timestamps - * @since 0.6.2 - */ -int iso_write_opts_set_default_timestamp(IsoWriteOpts *opts, time_t timestamp); - -/** - * Whether to always record timestamps in GMT. - * - * By default, libisofs stores local time information on image. You can set - * this to always store timestamps in GMT. This is useful if you want to hide - * your timezone, or you live in a timezone that can't be represented in - * ECMA-119. These are timezones whose offset from GMT is greater than +13 - * hours, lower than -12 hours, or not a multiple of 15 minutes. - * - * @since 0.6.2 - */ -int iso_write_opts_set_always_gmt(IsoWriteOpts *opts, int gmt); - -/** - * Set the charset to use for the RR names of the files that will be created - * on the image. - * NULL to use default charset, that is the locale charset. - * You can obtain the list of charsets supported on your system executing - * "iconv -l" in a shell. - * - * @since 0.6.2 - */ -int iso_write_opts_set_output_charset(IsoWriteOpts *opts, const char *charset); - -/** - * Set the type of the image to create. Libisofs support two kind of images: - * stand-alone and appendable. - * - * A stand-alone image is an image that is valid alone, and that can be - * mounted by its own. This is the kind of image you will want to create - * in most cases. A stand-alone image can be burned in an empty CD or DVD, - * or write to an .iso file for future burning or distribution. - * - * On the other side, an appendable image is not self contained, it refers - * to serveral files that are stored outside the image. Its usage is for - * multisession discs, where you add data in a new session, while the - * previous session data can still be accessed. In those cases, the old - * data is not written again. Instead, the new image refers to it, and thus - * it's only valid when appended to the original. Note that in those cases - * the image will be written after the original, and thus you will want - * to use a ms_block greater than 0. - * - * Note that if you haven't import a previous image (by means of - * iso_image_import()), the image will always be a stand-alone image, as - * there is no previous data to refer to. - * - * @param appendable - * 1 to create an appendable image, 0 for an stand-alone one. - * - * @since 0.6.2 - */ -int iso_write_opts_set_appendable(IsoWriteOpts *opts, int appendable); - -/** - * Set the start block of the image. It is supposed to be the lba where the - * first block of the image will be written on disc. All references inside the - * ISO image will take this into account, thus providing a mountable image. - * - * For appendable images, that are written to a new session, you should - * pass here the lba of the next writable address on disc. - * - * In stand alone images this is usually 0. However, you may want to - * provide a different ms_block if you don't plan to burn the image in the - * first session on disc, such as in some CD-Extra disc whether the data - * image is written in a new session after some audio tracks. - * - * @since 0.6.2 - */ -int iso_write_opts_set_ms_block(IsoWriteOpts *opts, uint32_t ms_block); - -/** - * Sets the buffer where to store the descriptors that need to be written - * at the beginning of a overwriteable media to grow the image. - * - * @param overwrite - * When not NULL, it should point to a buffer of at least 64KiB, where - * libisofs will write the contents that should be written at the - * beginning of a overwriteable media, to grow the image. The growing - * of an image is a way, used by first time in growisofs by Andy Polyakov, - * to allow the appending of new data to non-multisession media, such - * as DVD+RW, in the same way you append a new session to a multisession - * disc, i.e., without need to write again the contents of the previous - * image. - * - * Note that if you want this kind of image growing, you will also need to - * set appendable to "1" and provide a valid ms_block after the previous - * image. - * - * You should initialize the buffer either with 0s, or with the contents of - * the first blocks of the image you're growing. In most cases, 0 is good - * enought. - * - * If you don't need this information, for example because you're creating a - * new image from scratch of because you will create an image for a true - * multisession media, just don't set this buffer or set it to NULL. - * - * @since 0.6.2 - */ -int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite); - -/** - * Set the size, in number of blocks, of the FIFO buffer used between the - * writer thread and the burn_source. You have to provide at least a 32 - * blocks buffer. Default value is set to 2MB, if that is ok for you, you - * don't need to call this function. - * - * @since 0.6.2 - */ -int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size); - -/** - * Create a burn_source to actually write the image. That burn_source can be - * used with libburn as a data source for a track. - * - * @param image - * The image to write. - * @param opts - * The options for image generation. All needed data will be copied, so - * you can free the given struct once this function returns. - * @param burn_src - * Location where the pointer to the burn_source will be stored - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts, - struct burn_source **burn_src); - -/** - * Creates an IsoReadOpts for reading an existent image. You should set the - * options desired with the correspondent setters. Note that you may want to - * set the start block value. - * - * Options by default are determined by the selected profile. - * - * @param opts - * Pointer to the location where the newly created IsoReadOpts will be - * stored. You should free it with iso_read_opts_free() when no more - * needed. - * @param profile - * Default profile for image reading. For now the following values are - * defined: - * ---> 0 [STANDARD] - * Suitable for most situations. All extension are read. When both - * Joliet and RR extension are present, RR is used. - * @return - * 1 success, < 0 error - * - * @since 0.6.2 - */ -int iso_read_opts_new(IsoReadOpts **opts, int profile); - -/** - * Free an IsoReadOpts previously allocated with iso_read_opts_new(). - * - * @since 0.6.2 - */ -void iso_read_opts_free(IsoReadOpts *opts); - -/** - * Set the block where the image begins. It is usually 0, but may be different - * on a multisession disc. - * - * @since 0.6.2 - */ -int iso_read_opts_set_start_block(IsoReadOpts *opts, uint32_t block); - -/** - * Do not read Rock Ridge extensions. - * In most cases you don't want to use this. It could be useful if RR info - * is damaged, or if you want to use the Joliet tree. - * - * @since 0.6.2 - */ -int iso_read_opts_set_no_rockridge(IsoReadOpts *opts, int norr); - -/** - * Do not read Joliet extensions. - * - * @since 0.6.2 - */ -int iso_read_opts_set_no_joliet(IsoReadOpts *opts, int nojoliet); - -/** - * Do not read ISO 9660:1999 enhanced tree - * - * @since 0.6.2 - */ -int iso_read_opts_set_no_iso1999(IsoReadOpts *opts, int noiso1999); - -/** - * Whether to prefer Joliet over RR. libisofs usually prefers RR over - * Joliet, as it give us much more info about files. So, if both extensions - * are present, RR is used. You can set this if you prefer Joliet, but - * note that this is not very recommended. This doesn't mean than RR - * extensions are not read: if no Joliet is present, libisofs will read - * RR tree. - * - * @since 0.6.2 - */ -int iso_read_opts_set_preferjoliet(IsoReadOpts *opts, int preferjoliet); - -/** - * Set default uid for files when RR extensions are not present. - * - * @since 0.6.2 - */ -int iso_read_opts_set_default_uid(IsoReadOpts *opts, uid_t uid); - -/** - * Set default gid for files when RR extensions are not present. - * - * @since 0.6.2 - */ -int iso_read_opts_set_default_gid(IsoReadOpts *opts, gid_t gid); - -/** - * Set default permissions for files when RR extensions are not present. - * - * @param file_perm - * Permissions for files. - * @param dir_perm - * Permissions for directories. - * - * @since 0.6.2 - */ -int iso_read_opts_set_default_permissions(IsoReadOpts *opts, mode_t file_perm, - mode_t dir_perm); - -/** - * Set the input charset of the file names on the image. NULL to use locale - * charset. You have to specify a charset if the image filenames are encoded - * in a charset different that the local one. This could happen, for example, - * if the image was created on a system with different charset. - * - * @param charset - * The charset to use as input charset. You can obtain the list of - * charsets supported on your system executing "iconv -l" in a shell. - * - * @since 0.6.2 - */ -int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset); - -/** - * Import a previous session or image, for growing or modify. - * - * @param image - * The image context to which old image will be imported. Note that all - * files added to image, and image attributes, will be replaced with the - * contents of the old image. - * TODO #00025 support for merging old image files - * @param src - * Data Source from which old image will be read. A extra reference is - * added, so you still need to iso_data_source_unref() yours. - * @param opts - * Options for image import. All needed data will be copied, so you - * can free the given struct once this function returns. - * @param features - * If not NULL, a new IsoReadImageFeatures will be allocated and filled - * with the features of the old image. It should be freed with - * iso_read_image_features_destroy() when no more needed. You can pass - * NULL if you're not interested on them. - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_image_import(IsoImage *image, IsoDataSource *src, IsoReadOpts *opts, - IsoReadImageFeatures **features); - -/** - * Destroy an IsoReadImageFeatures object obtained with iso_image_import. - * - * @since 0.6.2 - */ -void iso_read_image_features_destroy(IsoReadImageFeatures *f); - -/** - * Get the size (in 2048 byte block) of the image, as reported in the PVM. - * - * @since 0.6.2 - */ -uint32_t iso_read_image_features_get_size(IsoReadImageFeatures *f); - -/** - * Whether RockRidge extensions are present in the image imported. - * - * @since 0.6.2 - */ -int iso_read_image_features_has_rockridge(IsoReadImageFeatures *f); - -/** - * Whether Joliet extensions are present in the image imported. - * - * @since 0.6.2 - */ -int iso_read_image_features_has_joliet(IsoReadImageFeatures *f); - -/** - * Whether the image is recorded according to ISO 9660:1999, i.e. it has - * a version 2 Enhanced Volume Descriptor. - * - * @since 0.6.2 - */ -int iso_read_image_features_has_iso1999(IsoReadImageFeatures *f); - -/** - * Whether El-Torito boot record is present present in the image imported. - * - * @since 0.6.2 - */ -int iso_read_image_features_has_eltorito(IsoReadImageFeatures *f); - -/** - * Increments the reference counting of the given image. - * - * @since 0.6.2 - */ -void iso_image_ref(IsoImage *image); - -/** - * Decrements the reference couting of the given image. - * If it reaches 0, the image is free, together with its tree nodes (whether - * their refcount reach 0 too, of course). - * - * @since 0.6.2 - */ -void iso_image_unref(IsoImage *image); - -/** - * Attach user defined data to the image. Use this if your application needs - * to store addition info together with the IsoImage. If the image already - * has data attached, the old data will be freed. - * - * @param data - * Pointer to application defined data that will be attached to the - * image. You can pass NULL to remove any already attached data. - * @param give_up - * Function that will be called when the image does not need the data - * any more. It receives the data pointer as an argumente, and eventually - * causes data to be freed. It can be NULL if you don't need it. - * @return - * 1 on succes, < 0 on error - * - * @since 0.6.2 - */ -int iso_image_attach_data(IsoImage *image, void *data, void (*give_up)(void*)); - -/** - * The the data previously attached with iso_image_attach_data() - * - * @since 0.6.2 - */ -void *iso_image_get_attached_data(IsoImage *image); - -/** - * Get the root directory of the image. - * No extra ref is added to it, so you musn't unref it. Use iso_node_ref() - * if you want to get your own reference. - * - * @since 0.6.2 - */ -IsoDir *iso_image_get_root(const IsoImage *image); - -/** - * Fill in the volset identifier for a image. - * - * @since 0.6.2 - */ -void iso_image_set_volset_id(IsoImage *image, const char *volset_id); - -/** - * Get the volset identifier. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_volset_id(const IsoImage *image); - -/** - * Fill in the volume identifier for a image. - * - * @since 0.6.2 - */ -void iso_image_set_volume_id(IsoImage *image, const char *volume_id); - -/** - * Get the volume identifier. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_volume_id(const IsoImage *image); - -/** - * Fill in the publisher for a image. - * - * @since 0.6.2 - */ -void iso_image_set_publisher_id(IsoImage *image, const char *publisher_id); - -/** - * Get the publisher of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_publisher_id(const IsoImage *image); - -/** - * Fill in the data preparer for a image. - * - * @since 0.6.2 - */ -void iso_image_set_data_preparer_id(IsoImage *image, - const char *data_preparer_id); - -/** - * Get the data preparer of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_data_preparer_id(const IsoImage *image); - -/** - * Fill in the system id for a image. Up to 32 characters. - * - * @since 0.6.2 - */ -void iso_image_set_system_id(IsoImage *image, const char *system_id); - -/** - * Get the system id of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_system_id(const IsoImage *image); - -/** - * Fill in the application id for a image. Up to 128 chars. - * - * @since 0.6.2 - */ -void iso_image_set_application_id(IsoImage *image, const char *application_id); - -/** - * Get the application id of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_application_id(const IsoImage *image); - -/** - * Fill copyright information for the image. Usually this refers - * to a file on disc. Up to 37 characters. - * - * @since 0.6.2 - */ -void iso_image_set_copyright_file_id(IsoImage *image, - const char *copyright_file_id); - -/** - * Get the copyright information of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_copyright_file_id(const IsoImage *image); - -/** - * Fill abstract information for the image. Usually this refers - * to a file on disc. Up to 37 characters. - * - * @since 0.6.2 - */ -void iso_image_set_abstract_file_id(IsoImage *image, - const char *abstract_file_id); - -/** - * Get the abstract information of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_abstract_file_id(const IsoImage *image); - -/** - * Fill biblio information for the image. Usually this refers - * to a file on disc. Up to 37 characters. - * - * @since 0.6.2 - */ -void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id); - -/** - * Get the biblio information of a image. - * The returned string is owned by the image and should not be freed nor - * changed. - * - * @since 0.6.2 - */ -const char *iso_image_get_biblio_file_id(const IsoImage *image); - -/** - * Create a bootable image by adding a El-Torito boot image. - * - * This also add a catalog boot node to the image filesystem tree. - * - * @param image - * The image to make bootable. If it was already bootable this function - * returns an error and the image remains unmodified. - * @param image_path - * The path on the image tree of a regular file to use as default boot - * image. - * @param type - * The boot media type. This can be one of 3 types: - * - Floppy emulation: Boot image file must be exactly - * 1200 kB, 1440 kB or 2880 kB. - * - Hard disc emulation: The image must begin with a master - * boot record with a single image. - * - No emulation. You should specify load segment and load size - * of image. - * @param catalog_path - * The path on the image tree where the catalog will be stored. The - * directory component of this path must be a directory existent on the - * image tree, and the filename component must be unique among all - * children of that directory on image. Otherwise a correspodent error - * code will be returned. This function will add an IsoBoot node that acts - * as a placeholder for the real catalog, that will be generated at image - * creation time. - * @param boot - * Location where a pointer to the added boot image will be stored. That - * object is owned by the IsoImage and should not be freed by the user, - * nor dereferenced once the last reference to the IsoImage was disposed - * via iso_image_unref(). A NULL value is allowed if you don't need a - * reference to the boot image. - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_image_set_boot_image(IsoImage *image, const char *image_path, - enum eltorito_boot_media_type type, - const char *catalog_path, - ElToritoBootImage **boot); - -/* TODO #00026 : add support for "hidden" bootable images. */ - -/** - * Get El-Torito boot image of an ISO image, if any. - * - * This can be useful, for example, to check if a volume read from a previous - * session or an existing image is bootable. It can also be useful to get - * the image and catalog tree nodes. An application would want those, for - * example, to prevent the user removing it. - * - * Both nodes are owned by libisofs and should not be freed. You can get your - * own ref with iso_node_ref(). You can can also check if the node is already - * on the tree by getting its parent (note that when reading El-Torito info - * from a previous image, the nodes might not be on the tree even if you haven't - * removed them). Remember that you'll need to get a new ref - * (with iso_node_ref()) before inserting them again to the tree, and probably - * you will also need to set the name or permissions. - * - * @param image - * The image from which to get the boot image. - * @param boot - * If not NULL, it will be filled with a pointer to the boot image, if - * any. That object is owned by the IsoImage and should not be freed by - * the user, nor dereferenced once the last reference to the IsoImage was - * disposed via iso_image_unref(). - * @param imgnode - * When not NULL, it will be filled with the image tree node. No extra ref - * is added, you can use iso_node_ref() to get one if you need it. - * @param catnode - * When not NULL, it will be filled with the catnode tree node. No extra - * ref is added, you can use iso_node_ref() to get one if you need it. - * @return - * 1 on success, 0 is the image is not bootable (i.e., it has no El-Torito - * image), < 0 error. - * - * @since 0.6.2 - */ -int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot, - IsoFile **imgnode, IsoBoot **catnode); - -/** - * Removes the El-Torito bootable image. - * - * The IsoBoot node that acts as placeholder for the catalog is also removed - * for the image tree, if there. - * If the image is not bootable (don't have el-torito boot image) this function - * just returns. - * - * @since 0.6.2 - */ -void iso_image_remove_boot_image(IsoImage *image); - -/** - * Sets the load segment for the initial boot image. This is only for - * no emulation boot images, and is a NOP for other image types. - * - * @since 0.6.2 - */ -void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment); - -/** - * Sets the number of sectors (512b) to be load at load segment during - * the initial boot procedure. This is only for - * no emulation boot images, and is a NOP for other image types. - * - * @since 0.6.2 - */ -void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors); - -/** - * Marks the specified boot image as not bootable - * - * @since 0.6.2 - */ -void el_torito_set_no_bootable(ElToritoBootImage *bootimg); - -/** - * Specifies that this image needs to be patched. This involves the writting - * of a 56 bytes boot information table at offset 8 of the boot image file. - * The original boot image file won't be modified. - * This is needed for isolinux boot images. - * - * @since 0.6.2 - */ -void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg); - -/** - * Increments the reference counting of the given node. - * - * @since 0.6.2 - */ -void iso_node_ref(IsoNode *node); - -/** - * Decrements the reference couting of the given node. - * If it reach 0, the node is free, and, if the node is a directory, - * its children will be unref() too. - * - * @since 0.6.2 - */ -void iso_node_unref(IsoNode *node); - -/** - * Get the type of an IsoNode. - * - * @since 0.6.2 - */ -enum IsoNodeType iso_node_get_type(IsoNode *node); - -/** - * Set the name of a node. Note that if the node is already added to a dir - * this can fail if dir already contains a node with the new name. - * - * @param node - * The node whose name you want to change. Note that you can't change - * the name of the root. - * @param name - * The name for the node. If you supply an empty string or a - * name greater than 255 characters this returns with failure, and - * node name is not modified. - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_node_set_name(IsoNode *node, const char *name); - -/** - * Get the name of a node. - * The returned string belongs to the node and should not be modified nor - * freed. Use strdup if you really need your own copy. - * - * @since 0.6.2 - */ -const char *iso_node_get_name(const IsoNode *node); - -/** - * Set the permissions for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - * - * @param mode - * bitmask with the permissions of the node, as specified in 'man 2 stat'. - * The file type bitfields will be ignored, only file permissions will be - * modified. - * - * @since 0.6.2 - */ -void iso_node_set_permissions(IsoNode *node, mode_t mode); - -/** - * Get the permissions for the node - * - * @since 0.6.2 - */ -mode_t iso_node_get_permissions(const IsoNode *node); - -/** - * Get the mode of the node, both permissions and file type, as specified in - * 'man 2 stat'. - * - * @since 0.6.2 - */ -mode_t iso_node_get_mode(const IsoNode *node); - -/** - * Set the user id for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - * - * @since 0.6.2 - */ -void iso_node_set_uid(IsoNode *node, uid_t uid); - -/** - * Get the user id of the node. - * - * @since 0.6.2 - */ -uid_t iso_node_get_uid(const IsoNode *node); - -/** - * Set the group id for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - * - * @since 0.6.2 - */ -void iso_node_set_gid(IsoNode *node, gid_t gid); - -/** - * Get the group id of the node. - * - * @since 0.6.2 - */ -gid_t iso_node_get_gid(const IsoNode *node); - -/** - * Set the time of last modification of the file - * - * @since 0.6.2 - */ -void iso_node_set_mtime(IsoNode *node, time_t time); - -/** - * Get the time of last modification of the file - * - * @since 0.6.2 - */ -time_t iso_node_get_mtime(const IsoNode *node); - -/** - * Set the time of last access to the file - * - * @since 0.6.2 - */ -void iso_node_set_atime(IsoNode *node, time_t time); - -/** - * Get the time of last access to the file - * - * @since 0.6.2 - */ -time_t iso_node_get_atime(const IsoNode *node); - -/** - * Set the time of last status change of the file - * - * @since 0.6.2 - */ -void iso_node_set_ctime(IsoNode *node, time_t time); - -/** - * Get the time of last status change of the file - * - * @since 0.6.2 - */ -time_t iso_node_get_ctime(const IsoNode *node); - -/** - * Set if the node will be hidden in RR/ISO tree, Joliet tree or both. - * - * If the file is setted as hidden in one tree, it won't be included there, so - * it won't be visible in a OS accessing CD using that tree. For example, - * GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see - * what is recorded on CD, while MS Windows make use of the Joliet tree. If a - * file is hidden only in Joliet, it won't be visible in Windows systems, - * while still visible in Linux. - * - * If a file is hidden in both trees, it won't be written to image. - * - * @param node - * The node that is to be hidden. - * @param hide_attrs - * IsoHideNodeFlag's to set the trees in which file will be hidden. - * - * @since 0.6.2 - */ -void iso_node_set_hidden(IsoNode *node, int hide_attrs); - -/** - * Add a new node to a dir. Note that this function don't add a new ref to - * the node, so you don't need to free it, it will be automatically freed - * when the dir is deleted. Of course, if you want to keep using the node - * after the dir life, you need to iso_node_ref() it. - * - * @param dir - * the dir where to add the node - * @param child - * the node to add. You must ensure that the node hasn't previously added - * to other dir, and that the node name is unique inside the child. - * Otherwise this function will return a failure, and the child won't be - * inserted. - * @param replace - * if the dir already contains a node with the same name, whether to - * replace or not the old node with this. - * @return - * number of nodes in dir if succes, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if dir or child are NULL - * ISO_NODE_ALREADY_ADDED, if child is already added to other dir - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_WRONG_ARG_VALUE, if child == dir, or replace != (0,1) - * - * @since 0.6.2 - */ -int iso_dir_add_node(IsoDir *dir, IsoNode *child, - enum iso_replace_mode replace); - -/** - * Locate a node inside a given dir. - * - * @param dir - * The dir where to look for the node. - * @param name - * The name of the node - * @param node - * Location for a pointer to the node, it will filled with NULL if the dir - * doesn't have a child with the given name. - * The node will be owned by the dir and shouldn't be unref(). Just call - * iso_node_ref() to get your own reference to the node. - * Note that you can pass NULL is the only thing you want to do is check - * if a node with such name already exists on dir. - * @return - * 1 node found, 0 child has no such node, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if dir or name are NULL - * - * @since 0.6.2 - */ -int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node); - -/** - * Get the number of children of a directory. - * - * @return - * >= 0 number of items, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if dir is NULL - * - * @since 0.6.2 - */ -int iso_dir_get_children_count(IsoDir *dir); - -/** - * Removes a child from a directory. - * The child is not freed, so you will become the owner of the node. Later - * you can add the node to another dir (calling iso_dir_add_node), or free - * it if you don't need it (with iso_node_unref). - * - * @return - * 1 on success, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if node is NULL - * ISO_NODE_NOT_ADDED_TO_DIR, if node doesn't belong to a dir - * - * @since 0.6.2 - */ -int iso_node_take(IsoNode *node); - -/** - * Removes a child from a directory and free (unref) it. - * If you want to keep the child alive, you need to iso_node_ref() it - * before this call, but in that case iso_node_take() is a better - * alternative. - * - * @return - * 1 on success, < 0 error - * - * @since 0.6.2 - */ -int iso_node_remove(IsoNode *node); - -/* - * Get the parent of the given iso tree node. No extra ref is added to the - * returned directory, you must take your ref. with iso_node_ref() if you - * need it. - * - * If node is the root node, the same node will be returned as its parent. - * - * This returns NULL if the node doesn't pertain to any tree - * (it was removed/take). - * - * @since 0.6.2 - */ -IsoDir *iso_node_get_parent(IsoNode *node); - -/** - * Get an iterator for the children of the given dir. - * - * You can iterate over the children with iso_dir_iter_next. When finished, - * you should free the iterator with iso_dir_iter_free. - * You musn't delete a child of the same dir, using iso_node_take() or - * iso_node_remove(), while you're using the iterator. You can use - * iso_dir_iter_take() or iso_dir_iter_remove() instead. - * - * You can use the iterator in the way like this - * - * IsoDirIter *iter; - * IsoNode *node; - * if ( iso_dir_get_children(dir, &iter) != 1 ) { - * // handle error - * } - * while ( iso_dir_iter_next(iter, &node) == 1 ) { - * // do something with the child - * } - * iso_dir_iter_free(iter); - * - * An iterator is intended to be used in a single iteration over the - * children of a dir. Thus, it should be treated as a temporary object, - * and free as soon as possible. - * - * @return - * 1 success, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if dir or iter are NULL - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter); - -/** - * Get the next child. - * Take care that the node is owned by its parent, and will be unref() when - * the parent is freed. If you want your own ref to it, call iso_node_ref() - * on it. - * - * @return - * 1 success, 0 if dir has no more elements, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if node or iter are NULL - * ISO_ERROR, on wrong iter usage, usual caused by modiying the - * dir during iteration - * - * @since 0.6.2 - */ -int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node); - -/** - * Check if there're more children. - * - * @return - * 1 dir has more elements, 0 no, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if iter is NULL - * - * @since 0.6.2 - */ -int iso_dir_iter_has_next(IsoDirIter *iter); - -/** - * Free a dir iterator. - * - * @since 0.6.2 - */ -void iso_dir_iter_free(IsoDirIter *iter); - -/** - * Removes a child from a directory during an iteration, without freeing it. - * It's like iso_node_take(), but to be used during a directory iteration. - * The node removed will be the last returned by the iteration. - * - * The behavior on two call to this function without calling iso_dir_iter_next - * between then is undefined, and should never occur. (TODO protect against this?) - * - * @return - * 1 on succes, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if iter is NULL - * ISO_ERROR, on wrong iter usage, for example by call this before - * iso_dir_iter_next. - * - * @since 0.6.2 - */ -int iso_dir_iter_take(IsoDirIter *iter); - -/** - * Removes a child from a directory during an iteration and unref() it. - * It's like iso_node_remove(), but to be used during a directory iteration. - * The node removed will be the last returned by the iteration. - * - * The behavior on two call to this function without calling iso_tree_iter_next - * between then is undefined, and should never occur. (TODO protect against this?) - * - * @return - * 1 on succes, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if iter is NULL - * ISO_ERROR, on wrong iter usage, for example by call this before - * iso_dir_iter_next. - * - * @since 0.6.2 - */ -int iso_dir_iter_remove(IsoDirIter *iter); - - -/** - * @since 0.6.4 - */ -typedef struct iso_find_condition IsoFindCondition; - -/** - * Create a new condition that checks if the node name matches the given - * wildcard. - * - * @param wildcard - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_name(const char *wildcard); - -/** - * Create a new condition that checks the node mode against a mode mask. It - * can be used to check both file type and permissions. - * - * For example: - * - * iso_new_find_conditions_mode(S_IFREG) : search for regular files - * iso_new_find_conditions_mode(S_IFCHR | S_IWUSR) : search for character - * devices where owner has write permissions. - * - * @param mask - * Mode mask to AND against node mode. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_mode(mode_t mask); - -/** - * Create a new condition that checks the node gid. - * - * @param gid - * Desired Group Id. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_gid(gid_t gid); - -/** - * Create a new condition that checks the node uid. - * - * @param uid - * Desired User Id. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_uid(uid_t uid); - -/** - * Possible comparison between IsoNode and given conditions. - * - * @since 0.6.4 - */ -enum iso_find_comparisons { - ISO_FIND_COND_GREATER, - ISO_FIND_COND_GREATER_OR_EQUAL, - ISO_FIND_COND_EQUAL, - ISO_FIND_COND_LESS, - ISO_FIND_COND_LESS_OR_EQUAL -}; - -/** - * Create a new condition that checks the time of last access. - * - * @param time - * Time to compare against IsoNode atime. - * @param comparison - * Comparison to be done between IsoNode atime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_atime(time_t time, - enum iso_find_comparisons comparison); - -/** - * Create a new condition that checks the time of last modification. - * - * @param time - * Time to compare against IsoNode mtime. - * @param comparison - * Comparison to be done between IsoNode mtime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_mtime(time_t time, - enum iso_find_comparisons comparison); - -/** - * Create a new condition that checks the time of last status change. - * - * @param time - * Time to compare against IsoNode ctime. - * @param comparison - * Comparison to be done between IsoNode ctime and submitted time. - * Note that ISO_FIND_COND_GREATER, for example, is true if the node - * time is greater than the submitted time. - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_ctime(time_t time, - enum iso_find_comparisons comparison); - -/** - * Create a new condition that check if the two given conditions are - * valid. - * - * @param a - * @param b - * IsoFindCondition to compare - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_and(IsoFindCondition *a, - IsoFindCondition *b); - -/** - * Create a new condition that check if at least one the two given conditions - * is valid. - * - * @param a - * @param b - * IsoFindCondition to compare - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_or(IsoFindCondition *a, - IsoFindCondition *b); - -/** - * Create a new condition that check if the given conditions is false. - * - * @param negate - * @result - * The created IsoFindCondition, NULL on error. - * - * @since 0.6.4 - */ -IsoFindCondition *iso_new_find_conditions_not(IsoFindCondition *negate); - -/** - * Find all directory children that match the given condition. - * - * @param dir - * Directory where we will search children. - * @param cond - * Condition that the children must match in order to be returned. - * It will be free together with the iterator. Remember to delete it - * if this function return error. - * @param iter - * Iterator that returns only the children that match condition. - * @return - * 1 on success, < 0 on error - * - * @since 0.6.4 - */ -int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond, - IsoDirIter **iter); - -/** - * Get the destination of a node. - * The returned string belongs to the node and should not be modified nor - * freed. Use strdup if you really need your own copy. - * - * @since 0.6.2 - */ -const char *iso_symlink_get_dest(const IsoSymlink *link); - -/** - * Set the destination of a link. - * - * @param dest - * New destination for the link. It must be a non-empty string, otherwise - * this function doesn't modify previous destination. - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_symlink_set_dest(IsoSymlink *link, const char *dest); - -/** - * Sets the order in which a node will be written on image. High weihted files - * will be written first, so in a disc them will be written near the center. - * - * @param node - * The node which weight will be changed. If it's a dir, this function - * will change the weight of all its children. For nodes other that dirs - * or regular files, this function has no effect. - * @param w - * The weight as a integer number, the greater this value is, the - * closer from the begining of image the file will be written. - * - * @since 0.6.2 - */ -void iso_node_set_sort_weight(IsoNode *node, int w); - -/** - * Get the sort weight of a file. - * - * @since 0.6.2 - */ -int iso_file_get_sort_weight(IsoFile *file); - -/** - * Get the size of the file, in bytes - * - * @since 0.6.2 - */ -off_t iso_file_get_size(IsoFile *file); - -/** - * Get the IsoStream that represents the contents of the given IsoFile. - * - * If you open() the stream, it should be close() before image generation. - * - * @return - * The IsoStream. No extra ref is added, so the IsoStream belong to the - * IsoFile, and it may be freed together with it. Add your own ref with - * iso_stream_ref() if you need it. - * - * @since 0.6.4 - */ -IsoStream *iso_file_get_stream(IsoFile *file); - -/** - * Get the block lba of a file node, if it was imported from an old image. - * - * @param file - * The file - * @param lba - * Will be filled with the kba - * @param flag - * Reserved for future usage, submit 0 - * @return - * 1 if lba is valid (file comes from old image), 0 if file was newly - * added, i.e. it does not come from an old image, < 0 error - * - * @since 0.6.4 - */ -int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag); - -/* - * Like iso_file_get_old_image_lba(), but take an IsoNode. - * - * @return - * 1 if lba is valid (file comes from old image), 0 if file was newly - * added, i.e. it does not come from an old image, 2 node type has no - * LBA (no regular file), < 0 error - * - * @since 0.6.4 - */ -int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag); - -/** - * Add a new directory to the iso tree. Permissions, owner and hidden atts - * are taken from parent, you can modify them later. - * - * @param parent - * the dir where the new directory will be created - * @param name - * name for the new dir. If a node with same name already exists on - * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param dir - * place where to store a pointer to the newly created dir. No extra - * ref is addded, so you will need to call iso_node_ref() if you really - * need it. You can pass NULL in this parameter if you don't need the - * pointer. - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent or name are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir); - -/* - TODO #00007 expose Stream and this function: - int iso_tree_add_new_file(IsoDir *parent, const char *name, stream, file) - */ - -/** - * Add a new symlink to the directory tree. Permissions are set to 0777, - * owner and hidden atts are taken from parent. You can modify any of them - * later. - * - * @param parent - * the dir where the new symlink will be created - * @param name - * name for the new symlink. If a node with same name already exists on - * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param dest - * destination of the link - * @param link - * place where to store a pointer to the newly created link. No extra - * ref is addded, so you will need to call iso_node_ref() if you really - * need it. You can pass NULL in this parameter if you don't need the - * pointer - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent, name or dest are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_tree_add_new_symlink(IsoDir *parent, const char *name, - const char *dest, IsoSymlink **link); - -/** - * Add a new special file to the directory tree. As far as libisofs concerns, - * an special file is a block device, a character device, a FIFO (named pipe) - * or a socket. You can choose the specific kind of file you want to add - * by setting mode propertly (see man 2 stat). - * - * Note that special files are only written to image when Rock Ridge - * extensions are enabled. Moreover, a special file is just a directory entry - * in the image tree, no data is written beyond that. - * - * Owner and hidden atts are taken from parent. You can modify any of them - * later. - * - * @param parent - * the dir where the new special file will be created - * @param name - * name for the new special file. If a node with same name already exists - * on parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param mode - * file type and permissions for the new node. Note that you can't - * specify any kind of file here, only special types are allowed. i.e, - * S_IFSOCK, S_IFBLK, S_IFCHR and S_IFIFO are valid types; S_IFLNK, - * S_IFREG and S_IFDIR aren't. - * @param dev - * device ID, equivalent to the st_rdev field in man 2 stat. - * @param special - * place where to store a pointer to the newly created special file. No - * extra ref is addded, so you will need to call iso_node_ref() if you - * really need it. You can pass NULL in this parameter if you don't need - * the pointer. - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent, name or dest are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_WRONG_ARG_VALUE if you select a incorrect mode - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode, - dev_t dev, IsoSpecial **special); - -/** - * Set whether to follow or not symbolic links when added a file from a source - * to IsoImage. Default behavior is to not follow symlinks. - * - * @since 0.6.2 - */ -void iso_tree_set_follow_symlinks(IsoImage *image, int follow); - -/** - * Get current setting for follow_symlinks. - * - * @see iso_tree_set_follow_symlinks - * @since 0.6.2 - */ -int iso_tree_get_follow_symlinks(IsoImage *image); - -/** - * Set whether to skip or not hidden files when adding a directory recursibely. - * Default behavior is to not ignore them, i.e., to add hidden files to image. - * - * @since 0.6.2 - */ -void iso_tree_set_ignore_hidden(IsoImage *image, int skip); - -/** - * Get current setting for ignore_hidden. - * - * @see iso_tree_set_ignore_hidden - * @since 0.6.2 - */ -int iso_tree_get_ignore_hidden(IsoImage *image); - -/** - * Set the replace mode, that defines the behavior of libisofs when adding - * a node whit the same name that an existent one, during a recursive - * directory addition. - * - * @since 0.6.2 - */ -void iso_tree_set_replace_mode(IsoImage *image, enum iso_replace_mode mode); - -/** - * Get current setting for replace_mode. - * - * @see iso_tree_set_replace_mode - * @since 0.6.2 - */ -enum iso_replace_mode iso_tree_get_replace_mode(IsoImage *image); - -/** - * Set whether to skip or not special files. Default behavior is to not skip - * them. Note that, despite of this setting, special files won't never be added - * to an image unless RR extensions were enabled. - * - * @param skip - * Bitmask to determine what kind of special files will be skipped: - * bit0: ignore FIFOs - * bit1: ignore Sockets - * bit2: ignore char devices - * bit3: ignore block devices - * - * @since 0.6.2 - */ -void iso_tree_set_ignore_special(IsoImage *image, int skip); - -/** - * Get current setting for ignore_special. - * - * @see iso_tree_set_ignore_special - * @since 0.6.2 - */ -int iso_tree_get_ignore_special(IsoImage *image); - -/** - * Add a excluded path. These are paths that won't never added to image, - * and will be excluded even when adding recursively its parent directory. - * - * For example, in - * - * iso_tree_add_exclude(image, "/home/user/data/private"); - * iso_tree_add_dir_rec(image, root, "/home/user/data"); - * - * the directory /home/user/data/private won't be added to image. - * - * However, if you explicity add a deeper dir, it won't be excluded. i.e., - * in the following example. - * - * iso_tree_add_exclude(image, "/home/user/data"); - * iso_tree_add_dir_rec(image, root, "/home/user/data/private"); - * - * the directory /home/user/data/private is added. On the other, side, and - * foollowing the the example above, - * - * iso_tree_add_dir_rec(image, root, "/home/user"); - * - * will exclude the directory "/home/user/data". - * - * Absolute paths are not mandatory, you can, for example, add a relative - * path such as: - * - * iso_tree_add_exclude(image, "private"); - * iso_tree_add_exclude(image, "user/data"); - * - * to excluve, respectively, all files or dirs named private, and also all - * files or dirs named data that belong to a folder named "user". Not that the - * above rule about deeper dirs is still valid. i.e., if you call - * - * iso_tree_add_dir_rec(image, root, "/home/user/data/music"); - * - * it is included even containing "user/data" string. However, a possible - * "/home/user/data/music/user/data" is not added. - * - * Usual wildcards, such as * or ? are also supported, with the usual meaning - * as stated in "man 7 glob". For example - * - * // to exclude backup text files - * iso_tree_add_exclude(image, "*.~"); - * - * @return - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_tree_add_exclude(IsoImage *image, const char *path); - -/** - * Remove a previously added exclude. - * - * @see iso_tree_add_exclude - * @return - * 1 on success, 0 exclude do not exists, < 0 on error - * - * @since 0.6.2 - */ -int iso_tree_remove_exclude(IsoImage *image, const char *path); - -/** - * Set a callback function that libisofs will call for each file that is - * added to the given image by a recursive addition function. This includes - * image import. - * - * @param report - * pointer to a function that will be called just before a file will be - * added to the image. You can control whether the file will be in fact - * added or ignored. - * This function should return 1 to add the file, 0 to ignore it and - * continue, < 0 to abort the process - * NULL is allowed if you don't want any callback. - * - * @since 0.6.2 - */ -void iso_tree_set_report_callback(IsoImage *image, - int (*report)(IsoImage*, IsoFileSource*)); - -/** - * Add a new node to the image tree, from an existing file. - * - * TODO comment Builder and Filesystem related issues when exposing both - * - * All attributes will be taken from the source file. The appropriate file - * type will be created. - * - * @param image - * The image - * @param parent - * The directory in the image tree where the node will be added. - * @param path - * The path of the file to add in the filesystem. - * @param node - * place where to store a pointer to the newly added file. No - * extra ref is addded, so you will need to call iso_node_ref() if you - * really need it. You can pass NULL in this parameter if you don't need - * the pointer. - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if image, parent or path are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path, - IsoNode **node); - -/** - * Add a new node to the image tree, from an existing file, and with the - * given name, that must not exist on dir. - * - * @param image - * The image - * @param parent - * The directory in the image tree where the node will be added. - * @param name - * The name that the node will have on image. - * @param path - * The path of the file to add in the filesystem. - * @param node - * place where to store a pointer to the newly added file. No - * extra ref is addded, so you will need to call iso_node_ref() if you - * really need it. You can pass NULL in this parameter if you don't need - * the pointer. - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if image, parent or path are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - * - * @since 0.6.4 - */ -int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name, - const char *path, IsoNode **node); - -/** - * Add the contents of a dir to a given directory of the iso tree. - * - * There are several options to control what files are added or how they are - * managed. Take a look at iso_tree_set_* functions to see diferent options - * for recursive directory addition. - * - * TODO comment Builder and Filesystem related issues when exposing both - * - * @param image - * The image to which the directory belong. - * @param parent - * Directory on the image tree where to add the contents of the dir - * @param dir - * Path to a dir in the filesystem - * @return - * number of nodes in parent if success, < 0 otherwise - * - * @since 0.6.2 - */ -int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir); - -/** - * Locate a node by its path on image. - * - * @param node - * Location for a pointer to the node, it will filled with NULL if the - * given path does not exists on image. - * The node will be owned by the image and shouldn't be unref(). Just call - * iso_node_ref() to get your own reference to the node. - * Note that you can pass NULL is the only thing you want to do is check - * if a node with such path really exists. - * @return - * 1 found, 0 not found, < 0 error - * - * @since 0.6.2 - */ -int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node); - -/** - * Increments the reference counting of the given IsoDataSource. - * - * @since 0.6.2 - */ -void iso_data_source_ref(IsoDataSource *src); - -/** - * Decrements the reference counting of the given IsoDataSource, freeing it - * if refcount reach 0. - * - * @since 0.6.2 - */ -void iso_data_source_unref(IsoDataSource *src); - -/** - * Create a new IsoDataSource from a local file. This is suitable for - * accessing regular .iso images, or to acces drives via its block device - * and standard POSIX I/O calls. - * - * @param path - * The path of the file - * @param src - * Will be filled with the pointer to the newly created data source. - * @return - * 1 on success, < 0 on error. - * - * @since 0.6.2 - */ -int iso_data_source_new_from_file(const char *path, IsoDataSource **src); - -/** - * Get the status of the buffer used by a burn_source. - * - * @param b - * A burn_source previously obtained with - * iso_image_create_burn_source(). - * @param size - * Will be filled with the total size of the buffer, in bytes - * @param free_bytes - * Will be filled with the bytes currently available in buffer - * @return - * < 0 error, > 0 state: - * 1="active" : input and consumption are active - * 2="ending" : input has ended without error - * 3="failing" : input had error and ended, - * 5="abandoned" : consumption has ended prematurely - * 6="ended" : consumption has ended without input error - * 7="aborted" : consumption has ended after input error - * - * @since 0.6.2 - */ -int iso_ring_buffer_get_status(struct burn_source *b, size_t *size, - size_t *free_bytes); - -#define ISO_MSGS_MESSAGE_LEN 4096 - -/** - * Control queueing and stderr printing of messages from libisofs. - * Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - * "NOTE", "UPDATE", "DEBUG", "ALL". - * - * @param queue_severity Gives the minimum limit for messages to be queued. - * Default: "NEVER". If you queue messages then you - * must consume them by iso_msgs_obtain(). - * @param print_severity Does the same for messages to be printed directly - * to stderr. - * @param print_id A text prefix to be printed before the message. - * @return >0 for success, <=0 for error - * - * @since 0.6.2 - */ -int iso_set_msgs_severities(char *queue_severity, char *print_severity, - char *print_id); - -/** - * Obtain the oldest pending libisofs message from the queue which has at - * least the given minimum_severity. This message and any older message of - * lower severity will get discarded from the queue and is then lost forever. - * - * Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - * "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" - * will discard the whole queue. - * - * @param error_code - * Will become a unique error code as listed at the end of this header - * @param imgid - * Id of the image that was issued the message. - * @param msg_text - * Must provide at least ISO_MSGS_MESSAGE_LEN bytes. - * @param severity - * Will become the severity related to the message and should provide at - * least 80 bytes. - * @return - * 1 if a matching item was found, 0 if not, <0 for severe errors - * - * @since 0.6.2 - */ -int iso_obtain_msgs(char *minimum_severity, int *error_code, int *imgid, - char msg_text[], char severity[]); - - -/** - * Submit a message to the libisofs queueing system. It will be queued or - * printed as if it was generated by libisofs itself. - * - * @param error_code - * The unique error code of your message. - * Submit 0 if you do not have reserved error codes within the libburnia - * project. - * @param msg_text - * Not more than ISO_MSGS_MESSAGE_LEN characters of message text. - * @param os_errno - * Eventual errno related to the message. Submit 0 if the message is not - * related to a operating system error. - * @param severity - * One of "ABORT", "FATAL", "FAILURE", "SORRY", "WARNING", "HINT", "NOTE", - * "UPDATE", "DEBUG". Defaults to "FATAL". - * @param origin - * Submit 0 for now. - * @return - * 1 if message was delivered, <=0 if failure - * - * @since 0.6.4 - */ -int iso_msgs_submit(int error_code, char msg_text[], int os_errno, - char severity[], int origin); - - -/** - * Convert a severity name into a severity number, which gives the severity - * rank of the name. - * - * @param severity_name - * A name as with iso_msgs_submit(), e.g. "SORRY". - * @param severity_number - * The rank number: the higher, the more severe. - * @return - * >0 success, <=0 failure - * - * @since 0.6.4 - */ -int iso_text_to_sev(char *severity_name, int *severity_number); - - -/** - * Convert a severity number into a severity name - * - * @param severity_number - * The rank number: the higher, the more severe. - * @param severity_name - * A name as with iso_msgs_submit(), e.g. "SORRY". - * - * @since 0.6.4 - */ -int iso_sev_to_text(int severity_number, char **severity_name); - - -/** - * Get the id of an IsoImage, used for message reporting. This message id, - * retrieved with iso_obtain_msgs(), can be used to distinguish what - * IsoImage has isssued a given message. - * - * @since 0.6.2 - */ -int iso_image_get_msg_id(IsoImage *image); - -/** - * Get a textual description of a libisofs error. - * - * @since 0.6.2 - */ -const char *iso_error_to_msg(int errcode); - -/** - * Get the severity of a given error code - * @return - * 0x10000000 -> DEBUG - * 0x20000000 -> UPDATE - * 0x30000000 -> NOTE - * 0x40000000 -> HINT - * 0x50000000 -> WARNING - * 0x60000000 -> SORRY - * 0x64000000 -> MISHAP - * 0x68000000 -> FAILURE - * 0x70000000 -> FATAL - * 0x71000000 -> ABORT - * - * @since 0.6.2 - */ -int iso_error_get_severity(int e); - -/** - * Get the priority of a given error. - * @return - * 0x00000000 -> ZERO - * 0x10000000 -> LOW - * 0x20000000 -> MEDIUM - * 0x30000000 -> HIGH - * - * @since 0.6.2 - */ -int iso_error_get_priority(int e); - -/** - * Get the message queue code of a libisofs error. - */ -int iso_error_get_code(int e); - -/** - * Set the minimum error severity that causes a libisofs operation to - * be aborted as soon as possible. - * - * @param severity - * one of "FAILURE", "MISHAP", "SORRY", "WARNING", "HINT", "NOTE". - * Severities greater or equal than FAILURE always cause program to abort. - * Severities under NOTE won't never cause function abort. - * @return - * Previous abort priority on success, < 0 on error. - * - * @since 0.6.2 - */ -int iso_set_abort_severity(char *severity); - -/** - * Return the messenger object handle used by libisofs. This handle - * may be used by related libraries to their own compatible - * messenger objects and thus to direct their messages to the libisofs - * message queue. See also: libburn, API function burn_set_messenger(). - * - * @return the handle. Do only use with compatible - * - * @since 0.6.2 - */ -void *iso_get_messenger(); - -/** - * Take a ref to the given IsoFileSource. - * - * @since 0.6.2 - */ -void iso_file_source_ref(IsoFileSource *src); - -/** - * Drop your ref to the given IsoFileSource, eventually freeing the associated - * system resources. - * - * @since 0.6.2 - */ -void iso_file_source_unref(IsoFileSource *src); - -/* - * this are just helpers to invoque methods in class - */ - -/** - * Get the path, relative to the filesystem this file source - * belongs to. - * - * @return - * the path of the FileSource inside the filesystem, it should be - * freed when no more needed. - * - * @since 0.6.2 - */ -char* iso_file_source_get_path(IsoFileSource *src); - -/** - * Get the name of the file, with the dir component of the path. - * - * @return - * the name of the file, it should be freed when no more needed. - * - * @since 0.6.2 - */ -char* iso_file_source_get_name(IsoFileSource *src); - -/** - * Get information about the file. - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * - * @since 0.6.2 - */ -int iso_file_source_lstat(IsoFileSource *src, struct stat *info); - -/** - * Check if the process has access to read file contents. Note that this - * is not necessarily related with (l)stat functions. For example, in a - * filesystem implementation to deal with an ISO image, if the user has - * read access to the image it will be able to read all files inside it, - * despite of the particular permission of each file in the RR tree, that - * are what the above functions return. - * - * @return - * 1 if process has read access, < 0 on error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * - * @since 0.6.2 - */ -int iso_file_source_access(IsoFileSource *src); - -/** - * Get information about the file. If the file is a symlink, the info - * returned refers to the destination. - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * - * @since 0.6.2 - */ -int iso_file_source_stat(IsoFileSource *src, struct stat *info); - -/** - * Opens the source. - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ALREADY_OPENED - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_OUT_OF_MEM - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * - * @since 0.6.2 - */ -int iso_file_source_open(IsoFileSource *src); - -/** - * Close a previuously openned file - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * - * @since 0.6.2 - */ -int iso_file_source_close(IsoFileSource *src); - -/** - * Attempts to read up to count bytes from the given source into - * the buffer starting at buf. - * - * The file src must be open() before calling this, and close() when no - * more needed. Not valid for dirs. On symlinks it reads the destination - * file. - * - * @param src - * The given source - * @param buf - * Pointer to a buffer of at least count bytes where the read data will be - * stored - * @param count - * Bytes to read - * @return - * number of bytes read, 0 if EOF, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * ISO_WRONG_ARG_VALUE -> if count == 0 - * ISO_FILE_IS_DIR - * ISO_OUT_OF_MEM - * ISO_INTERRUPTED - * - * @since 0.6.2 - */ -int iso_file_source_read(IsoFileSource *src, void *buf, size_t count); - -/** - * Read a directory. - * - * Each call to this function will return a new children, until we reach - * the end of file (i.e, no more children), in that case it returns 0. - * - * The dir must be open() before calling this, and close() when no more - * needed. Only valid for dirs. - * - * Note that "." and ".." children MUST NOT BE returned. - * - * @param child - * pointer to be filled with the given child. Undefined on error or OEF - * @return - * 1 on success, 0 if EOF (no more children), < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENED - * ISO_FILE_IS_NOT_DIR - * ISO_OUT_OF_MEM - * - * @since 0.6.2 - */ -int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child); - -/** - * Read the destination of a symlink. You don't need to open the file - * to call this. - * - * @param src - * An IsoFileSource corresponding to a symbolic link. - * @param buf - * allocated buffer of at least bufsiz bytes. - * The dest. will be copied there, and it will be NULL-terminated - * @param bufsiz - * characters to be copied. Destination link will be truncated if - * it is larger than given size. This include the '\0' character. - * @return - * 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 - * ISO_FILE_IS_NOT_SYMLINK - * ISO_OUT_OF_MEM - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * - * @since 0.6.2 - */ -int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz); - -/** - * Get the filesystem for this source. No extra ref is added, so you - * musn't unref the IsoFilesystem. - * - * @return - * The filesystem, NULL on error - * - * @since 0.6.2 - */ -IsoFilesystem* iso_file_source_get_filesystem(IsoFileSource *src); - -/** - * Take a ref to the given IsoFilesystem - * - * @since 0.6.2 - */ -void iso_filesystem_ref(IsoFilesystem *fs); - -/** - * Drop your ref to the given IsoFilesystem, evetually freeing associated - * resources. - * - * @since 0.6.2 - */ -void iso_filesystem_unref(IsoFilesystem *fs); - -/** - * Create a new IsoFilesystem to access a existent ISO image. - * - * @param src - * Data source to access data. - * @param opts - * Image read options - * @param msgid - * An image identifer, obtained with iso_image_get_msg_id(), used to - * associated messages issued by the filesystem implementation with an - * existent image. If you are not using this filesystem in relation with - * any image context, just use 0x1fffff as the value for this parameter. - * @param fs - * Will be filled with a pointer to the filesystem that can be used - * to access image contents. - * @param - * 1 on success, < 0 on error - * - * @since 0.6.2 - */ -int iso_image_filesystem_new(IsoDataSource *src, IsoReadOpts *opts, int msgid, - IsoImageFilesystem **fs); - -/** - * Get the volset identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_volset_id(IsoImageFilesystem *fs); - -/** - * Get the volume identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_volume_id(IsoImageFilesystem *fs); - -/** - * Get the publisher identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_publisher_id(IsoImageFilesystem *fs); - -/** - * Get the data preparer identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_data_preparer_id(IsoImageFilesystem *fs); - -/** - * Get the system identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_system_id(IsoImageFilesystem *fs); - -/** - * Get the application identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_application_id(IsoImageFilesystem *fs); - -/** - * Get the copyright file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_copyright_file_id(IsoImageFilesystem *fs); - -/** - * Get the abstract file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_abstract_file_id(IsoImageFilesystem *fs); - -/** - * Get the biblio file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - * - * @since 0.6.2 - */ -const char *iso_image_fs_get_biblio_file_id(IsoImageFilesystem *fs); - -/** - * Increment reference count of an IsoStream. - * - * @since 0.6.4 - */ -void iso_stream_ref(IsoStream *stream); - -/** - * Decrement reference count of an IsoStream, and eventually free it if - * refcount reach 0. - * - * @since 0.6.4 - */ -void iso_stream_unref(IsoStream *stream); - -/** - * Opens the given stream. Remember to close the Stream before writing the - * image. - * - * @return - * 1 on success, 2 file greater than expected, 3 file smaller than - * expected, < 0 on error - * - * @since 0.6.4 - */ -int iso_stream_open(IsoStream *stream); - -/** - * Close a previously openned IsoStream. - * - * @return - * 1 on success, < 0 on error - * - * @since 0.6.4 - */ -int iso_stream_close(IsoStream *stream); - -/** - * Get the size of a given stream. This function should always return the same - * size, even if the underlying source size changes. - * - * @return - * IsoStream size in bytes - * - * @since 0.6.4 - */ -off_t iso_stream_get_size(IsoStream *stream); - -/** - * Attempts to read up to count bytes from the given stream into - * the buffer starting at buf. - * - * The stream must be open() before calling this, and close() when no - * more needed. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - * - * @since 0.6.4 - */ -int iso_stream_read(IsoStream *stream, void *buf, size_t count); - -/** - * Whether the given IsoStream can be read several times, with the same - * results. - * For example, a regular file is repeatable, you can read it as many - * times as you want. However, a pipe isn't. - * - * This function doesn't take into account if the file has been modified - * between the two reads. - * - * @return - * 1 if stream is repeatable, 0 if not, < 0 on error - * - * @since 0.6.4 - */ -int iso_stream_is_repeatable(IsoStream *stream); - -/** - * Get an unique identifier for a given IsoStream. - * - * @since 0.6.4 - */ -void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id); - -/************ Error codes and return values for libisofs ********************/ - -/** successfully execution */ -#define ISO_SUCCESS 1 - -/** - * special return value, it could be or not an error depending on the - * context. - */ -#define ISO_NONE 0 - -/** Operation canceled (FAILURE,HIGH, -1) */ -#define ISO_CANCELED 0xE830FFFF - -/** Unknown or unexpected fatal error (FATAL,HIGH, -2) */ -#define ISO_FATAL_ERROR 0xF030FFFE - -/** Unknown or unexpected error (FAILURE,HIGH, -3) */ -#define ISO_ERROR 0xE830FFFD - -/** Internal programming error. Please report this bug (FATAL,HIGH, -4) */ -#define ISO_ASSERT_FAILURE 0xF030FFFC - -/** - * NULL pointer as value for an arg. that doesn't allow NULL (FAILURE,HIGH, -5) - */ -#define ISO_NULL_POINTER 0xE830FFFB - -/** Memory allocation error (FATAL,HIGH, -6) */ -#define ISO_OUT_OF_MEM 0xF030FFFA - -/** Interrupted by a signal (FATAL,HIGH, -7) */ -#define ISO_INTERRUPTED 0xF030FFF9 - -/** Invalid parameter value (FAILURE,HIGH, -8) */ -#define ISO_WRONG_ARG_VALUE 0xE830FFF8 - -/** Can't create a needed thread (FATAL,HIGH, -9) */ -#define ISO_THREAD_ERROR 0xF030FFF7 - -/** Write error (FAILURE,HIGH, -10) */ -#define ISO_WRITE_ERROR 0xE830FFF6 - -/** Buffer read error (FAILURE,HIGH, -11) */ -#define ISO_BUF_READ_ERROR 0xE830FFF5 - -/** Trying to add to a dir a node already added to a dir (FAILURE,HIGH, -64) */ -#define ISO_NODE_ALREADY_ADDED 0xE830FFC0 - -/** Node with same name already exists (FAILURE,HIGH, -65) */ -#define ISO_NODE_NAME_NOT_UNIQUE 0xE830FFBF - -/** Trying to remove a node that was not added to dir (FAILURE,HIGH, -65) */ -#define ISO_NODE_NOT_ADDED_TO_DIR 0xE830FFBE - -/** A requested node does not exist (FAILURE,HIGH, -66) */ -#define ISO_NODE_DOESNT_EXIST 0xE830FFBD - -/** - * Try to set the boot image of an already bootable image (FAILURE,HIGH, -67) - */ -#define ISO_IMAGE_ALREADY_BOOTABLE 0xE830FFBC - -/** Trying to use an invalid file as boot image (FAILURE,HIGH, -68) */ -#define ISO_BOOT_IMAGE_NOT_VALID 0xE830FFBB - -/** - * Error on file operation (FAILURE,HIGH, -128) - * (take a look at more specified error codes below) - */ -#define ISO_FILE_ERROR 0xE830FF80 - -/** Trying to open an already openned file (FAILURE,HIGH, -129) */ -#define ISO_FILE_ALREADY_OPENED 0xE830FF7F - -/* @deprecated use ISO_FILE_ALREADY_OPENED instead */ -#define ISO_FILE_ALREADY_OPENNED 0xE830FF7F - -/** Access to file is not allowed (FAILURE,HIGH, -130) */ -#define ISO_FILE_ACCESS_DENIED 0xE830FF7E - -/** Incorrect path to file (FAILURE,HIGH, -131) */ -#define ISO_FILE_BAD_PATH 0xE830FF7D - -/** The file does not exist in the filesystem (FAILURE,HIGH, -132) */ -#define ISO_FILE_DOESNT_EXIST 0xE830FF7C - -/** Trying to read or close a file not openned (FAILURE,HIGH, -133) */ -#define ISO_FILE_NOT_OPENED 0xE830FF7B - -/* @deprecated use ISO_FILE_NOT_OPENED instead */ -#define ISO_FILE_NOT_OPENNED ISO_FILE_NOT_OPENED - -/** Directory used where no dir is expected (FAILURE,HIGH, -134) */ -#define ISO_FILE_IS_DIR 0xE830FF7A - -/** Read error (FAILURE,HIGH, -135) */ -#define ISO_FILE_READ_ERROR 0xE830FF79 - -/** Not dir used where a dir is expected (FAILURE,HIGH, -136) */ -#define ISO_FILE_IS_NOT_DIR 0xE830FF78 - -/** Not symlink used where a symlink is expected (FAILURE,HIGH, -137) */ -#define ISO_FILE_IS_NOT_SYMLINK 0xE830FF77 - -/** Can't seek to specified location (FAILURE,HIGH, -138) */ -#define ISO_FILE_SEEK_ERROR 0xE830FF76 - -/** File not supported in ECMA-119 tree and thus ignored (HINT,MEDIUM, -139) */ -#define ISO_FILE_IGNORED 0xC020FF75 - -/* A file is bigger than supported by used standard (HINT,MEDIUM, -140) */ -#define ISO_FILE_TOO_BIG 0xC020FF74 - -/* File read error during image creation (MISHAP,HIGH, -141) */ -#define ISO_FILE_CANT_WRITE 0xE430FF73 - -/* Can't convert filename to requested charset (HINT,MEDIUM, -142) */ -#define ISO_FILENAME_WRONG_CHARSET 0xC020FF72 - -/* File can't be added to the tree (SORRY,HIGH, -143) */ -#define ISO_FILE_CANT_ADD 0xE030FF71 - -/** - * File path break specification constraints and will be ignored - * (HINT,MEDIUM, -141) - */ -#define ISO_FILE_IMGPATH_WRONG 0xC020FF70 - -/** Charset conversion error (FAILURE,HIGH, -256) */ -#define ISO_CHARSET_CONV_ERROR 0xE830FF00 - -/** - * Too much files to mangle, i.e. we cannot guarantee unique file names - * (FAILURE,HIGH, -257) - */ -#define ISO_MANGLE_TOO_MUCH_FILES 0xE830FEFF - -/* image related errors */ - -/** - * Wrong or damaged Primary Volume Descriptor (FAILURE,HIGH, -320) - * This could mean that the file is not a valid ISO image. - */ -#define ISO_WRONG_PVD 0xE830FEC0 - -/** Wrong or damaged RR entry (SORRY,HIGH, -321) */ -#define ISO_WRONG_RR 0xE030FEBF - -/** Unsupported RR feature (SORRY,HIGH, -322) */ -#define ISO_UNSUPPORTED_RR 0xE030FEBE - -/** Wrong or damaged ECMA-119 (FAILURE,HIGH, -323) */ -#define ISO_WRONG_ECMA119 0xE830FEBD - -/** Unsupported ECMA-119 feature (FAILURE,HIGH, -324) */ -#define ISO_UNSUPPORTED_ECMA119 0xE830FEBC - -/** Wrong or damaged El-Torito catalog (SORRY,HIGH, -325) */ -#define ISO_WRONG_EL_TORITO 0xE030FEBB - -/** Unsupported El-Torito feature (SORRY,HIGH, -326) */ -#define ISO_UNSUPPORTED_EL_TORITO 0xE030FEBA - -/** Can't patch an isolinux boot image (SORRY,HIGH, -327) */ -#define ISO_ISOLINUX_CANT_PATCH 0xE030FEB9 - -/** Unsupported SUSP feature (SORRY,HIGH, -328) */ -#define ISO_UNSUPPORTED_SUSP 0xE030FEB8 - -/** Error on a RR entry that can be ignored (WARNING,HIGH, -329) */ -#define ISO_WRONG_RR_WARN 0xD030FEB7 - -/** Error on a RR entry that can be ignored (HINT,MEDIUM, -330) */ -#define ISO_SUSP_UNHANDLED 0xC020FEB6 - -/** Multiple ER SUSP entries found (WARNING,HIGH, -331) */ -#define ISO_SUSP_MULTIPLE_ER 0xD030FEB5 - -/** Unsupported volume descriptor found (HINT,MEDIUM, -332) */ -#define ISO_UNSUPPORTED_VD 0xC020FEB4 - -/** El-Torito related warning (WARNING,HIGH, -333) */ -#define ISO_EL_TORITO_WARN 0xD030FEB3 - -/** Image write cancelled (MISHAP,HIGH, -334) */ -#define ISO_IMAGE_WRITE_CANCELED 0xE430FEB2 - -/** El-Torito image is hidden (WARNING,HIGH, -335) */ -#define ISO_EL_TORITO_HIDDEN 0xD030FEB1 - -#endif /*LIBISO_LIBISOFS_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.c deleted file mode 100644 index 8b55b45e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#include -#include -#include -#include - -#include "libiso_msgs.h" -#include "libisofs.h" -#include "messages.h" - -/* - * error codes are 32 bit numbers, that follow the following conventions: - * - * bit 31 (MSB) -> 1 (to make the value always negative) - * bits 30-24 -> Encoded severity (Use ISO_ERR_SEV to translate an error code - * to a LIBISO_MSGS_SEV_* constant) - * = 0x10 -> DEBUG - * = 0x20 -> UPDATE - * = 0x30 -> NOTE - * = 0x40 -> HINT - * = 0x50 -> WARNING - * = 0x60 -> SORRY - * = 0x64 -> MISHAP - * = 0x68 -> FAILURE - * = 0x70 -> FATAL - * = 0x71 -> ABORT - * bits 23-20 -> Encoded priority (Use ISO_ERR_PRIO to translate an error code - * to a LIBISO_MSGS_PRIO_* constant) - * = 0x0 -> ZERO - * = 0x1 -> LOW - * = 0x2 -> MEDIUM - * = 0x3 -> HIGH - * bits 19-16 -> Reserved for future usage (maybe message ranges) - * bits 15-0 -> Error code - */ -#define ISO_ERR_SEV(e) (e & 0x7F000000) -#define ISO_ERR_PRIO(e) ((e & 0x00F00000) << 8) -#define ISO_ERR_CODE(e) ((e & 0x0000FFFF) | 0x00030000) - -int iso_message_id = LIBISO_MSGS_ORIGIN_IMAGE_BASE; - -/** - * Threshold for aborting. - */ -int abort_threshold = LIBISO_MSGS_SEV_FAILURE; - -#define MAX_MSG_LEN 4096 - -struct libiso_msgs *libiso_msgr = NULL; - -int iso_init() -{ - if (libiso_msgr == NULL) { - if (libiso_msgs_new(&libiso_msgr, 0) <= 0) - return ISO_FATAL_ERROR; - } - libiso_msgs_set_severities(libiso_msgr, LIBISO_MSGS_SEV_NEVER, - LIBISO_MSGS_SEV_FATAL, "libisofs: ", 0); - return 1; -} - -void iso_finish() -{ - libiso_msgs_destroy(&libiso_msgr, 0); -} - -int iso_set_abort_severity(char *severity) -{ - int ret, sevno; - - ret = libiso_msgs__text_to_sev(severity, &sevno, 0); - if (ret <= 0) - return ISO_WRONG_ARG_VALUE; - if (sevno > LIBISO_MSGS_SEV_FAILURE || sevno < LIBISO_MSGS_SEV_NOTE) - return ISO_WRONG_ARG_VALUE; - ret = abort_threshold; - abort_threshold = sevno; - return ret; -} - -void iso_msg_debug(int imgid, const char *fmt, ...) -{ - char msg[MAX_MSG_LEN]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(msg, MAX_MSG_LEN, fmt, ap); - va_end(ap); - - libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG, - LIBISO_MSGS_PRIO_ZERO, msg, 0, 0); -} - -const char *iso_error_to_msg(int errcode) -{ - switch(errcode) { - case ISO_CANCELED: - return "Operation canceled"; - case ISO_FATAL_ERROR: - return "Unknown or unexpected fatal error"; - case ISO_ERROR: - return "Unknown or unexpected error"; - case ISO_ASSERT_FAILURE: - return "Internal programming error. Please report this bug"; - case ISO_NULL_POINTER: - return "NULL pointer as value for an arg. that doesn't allow NULL"; - case ISO_OUT_OF_MEM: - return "Memory allocation error"; - case ISO_INTERRUPTED: - return "Interrupted by a signal"; - case ISO_WRONG_ARG_VALUE: - return "Invalid parameter value"; - case ISO_THREAD_ERROR: - return "Can't create a needed thread"; - case ISO_WRITE_ERROR: - return "Write error"; - case ISO_BUF_READ_ERROR: - return "Buffer read error"; - case ISO_NODE_ALREADY_ADDED: - return "Trying to add to a dir a node already added to a dir"; - case ISO_NODE_NAME_NOT_UNIQUE: - return "Node with same name already exists"; - case ISO_NODE_NOT_ADDED_TO_DIR: - return "Trying to remove a node that was not added to dir"; - case ISO_NODE_DOESNT_EXIST: - return "A requested node does not exist"; - case ISO_IMAGE_ALREADY_BOOTABLE: - return "Try to set the boot image of an already bootable image"; - case ISO_BOOT_IMAGE_NOT_VALID: - return "Trying to use an invalid file as boot image"; - case ISO_FILE_ERROR: - return "Error on file operation"; - case ISO_FILE_ALREADY_OPENED: - return "Trying to open an already opened file"; - case ISO_FILE_ACCESS_DENIED: - return "Access to file is not allowed"; - case ISO_FILE_BAD_PATH: - return "Incorrect path to file"; - case ISO_FILE_DOESNT_EXIST: - return "The file does not exist in the filesystem"; - case ISO_FILE_NOT_OPENED: - return "Trying to read or close a file not opened"; - case ISO_FILE_IS_DIR: - return "Directory used where no dir is expected"; - case ISO_FILE_READ_ERROR: - return "Read error"; - case ISO_FILE_IS_NOT_DIR: - return "Not dir used where a dir is expected"; - case ISO_FILE_IS_NOT_SYMLINK: - return "Not symlink used where a symlink is expected"; - case ISO_FILE_SEEK_ERROR: - return "Can't seek to specified location"; - case ISO_FILE_IGNORED: - return "File not supported in ECMA-119 tree and thus ignored"; - case ISO_FILE_TOO_BIG: - return "A file is bigger than supported by used standard"; - case ISO_FILE_CANT_WRITE: - return "File read error during image creation"; - case ISO_FILENAME_WRONG_CHARSET: - return "Can't convert filename to requested charset"; - case ISO_FILE_CANT_ADD: - return "File can't be added to the tree"; - case ISO_FILE_IMGPATH_WRONG: - return "File path break specification constraints and will be ignored"; - case ISO_CHARSET_CONV_ERROR: - return "Charset conversion error"; - case ISO_MANGLE_TOO_MUCH_FILES: - return "Too much files to mangle, can't guarantee unique file names"; - case ISO_WRONG_PVD: - return "Wrong or damaged Primary Volume Descriptor"; - case ISO_WRONG_RR: - return "Wrong or damaged RR entry"; - case ISO_UNSUPPORTED_RR: - return "Unsupported RR feature"; - case ISO_WRONG_ECMA119: - return "Wrong or damaged ECMA-119"; - case ISO_UNSUPPORTED_ECMA119: - return "Unsupported ECMA-119 feature"; - case ISO_WRONG_EL_TORITO: - return "Wrong or damaged El-Torito catalog"; - case ISO_UNSUPPORTED_EL_TORITO: - return "Unsupported El-Torito feature"; - case ISO_ISOLINUX_CANT_PATCH: - return "Can't patch isolinux boot image"; - case ISO_UNSUPPORTED_SUSP: - return "Unsupported SUSP feature"; - case ISO_WRONG_RR_WARN: - return "Error on a RR entry that can be ignored"; - case ISO_SUSP_UNHANDLED: - return "Error on a RR entry that can be ignored"; - case ISO_SUSP_MULTIPLE_ER: - return "Multiple ER SUSP entries found"; - case ISO_UNSUPPORTED_VD: - return "Unsupported volume descriptor found"; - case ISO_EL_TORITO_WARN: - return "El-Torito related warning"; - case ISO_IMAGE_WRITE_CANCELED: - return "Image write cancelled"; - case ISO_EL_TORITO_HIDDEN: - return "El-Torito image is hidden"; - default: - return "Unknown error"; - } -} - -int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...) -{ - char msg[MAX_MSG_LEN]; - va_list ap; - - /* when called with ISO_CANCELED, we don't need to submit any message */ - if (errcode == ISO_CANCELED && fmt == NULL) { - return ISO_CANCELED; - } - - if (fmt) { - va_start(ap, fmt); - vsnprintf(msg, MAX_MSG_LEN, fmt, ap); - va_end(ap); - } else { - strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN); - } - - libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(errcode), - ISO_ERR_SEV(errcode), ISO_ERR_PRIO(errcode), msg, 0, 0); - if (causedby != 0) { - snprintf(msg, MAX_MSG_LEN, " > Caused by: %s", - iso_error_to_msg(causedby)); - libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(causedby), - LIBISO_MSGS_SEV_NOTE, LIBISO_MSGS_PRIO_LOW, msg, 0, 0); - if (ISO_ERR_SEV(causedby) == LIBISO_MSGS_SEV_FATAL) { - return ISO_CANCELED; - } - } - - if (ISO_ERR_SEV(errcode) >= abort_threshold) { - return ISO_CANCELED; - } else { - return 0; - } -} - -/** - * Control queueing and stderr printing of messages from libisofs. - * Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - * "NOTE", "UPDATE", "DEBUG", "ALL". - * - * @param queue_severity Gives the minimum limit for messages to be queued. - * Default: "NEVER". If you queue messages then you - * must consume them by iso_msgs_obtain(). - * @param print_severity Does the same for messages to be printed directly - * to stderr. - * @param print_id A text prefix to be printed before the message. - * @return >0 for success, <=0 for error - */ -int iso_set_msgs_severities(char *queue_severity, char *print_severity, - char *print_id) -{ - int ret, queue_sevno, print_sevno; - - ret = libiso_msgs__text_to_sev(queue_severity, &queue_sevno, 0); - if (ret <= 0) - return 0; - ret = libiso_msgs__text_to_sev(print_severity, &print_sevno, 0); - if (ret <= 0) - return 0; - ret = libiso_msgs_set_severities(libiso_msgr, queue_sevno, print_sevno, - print_id, 0); - if (ret <= 0) - return 0; - return 1; -} - -/** - * Obtain the oldest pending libisofs message from the queue which has at - * least the given minimum_severity. This message and any older message of - * lower severity will get discarded from the queue and is then lost forever. - * - * Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - * "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" - * will discard the whole queue. - * - * @param error_code Will become a unique error code as listed in messages.h - * @param imgid Id of the image that was issued the message. - * @param msg_text Must provide at least ISO_MSGS_MESSAGE_LEN bytes. - * @param severity Will become the severity related to the message and - * should provide at least 80 bytes. - * @return 1 if a matching item was found, 0 if not, <0 for severe errors - */ -int iso_obtain_msgs(char *minimum_severity, int *error_code, int *imgid, - char msg_text[], char severity[]) -{ - int ret, minimum_sevno, sevno, priority, os_errno; - double timestamp; - pid_t pid; - char *textpt, *sev_name; - struct libiso_msgs_item *item= NULL; - - ret = libiso_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0); - if (ret <= 0) - return 0; - ret = libiso_msgs_obtain(libiso_msgr, &item, minimum_sevno, - LIBISO_MSGS_PRIO_ZERO, 0); - if (ret <= 0) - goto ex; - ret = libiso_msgs_item_get_msg(item, error_code, &textpt, &os_errno, 0); - if (ret <= 0) - goto ex; - strncpy(msg_text, textpt, ISO_MSGS_MESSAGE_LEN-1); - if (strlen(textpt) >= ISO_MSGS_MESSAGE_LEN) - msg_text[ISO_MSGS_MESSAGE_LEN-1] = 0; - - ret = libiso_msgs_item_get_origin(item, ×tamp, &pid, imgid, 0); - if (ret <= 0) - goto ex; - - severity[0]= 0; - ret = libiso_msgs_item_get_rank(item, &sevno, &priority, 0); - if (ret <= 0) - goto ex; - ret = libiso_msgs__sev_to_text(sevno, &sev_name, 0); - if (ret <= 0) - goto ex; - strcpy(severity, sev_name); - - ret = 1; - ex: ; - libiso_msgs_destroy_item(libiso_msgr, &item, 0); - return ret; -} - - -/* ts A80222 : derived from libburn/init.c:burn_msgs_submit() -*/ -int iso_msgs_submit(int error_code, char msg_text[], int os_errno, - char severity[], int origin) -{ - int ret, sevno; - - ret = libiso_msgs__text_to_sev(severity, &sevno, 0); - if (ret <= 0) - sevno = LIBISO_MSGS_SEV_ALL; - if (error_code <= 0) { - switch(sevno) { - case LIBISO_MSGS_SEV_ABORT: error_code = 0x00040000; - break; case LIBISO_MSGS_SEV_FATAL: error_code = 0x00040001; - break; case LIBISO_MSGS_SEV_SORRY: error_code = 0x00040002; - break; case LIBISO_MSGS_SEV_WARNING: error_code = 0x00040003; - break; case LIBISO_MSGS_SEV_HINT: error_code = 0x00040004; - break; case LIBISO_MSGS_SEV_NOTE: error_code = 0x00040005; - break; case LIBISO_MSGS_SEV_UPDATE: error_code = 0x00040006; - break; case LIBISO_MSGS_SEV_DEBUG: error_code = 0x00040007; - break; default: error_code = 0x00040008; - } - } - ret = libiso_msgs_submit(libiso_msgr, origin, error_code, - sevno, LIBISO_MSGS_PRIO_HIGH, msg_text, os_errno, 0); - return ret; -} - - -/* ts A80222 : derived from libburn/init.c:burn_text_to_sev() -*/ -int iso_text_to_sev(char *severity_name, int *sevno) -{ - int ret; - - ret = libiso_msgs__text_to_sev(severity_name, sevno, 0); - if (ret <= 0) - *sevno = LIBISO_MSGS_SEV_FATAL; - return ret; -} - - -/* ts A80222 : derived from libburn/init.c:burn_sev_to_text() -*/ -int iso_sev_to_text(int severity_number, char **severity_name) -{ - int ret; - - ret = libiso_msgs__sev_to_text(severity_number, severity_name, 0); - return ret; -} - - -/** - * Return the messenger object handle used by libisofs. This handle - * may be used by related libraries to their own compatible - * messenger objects and thus to direct their messages to the libisofs - * message queue. See also: libburn, API function burn_set_messenger(). - * - * @return the handle. Do only use with compatible - */ -void *iso_get_messenger() -{ - return libiso_msgr; -} - -int iso_error_get_severity(int e) -{ - return ISO_ERR_SEV(e); -} - -int iso_error_get_priority(int e) -{ - return ISO_ERR_PRIO(e); -} - -int iso_error_get_code(int e) -{ - return ISO_ERR_CODE(e); -} - - -/* ts A80222 */ -int iso_report_errfile(char *path, int error_code, int os_errno, int flag) -{ - libiso_msgs_submit(libiso_msgr, 0, error_code, - LIBISO_MSGS_SEV_ERRFILE, LIBISO_MSGS_PRIO_HIGH, - path, os_errno, 0); - return(1); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.h deleted file mode 100644 index dc8b98c2..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/messages.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * Message handling for libisofs - */ - -#ifndef MESSAGES_H_ -#define MESSAGES_H_ - -/** - * Take and increment this variable to get a valid identifier for message - * origin. - */ -extern int iso_message_id; - -/** - * Submit a debug message. - */ -void iso_msg_debug(int imgid, const char *fmt, ...); - -/** - * - * @param errcode - * The error code. - * @param causedby - * Error that was caused the errcode. If this error is a FATAL error, - * < 0 will be returned in any case. Use 0 if there is no previous - * cause for the error. - * @return - * 1 on success, < 0 if function must abort asap. - */ -int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...); - - -/* ts A80222 */ -/* To be called with events which report incidents with individual input - files from the local filesystem. Not with image nodes, files containing an - image or similar file-like objects. -*/ -int iso_report_errfile(char *path, int error_code, int os_errno, int flag); - - -#endif /*MESSAGES_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.c deleted file mode 100644 index 95a0095e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.c +++ /dev/null @@ -1,1171 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "node.h" -#include "stream.h" - -#include -#include -#include -#include - -struct dir_iter_data -{ - /* points to the last visited child, to NULL before start */ - IsoNode *pos; - - /* Some control flags. - * bit 0 -> 1 if next called, 0 reseted at start or on deletion - */ - int flag; -}; - -/** - * Increments the reference counting of the given node. - */ -void iso_node_ref(IsoNode *node) -{ - ++node->refcount; -} - -/** - * Decrements the reference couting of the given node. - * If it reach 0, the node is free, and, if the node is a directory, - * its children will be unref() too. - */ -void iso_node_unref(IsoNode *node) -{ - if (--node->refcount == 0) { - switch (node->type) { - case LIBISO_DIR: - { - IsoNode *child = ((IsoDir*)node)->children; - while (child != NULL) { - IsoNode *tmp = child->next; - child->parent = NULL; - iso_node_unref(child); - child = tmp; - } - } - break; - case LIBISO_FILE: - { - IsoFile *file = (IsoFile*) node; - iso_stream_unref(file->stream); - } - break; - case LIBISO_SYMLINK: - { - IsoSymlink *link = (IsoSymlink*) node; - free(link->dest); - } - default: - /* other kind of nodes does not need to delete anything here */ - break; - } - -#ifdef LIBISO_EXTENDED_INFORMATION - if (node->xinfo) { - /* free extended info */ - node->xinfo->process(node->xinfo->data, 1); - free(node->xinfo); - } -#endif - free(node->name); - free(node); - } -} - -/** - * Get the type of an IsoNode. - */ -enum IsoNodeType iso_node_get_type(IsoNode *node) -{ - return node->type; -} - -/** - * Set the name of a node. - * - * @param name The name in UTF-8 encoding - */ -int iso_node_set_name(IsoNode *node, const char *name) -{ - char *new; - - if ((IsoNode*)node->parent == node) { - /* you can't change name of the root node */ - return ISO_WRONG_ARG_VALUE; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - if (node->parent != NULL) { - /* check if parent already has a node with same name */ - if (iso_dir_get_node(node->parent, name, NULL) == 1) { - return ISO_NODE_NAME_NOT_UNIQUE; - } - } - - new = strdup(name); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - free(node->name); - node->name = new; - if (node->parent != NULL) { - IsoDir *parent; - int res; - /* take and add again to ensure correct children order */ - parent = node->parent; - iso_node_take(node); - res = iso_dir_add_node(parent, node, 0); - if (res < 0) { - return res; - } - } - return ISO_SUCCESS; -} - -/** - * Get the name of a node (in UTF-8). - * The returned string belongs to the node and should not be modified nor - * freed. Use strdup if you really need your own copy. - */ -const char *iso_node_get_name(const IsoNode *node) -{ - return node->name; -} - -/** - * Set the permissions for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - * - * @param mode - * bitmask with the permissions of the node, as specified in 'man 2 stat'. - * The file type bitfields will be ignored, only file permissions will be - * modified. - */ -void iso_node_set_permissions(IsoNode *node, mode_t mode) -{ - node->mode = (node->mode & S_IFMT) | (mode & ~S_IFMT); -} - -/** - * Get the permissions for the node - */ -mode_t iso_node_get_permissions(const IsoNode *node) -{ - return node->mode & ~S_IFMT; -} - -/** - * Get the mode of the node, both permissions and file type, as specified in - * 'man 2 stat'. - */ -mode_t iso_node_get_mode(const IsoNode *node) -{ - return node->mode; -} - -/** - * Set the user id for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - */ -void iso_node_set_uid(IsoNode *node, uid_t uid) -{ - node->uid = uid; -} - -/** - * Get the user id of the node. - */ -uid_t iso_node_get_uid(const IsoNode *node) -{ - return node->uid; -} - -/** - * Set the group id for the node. This attribute is only useful when - * Rock Ridge extensions are enabled. - */ -void iso_node_set_gid(IsoNode *node, gid_t gid) -{ - node->gid = gid; -} - -/** - * Get the group id of the node. - */ -gid_t iso_node_get_gid(const IsoNode *node) -{ - return node->gid; -} - -/** - * Set the time of last modification of the file - */ -void iso_node_set_mtime(IsoNode *node, time_t time) -{ - node->mtime = time; -} - -/** - * Get the time of last modification of the file - */ -time_t iso_node_get_mtime(const IsoNode *node) -{ - return node->mtime; -} - -/** - * Set the time of last access to the file - */ -void iso_node_set_atime(IsoNode *node, time_t time) -{ - node->atime = time; -} - -/** - * Get the time of last access to the file - */ -time_t iso_node_get_atime(const IsoNode *node) -{ - return node->atime; -} - -/** - * Set the time of last status change of the file - */ -void iso_node_set_ctime(IsoNode *node, time_t time) -{ - node->ctime = time; -} - -/** - * Get the time of last status change of the file - */ -time_t iso_node_get_ctime(const IsoNode *node) -{ - return node->ctime; -} - -void iso_node_set_hidden(IsoNode *node, int hide_attrs) -{ - /* you can't hide root node */ - if ((IsoNode*)node->parent != node) { - node->hidden = hide_attrs; - } -} - -/** - * Add a new node to a dir. Note that this function don't add a new ref to - * the node, so you don't need to free it, it will be automatically freed - * when the dir is deleted. Of course, if you want to keep using the node - * after the dir life, you need to iso_node_ref() it. - * - * @param dir - * the dir where to add the node - * @param child - * the node to add. You must ensure that the node hasn't previously added - * to other dir, and that the node name is unique inside the child. - * Otherwise this function will return a failure, and the child won't be - * inserted. - * @param replace - * if the dir already contains a node with the same name, whether to - * replace or not the old node with this. - * @return - * number of nodes in dir if succes, < 0 otherwise - */ -int iso_dir_add_node(IsoDir *dir, IsoNode *child, - enum iso_replace_mode replace) -{ - IsoNode **pos; - - if (dir == NULL || child == NULL) { - return ISO_NULL_POINTER; - } - if ((IsoNode*)dir == child) { - return ISO_WRONG_ARG_VALUE; - } - - /* - * check if child is already added to another dir, or if child - * is the root node, where parent == itself - */ - if (child->parent != NULL || child->parent == (IsoDir*)child) { - return ISO_NODE_ALREADY_ADDED; - } - - iso_dir_find(dir, child->name, &pos); - return iso_dir_insert(dir, child, pos, replace); -} - -/** - * Locate a node inside a given dir. - * - * @param name - * The name of the node - * @param node - * Location for a pointer to the node, it will filled with NULL if the dir - * doesn't have a child with the given name. - * The node will be owned by the dir and shouldn't be unref(). Just call - * iso_node_ref() to get your own reference to the node. - * Note that you can pass NULL is the only thing you want to do is check - * if a node with such name already exists on dir. - * @return - * 1 node found, 0 child has no such node, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if dir or name are NULL - */ -int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node) -{ - int ret; - IsoNode **pos; - if (dir == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - - ret = iso_dir_exists(dir, name, &pos); - if (ret == 0) { - if (node) { - *node = NULL; - } - return 0; /* node not found */ - } - - if (node) { - *node = *pos; - } - return 1; -} - -/** - * Get the number of children of a directory. - * - * @return - * >= 0 number of items, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if dir is NULL - */ -int iso_dir_get_children_count(IsoDir *dir) -{ - if (dir == NULL) { - return ISO_NULL_POINTER; - } - return dir->nchildren; -} - -static -int iter_next(IsoDirIter *iter, IsoNode **node) -{ - struct dir_iter_data *data; - if (iter == NULL || node == NULL) { - return ISO_NULL_POINTER; - } - - data = iter->data; - - /* clear next flag */ - data->flag &= ~0x01; - - if (data->pos == NULL) { - /* we are at the beginning */ - data->pos = iter->dir->children; - if (data->pos == NULL) { - /* empty dir */ - *node = NULL; - return 0; - } - } else { - if (data->pos->parent != iter->dir) { - /* this can happen if the node has been moved to another dir */ - /* TODO specific error */ - return ISO_ERROR; - } - if (data->pos->next == NULL) { - /* no more children */ - *node = NULL; - return 0; - } else { - /* free reference to current position */ - iso_node_unref(data->pos); /* it is never last ref!! */ - - /* advance a position */ - data->pos = data->pos->next; - } - } - - /* ok, take a ref to the current position, to prevent internal errors - * if deleted somewhere */ - iso_node_ref(data->pos); - data->flag |= 0x01; /* set next flag */ - - /* return pointed node */ - *node = data->pos; - return ISO_SUCCESS; -} - -/** - * Check if there're more children. - * - * @return - * 1 dir has more elements, 0 no, < 0 error - * Possible errors: - * ISO_NULL_POINTER, if iter is NULL - */ -static -int iter_has_next(IsoDirIter *iter) -{ - struct dir_iter_data *data; - if (iter == NULL) { - return ISO_NULL_POINTER; - } - data = iter->data; - if (data->pos == NULL) { - return iter->dir->children == NULL ? 0 : 1; - } else { - return data->pos->next == NULL ? 0 : 1; - } -} - -static -void iter_free(IsoDirIter *iter) -{ - struct dir_iter_data *data; - data = iter->data; - if (data->pos != NULL) { - iso_node_unref(data->pos); - } - free(data); -} - -static IsoNode** iso_dir_find_node(IsoDir *dir, IsoNode *node) -{ - IsoNode **pos; - pos = &(dir->children); - while (*pos != NULL && *pos != node) { - pos = &((*pos)->next); - } - return pos; -} - -/** - * Removes a child from a directory. - * The child is not freed, so you will become the owner of the node. Later - * you can add the node to another dir (calling iso_dir_add_node), or free - * it if you don't need it (with iso_node_unref). - * - * @return - * 1 on success, < 0 error - */ -int iso_node_take(IsoNode *node) -{ - IsoNode **pos; - IsoDir* dir; - - if (node == NULL) { - return ISO_NULL_POINTER; - } - dir = node->parent; - if (dir == NULL) { - return ISO_NODE_NOT_ADDED_TO_DIR; - } - pos = iso_dir_find_node(dir, node); - if (pos == NULL) { - /* should never occur */ - return ISO_ASSERT_FAILURE; - } - - /* notify iterators just before remove */ - iso_notify_dir_iters(node, 0); - - *pos = node->next; - node->parent = NULL; - node->next = NULL; - dir->nchildren--; - return ISO_SUCCESS; -} - -/** - * Removes a child from a directory and free (unref) it. - * If you want to keep the child alive, you need to iso_node_ref() it - * before this call, but in that case iso_node_take() is a better - * alternative. - * - * @return - * 1 on success, < 0 error - */ -int iso_node_remove(IsoNode *node) -{ - int ret; - ret = iso_node_take(node); - if (ret == ISO_SUCCESS) { - iso_node_unref(node); - } - return ret; -} - -/* - * Get the parent of the given iso tree node. No extra ref is added to the - * returned directory, you must take your ref. with iso_node_ref() if you - * need it. - * - * If node is the root node, the same node will be returned as its parent. - * - * This returns NULL if the node doesn't pertain to any tree - * (it was removed/take). - */ -IsoDir *iso_node_get_parent(IsoNode *node) -{ - return node->parent; -} - -/* TODO #00005 optimize iso_dir_iter_take */ -static -int iter_take(IsoDirIter *iter) -{ - struct dir_iter_data *data; - if (iter == NULL) { - return ISO_NULL_POINTER; - } - - data = iter->data; - - if (!(data->flag & 0x01)) { - return ISO_ERROR; /* next not called or end of dir */ - } - - if (data->pos == NULL) { - return ISO_ASSERT_FAILURE; - } - - /* clear next flag */ - data->flag &= ~0x01; - - return iso_node_take(data->pos); -} - -static -int iter_remove(IsoDirIter *iter) -{ - int ret; - IsoNode *pos; - struct dir_iter_data *data; - - if (iter == NULL) { - return ISO_NULL_POINTER; - } - data = iter->data; - pos = data->pos; - - ret = iter_take(iter); - if (ret == ISO_SUCCESS) { - /* remove node */ - iso_node_unref(pos); - } - return ret; -} - -void iter_notify_child_taken(IsoDirIter *iter, IsoNode *node) -{ - IsoNode *pos, *pre; - struct dir_iter_data *data; - data = iter->data; - - if (data->pos == node) { - pos = iter->dir->children; - pre = NULL; - while (pos != NULL && pos != data->pos) { - pre = pos; - pos = pos->next; - } - if (pos == NULL || pos != data->pos) { - return; - } - - /* dispose iterator reference */ - iso_node_unref(data->pos); - - if (pre == NULL) { - /* node is a first position */ - iter->dir->children = pos->next; - data->pos = NULL; - } else { - pre->next = pos->next; - data->pos = pre; - iso_node_ref(pre); /* take iter ref */ - } - } -} - -static -struct iso_dir_iter_iface iter_class = { - iter_next, - iter_has_next, - iter_free, - iter_take, - iter_remove, - iter_notify_child_taken -}; - -int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter) -{ - IsoDirIter *it; - struct dir_iter_data *data; - - if (dir == NULL || iter == NULL) { - return ISO_NULL_POINTER; - } - it = malloc(sizeof(IsoDirIter)); - if (it == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(struct dir_iter_data)); - if (data == NULL) { - free(it); - return ISO_OUT_OF_MEM; - } - - it->class = &iter_class; - it->dir = (IsoDir*)dir; - data->pos = NULL; - data->flag = 0x00; - it->data = data; - - if (iso_dir_iter_register(it) < 0) { - free(it); - return ISO_OUT_OF_MEM; - } - - *iter = it; - return ISO_SUCCESS; -} - -int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node) -{ - if (iter == NULL || node == NULL) { - return ISO_NULL_POINTER; - } - return iter->class->next(iter, node); -} - -int iso_dir_iter_has_next(IsoDirIter *iter) -{ - if (iter == NULL) { - return ISO_NULL_POINTER; - } - return iter->class->has_next(iter); -} - -void iso_dir_iter_free(IsoDirIter *iter) -{ - if (iter != NULL) { - iso_dir_iter_unregister(iter); - iter->class->free(iter); - free(iter); - } -} - -int iso_dir_iter_take(IsoDirIter *iter) -{ - if (iter == NULL) { - return ISO_NULL_POINTER; - } - return iter->class->take(iter); -} - -int iso_dir_iter_remove(IsoDirIter *iter) -{ - if (iter == NULL) { - return ISO_NULL_POINTER; - } - return iter->class->remove(iter); -} - -/** - * Get the destination of a node. - * The returned string belongs to the node and should not be modified nor - * freed. Use strdup if you really need your own copy. - */ -const char *iso_symlink_get_dest(const IsoSymlink *link) -{ - return link->dest; -} - -/** - * Set the destination of a link. - */ -int iso_symlink_set_dest(IsoSymlink *link, const char *dest) -{ - char *d; - if (!iso_node_is_valid_link_dest(dest)) { - /* guard against null or empty dest */ - return ISO_WRONG_ARG_VALUE; - } - d = strdup(dest); - if (d == NULL) { - return ISO_OUT_OF_MEM; - } - free(link->dest); - link->dest = d; - return ISO_SUCCESS; -} - -/** - * Sets the order in which a node will be written on image. High weihted files - * will be written first, so in a disc them will be written near the center. - * - * @param node - * The node which weight will be changed. If it's a dir, this function - * will change the weight of all its children. For nodes other that dirs - * or regular files, this function has no effect. - * @param w - * The weight as a integer number, the greater this value is, the - * closer from the begining of image the file will be written. - */ -void iso_node_set_sort_weight(IsoNode *node, int w) -{ - if (node->type == LIBISO_DIR) { - IsoNode *child = ((IsoDir*)node)->children; - while (child) { - iso_node_set_sort_weight(child, w); - child = child->next; - } - } else if (node->type == LIBISO_FILE) { - ((IsoFile*)node)->sort_weight = w; - } -} - -/** - * Get the sort weight of a file. - */ -int iso_file_get_sort_weight(IsoFile *file) -{ - return file->sort_weight; -} - -/** - * Get the size of the file, in bytes - */ -off_t iso_file_get_size(IsoFile *file) -{ - return iso_stream_get_size(file->stream); -} - -/** - * Get the IsoStream that represents the contents of the given IsoFile. - * - * If you open() the stream, it should be close() before image generation. - * - * @return - * The IsoStream. No extra ref is added, so the IsoStream belong to the - * IsoFile, and it may be freed together with it. Add your own ref with - * iso_stream_ref() if you need it. - * - * @since 0.6.4 - */ -IsoStream *iso_file_get_stream(IsoFile *file) -{ - return file->stream; -} - -/** - * Get the block lba of a file node, if it was imported from an old image. - * - * @param file - * The file - * @param lba - * Will be filled with the kba - * @param flag - * Reserved for future usage, submit 0 - * @return - * 1 if lba is valid (file comes from old image), 0 if file was newly - * added, i.e. it does not come from an old image, < 0 error - * - * @since 0.6.4 - */ -int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag) -{ - if (file == NULL || lba == NULL) { - return ISO_NULL_POINTER; - } - if (flag != 0) { - return ISO_WRONG_ARG_VALUE; - } - if (file->msblock != 0) { - *lba = file->msblock; - return 1; - } - return 0; -} - -/* - * Like iso_file_get_old_image_lba(), but take an IsoNode. - * - * @return - * 1 if lba is valid (file comes from old image), 0 if file was newly - * added, i.e. it does not come from an old image, 2 node type has no - * LBA (no regular file), < 0 error - * - * @since 0.6.4 - */ -int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag) -{ - if (node == NULL) { - return ISO_NULL_POINTER; - } - if (ISO_NODE_IS_FILE(node)) { - return iso_file_get_old_image_lba((IsoFile*)node, lba, flag); - } else { - return 2; - } -} - -/** - * Check if a given name is valid for an iso node. - * - * @return - * 1 if yes, 0 if not - */ -int iso_node_is_valid_name(const char *name) -{ - /* a name can't be NULL */ - if (name == NULL) { - return 0; - } - - /* guard against the empty string or big names... */ - if (name[0] == '\0' || strlen(name) > 255) { - return 0; - } - - /* ...against "." and ".." names... */ - if (!strcmp(name, ".") || !strcmp(name, "..")) { - return 0; - } - - /* ...and against names with '/' */ - if (strchr(name, '/') != NULL) { - return 0; - } - return 1; -} - -/** - * Check if a given path is valid for the destination of a link. - * - * @return - * 1 if yes, 0 if not - */ -int iso_node_is_valid_link_dest(const char *dest) -{ - int ret; - char *ptr, *brk_info, *component; - - /* a dest can't be NULL */ - if (dest == NULL) { - return 0; - } - - /* guard against the empty string or big dest... */ - if (dest[0] == '\0' || strlen(dest) > PATH_MAX) { - return 0; - } - - /* check that all components are valid */ - if (!strcmp(dest, "/")) { - /* "/" is a valid component */ - return 1; - } - - ptr = strdup(dest); - if (ptr == NULL) { - return 0; - } - - ret = 1; - component = strtok_r(ptr, "/", &brk_info); - while (component) { - if (strcmp(component, ".") && strcmp(component, "..")) { - ret = iso_node_is_valid_name(component); - if (ret == 0) { - break; - } - } - component = strtok_r(NULL, "/", &brk_info); - } - free(ptr); - - return ret; -} - -void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos) -{ - *pos = &(dir->children); - while (**pos != NULL && strcmp((**pos)->name, name) < 0) { - *pos = &((**pos)->next); - } -} - -int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos) -{ - IsoNode **node; - - iso_dir_find(dir, name, &node); - if (pos) { - *pos = node; - } - return (*node != NULL && !strcmp((*node)->name, name)) ? 1 : 0; -} - -int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos, - enum iso_replace_mode replace) -{ - if (*pos != NULL && !strcmp((*pos)->name, node->name)) { - /* a node with same name already exists */ - switch(replace) { - case ISO_REPLACE_NEVER: - return ISO_NODE_NAME_NOT_UNIQUE; - case ISO_REPLACE_IF_NEWER: - if ((*pos)->mtime >= node->mtime) { - /* old file is newer */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - break; - case ISO_REPLACE_IF_SAME_TYPE_AND_NEWER: - if ((*pos)->mtime >= node->mtime) { - /* old file is newer */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - /* fall down */ - case ISO_REPLACE_IF_SAME_TYPE: - if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) { - /* different file types */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - break; - case ISO_REPLACE_ALWAYS: - break; - default: - /* CAN'T HAPPEN */ - return ISO_ASSERT_FAILURE; - } - - /* if we are reach here we have to replace */ - node->next = (*pos)->next; - (*pos)->parent = NULL; - (*pos)->next = NULL; - iso_node_unref(*pos); - *pos = node; - node->parent = dir; - return dir->nchildren; - } - - node->next = *pos; - *pos = node; - node->parent = dir; - - return ++dir->nchildren; -} - -/* iterators are stored in a linked list */ -struct iter_reg_node { - IsoDirIter *iter; - struct iter_reg_node *next; -}; - -/* list header */ -static -struct iter_reg_node *iter_reg = NULL; - -/** - * Add a new iterator to the registry. The iterator register keeps track of - * all iterators being used, and are notified when directory structure - * changes. - */ -int iso_dir_iter_register(IsoDirIter *iter) -{ - struct iter_reg_node *new; - new = malloc(sizeof(struct iter_reg_node)); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - new->iter = iter; - new->next = iter_reg; - iter_reg = new; - return ISO_SUCCESS; -} - -/** - * Unregister a directory iterator. - */ -void iso_dir_iter_unregister(IsoDirIter *iter) -{ - struct iter_reg_node **pos; - pos = &iter_reg; - while (*pos != NULL && (*pos)->iter != iter) { - pos = &(*pos)->next; - } - if (*pos) { - struct iter_reg_node *tmp = (*pos)->next; - free(*pos); - *pos = tmp; - } -} - -void iso_notify_dir_iters(IsoNode *node, int flag) -{ - struct iter_reg_node *pos = iter_reg; - while (pos != NULL) { - IsoDirIter *iter = pos->iter; - if (iter->dir == node->parent) { - iter->class->notify_child_taken(iter, node); - } - pos = pos->next; - } -} - -int iso_node_new_root(IsoDir **root) -{ - IsoDir *dir; - - dir = calloc(1, sizeof(IsoDir)); - if (dir == NULL) { - return ISO_OUT_OF_MEM; - } - dir->node.refcount = 1; - dir->node.type = LIBISO_DIR; - dir->node.atime = dir->node.ctime = dir->node.mtime = time(NULL); - dir->node.mode = S_IFDIR | 0555; - - /* set parent to itself, to prevent root to be added to another dir */ - dir->node.parent = dir; - *root = dir; - return ISO_SUCCESS; -} - -int iso_node_new_dir(char *name, IsoDir **dir) -{ - IsoDir *new; - - if (dir == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - new = calloc(1, sizeof(IsoDir)); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - new->node.refcount = 1; - new->node.type = LIBISO_DIR; - new->node.name = name; - new->node.mode = S_IFDIR; - *dir = new; - return ISO_SUCCESS; -} - -int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file) -{ - IsoFile *new; - - if (file == NULL || name == NULL || stream == NULL) { - return ISO_NULL_POINTER; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - new = calloc(1, sizeof(IsoFile)); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - new->node.refcount = 1; - new->node.type = LIBISO_FILE; - new->node.name = name; - new->node.mode = S_IFREG; - new->stream = stream; - - *file = new; - return ISO_SUCCESS; -} - -int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link) -{ - IsoSymlink *new; - - if (link == NULL || name == NULL || dest == NULL) { - return ISO_NULL_POINTER; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - /* check if destination is valid */ - if (!iso_node_is_valid_link_dest(dest)) { - /* guard against null or empty dest */ - return ISO_WRONG_ARG_VALUE; - } - - new = calloc(1, sizeof(IsoSymlink)); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - new->node.refcount = 1; - new->node.type = LIBISO_SYMLINK; - new->node.name = name; - new->dest = dest; - new->node.mode = S_IFLNK; - *link = new; - return ISO_SUCCESS; -} - -int iso_node_new_special(char *name, mode_t mode, dev_t dev, - IsoSpecial **special) -{ - IsoSpecial *new; - - if (special == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - if (S_ISLNK(mode) || S_ISREG(mode) || S_ISDIR(mode)) { - return ISO_WRONG_ARG_VALUE; - } - - /* check if the name is valid */ - if (!iso_node_is_valid_name(name)) { - return ISO_WRONG_ARG_VALUE; - } - - new = calloc(1, sizeof(IsoSpecial)); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - new->node.refcount = 1; - new->node.type = LIBISO_SPECIAL; - new->node.name = name; - - new->node.mode = mode; - new->dev = dev; - - *special = new; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.h deleted file mode 100644 index dd13469f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/node.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_NODE_H_ -#define LIBISO_NODE_H_ - -/* - * Definitions for the public iso tree - */ - -#include "libisofs.h" -#include "stream.h" - -#include -#include -#include -#include - -/* #define LIBISO_EXTENDED_INFORMATION */ -#ifdef LIBISO_EXTENDED_INFORMATION - -/** - * The extended information is a way to attach additional information to each - * IsoNode. External applications may want to use this extension system to - * store application speficic information related to each node. On the other - * side, libisofs may make use of this struct to attach information to nodes in - * some particular, uncommon, cases, without incrementing the size of the - * IsoNode struct. - * - * It is implemented like a chained list. - */ -typedef struct iso_extended_info IsoExtendedInfo; - -struct iso_extended_info { - /** - * Next struct in the chain. NULL if it is the last item - */ - IsoExtendedInfo *next; - - /** - * Function to handle this particular extended information. The function - * pointer acts as an identifier for the type of the information. Structs - * with same information type must use the same function. - * - * @param data - * Attached data - * @param flag - * What to do with the data. At this time the following values are - * defined: - * -> 1 the data must be freed - * @return - * 1 - */ - int (*process)(void *data, int flag); - - /** - * Pointer to information specific data. - */ - void *data; -}; - -#endif - -/** - * - */ -struct Iso_Node -{ - /* - * Initilized to 1, originally owned by user, until added to another node. - * Then it is owned by the parent node, so the user must take his own ref - * if needed. With the exception of the creation functions, none of the - * other libisofs functions that return an IsoNode increment its - * refcount. This is responsablity of the client, if (s)he needs it. - */ - int refcount; - - /** Type of the IsoNode, do not confuse with mode */ - enum IsoNodeType type; - - char *name; /**< Real name, in default charset */ - - mode_t mode; /**< protection */ - uid_t uid; /**< user ID of owner */ - gid_t gid; /**< group ID of owner */ - - /* TODO #00001 : consider adding new timestamps */ - time_t atime; /**< time of last access */ - time_t mtime; /**< time of last modification */ - time_t ctime; /**< time of last status change */ - - int hidden; /**< whether the node will be hidden, see IsoHideNodeFlag */ - - IsoDir *parent; /**< parent node, NULL for root */ - - /* - * Pointer to the linked list of children in a dir. - */ - IsoNode *next; - -#ifdef LIBISO_EXTENDED_INFORMATION - /** - * Extended information for the node. - */ - IsoExtendedInfo *xinfo; -#endif -}; - -struct Iso_Dir -{ - IsoNode node; - - size_t nchildren; /**< The number of children of this directory. */ - IsoNode *children; /**< list of children. ptr to first child */ -}; - -struct Iso_File -{ - IsoNode node; - - /** - * Location of a file extent in a ms disc, 0 for newly added file - */ - uint32_t msblock; - - /** - * It sorts the order in which the file data is written to the CD image. - * Higher weighting files are written at the beginning of image - */ - int sort_weight; - IsoStream *stream; -}; - -struct Iso_Symlink -{ - IsoNode node; - - char *dest; -}; - -struct Iso_Special -{ - IsoNode node; - dev_t dev; -}; - -struct iso_dir_iter_iface -{ - - int (*next)(IsoDirIter *iter, IsoNode **node); - - int (*has_next)(IsoDirIter *iter); - - void (*free)(IsoDirIter *iter); - - int (*take)(IsoDirIter *iter); - - int (*remove)(IsoDirIter *iter); - - /** - * This is called just before remove a node from a directory. The iterator - * may want to update its internal state according to this. - */ - void (*notify_child_taken)(IsoDirIter *iter, IsoNode *node); -}; - -/** - * An iterator for directory children. - */ -struct Iso_Dir_Iter -{ - struct iso_dir_iter_iface *class; - - /* the directory this iterator iterates over */ - IsoDir *dir; - - void *data; -}; - -int iso_node_new_root(IsoDir **root); - -/** - * Create a new IsoDir. Attributes, uid/gid, timestamps, etc are set to - * default (0) values. You must set them. - * - * @param name - * Name for the node. It is not strdup() so you shouldn't use this - * reference when this function returns successfully. NULL is not - * allowed. - * @param dir - * - * @return - * 1 on success, < 0 on error. - */ -int iso_node_new_dir(char *name, IsoDir **dir); - -/** - * Create a new file node. Attributes, uid/gid, timestamps, etc are set to - * default (0) values. You must set them. - * - * @param name - * Name for the node. It is not strdup() so you shouldn't use this - * reference when this function returns successfully. NULL is not - * allowed. - * @param stream - * Source for file contents. The reference is taken by the node, - * you must call iso_stream_ref() if you need your own ref. - * @return - * 1 on success, < 0 on error. - */ -int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file); - -/** - * Creates a new IsoSymlink node. Attributes, uid/gid, timestamps, etc are set - * to default (0) values. You must set them. - * - * @param name - * name for the new symlink. It is not strdup() so you shouldn't use this - * reference when this function returns successfully. NULL is not - * allowed. - * @param dest - * destination of the link. It is not strdup() so you shouldn't use this - * reference when this function returns successfully. NULL is not - * allowed. - * @param link - * place where to store a pointer to the newly created link. - * @return - * 1 on success, < 0 otherwise - */ -int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link); - -/** - * Create a new special file node. As far as libisofs concerns, - * an special file is a block device, a character device, a FIFO (named pipe) - * or a socket. You can choose the specific kind of file you want to add - * by setting mode propertly (see man 2 stat). - * - * Note that special files are only written to image when Rock Ridge - * extensions are enabled. Moreover, a special file is just a directory entry - * in the image tree, no data is written beyond that. - * - * Owner and hidden atts are taken from parent. You can modify any of them - * later. - * - * @param name - * name for the new special file. It is not strdup() so you shouldn't use - * this reference when this function returns successfully. NULL is not - * allowed. - * @param mode - * file type and permissions for the new node. Note that you can't - * specify any kind of file here, only special types are allowed. i.e, - * S_IFSOCK, S_IFBLK, S_IFCHR and S_IFIFO are valid types; S_IFLNK, - * S_IFREG and S_IFDIR aren't. - * @param dev - * device ID, equivalent to the st_rdev field in man 2 stat. - * @param special - * place where to store a pointer to the newly created special file. - * @return - * 1 on success, < 0 otherwise - */ -int iso_node_new_special(char *name, mode_t mode, dev_t dev, - IsoSpecial **special); - -/** - * Check if a given name is valid for an iso node. - * - * @return - * 1 if yes, 0 if not - */ -int iso_node_is_valid_name(const char *name); - -/** - * Check if a given path is valid for the destination of a link. - * - * @return - * 1 if yes, 0 if not - */ -int iso_node_is_valid_link_dest(const char *dest); - -/** - * Find the position where to insert a node - * - * @param dir - * A valid dir. It can't be NULL - * @param name - * The node name to search for. It can't be NULL - * @param pos - * Will be filled with the position where to insert. It can't be NULL - */ -void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos); - -/** - * Check if a node with the given name exists in a dir. - * - * @param dir - * A valid dir. It can't be NULL - * @param name - * The node name to search for. It can't be NULL - * @param pos - * If not NULL, will be filled with the position where to insert. If the - * node exists, (**pos) will refer to the given node. - * @return - * 1 if node exists, 0 if not - */ -int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos); - -/** - * Inserts a given node in a dir, at the specified position. - * - * @param dir - * Dir where to insert. It can't be NULL - * @param node - * The node to insert. It can't be NULL - * @param pos - * Position where the node will be inserted. It is a pointer previously - * obtained with a call to iso_dir_exists() or iso_dir_find(). - * It can't be NULL. - * @param replace - * Whether to replace an old node with the same name with the new node. - * @return - * If success, number of children in dir. < 0 on error - */ -int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos, - enum iso_replace_mode replace); - -/** - * Add a new iterator to the registry. The iterator register keeps track of - * all iterators being used, and are notified when directory structure - * changes. - */ -int iso_dir_iter_register(IsoDirIter *iter); - -/** - * Unregister a directory iterator. - */ -void iso_dir_iter_unregister(IsoDirIter *iter); - -void iso_notify_dir_iters(IsoNode *node, int flag); - -#endif /*LIBISO_NODE_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.c deleted file mode 100644 index e57ed3d1..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.c +++ /dev/null @@ -1,1208 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "rockridge.h" -#include "node.h" -#include "ecma119_tree.h" -#include "writer.h" -#include "messages.h" -#include "image.h" - -#include - -static -int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data) -{ - susp->n_susp_fields++; - susp->susp_fields = realloc(susp->susp_fields, sizeof(void*) - * susp->n_susp_fields); - if (susp->susp_fields == NULL) { - return ISO_OUT_OF_MEM; - } - susp->susp_fields[susp->n_susp_fields - 1] = data; - susp->suf_len += data[2]; - return ISO_SUCCESS; -} - -static -int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data) -{ - susp->n_ce_susp_fields++; - susp->ce_susp_fields = realloc(susp->ce_susp_fields, sizeof(void*) - * susp->n_ce_susp_fields); - if (susp->ce_susp_fields == NULL) { - return ISO_OUT_OF_MEM; - } - susp->ce_susp_fields[susp->n_ce_susp_fields - 1] = data; - susp->ce_len += data[2]; - return ISO_SUCCESS; -} - -static -uid_t px_get_uid(Ecma119Image *t, Ecma119Node *n) -{ - if (t->replace_uid) { - return t->uid; - } else { - return n->node->uid; - } -} - -static -uid_t px_get_gid(Ecma119Image *t, Ecma119Node *n) -{ - if (t->replace_gid) { - return t->gid; - } else { - return n->node->gid; - } -} - -static -mode_t px_get_mode(Ecma119Image *t, Ecma119Node *n) -{ - if ((n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER)) { - if (t->replace_dir_mode) { - return (n->node->mode & S_IFMT) | t->dir_mode; - } - } else { - if (t->replace_file_mode) { - return (n->node->mode & S_IFMT) | t->file_mode; - } - } - return n->node->mode; -} - -/** - * Add a PX System Use Entry. The PX System Use Entry is used to add POSIX - * file attributes, such as access permissions or user and group id, to a - * ECMA 119 directory record. (RRIP, 4.1.1) - */ -static -int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - uint8_t *PX = malloc(44); - if (PX == NULL) { - return ISO_OUT_OF_MEM; - } - - PX[0] = 'P'; - PX[1] = 'X'; - PX[2] = 44; - PX[3] = 1; - iso_bb(&PX[4], px_get_mode(t, n), 4); - iso_bb(&PX[12], n->nlink, 4); - iso_bb(&PX[20], px_get_uid(t, n), 4); - iso_bb(&PX[28], px_get_gid(t, n), 4); - iso_bb(&PX[36], n->ino, 4); - - return susp_append(t, susp, PX); -} - -/** - * Add to the given tree node a TF System Use Entry, used to record some - * time stamps related to the file (RRIP, 4.1.6). - */ -static -int rrip_add_TF(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - IsoNode *iso; - uint8_t *TF = malloc(5 + 3 * 7); - if (TF == NULL) { - return ISO_OUT_OF_MEM; - } - - TF[0] = 'T'; - TF[1] = 'F'; - TF[2] = 5 + 3 * 7; - TF[3] = 1; - TF[4] = (1 << 1) | (1 << 2) | (1 << 3); - - iso = n->node; - iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime, - t->always_gmt); - iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime, - t->always_gmt); - iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime, - t->always_gmt); - return susp_append(t, susp, TF); -} - -/** - * Add a PL System Use Entry, used to record the location of the original - * parent directory of a directory which has been relocated. - * - * This is special because it doesn't modify the susp fields of the directory - * that gets passed to it; it modifies the susp fields of the ".." entry in - * that directory. - * - * See RRIP, 4.1.5.2 for more details. - */ -static -int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - uint8_t *PL; - - if (n->type != ECMA119_DIR || n->info.dir->real_parent == NULL) { - /* should never occur */ - return ISO_ASSERT_FAILURE; - } - - PL = malloc(12); - if (PL == NULL) { - return ISO_OUT_OF_MEM; - } - - PL[0] = 'P'; - PL[1] = 'L'; - PL[2] = 12; - PL[3] = 1; - - /* write the location of the real parent, already computed */ - iso_bb(&PL[4], n->info.dir->real_parent->info.dir->block, 4); - return susp_append(t, susp, PL); -} - -/** - * Add a RE System Use Entry to the given tree node. The purpose of the - * this System Use Entry is to indicate to an RRIP-compliant receiving - * system that the Directory Record in which an "RE" System Use Entry is - * recorded has been relocated from another position in the original - * Directory Hierarchy. - * - * See RRIP, 4.1.5.3 for more details. - */ -static -int rrip_add_RE(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - uint8_t *RE = malloc(4); - if (RE == NULL) { - return ISO_OUT_OF_MEM; - } - - RE[0] = 'R'; - RE[1] = 'E'; - RE[2] = 4; - RE[3] = 1; - return susp_append(t, susp, RE); -} - -/** - * Add a PN System Use Entry to the given tree node. - * The PN System Use Entry is used to store the device number, and it's - * mandatory if the tree node corresponds to a character or block device. - * - * See RRIP, 4.1.2 for more details. - */ -static -int rrip_add_PN(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - IsoSpecial *node; - uint8_t *PN; - - node = (IsoSpecial*)n->node; - if (node->node.type != LIBISO_SPECIAL) { - /* should never occur */ - return ISO_ASSERT_FAILURE; - } - - PN = malloc(20); - if (PN == NULL) { - return ISO_OUT_OF_MEM; - } - - PN[0] = 'P'; - PN[1] = 'N'; - PN[2] = 20; - PN[3] = 1; - iso_bb(&PN[4], node->dev >> 32, 4); - iso_bb(&PN[12], node->dev & 0xffffffff, 4); - return susp_append(t, susp, PN); -} - -/** - * Add to the given tree node a CL System Use Entry, that is used to record - * the new location of a directory which has been relocated. - * - * See RRIP, 4.1.5.1 for more details. - */ -static -int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) -{ - uint8_t *CL; - if (n->type != ECMA119_PLACEHOLDER) { - /* should never occur */ - return ISO_ASSERT_FAILURE; - } - CL = malloc(12); - if (CL == NULL) { - return ISO_OUT_OF_MEM; - } - - CL[0] = 'C'; - CL[1] = 'L'; - CL[2] = 12; - CL[3] = 1; - iso_bb(&CL[4], n->info.real_me->info.dir->block, 4); - return susp_append(t, susp, CL); -} - -/** - * Convert a RR filename to the requested charset. On any conversion error, - * the original name will be used. - */ -static -char *get_rr_fname(Ecma119Image *t, const char *str) -{ - int ret; - char *name; - - if (!strcmp(t->input_charset, t->output_charset)) { - /* no conversion needed */ - return strdup(str); - } - - ret = strconv(str, t->input_charset, t->output_charset, &name); - if (ret < 0) { - /* TODO we should check for possible cancelation */ - iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret, - "Charset conversion error. Can't convert %s from %s to %s", - str, t->input_charset, t->output_charset); - - /* use the original name, it's the best we can do */ - name = strdup(str); - } - - return name; -} - -/** - * Add a NM System Use Entry to the given tree node. The purpose of this - * System Use Entry is to store the content of an Alternate Name to support - * POSIX-style or other names. - * - * See RRIP, 4.1.4 for more details. - * - * @param size - * Length of the name to be included into the NM - * @param flags - * @param ce - * Whether to add or not to CE - */ -static -int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size, - int flags, int ce) -{ - uint8_t *NM = malloc(size + 5); - if (NM == NULL) { - return ISO_OUT_OF_MEM; - } - - NM[0] = 'N'; - NM[1] = 'M'; - NM[2] = size + 5; - NM[3] = 1; - NM[4] = flags; - if (size) { - memcpy(&NM[5], name, size); - } - if (ce) { - return susp_append_ce(t, susp, NM); - } else { - return susp_append(t, susp, NM); - } -} - -/** - * Add a new SL component (RRIP, 4.1.3.1) to a list of components. - * - * @param n - * Number of components. It will be updated. - * @param compos - * Pointer to the list of components. - * @param s - * The component content - * @param size - * Size of the component content - * @param fl - * Flags - * @return - * 1 on success, < 0 on error - */ -static -int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl) -{ - uint8_t *comp = malloc(size + 2); - if (comp == NULL) { - return ISO_OUT_OF_MEM; - } - - (*n)++; - comp[0] = fl; - comp[1] = size; - *comps = realloc(*comps, (*n) * sizeof(void*)); - if (*comps == NULL) { - free(comp); - return ISO_OUT_OF_MEM; - } - (*comps)[(*n) - 1] = comp; - - if (size) { - memcpy(&comp[2], s, size); - } - return ISO_SUCCESS; -} - -/** - * Add a SL System Use Entry to the given tree node. This is used to store - * the content of a symbolic link, and is mandatory if the tree node - * indicates a symbolic link (RRIP, 4.1.3). - * - * @param comp - * Components of the SL System Use Entry. If they don't fit in a single - * SL, more than one SL will be added. - * @param n - * Number of components in comp - * @param ce - * Whether to add to a continuation area or system use field. - */ -static -int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp, - size_t n, int ce) -{ - int ret, i, j; - - int total_comp_len = 0; - size_t pos, written = 0; - - uint8_t *SL; - - for (i = 0; i < n; i++) { - - total_comp_len += comp[i][1] + 2; - if (total_comp_len > 250) { - /* we need a new SL entry */ - total_comp_len -= comp[i][1] + 2; - SL = malloc(total_comp_len + 5); - if (SL == NULL) { - return ISO_OUT_OF_MEM; - } - - SL[0] = 'S'; - SL[1] = 'L'; - SL[2] = total_comp_len + 5; - SL[3] = 1; - SL[4] = 1; /* CONTINUE */ - pos = 5; - for (j = written; j < i; j++) { - memcpy(&SL[pos], comp[j], comp[j][1] + 2); - pos += comp[j][1] + 2; - } - - /* - * In this case we are sure we're writting to CE. Check for - * debug purposes - */ - if (ce == 0) { - return ISO_ASSERT_FAILURE; - } - ret = susp_append_ce(t, susp, SL); - if (ret < 0) { - return ret; - } - written = i; - total_comp_len = comp[i][1] + 2; - } - } - - SL = malloc(total_comp_len + 5); - if (SL == NULL) { - return ISO_OUT_OF_MEM; - } - - SL[0] = 'S'; - SL[1] = 'L'; - SL[2] = total_comp_len + 5; - SL[3] = 1; - SL[4] = 0; - pos = 5; - - for (j = written; j < n; j++) { - memcpy(&SL[pos], comp[j], comp[j][1] + 2); - pos += comp[j][1] + 2; - } - if (ce) { - ret = susp_append_ce(t, susp, SL); - } else { - ret = susp_append(t, susp, SL); - } - return ret; -} - -/** - * Add a SUSP "ER" System Use Entry to identify the Rock Ridge specification. - * - * The "ER" System Use Entry is used to uniquely identify a specification - * compliant with SUSP. This method adds to the given tree node "." entry - * the "ER" corresponding to the RR protocol. - * - * See SUSP, 5.5 and RRIP, 4.3 for more details. - */ -static -int rrip_add_ER(Ecma119Image *t, struct susp_info *susp) -{ - unsigned char *ER = malloc(182); - if (ER == NULL) { - return ISO_OUT_OF_MEM; - } - - ER[0] = 'E'; - ER[1] = 'R'; - ER[2] = 182; - ER[3] = 1; - ER[4] = 9; - ER[5] = 72; - ER[6] = 93; - ER[7] = 1; - memcpy(&ER[8], "IEEE_1282", 9); - memcpy(&ER[17], "THE IEEE 1282 PROTOCOL PROVIDES SUPPORT FOR POSIX " - "FILE SYSTEM SEMANTICS.", 72); - memcpy(&ER[89], "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, " - "PISCATAWAY, NJ, USA FOR THE 1282 SPECIFICATION.", 93); - - /** This always goes to continuation area */ - return susp_append_ce(t, susp, ER); -} - -/** - * Add a CE System Use Entry to the given tree node. A "CE" is used to add - * a continuation area, where additional System Use Entry can be written. - * (SUSP, 5.1). - */ -static -int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp) -{ - uint8_t *CE = malloc(28); - if (CE == NULL) { - return ISO_OUT_OF_MEM; - } - - CE[0] = 'C'; - CE[1] = 'E'; - CE[2] = 28; - CE[3] = 1; - iso_bb(&CE[4], susp->ce_block, 4); - iso_bb(&CE[12], susp->ce_len, 4); - iso_bb(&CE[20], ce_len, 4); - - return susp_append(t, susp, CE); -} - -/** - * Add a SP System Use Entry. The SP provide an identifier that the SUSP is - * used within the volume. The SP shall be recorded in the "." entry of the - * root directory. See SUSP, 5.3 for more details. - */ -static -int susp_add_SP(Ecma119Image *t, struct susp_info *susp) -{ - unsigned char *SP = malloc(7); - if (SP == NULL) { - return ISO_OUT_OF_MEM; - } - - SP[0] = 'S'; - SP[1] = 'P'; - SP[2] = (char)7; - SP[3] = (char)1; - SP[4] = 0xbe; - SP[5] = 0xef; - SP[6] = 0; - return susp_append(t, susp, SP); -} - -/** - * Compute the length needed for write all RR and SUSP entries for a given - * node. - * - * @param type - * 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".." - * for that node (i.e., it will refer to the parent) - * @param space - * Available space in the System Use Area for the directory record. - * @param ce - * Will be filled with the space needed in a CE - * @return - * The size needed for the RR entries in the System Use Area - */ -size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, - size_t *ce) -{ - size_t su_size; - - /* space min is 255 - 33 - 37 = 185 - * At the same time, it is always an odd number, but we need to pad it - * propertly to ensure the length of a directory record is a even number - * (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1 - */ - space--; - *ce = 0; - - /* PX and TF, we are sure they always fit in SUA */ - su_size = 44 + 26; - - if (n->type == ECMA119_DIR) { - if (n->info.dir->real_parent != NULL) { - /* it is a reallocated entry */ - if (type == 2) { - /* we need to add a PL entry */ - su_size += 12; - } else if (type == 0) { - /* we need to add a RE entry */ - su_size += 4; - } - } - } else if (n->type == ECMA119_SPECIAL) { - if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) { - /* block or char device, we need a PN entry */ - su_size += 20; - } - } else if (n->type == ECMA119_PLACEHOLDER) { - /* we need the CL entry */ - su_size += 12; - } - - if (type == 0) { - char *name = get_rr_fname(t, n->node->name); - size_t namelen = strlen(name); - free(name); - - /* NM entry */ - if (su_size + 5 + namelen <= space) { - /* ok, it fits in System Use Area */ - su_size += 5 + namelen; - } else { - /* the NM will be divided in a CE */ - namelen = namelen - (space - su_size - 5 - 28); - *ce = 5 + namelen; - su_size = space; - } - if (n->type == ECMA119_SYMLINK) { - /* - * for symlinks, we also need to write the SL - */ - char *dest, *cur, *prev; - size_t sl_len = 5; - int cew = (*ce != 0); /* are we writing to CE? */ - - dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest); - prev = dest; - cur = strchr(prev, '/'); - while (1) { - size_t clen; - if (cur) { - clen = cur - prev; - } else { - /* last component */ - clen = strlen(prev); - } - - if (clen == 1 && prev[0] == '.') { - clen = 0; - } else if (clen == 2 && prev[0] == '.' && prev[1] == '.') { - clen = 0; - } - - /* flags and len for each component record (RRIP, 4.1.3.1) */ - clen += 2; - - if (!cew) { - /* we are still writing to the SUA */ - if (su_size + sl_len + clen > space) { - /* - * ok, we need a Continuation Area anyway - * TODO this can be handled better, but for now SL - * will be completelly moved into the CA - */ - if (su_size + 28 <= space) { - /* the CE entry fills without reducing NM */ - su_size += 28; - } else { - /* we need to reduce NM */ - *ce = (28 - (space - su_size)) + 5; - su_size = space; - } - cew = 1; - } else { - sl_len += clen; - } - } - if (cew) { - if (sl_len + clen > 255) { - /* we need an additional SL entry */ - if (clen > 250) { - /* - * case 1, component too large to fit in a - * single SL entry. Thus, the component need - * to be divided anyway. - * Note than clen can be up to 255 + 2 = 257. - * - * First, we check how many bytes fit in current - * SL field - */ - int fit = 255 - sl_len - 2; - if (clen - 250 <= fit) { - /* - * the component can be divided between this - * and another SL entry - */ - *ce += 255; /* this SL, full */ - sl_len = 5 + (clen - fit); - } else { - /* - * the component will need a 2rd SL entry in - * any case, so we prefer to don't write - * anything in this SL - */ - *ce += sl_len + 255; - sl_len = 5 + (clen - 250) + 2; - } - } else { - /* case 2, create a new SL entry */ - *ce += sl_len; - sl_len = 5 + clen; - } - } else { - sl_len += clen; - } - } - - if (!cur || cur[1] == '\0') { - /* cur[1] can be \0 if dest ends with '/' */ - break; - } - prev = cur + 1; - cur = strchr(prev, '/'); - } - - free(dest); - - /* and finally write the pending SL field */ - if (!cew) { - /* the whole SL fits into the SUA */ - su_size += sl_len; - } else { - *ce += sl_len; - } - - } - } else { - - /* "." or ".." entry */ - su_size += 5; /* NM field */ - if (type == 1 && n->parent == NULL) { - /* - * "." for root directory - * we need to write SP and ER entries. The first fits in SUA, - * ER needs a Continuation Area, thus we also need a CE entry - */ - su_size += 7 + 28; /* SP + CE */ - *ce = 182; /* ER */ - } - } - - /* - * The System Use field inside the directory record must be padded if - * it is an odd number (ECMA-119, 9.1.13) - */ - su_size += (su_size % 2); - return su_size; -} - -/** - * Free all info in a struct susp_info. - */ -static -void susp_info_free(struct susp_info* susp) -{ - size_t i; - - for (i = 0; i < susp->n_susp_fields; ++i) { - free(susp->susp_fields[i]); - } - free(susp->susp_fields); - - for (i = 0; i < susp->n_ce_susp_fields; ++i) { - free(susp->ce_susp_fields[i]); - } - free(susp->ce_susp_fields); -} - -/** - * Fill a struct susp_info with the RR/SUSP entries needed for a given - * node. - * - * @param type - * 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".." - * for that node (i.e., it will refer to the parent) - * @param space - * Available space in the System Use Area for the directory record. - * @param info - * Pointer to the struct susp_info where the entries will be stored. - * If some entries need to go to a Continuation Area, they will be added - * to the existing ce_susp_fields, and ce_len will be incremented - * propertly. Please ensure ce_block is initialized propertly. - * @return - * 1 success, < 0 error - */ -int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, - size_t space, struct susp_info *info) -{ - int ret; - size_t i; - Ecma119Node *node; - char *name = NULL; - char *dest = NULL; - - if (t == NULL || n == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - if (type < 0 || type > 2 || space < 185) { - /* space min is 255 - 33 - 37 = 185 */ - return ISO_WRONG_ARG_VALUE; - } - - if (type == 2 && n->parent != NULL) { - node = n->parent; - } else { - node = n; - } - - /* space min is 255 - 33 - 37 = 185 - * At the same time, it is always an odd number, but we need to pad it - * propertly to ensure the length of a directory record is a even number - * (ECMA-119, 9.1.13). Thus, in fact the real space is always space - 1 - */ - space--; - - /* - * SP must be the first entry for the "." record of the root directory - * (SUSP, 5.3) - */ - if (type == 1 && n->parent == NULL) { - ret = susp_add_SP(t, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - - /* PX and TF, we are sure they always fit in SUA */ - ret = rrip_add_PX(t, node, info); - if (ret < 0) { - goto add_susp_cleanup; - } - ret = rrip_add_TF(t, node, info); - if (ret < 0) { - goto add_susp_cleanup; - } - - if (n->type == ECMA119_DIR) { - if (n->info.dir->real_parent != NULL) { - /* it is a reallocated entry */ - if (type == 2) { - /* - * we need to add a PL entry - * Note that we pass "n" as parameter, not "node" - */ - ret = rrip_add_PL(t, n, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } else if (type == 0) { - /* we need to add a RE entry */ - ret = rrip_add_RE(t, node, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - } - } else if (n->type == ECMA119_SPECIAL) { - if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) { - /* block or char device, we need a PN entry */ - ret = rrip_add_PN(t, node, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - } else if (n->type == ECMA119_PLACEHOLDER) { - /* we need the CL entry */ - ret = rrip_add_CL(t, node, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - - if (type == 0) { - size_t sua_free; /* free space in the SUA */ - int nm_type = 0; /* 0 whole entry in SUA, 1 part in CE */ - size_t ce_len = 0; /* len of the CE */ - size_t namelen; - - /* this two are only defined for symlinks */ - uint8_t **comps= NULL; /* components of the SL field */ - size_t n_comp = 0; /* number of components */ - - name = get_rr_fname(t, n->node->name); - namelen = strlen(name); - - sua_free = space - info->suf_len; - - /* NM entry */ - if (5 + namelen <= sua_free) { - /* ok, it fits in System Use Area */ - sua_free -= (5 + namelen); - nm_type = 0; - } else { - /* the NM will be divided in a CE */ - nm_type = 1; - namelen = namelen - (sua_free - 5 - 28); - ce_len = 5 + namelen; - sua_free = 0; - } - if (n->type == ECMA119_SYMLINK) { - /* - * for symlinks, we also need to write the SL - */ - char *cur, *prev; - size_t sl_len = 5; - int cew = (nm_type == 1); /* are we writing to CE? */ - - dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest); - prev = dest; - cur = strchr(prev, '/'); - while (1) { - size_t clen; - char cflag = 0; /* component flag (RRIP, 4.1.3.1) */ - if (cur) { - clen = cur - prev; - } else { - /* last component */ - clen = strlen(prev); - } - - if (clen == 0) { - /* this refers to the roor directory, '/' */ - cflag = 1 << 3; - } - if (clen == 1 && prev[0] == '.') { - clen = 0; - cflag = 1 << 1; - } else if (clen == 2 && prev[0] == '.' && prev[1] == '.') { - clen = 0; - cflag = 1 << 2; - } - - /* flags and len for each component record (RRIP, 4.1.3.1) */ - clen += 2; - - if (!cew) { - /* we are still writing to the SUA */ - if (sl_len + clen > sua_free) { - /* - * ok, we need a Continuation Area anyway - * TODO this can be handled better, but for now SL - * will be completelly moved into the CA - */ - if (28 <= sua_free) { - /* the CE entry fills without reducing NM */ - sua_free -= 28; - cew = 1; - } else { - /* we need to reduce NM */ - nm_type = 1; - ce_len = (28 - sua_free) + 5; - sua_free = 0; - cew = 1; - } - } else { - /* add the component */ - ret = rrip_SL_append_comp(&n_comp, &comps, prev, - clen - 2, cflag); - if (ret < 0) { - goto add_susp_cleanup; - } - sl_len += clen; - } - } - if (cew) { - if (sl_len + clen > 255) { - /* we need an addition SL entry */ - if (clen > 250) { - /* - * case 1, component too large to fit in a - * single SL entry. Thus, the component need - * to be divided anyway. - * Note than clen can be up to 255 + 2 = 257. - * - * First, we check how many bytes fit in current - * SL field - */ - int fit = 255 - sl_len - 2; - if (clen - 250 <= fit) { - /* - * the component can be divided between this - * and another SL entry - */ - ret = rrip_SL_append_comp(&n_comp, &comps, - prev, fit, 0x01); - if (ret < 0) { - goto add_susp_cleanup; - } - /* - * and another component, that will go in - * other SL entry - */ - ret = rrip_SL_append_comp(&n_comp, &comps, prev - + fit, clen - fit - 2, 0); - if (ret < 0) { - goto add_susp_cleanup; - } - ce_len += 255; /* this SL, full */ - sl_len = 5 + (clen - fit); - } else { - /* - * the component will need a 2rd SL entry in - * any case, so we prefer to don't write - * anything in this SL - */ - ret = rrip_SL_append_comp(&n_comp, &comps, - prev, 248, 0x01); - if (ret < 0) { - goto add_susp_cleanup; - } - ret = rrip_SL_append_comp(&n_comp, &comps, prev - + 248, strlen(prev + 248), 0x00); - if (ret < 0) { - goto add_susp_cleanup; - } - ce_len += sl_len + 255; - sl_len = 5 + (clen - 250) + 2; - } - } else { - /* case 2, create a new SL entry */ - ret = rrip_SL_append_comp(&n_comp, &comps, prev, - clen - 2, cflag); - if (ret < 0) { - goto add_susp_cleanup; - } - ce_len += sl_len; - sl_len = 5 + clen; - } - } else { - /* the component fit in the SL entry */ - ret = rrip_SL_append_comp(&n_comp, &comps, prev, - clen - 2, cflag); - if (ret < 0) { - goto add_susp_cleanup; - } - sl_len += clen; - } - } - - if (!cur || cur[1] == '\0') { - /* cur[1] can be \0 if dest ends with '/' */ - break; - } - prev = cur + 1; - cur = strchr(prev, '/'); - } - - if (cew) { - ce_len += sl_len; - } - } - - /* - * We we reach here: - * - We know if NM fill in the SUA (nm_type == 0) - * - If SL needs an to be written in CE (ce_len > 0) - * - The components for SL entry (or entries) - */ - - if (nm_type == 0) { - /* the full NM fills in SUA */ - ret = rrip_add_NM(t, info, name, strlen(name), 0, 0); - if (ret < 0) { - goto add_susp_cleanup; - } - } else { - /* - * Write the NM part that fits in SUA... Note that CE - * entry and NM in the continuation area is added below - */ - namelen = space - info->suf_len - 28 - 5; - ret = rrip_add_NM(t, info, name, namelen, 1, 0); - if (ret < 0) { - goto add_susp_cleanup; - } - } - - if (ce_len > 0) { - /* Add the CE entry */ - ret = susp_add_CE(t, ce_len, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - - if (nm_type == 1) { - /* - * ..and the part that goes to continuation area. - */ - ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen), - 0, 1); - if (ret < 0) { - goto add_susp_cleanup; - } - } - - if (n->type == ECMA119_SYMLINK) { - - /* add the SL entry (or entries) */ - ret = rrip_add_SL(t, info, comps, n_comp, (ce_len > 0)); - - /* free the components */ - for (i = 0; i < n_comp; i++) { - free(comps[i]); - } - free(comps); - - if (ret < 0) { - goto add_susp_cleanup; - } - } - - } else { - - /* "." or ".." entry */ - - /* write the NM entry */ - ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0); - if (ret < 0) { - goto add_susp_cleanup; - } - if (type == 1 && n->parent == NULL) { - /* - * "." for root directory - * we need to write SP and ER entries. The first fits in SUA, - * ER needs a Continuation Area, thus we also need a CE entry. - * Note that SP entry was already added above - */ - ret = susp_add_CE(t, 182, info); /* 182 is ER length */ - if (ret < 0) { - goto add_susp_cleanup; - } - ret = rrip_add_ER(t, info); - if (ret < 0) { - goto add_susp_cleanup; - } - } - } - - /* - * The System Use field inside the directory record must be padded if - * it is an odd number (ECMA-119, 9.1.13) - */ - info->suf_len += (info->suf_len % 2); - - free(name); - free(dest); - return ISO_SUCCESS; - - add_susp_cleanup: ; - free(name); - free(dest); - susp_info_free(info); - return ret; -} - -/** - * Write the given SUSP fields into buf. Note that Continuation Area - * fields are not written. - * If info does not contain any SUSP entry this function just return. - * After written, the info susp_fields array will be freed, and the counters - * updated propertly. - */ -void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info, - uint8_t *buf) -{ - size_t i; - size_t pos = 0; - - if (info->n_susp_fields == 0) { - return; - } - - for (i = 0; i < info->n_susp_fields; i++) { - memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]); - pos += info->susp_fields[i][2]; - } - - /* free susp_fields */ - for (i = 0; i < info->n_susp_fields; ++i) { - free(info->susp_fields[i]); - } - free(info->susp_fields); - info->susp_fields = NULL; - info->n_susp_fields = 0; - info->suf_len = 0; -} - -/** - * Write the Continuation Area entries for the given struct susp_info, using - * the iso_write() function. - * After written, the ce_susp_fields array will be freed. - */ -int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info) -{ - size_t i; - uint8_t padding[BLOCK_SIZE]; - int ret= ISO_SUCCESS; - - if (info->n_ce_susp_fields == 0) { - return ret; - } - - for (i = 0; i < info->n_ce_susp_fields; i++) { - ret = iso_write(t, info->ce_susp_fields[i], - info->ce_susp_fields[i][2]); - if (ret < 0) { - goto write_ce_field_cleanup; - } - } - - /* pad continuation area until block size */ - i = BLOCK_SIZE - (info->ce_len % BLOCK_SIZE); - if (i > 0 && i < BLOCK_SIZE) { - memset(padding, 0, i); - ret = iso_write(t, padding, i); - } - - write_ce_field_cleanup: ; - /* free ce_susp_fields */ - for (i = 0; i < info->n_ce_susp_fields; ++i) { - free(info->ce_susp_fields[i]); - } - free(info->ce_susp_fields); - info->ce_susp_fields = NULL; - info->n_ce_susp_fields = 0; - info->ce_len = 0; - return ret; -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.h deleted file mode 100644 index c21a954d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/** - * This header defines the functions and structures needed to add RockRidge - * extensions to an ISO image. - * - * References: - * - * - SUSP (IEEE 1281). - * System Use Sharing Protocol, draft standard version 1.12. - * - * - RRIP (IEEE 1282) - * Rock Ridge Interchange Protocol, Draft Standard version 1.12. - * - * - ECMA-119 (ISO-9660) - * Volume and File Structure of CDROM for Information Interchange. - */ - -#ifndef LIBISO_ROCKRIDGE_H -#define LIBISO_ROCKRIDGE_H - -#include "ecma119.h" - -#define SUSP_SIG(entry, a, b) ((entry->sig[0] == a) && (entry->sig[1] == b)) - -/** - * This contains the information about the System Use Fields (SUSP, 4.1), - * that will be written in the System Use Areas, both in the ISO directory - * record System Use field (ECMA-119, 9.1.13) or in a Continuation Area as - * defined by SUSP. - */ -struct susp_info -{ - /** Number of SUSP fields in the System Use field */ - size_t n_susp_fields; - uint8_t **susp_fields; - - /** Length of the part of the SUSP area that fits in the dirent. */ - int suf_len; - - /** Length of the part of the SUSP area that will go in a CE area. */ - uint32_t ce_block; - uint32_t ce_len; - - size_t n_ce_susp_fields; - uint8_t **ce_susp_fields; -}; - -/* SUSP 5.1 */ -struct susp_CE { - uint8_t block[8]; - uint8_t offset[8]; - uint8_t len[8]; -}; - -/* SUSP 5.3 */ -struct susp_SP { - uint8_t be[1]; - uint8_t ef[1]; - uint8_t len_skp[1]; -}; - -/* SUSP 5.5 */ -struct susp_ER { - uint8_t len_id[1]; - uint8_t len_des[1]; - uint8_t len_src[1]; - uint8_t ext_ver[1]; - uint8_t ext_id[1]; /*< up to len_id bytes */ - /* ext_des, ext_src */ -}; - -/** POSIX file attributes (RRIP, 4.1.1) */ -struct rr_PX { - uint8_t mode[8]; - uint8_t links[8]; - uint8_t uid[8]; - uint8_t gid[8]; - uint8_t serial[8]; -}; - -/** Time stamps for a file (RRIP, 4.1.6) */ -struct rr_TF { - uint8_t flags[1]; - uint8_t t_stamps[1]; -}; - -/** Info for character and block device (RRIP, 4.1.2) */ -struct rr_PN { - uint8_t high[8]; - uint8_t low[8]; -}; - -/** Alternate name (RRIP, 4.1.4) */ -struct rr_NM { - uint8_t flags[1]; - uint8_t name[1]; -}; - -/** Link for a relocated directory (RRIP, 4.1.5.1) */ -struct rr_CL { - uint8_t child_loc[8]; -}; - -/** Sim link (RRIP, 4.1.3) */ -struct rr_SL { - uint8_t flags[1]; - uint8_t comps[1]; -}; - -/** - * Struct for a SUSP System User Entry (SUSP, 4.1) - */ -struct susp_sys_user_entry -{ - uint8_t sig[2]; - uint8_t len_sue[1]; - uint8_t version[1]; - union { - struct susp_CE CE; - struct susp_SP SP; - struct susp_ER ER; - struct rr_PX PX; - struct rr_TF TF; - struct rr_PN PN; - struct rr_NM NM; - struct rr_CL CL; - struct rr_SL SL; - } data; /* 5 to 4+len_sue */ -}; - -/** - * Compute the length needed for write all RR and SUSP entries for a given - * node. - * - * @param type - * 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".." - * for that node (i.e., it will refer to the parent) - * @param space - * Available space in the System Use Area for the directory record. - * @param ce - * Will be filled with the space needed in a CE - * @return - * The size needed for the RR entries in the System Use Area - */ -size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space, - size_t *ce); - -/** - * Fill a struct susp_info with the RR/SUSP entries needed for a given - * node. - * - * @param type - * 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".." - * for that node (i.e., it will refer to the parent) - * @param space - * Available space in the System Use Area for the directory record. - * @param info - * Pointer to the struct susp_info where the entries will be stored. - * If some entries need to go to a Continuation Area, they will be added - * to the existing ce_susp_fields, and ce_len will be incremented - * propertly. Please ensure ce_block is initialized propertly. - * @return - * 1 success, < 0 error - */ -int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, - size_t space, struct susp_info *info); - -/** - * Write the given SUSP fields into buf. Note that Continuation Area - * fields are not written. - * If info does not contain any SUSP entry this function just return. - * After written, the info susp_fields array will be freed, and the counters - * updated propertly. - */ -void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info, - uint8_t *buf); - -/** - * Write the Continuation Area entries for the given struct susp_info, using - * the iso_write() function. - * After written, the ce_susp_fields array will be freed. - */ -int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info); - -/** - * The SUSP iterator is used to iterate over the System User Entries - * of a ECMA-168 directory record. - * It takes care about Continuation Areas, handles the end of the different - * system user entries and skip padding areas. Thus, using an iteration - * we are accessing just to the meaning entries. - */ -typedef struct susp_iterator SuspIterator; - -SuspIterator * -susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record, - uint8_t len_skp, int msgid); - -/** - * Get the next SUSP System User Entry using given iterator. - * - * @param sue - * Pointer to the next susp entry. It refers to an internal buffer and - * it's not guaranteed to be allocated after calling susp_iter_next() - * again. Thus, if you need to keep some entry you have to do a copy. - * @return - * 1 on success, 0 if no more entries, < 0 error - */ -int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue); - -/** - * Free a given susp iterator. - */ -void susp_iter_free(SuspIterator *iter); - - -/** - * Fills a struct stat with the values of a Rock Ridge PX entry (RRIP, 4.1.1). - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st); - -/** - * Fills a struct stat with the values of a Rock Ridge TF entry (RRIP, 4.1.6) - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st); - -/** - * Read a RR NM entry (RRIP, 4.1.4), and appends the name stored there to - * the given name. You can pass a pointer to NULL as name. - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_NM(struct susp_sys_user_entry *nm, char **name, int *cont); - -/** - * Read a SL RR entry (RRIP, 4.1.3), checking if the destination continues. - * - * @param cont - * 0 not continue, 1 continue, 2 continue component - * @return - * 1 on success, < 0 on error - */ -int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont); - -/** - * Fills a struct stat with the values of a Rock Ridge PN entry (RRIP, 4.1.2). - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st); - -#endif /* LIBISO_ROCKRIDGE_H */ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge_read.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge_read.c deleted file mode 100644 index 02dbc869..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/rockridge_read.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * This file contains functions related to the reading of SUSP and - * Rock Ridge extensions on an ECMA-119 image. - */ - -#include "libisofs.h" -#include "ecma119.h" -#include "util.h" -#include "rockridge.h" -#include "messages.h" - -#include -#include -#include - -struct susp_iterator -{ - uint8_t* base; - int pos; - int size; - IsoDataSource *src; - int msgid; - - /* block and offset for next continuation area */ - uint32_t ce_block; - uint32_t ce_off; - - /** Length of the next continuation area, 0 if no more CA are specified */ - uint32_t ce_len; - - uint8_t *buffer; /*< If there are continuation areas */ -}; - -SuspIterator* -susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record, - uint8_t len_skp, int msgid) -{ - int pad = (record->len_fi[0] + 1) % 2; - struct susp_iterator *iter = malloc(sizeof(struct susp_iterator)); - if (iter == NULL) { - return NULL; - } - - iter->base = record->file_id + record->len_fi[0] + pad; - iter->pos = len_skp; /* 0 in most cases */ - iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad; - iter->src = src; - iter->msgid = msgid; - - iter->ce_len = 0; - iter->buffer = NULL; - - return iter; -} - -int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue) -{ - struct susp_sys_user_entry *entry; - - entry = (struct susp_sys_user_entry*)(iter->base + iter->pos); - - if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) { - - /* - * End of the System Use Area or Continuation Area. - * Note that ST is not needed when the space left is less than 4. - * (IEEE 1281, SUSP. section 4) - */ - if (iter->ce_len) { - uint32_t block; - int nblocks; - - /* A CE has found, there is another continuation area */ - nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE); - iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE); - - /* read all blocks needed to cache the full CE */ - for (block = 0; block < nblocks; ++block) { - int ret; - ret = iter->src->read_block(iter->src, iter->ce_block + block, - iter->buffer + block * BLOCK_SIZE); - if (ret < 0) { - return ret; - } - } - iter->base = iter->buffer + iter->ce_off; - iter->pos = 0; - iter->size = iter->ce_len; - iter->ce_len = 0; - entry = (struct susp_sys_user_entry*)iter->base; - } else { - return 0; - } - } - - if (entry->len_sue[0] == 0) { - /* a wrong image with this lead us to a infinity loop */ - iso_msg_submit(iter->msgid, ISO_WRONG_RR, 0, - "Damaged RR/SUSP information."); - return ISO_WRONG_RR; - } - - iter->pos += entry->len_sue[0]; - - if (SUSP_SIG(entry, 'C', 'E')) { - /* Continuation entry */ - if (iter->ce_len) { - int ret; - ret = iso_msg_submit(iter->msgid, ISO_UNSUPPORTED_SUSP, 0, - "More than one CE System user entry has found in a single " - "System Use field or continuation area. This breaks SUSP " - "standard and it's not supported. Ignoring last CE. Maybe " - "the image is damaged."); - if (ret < 0) { - return ret; - } - } else { - iter->ce_block = iso_read_bb(entry->data.CE.block, 4, NULL); - iter->ce_off = iso_read_bb(entry->data.CE.offset, 4, NULL); - iter->ce_len = iso_read_bb(entry->data.CE.len, 4, NULL); - } - - /* we don't want to return CE entry to the user */ - return susp_iter_next(iter, sue); - } else if (SUSP_SIG(entry, 'P', 'D')) { - /* skip padding */ - return susp_iter_next(iter, sue); - } - - *sue = entry; - return ISO_SUCCESS; -} - -void susp_iter_free(SuspIterator *iter) -{ - free(iter->buffer); - free(iter); -} - -/** - * Fills a struct stat with the values of a Rock Ridge PX entry (RRIP, 4.1.1). - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st) -{ - if (px == NULL || st == NULL) { - return ISO_NULL_POINTER; - } - if (px->sig[0] != 'P' || px->sig[1] != 'X') { - return ISO_WRONG_ARG_VALUE; - } - - if (px->len_sue[0] != 44 && px->len_sue[0] != 36) { - return ISO_WRONG_RR; - } - - st->st_mode = iso_read_bb(px->data.PX.mode, 4, NULL); - st->st_nlink = iso_read_bb(px->data.PX.links, 4, NULL); - st->st_uid = iso_read_bb(px->data.PX.uid, 4, NULL); - st->st_gid = iso_read_bb(px->data.PX.gid, 4, NULL); - if (px->len_sue[0] == 44) { - /* this corresponds to RRIP 1.12, so we have inode serial number */ - st->st_ino = iso_read_bb(px->data.PX.serial, 4, NULL); - } - return ISO_SUCCESS; -} - -/** - * Fills a struct stat with the values of a Rock Ridge TF entry (RRIP, 4.1.6) - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st) -{ - time_t time; - int s; - int nts = 0; - - if (tf == NULL || st == NULL) { - return ISO_NULL_POINTER; - } - if (tf->sig[0] != 'T' || tf->sig[1] != 'F') { - return ISO_WRONG_ARG_VALUE; - } - - if (tf->data.TF.flags[0] & (1 << 7)) { - /* long form */ - s = 17; - } else { - s = 7; - } - - /* 1. Creation time */ - if (tf->data.TF.flags[0] & (1 << 0)) { - - /* the creation is the recording time. we ignore this */ - /* TODO maybe it would be good to manage it in ms discs, where - * the recording time could be different than now!! */ - ++nts; - } - - /* 2. modify time */ - if (tf->data.TF.flags[0] & (1 << 1)) { - if (tf->len_sue[0] < 5 + (nts+1) * s) { - /* RR TF entry too short. */ - return ISO_WRONG_RR; - } - if (s == 7) { - time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]); - } else { - time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]); - } - st->st_mtime = time; - ++nts; - } - - /* 3. access time */ - if (tf->data.TF.flags[0] & (1 << 2)) { - if (tf->len_sue[0] < 5 + (nts+1) * s) { - /* RR TF entry too short. */ - return ISO_WRONG_RR; - } - if (s == 7) { - time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]); - } else { - time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]); - } - st->st_atime = time; - ++nts; - } - - /* 4. attributes time */ - if (tf->data.TF.flags[0] & (1 << 3)) { - if (tf->len_sue[0] < 5 + (nts+1) * s) { - /* RR TF entry too short. */ - return ISO_WRONG_RR; - } - if (s == 7) { - time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]); - } else { - time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]); - } - st->st_ctime = time; - ++nts; - } - - /* we ignore backup, expire and effect times */ - - return ISO_SUCCESS; -} - -/** - * Read a RR NM entry (RRIP, 4.1.4), and appends the name stored there to - * the given name. You can pass a pointer to NULL as name. - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_NM(struct susp_sys_user_entry *nm, char **name, int *cont) -{ - if (nm == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - if (nm->sig[0] != 'N' || nm->sig[1] != 'M') { - return ISO_WRONG_ARG_VALUE; - } - - if (nm->len_sue[0] == 5) { - if (nm->data.NM.flags[0] & 0x2) { - /* it is a "." entry */ - if (*name == NULL) { - return ISO_SUCCESS; - } else { - /* we can't have a previous not-NULL name */ - return ISO_WRONG_RR; - } - } - } - - if (nm->len_sue[0] <= 5) { - /* ".." entry is an error, as we will never call it */ - return ISO_WRONG_RR; - } - - /* concatenate the results */ - if (*cont) { - *name = realloc(*name, strlen(*name) + nm->len_sue[0] - 5 + 1); - strncat(*name, (char*)nm->data.NM.name, nm->len_sue[0] - 5); - } else { - *name = strcopy((char*)nm->data.NM.name, nm->len_sue[0] - 5); - } - if (*name == NULL) { - return ISO_OUT_OF_MEM; - } - - /* and set cond according to the value of CONTINUE flag */ - *cont = nm->data.NM.flags[0] & 0x01; - return ISO_SUCCESS; -} - -/** - * Read a SL RR entry (RRIP, 4.1.3), checking if the destination continues. - * - * @param cont - * 0 not continue, 1 continue, 2 continue component - * @return - * 1 on success, < 0 on error - */ -int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont) -{ - int pos; - - if (sl == NULL || dest == NULL) { - return ISO_NULL_POINTER; - } - if (sl->sig[0] != 'S' || sl->sig[1] != 'L') { - return ISO_WRONG_ARG_VALUE; - } - - for (pos = 0; pos + 5 < sl->len_sue[0]; - pos += 2 + sl->data.SL.comps[pos + 1]) { - char *comp; - uint8_t len; - uint8_t flags = sl->data.SL.comps[pos]; - - if (flags & 0x2) { - /* current directory */ - len = 1; - comp = "."; - } else if (flags & 0x4) { - /* parent directory */ - len = 2; - comp = ".."; - } else if (flags & 0x8) { - /* root directory */ - len = 1; - comp = "/"; - } else if (flags & ~0x01) { - /* unsupported flag component */ - return ISO_UNSUPPORTED_RR; - } else { - len = sl->data.SL.comps[pos + 1]; - comp = (char*)&sl->data.SL.comps[pos + 2]; - } - - if (*cont == 1) { - /* new component */ - size_t size = strlen(*dest); - *dest = realloc(*dest, strlen(*dest) + len + 2); - if (*dest == NULL) { - return ISO_OUT_OF_MEM; - } - /* it is a new compoenent, add the '/' */ - if ((*dest)[size-1] != '/') { - (*dest)[size] = '/'; - (*dest)[size+1] = '\0'; - } - strncat(*dest, comp, len); - } else if (*cont == 2) { - /* the component continues */ - *dest = realloc(*dest, strlen(*dest) + len + 1); - if (*dest == NULL) { - return ISO_OUT_OF_MEM; - } - /* we don't have to add the '/' */ - strncat(*dest, comp, len); - } else { - *dest = strcopy(comp, len); - } - if (*dest == NULL) { - return ISO_OUT_OF_MEM; - } - /* do the component continue or not? */ - *cont = (flags & 0x01) ? 2 : 1; - } - - if (*cont == 2) { - /* TODO check that SL flag is set to continute too ?*/ - } else { - *cont = sl->data.SL.flags[0] & 0x1 ? 1 : 0; - } - - return ISO_SUCCESS; -} - -/** - * Fills a struct stat with the values of a Rock Ridge PN entry (RRIP, 4.1.2). - * - * @return - * 1 on success, < 0 on error - */ -int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st) -{ - if (pn == NULL || pn == NULL) { - return ISO_NULL_POINTER; - } - if (pn->sig[0] != 'P' || pn->sig[1] != 'N') { - return ISO_WRONG_ARG_VALUE; - } - - if (pn->len_sue[0] != 20) { - return ISO_WRONG_RR; - } - - st->st_rdev = (dev_t)((dev_t)iso_read_bb(pn->data.PN.high, 4, NULL) << 32) - || (dev_t)iso_read_bb(pn->data.PN.low, 4, NULL); - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.c deleted file mode 100644 index 6058e894..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "libisofs.h" -#include "stream.h" -#include "fsource.h" -#include "util.h" - -#include -#include -#include - -ino_t serial_id = (ino_t)1; -ino_t mem_serial_id = (ino_t)1; - -typedef struct -{ - IsoFileSource *src; - - /* key for file identification inside filesystem */ - dev_t dev_id; - ino_t ino_id; - off_t size; /**< size of this file */ -} FSrcStreamData; - -static -int fsrc_open(IsoStream *stream) -{ - int ret; - struct stat info; - off_t esize; - IsoFileSource *src; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - src = ((FSrcStreamData*)stream->data)->src; - ret = iso_file_source_stat(src, &info); - if (ret < 0) { - return ret; - } - ret = iso_file_source_open(src); - if (ret < 0) { - return ret; - } - esize = ((FSrcStreamData*)stream->data)->size; - if (info.st_size == esize) { - return ISO_SUCCESS; - } else { - return (esize > info.st_size) ? 3 : 2; - } -} - -static -int fsrc_close(IsoStream *stream) -{ - IsoFileSource *src; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - src = ((FSrcStreamData*)stream->data)->src; - return iso_file_source_close(src); -} - -static -off_t fsrc_get_size(IsoStream *stream) -{ - FSrcStreamData *data; - data = (FSrcStreamData*)stream->data; - - return data->size; -} - -static -int fsrc_read(IsoStream *stream, void *buf, size_t count) -{ - IsoFileSource *src; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - src = ((FSrcStreamData*)stream->data)->src; - return iso_file_source_read(src, buf, count); -} - -static -int fsrc_is_repeatable(IsoStream *stream) -{ - int ret; - struct stat info; - FSrcStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = (FSrcStreamData*)stream->data; - - /* mode is not cached, this function is only useful for filters */ - ret = iso_file_source_stat(data->src, &info); - if (ret < 0) { - return ret; - } - if (S_ISREG(info.st_mode) || S_ISBLK(info.st_mode)) { - return 1; - } else { - return 0; - } -} - -static -void fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id) -{ - FSrcStreamData *data; - IsoFilesystem *fs; - - data = (FSrcStreamData*)stream->data; - fs = iso_file_source_get_filesystem(data->src); - - *fs_id = fs->get_id(fs); - *dev_id = data->dev_id; - *ino_id = data->ino_id; -} - -static -void fsrc_free(IsoStream *stream) -{ - FSrcStreamData *data; - data = (FSrcStreamData*)stream->data; - iso_file_source_unref(data->src); - free(data); -} - -IsoStreamIface fsrc_stream_class = { - 0, - "fsrc", - fsrc_open, - fsrc_close, - fsrc_get_size, - fsrc_read, - fsrc_is_repeatable, - fsrc_get_id, - fsrc_free -}; - -int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream) -{ - int r; - struct stat info; - IsoStream *str; - FSrcStreamData *data; - - if (src == NULL || stream == NULL) { - return ISO_NULL_POINTER; - } - - r = iso_file_source_stat(src, &info); - if (r < 0) { - return r; - } - if (S_ISDIR(info.st_mode)) { - return ISO_FILE_IS_DIR; - } - - /* check for read access to contents */ - r = iso_file_source_access(src); - if (r < 0) { - return r; - } - - str = malloc(sizeof(IsoStream)); - if (str == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(FSrcStreamData)); - if (str == NULL) { - free(str); - return ISO_OUT_OF_MEM; - } - - /* take the ref to IsoFileSource */ - data->src = src; - data->size = info.st_size; - - /* get the id numbers */ - { - IsoFilesystem *fs; - unsigned int fs_id; - fs = iso_file_source_get_filesystem(data->src); - - fs_id = fs->get_id(fs); - if (fs_id == 0) { - /* - * the filesystem implementation is unable to provide valid - * st_dev and st_ino fields. Use serial_id. - */ - data->dev_id = (dev_t) 0; - data->ino_id = serial_id++; - } else { - data->dev_id = info.st_dev; - data->ino_id = info.st_ino; - } - } - - str->refcount = 1; - str->data = data; - str->class = &fsrc_stream_class; - - *stream = str; - return ISO_SUCCESS; -} - - - -typedef struct -{ - uint8_t *buf; - ssize_t offset; /* -1 if stream closed */ - ino_t ino_id; - size_t size; -} MemStreamData; - -static -int mem_open(IsoStream *stream) -{ - MemStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = (MemStreamData*)stream->data; - if (data->offset != -1) { - return ISO_FILE_ALREADY_OPENED; - } - data->offset = 0; - return ISO_SUCCESS; -} - -static -int mem_close(IsoStream *stream) -{ - MemStreamData *data; - if (stream == NULL) { - return ISO_NULL_POINTER; - } - data = (MemStreamData*)stream->data; - if (data->offset == -1) { - return ISO_FILE_NOT_OPENED; - } - data->offset = -1; - return ISO_SUCCESS; -} - -static -off_t mem_get_size(IsoStream *stream) -{ - MemStreamData *data; - data = (MemStreamData*)stream->data; - - return (off_t)data->size; -} - -static -int mem_read(IsoStream *stream, void *buf, size_t count) -{ - size_t len; - MemStreamData *data; - if (stream == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - if (count == 0) { - return ISO_WRONG_ARG_VALUE; - } - data = stream->data; - - if (data->offset == -1) { - return ISO_FILE_NOT_OPENED; - } - - if (data->offset >= data->size) { - return 0; /* EOF */ - } - - len = MIN(count, data->size - data->offset); - memcpy(buf, data->buf + data->offset, len); - data->offset += len; - return len; -} - -static -int mem_is_repeatable(IsoStream *stream) -{ - return 1; -} - -static -void mem_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id) -{ - MemStreamData *data; - data = (MemStreamData*)stream->data; - *fs_id = ISO_MEM_FS_ID; - *dev_id = 0; - *ino_id = data->ino_id; -} - -static -void mem_free(IsoStream *stream) -{ - MemStreamData *data; - data = (MemStreamData*)stream->data; - free(data->buf); - free(data); -} - -IsoStreamIface mem_stream_class = { - 0, - "mem ", - mem_open, - mem_close, - mem_get_size, - mem_read, - mem_is_repeatable, - mem_get_id, - mem_free -}; - -/** - * Create a stream for reading from a arbitrary memory buffer. - * When the Stream refcount reach 0, the buffer is free(3). - * - * @return - * 1 sucess, < 0 error - */ -int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream) -{ - IsoStream *str; - MemStreamData *data; - - if (buf == NULL || stream == NULL) { - return ISO_NULL_POINTER; - } - - str = malloc(sizeof(IsoStream)); - if (str == NULL) { - return ISO_OUT_OF_MEM; - } - data = malloc(sizeof(MemStreamData)); - if (str == NULL) { - free(str); - return ISO_OUT_OF_MEM; - } - - /* fill data */ - data->buf = buf; - data->size = size; - data->offset = -1; - data->ino_id = mem_serial_id++; - - str->refcount = 1; - str->data = data; - str->class = &mem_stream_class; - - *stream = str; - return ISO_SUCCESS; -} - -void iso_stream_ref(IsoStream *stream) -{ - ++stream->refcount; -} - -void iso_stream_unref(IsoStream *stream) -{ - if (--stream->refcount == 0) { - stream->class->free(stream); - free(stream); - } -} - -inline -int iso_stream_open(IsoStream *stream) -{ - return stream->class->open(stream); -} - -inline -int iso_stream_close(IsoStream *stream) -{ - return stream->class->close(stream); -} - -inline -off_t iso_stream_get_size(IsoStream *stream) -{ - return stream->class->get_size(stream); -} - -inline -int iso_stream_read(IsoStream *stream, void *buf, size_t count) -{ - return stream->class->read(stream, buf, count); -} - -inline -int iso_stream_is_repeatable(IsoStream *stream) -{ - return stream->class->is_repeatable(stream); -} - -inline -void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, - ino_t *ino_id) -{ - stream->class->get_id(stream, fs_id, dev_id, ino_id); -} - -void iso_stream_get_file_name(IsoStream *stream, char *name) -{ - char *type = stream->class->type; - - if (!strncmp(type, "fsrc", 4)) { - FSrcStreamData *data = stream->data; - char *path = iso_file_source_get_path(data->src); - strncpy(name, path, PATH_MAX); - } else if (!strncmp(type, "boot", 4)) { - strcpy(name, "BOOT CATALOG"); - } else if (!strncmp(type, "mem ", 4)) { - strcpy(name, "MEM SOURCE"); - } else { - strcpy(name, "UNKNOWN SOURCE"); - } -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.h deleted file mode 100644 index 804faf14..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/stream.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_STREAM_H_ -#define LIBISO_STREAM_H_ - -/* - * Definitions of streams. - */ -#include "fsource.h" - -/** - * Get an identifier for the file of the source, for debug purposes - * @param name - * Should provide at least PATH_MAX bytes - */ -void iso_stream_get_file_name(IsoStream *stream, char *name); - -/** - * Create a stream to read from a IsoFileSource. - * The stream will take the ref. to the IsoFileSource, so after a successfully - * exectution of this function, you musn't unref() the source, unless you - * take an extra ref. - * - * @return - * 1 sucess, < 0 error - * Possible errors: - * - */ -int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream); - -/** - * Create a stream for reading from a arbitrary memory buffer. - * When the Stream refcount reach 0, the buffer is free(3). - * - * @return - * 1 sucess, < 0 error - */ -int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream); - -#endif /*STREAM_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.c deleted file mode 100644 index 420b6113..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -/* - * Functions that act on the iso tree. - */ - -#include "libisofs.h" -#include "node.h" -#include "image.h" -#include "fsource.h" -#include "builder.h" -#include "messages.h" -#include "tree.h" - -#include -#include -#include -#include -#include -#include - -/** - * Add a new directory to the iso tree. - * - * @param parent - * the dir where the new directory will be created - * @param name - * name for the new dir. If a node with same name already exists on - * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param dir - * place where to store a pointer to the newly created dir. No extra - * ref is addded, so you will need to call iso_node_ref() if you really - * need it. You can pass NULL in this parameter if you don't need the - * pointer. - * @return - * number of nodes in dir if succes, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent or name are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - */ -int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir) -{ - int ret; - char *n; - IsoDir *node; - IsoNode **pos; - time_t now; - - if (parent == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - if (dir) { - *dir = NULL; - } - - /* find place where to insert and check if it exists */ - if (iso_dir_exists(parent, name, &pos)) { - /* a node with same name already exists */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - - n = strdup(name); - ret = iso_node_new_dir(n, &node); - if (ret < 0) { - free(n); - return ret; - } - - /* permissions from parent */ - iso_node_set_permissions((IsoNode*)node, parent->node.mode); - iso_node_set_uid((IsoNode*)node, parent->node.uid); - iso_node_set_gid((IsoNode*)node, parent->node.gid); - iso_node_set_hidden((IsoNode*)node, parent->node.hidden); - - /* current time */ - now = time(NULL); - iso_node_set_atime((IsoNode*)node, now); - iso_node_set_ctime((IsoNode*)node, now); - iso_node_set_mtime((IsoNode*)node, now); - - if (dir) { - *dir = node; - } - - /* add to dir */ - return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER); -} - -/** - * Add a new symlink to the directory tree. Permissions are set to 0777, - * owner and hidden atts are taken from parent. You can modify any of them - * later. - * - * @param parent - * the dir where the new symlink will be created - * @param name - * name for the new dir. If a node with same name already exists on - * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param dest - * destination of the link - * @param link - * place where to store a pointer to the newly created link. No extra - * ref is addded, so you will need to call iso_node_ref() if you really - * need it. You can pass NULL in this parameter if you don't need the - * pointer - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent, name or dest are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - */ -int iso_tree_add_new_symlink(IsoDir *parent, const char *name, - const char *dest, IsoSymlink **link) -{ - int ret; - char *n, *d; - IsoSymlink *node; - IsoNode **pos; - time_t now; - - if (parent == NULL || name == NULL || dest == NULL) { - return ISO_NULL_POINTER; - } - if (link) { - *link = NULL; - } - - /* find place where to insert */ - if (iso_dir_exists(parent, name, &pos)) { - /* a node with same name already exists */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - - n = strdup(name); - d = strdup(dest); - ret = iso_node_new_symlink(n, d, &node); - if (ret < 0) { - free(n); - free(d); - return ret; - } - - /* permissions from parent */ - iso_node_set_permissions((IsoNode*)node, 0777); - iso_node_set_uid((IsoNode*)node, parent->node.uid); - iso_node_set_gid((IsoNode*)node, parent->node.gid); - iso_node_set_hidden((IsoNode*)node, parent->node.hidden); - - /* current time */ - now = time(NULL); - iso_node_set_atime((IsoNode*)node, now); - iso_node_set_ctime((IsoNode*)node, now); - iso_node_set_mtime((IsoNode*)node, now); - - if (link) { - *link = node; - } - - /* add to dir */ - return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER); -} - -/** - * Add a new special file to the directory tree. As far as libisofs concerns, - * an special file is a block device, a character device, a FIFO (named pipe) - * or a socket. You can choose the specific kind of file you want to add - * by setting mode propertly (see man 2 stat). - * - * Note that special files are only written to image when Rock Ridge - * extensions are enabled. Moreover, a special file is just a directory entry - * in the image tree, no data is written beyond that. - * - * Owner and hidden atts are taken from parent. You can modify any of them - * later. - * - * @param parent - * the dir where the new special file will be created - * @param name - * name for the new special file. If a node with same name already exists - * on parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. - * @param mode - * file type and permissions for the new node. Note that you can't - * specify any kind of file here, only special types are allowed. i.e, - * S_IFSOCK, S_IFBLK, S_IFCHR and S_IFIFO are valid types; S_IFLNK, - * S_IFREG and S_IFDIR aren't. - * @param dev - * device ID, equivalent to the st_rdev field in man 2 stat. - * @param special - * place where to store a pointer to the newly created special file. No - * extra ref is addded, so you will need to call iso_node_ref() if you - * really need it. You can pass NULL in this parameter if you don't need - * the pointer. - * @return - * number of nodes in parent if success, < 0 otherwise - * Possible errors: - * ISO_NULL_POINTER, if parent, name or dest are NULL - * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists - * ISO_OUT_OF_MEM - * - */ -int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode, - dev_t dev, IsoSpecial **special) -{ - int ret; - char *n; - IsoSpecial *node; - IsoNode **pos; - time_t now; - - if (parent == NULL || name == NULL) { - return ISO_NULL_POINTER; - } - if (S_ISLNK(mode) || S_ISREG(mode) || S_ISDIR(mode)) { - return ISO_WRONG_ARG_VALUE; - } - if (special) { - *special = NULL; - } - - /* find place where to insert */ - if (iso_dir_exists(parent, name, &pos)) { - /* a node with same name already exists */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - - n = strdup(name); - ret = iso_node_new_special(n, mode, dev, &node); - if (ret < 0) { - free(n); - return ret; - } - - /* atts from parent */ - iso_node_set_uid((IsoNode*)node, parent->node.uid); - iso_node_set_gid((IsoNode*)node, parent->node.gid); - iso_node_set_hidden((IsoNode*)node, parent->node.hidden); - - /* current time */ - now = time(NULL); - iso_node_set_atime((IsoNode*)node, now); - iso_node_set_ctime((IsoNode*)node, now); - iso_node_set_mtime((IsoNode*)node, now); - - if (special) { - *special = node; - } - - /* add to dir */ - return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER); -} - -/** - * Set whether to follow or not symbolic links when added a file from a source - * to IsoImage. - */ -void iso_tree_set_follow_symlinks(IsoImage *image, int follow) -{ - image->follow_symlinks = follow ? 1 : 0; -} - -/** - * Get current setting for follow_symlinks. - * - * @see iso_tree_set_follow_symlinks - */ -int iso_tree_get_follow_symlinks(IsoImage *image) -{ - return image->follow_symlinks; -} - -/** - * Set whether to skip or not hidden files when adding a directory recursibely. - * Default behavior is to not ignore them, i.e., to add hidden files to image. - */ -void iso_tree_set_ignore_hidden(IsoImage *image, int skip) -{ - image->ignore_hidden = skip ? 1 : 0; -} - -/** - * Get current setting for ignore_hidden. - * - * @see iso_tree_set_ignore_hidden - */ -int iso_tree_get_ignore_hidden(IsoImage *image) -{ - return image->ignore_hidden; -} - -void iso_tree_set_replace_mode(IsoImage *image, enum iso_replace_mode mode) -{ - image->replace = mode; -} - -enum iso_replace_mode iso_tree_get_replace_mode(IsoImage *image) -{ - return image->replace; -} - -/** - * Set whether to skip or not special files. Default behavior is to not skip - * them. Note that, despite of this setting, special files won't never be added - * to an image unless RR extensions were enabled. - * - * @param skip - * Bitmask to determine what kind of special files will be skipped: - * bit0: ignore FIFOs - * bit1: ignore Sockets - * bit2: ignore char devices - * bit3: ignore block devices - */ -void iso_tree_set_ignore_special(IsoImage *image, int skip) -{ - image->ignore_special = skip & 0x0F; -} - -/** - * Get current setting for ignore_special. - * - * @see iso_tree_set_ignore_special - */ -int iso_tree_get_ignore_special(IsoImage *image) -{ - return image->ignore_special; -} - -/** - * Set a callback function that libisofs will call for each file that is - * added to the given image by a recursive addition function. This includes - * image import. - * - * @param report - * pointer to a function that will be called just before a file will be - * added to the image. You can control whether the file will be in fact - * added or ignored. - * This function should return 1 to add the file, 0 to ignore it and - * continue, < 0 to abort the process - * NULL is allowed if you don't want any callback. - */ -void iso_tree_set_report_callback(IsoImage *image, - int (*report)(IsoImage*, IsoFileSource*)) -{ - image->report = report; -} - -/** - * Add a excluded path. These are paths that won't never added to image, - * and will be excluded even when adding recursively its parent directory. - * - * For example, in - * - * iso_tree_add_exclude(image, "/home/user/data/private"); - * iso_tree_add_dir_rec(image, root, "/home/user/data"); - * - * the directory /home/user/data/private won't be added to image. - * - * @return - * 1 on success, < 0 on error - */ -int iso_tree_add_exclude(IsoImage *image, const char *path) -{ - if (image == NULL || path == NULL) { - return ISO_NULL_POINTER; - } - image->excludes = realloc(image->excludes, ++image->nexcludes * - sizeof(void*)); - if (image->excludes == NULL) { - return ISO_OUT_OF_MEM; - } - image->excludes[image->nexcludes - 1] = strdup(path); - if (image->excludes[image->nexcludes - 1] == NULL) { - return ISO_OUT_OF_MEM; - } - return ISO_SUCCESS; -} - -/** - * Remove a previously added exclude. - * - * @see iso_tree_add_exclude - * @return - * 1 on success, 0 exclude do not exists, < 0 on error - */ -int iso_tree_remove_exclude(IsoImage *image, const char *path) -{ - size_t i, j; - - if (image == NULL || path == NULL) { - return ISO_NULL_POINTER; - } - - for (i = 0; i < image->nexcludes; ++i) { - if (strcmp(image->excludes[i], path) == 0) { - /* exclude found */ - free(image->excludes[i]); - --image->nexcludes; - for (j = i; j < image->nexcludes; ++j) { - image->excludes[j] = image->excludes[j+1]; - } - image->excludes = realloc(image->excludes, image->nexcludes * - sizeof(void*)); - return ISO_SUCCESS; - } - } - return 0; -} - -static -int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent, - IsoFileSource *src, IsoNodeBuilder *builder, - IsoNode **node) -{ - int result; - IsoNode *new; - IsoNode **pos; - char *name; - - if (parent == NULL || src == NULL || builder == NULL) { - return ISO_NULL_POINTER; - } - if (node) { - *node = NULL; - } - - name = iso_file_source_get_name(src); - - /* find place where to insert */ - result = iso_dir_exists(parent, name, &pos); - free(name); - if (result) { - /* a node with same name already exists */ - return ISO_NODE_NAME_NOT_UNIQUE; - } - - result = builder->create_node(builder, image, src, &new); - if (result < 0) { - return result; - } - - if (node) { - *node = new; - } - - /* finally, add node to parent */ - return iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER); -} - -int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path, - IsoNode **node) -{ - int result; - IsoFilesystem *fs; - IsoFileSource *file; - - if (image == NULL || parent == NULL || path == NULL) { - return ISO_NULL_POINTER; - } - - fs = image->fs; - result = fs->get_by_path(fs, path, &file); - if (result < 0) { - return result; - } - result = iso_tree_add_node_builder(image, parent, file, image->builder, - node); - /* free the file */ - iso_file_source_unref(file); - return result; -} - -int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name, - const char *path, IsoNode **node) -{ - int result; - IsoFilesystem *fs; - IsoFileSource *file; - IsoNode *new; - IsoNode **pos; - - if (image == NULL || parent == NULL || name == NULL || path == NULL) { - return ISO_NULL_POINTER; - } - - if (node) { - *node = NULL; - } - - fs = image->fs; - result = fs->get_by_path(fs, path, &file); - if (result < 0) { - return result; - } - - /* find place where to insert */ - result = iso_dir_exists(parent, name, &pos); - if (result) { - /* a node with same name already exists */ - iso_file_source_unref(file); - return ISO_NODE_NAME_NOT_UNIQUE; - } - - result = image->builder->create_node(image->builder, image, file, &new); - if (result < 0) { - return result; - } - - /* free the file */ - iso_file_source_unref(file); - - result = iso_node_set_name(new, name); - if (result < 0) { - iso_node_unref(new); - return result; - } - - if (node) { - *node = new; - } - - /* finally, add node to parent */ - return iso_dir_insert(parent, new, pos, ISO_REPLACE_NEVER); -} - -static -int check_excludes(IsoImage *image, const char *path) -{ - int i; - - for (i = 0; i < image->nexcludes; ++i) { - char *exclude = image->excludes[i]; - if (exclude[0] == '/') { - /* absolute exclude, must completely match path */ - if (!fnmatch(exclude, path, FNM_PERIOD|FNM_PATHNAME)) { - return 1; - } - } else { - /* relative exclude, it is enought if a part of the path matches */ - char *pos = (char*)path; - while (pos != NULL) { - pos++; - if (!fnmatch(exclude, pos, FNM_PERIOD|FNM_PATHNAME)) { - return 1; - } - pos = strchr(pos, '/'); - } - } - } - return 0; -} - -static -int check_hidden(IsoImage *image, const char *name) -{ - return (image->ignore_hidden && name[0] == '.'); -} - -static -int check_special(IsoImage *image, mode_t mode) -{ - if (image->ignore_special != 0) { - switch(mode & S_IFMT) { - case S_IFBLK: - return image->ignore_special & 0x08 ? 1 : 0; - case S_IFCHR: - return image->ignore_special & 0x04 ? 1 : 0; - case S_IFSOCK: - return image->ignore_special & 0x02 ? 1 : 0; - case S_IFIFO: - return image->ignore_special & 0x01 ? 1 : 0; - default: - return 0; - } - } - return 0; -} - -/** - * Recursively add a given directory to the image tree. - * - * @return - * 1 continue, < 0 error (ISO_CANCELED stop) - */ -int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir) -{ - int ret; - IsoNodeBuilder *builder; - IsoFileSource *file; - IsoNode **pos; - struct stat info; - char *name, *path; - IsoNode *new; - enum iso_replace_mode replace; - - ret = iso_file_source_open(dir); - if (ret < 0) { - char *path = iso_file_source_get_path(dir); - /* instead of the probable error, we throw a sorry event */ - ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret, - "Can't open dir %s", path); - free(path); - return ret; - } - - builder = image->builder; - - /* iterate over all directory children */ - while (1) { - int skip = 0; - - ret = iso_file_source_readdir(dir, &file); - if (ret <= 0) { - if (ret < 0) { - /* error reading dir */ - ret = iso_msg_submit(image->id, ret, ret, "Error reading dir"); - } - break; - } - - path = iso_file_source_get_path(file); - name = strrchr(path, '/') + 1; - - if (image->follow_symlinks) { - ret = iso_file_source_stat(file, &info); - } else { - ret = iso_file_source_lstat(file, &info); - } - if (ret < 0) { - goto dir_rec_continue; - } - - if (check_excludes(image, path)) { - iso_msg_debug(image->id, "Skipping excluded file %s", path); - skip = 1; - } else if (check_hidden(image, name)) { - iso_msg_debug(image->id, "Skipping hidden file %s", path); - skip = 1; - } else if (check_special(image, info.st_mode)) { - iso_msg_debug(image->id, "Skipping special file %s", path); - skip = 1; - } - - if (skip) { - goto dir_rec_continue; - } - - replace = image->replace; - - /* find place where to insert */ - ret = iso_dir_exists(parent, name, &pos); - /* TODO - * if (ret && replace == ISO_REPLACE_ASK) { - * replace = /.... - * } - */ - - /* chek if we must insert or not */ - /* TODO check for other replace behavior */ - if (ret && (replace == ISO_REPLACE_NEVER)) { - /* skip file */ - goto dir_rec_continue; - } - - /* if we are here we must insert. Give user a chance for cancel */ - if (image->report) { - int r = image->report(image, file); - if (r <= 0) { - ret = (r < 0 ? ISO_CANCELED : ISO_SUCCESS); - goto dir_rec_continue; - } - } - ret = builder->create_node(builder, image, file, &new); - if (ret < 0) { - ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret, - "Error when adding file %s", path); - goto dir_rec_continue; - } - - /* ok, node has correctly created, we need to add it */ - ret = iso_dir_insert(parent, new, pos, replace); - if (ret < 0) { - iso_node_unref(new); - if (ret != ISO_NODE_NAME_NOT_UNIQUE) { - /* error */ - goto dir_rec_continue; - } else { - /* file ignored because a file with same node already exists */ - iso_msg_debug(image->id, "Skipping file %s. A node with same " - "file already exists", path); - ret = 0; - } - } else { - iso_msg_debug(image->id, "Added file %s", path); - } - - /* finally, if the node is a directory we need to recurse */ - if (new->type == LIBISO_DIR && S_ISDIR(info.st_mode)) { - ret = iso_add_dir_src_rec(image, (IsoDir*)new, file); - } - -dir_rec_continue:; - free(path); - iso_file_source_unref(file); - - /* check for error severity to decide what to do */ - if (ret < 0) { - ret = iso_msg_submit(image->id, ret, 0, NULL); - if (ret < 0) { - break; - } - } - } /* while */ - - iso_file_source_close(dir); - return ret < 0 ? ret : ISO_SUCCESS; -} - -int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir) -{ - int result; - struct stat info; - IsoFilesystem *fs; - IsoFileSource *file; - - if (image == NULL || parent == NULL || dir == NULL) { - return ISO_NULL_POINTER; - } - - fs = image->fs; - result = fs->get_by_path(fs, dir, &file); - if (result < 0) { - return result; - } - - /* we also allow dir path to be a symlink to a dir */ - result = iso_file_source_stat(file, &info); - if (result < 0) { - iso_file_source_unref(file); - return result; - } - - if (!S_ISDIR(info.st_mode)) { - iso_file_source_unref(file); - return ISO_FILE_IS_NOT_DIR; - } - result = iso_add_dir_src_rec(image, parent, file); - iso_file_source_unref(file); - return result; -} - -int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node) -{ - int result; - IsoNode *n; - IsoDir *dir; - char *ptr, *brk_info, *component; - - if (image == NULL || path == NULL) { - return ISO_NULL_POINTER; - } - - /* get the first child at the root of the image that is "/" */ - dir = image->root; - n = (IsoNode *)dir; - if (!strcmp(path, "/")) { - if (node) { - *node = n; - } - return ISO_SUCCESS; - } - - ptr = strdup(path); - result = 0; - - /* get the first component of the path */ - component = strtok_r(ptr, "/", &brk_info); - while (component) { - if (n->type != LIBISO_DIR) { - n = NULL; - break; - } - dir = (IsoDir *)n; - - result = iso_dir_get_node(dir, component, &n); - if (result != 1) { - n = NULL; - break; - } - - component = strtok_r(NULL, "/", &brk_info); - } - - free(ptr); - if (node) { - *node = n; - } - return result; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.h deleted file mode 100644 index 9c5347c8..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/tree.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_IMAGE_TREE_H_ -#define LIBISO_IMAGE_TREE_H_ - -#include "image.h" - -/** - * Recursively add a given directory to the image tree. - * - * @return - * 1 continue, 0 stop, < 0 error - */ -int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir); - -#endif /*LIBISO_IMAGE_TREE_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.c deleted file mode 100644 index 6317a8ba..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2007 Mario Danic - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "util.h" -#include "libisofs.h" -#include "../version.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* if we don't have eaccess, we check file access by openning it */ -#ifndef HAVE_EACCESS -#include -#include -#include -#endif - -int int_pow(int base, int power) -{ - int result = 1; - while (--power >= 0) { - result *= base; - } - return result; -} - -int strconv(const char *str, const char *icharset, const char *ocharset, - char **output) -{ - size_t inbytes; - size_t outbytes; - size_t n; - iconv_t conv; - char *out; - char *src; - char *ret; - - inbytes = strlen(str); - outbytes = (inbytes + 1) * MB_LEN_MAX; - out = alloca(outbytes); - if (out == NULL) { - return ISO_OUT_OF_MEM; - } - - conv = iconv_open(ocharset, icharset); - if (conv == (iconv_t)(-1)) { - return ISO_CHARSET_CONV_ERROR; - } - src = (char *)str; - ret = (char *)out; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - if (n == -1) { - /* error */ - iconv_close(conv); - return ISO_CHARSET_CONV_ERROR; - } - *ret = '\0'; - iconv_close(conv); - - *output = malloc(ret - out + 1); - if (*output == NULL) { - return ISO_OUT_OF_MEM; - } - memcpy(*output, out, ret - out + 1); - return ISO_SUCCESS; -} - -int strnconv(const char *str, const char *icharset, const char *ocharset, - size_t len, char **output) -{ - size_t inbytes; - size_t outbytes; - size_t n; - iconv_t conv; - char *out; - char *src; - char *ret; - - inbytes = len; - outbytes = (inbytes + 1) * MB_LEN_MAX; - out = alloca(outbytes); - if (out == NULL) { - return ISO_OUT_OF_MEM; - } - - conv = iconv_open(ocharset, icharset); - if (conv == (iconv_t)(-1)) { - return ISO_CHARSET_CONV_ERROR; - } - src = (char *)str; - ret = (char *)out; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - if (n == -1) { - /* error */ - iconv_close(conv); - return ISO_CHARSET_CONV_ERROR; - } - *ret = '\0'; - iconv_close(conv); - - *output = malloc(ret - out + 1); - if (*output == NULL) { - return ISO_OUT_OF_MEM; - } - memcpy(*output, out, ret - out + 1); - return ISO_SUCCESS; -} - -/** - * Convert a str in a specified codeset to WCHAR_T. - * The result must be free() when no more needed - * - * @return - * 1 success, < 0 error - */ -static -int str2wchar(const char *icharset, const char *input, wchar_t **output) -{ - iconv_t conv; - size_t inbytes; - size_t outbytes; - char *ret; - char *src; - wchar_t *wstr; - size_t n; - - if (icharset == NULL || input == NULL || output == NULL) { - return ISO_NULL_POINTER; - } - - conv = iconv_open("WCHAR_T", icharset); - if (conv == (iconv_t)-1) { - return ISO_CHARSET_CONV_ERROR; - } - - inbytes = strlen(input); - outbytes = (inbytes + 1) * sizeof(wchar_t); - - /* we are sure that numchars <= inbytes */ - wstr = malloc(outbytes); - if (wstr == NULL) { - return ISO_OUT_OF_MEM; - } - ret = (char *)wstr; - src = (char *)input; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - while (n == -1) { - - if (errno == E2BIG) { - /* error, should never occur */ - iconv_close(conv); - free(wstr); - return ISO_CHARSET_CONV_ERROR; - } else { - wchar_t *wret; - - /* - * Invalid input string charset. - * This can happen if input is in fact encoded in a charset - * different than icharset. - * We can't do anything better than replace by "_" and continue. - */ - inbytes--; - src++; - - wret = (wchar_t*) ret; - *wret++ = (wchar_t) '_'; - ret = (char *) wret; - outbytes -= sizeof(wchar_t); - - if (!inbytes) - break; - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - } - } - iconv_close(conv); - - *( (wchar_t *)ret )='\0'; - *output = wstr; - return ISO_SUCCESS; -} - -int str2ascii(const char *icharset, const char *input, char **output) -{ - int result; - wchar_t *wsrc_; - char *ret; - char *ret_; - char *src; - iconv_t conv; - size_t numchars; - size_t outbytes; - size_t inbytes; - size_t n; - - if (icharset == NULL || input == NULL || output == NULL) { - return ISO_NULL_POINTER; - } - - /* convert the string to a wide character string. Note: outbytes - * is in fact the number of characters in the string and doesn't - * include the last NULL character. - */ - result = str2wchar(icharset, input, &wsrc_); - if (result < 0) { - return result; - } - src = (char *)wsrc_; - numchars = wcslen(wsrc_); - - inbytes = numchars * sizeof(wchar_t); - - ret_ = malloc(numchars + 1); - if (ret_ == NULL) { - return ISO_OUT_OF_MEM; - } - outbytes = numchars; - ret = ret_; - - /* initialize iconv */ - conv = iconv_open("ASCII", "WCHAR_T"); - if (conv == (iconv_t)-1) { - free(wsrc_); - free(ret_); - return ISO_CHARSET_CONV_ERROR; - } - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - while (n == -1) { - /* The destination buffer is too small. Stops here. */ - if (errno == E2BIG) - break; - - /* An incomplete multi bytes sequence was found. We - * can't do anything here. That's quite unlikely. */ - if (errno == EINVAL) - break; - - /* The last possible error is an invalid multi bytes - * sequence. Just replace the character with a "_". - * Probably the character doesn't exist in ascii like - * "é, è, à, ç, ..." in French. */ - *ret++ = '_'; - outbytes--; - - if (!outbytes) - break; - - /* There was an error with one character but some other remain - * to be converted. That's probably a multibyte character. - * See above comment. */ - src += sizeof(wchar_t); - inbytes -= sizeof(wchar_t); - - if (!inbytes) - break; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - } - - iconv_close(conv); - - *ret='\0'; - free(wsrc_); - - *output = ret_; - return ISO_SUCCESS; -} - -static -void set_ucsbe(uint16_t *ucs, char c) -{ - char *v = (char*)ucs; - v[0] = (char)0; - v[1] = c; -} - -/** - * @return - * -1, 0, 1 if *ucs <, == or > than c - */ -static -int cmp_ucsbe(const uint16_t *ucs, char c) -{ - char *v = (char*)ucs; - if (v[0] != 0) { - return 1; - } else if (v[1] == c) { - return 0; - } else { - return (uint8_t)c > (uint8_t)v[1] ? -1 : 1; - } -} - -int str2ucs(const char *icharset, const char *input, uint16_t **output) -{ - int result; - wchar_t *wsrc_; - char *src; - char *ret; - char *ret_; - iconv_t conv; - size_t numchars; - size_t outbytes; - size_t inbytes; - size_t n; - - if (icharset == NULL || input == NULL || output == NULL) { - return ISO_NULL_POINTER; - } - - /* convert the string to a wide character string. Note: outbytes - * is in fact the number of characters in the string and doesn't - * include the last NULL character. - */ - result = str2wchar(icharset, input, &wsrc_); - if (result < 0) { - return result; - } - src = (char *)wsrc_; - numchars = wcslen(wsrc_); - - inbytes = numchars * sizeof(wchar_t); - - ret_ = malloc((numchars+1) * sizeof(uint16_t)); - if (ret_ == NULL) { - return ISO_OUT_OF_MEM; - } - outbytes = numchars * sizeof(uint16_t); - ret = ret_; - - /* initialize iconv */ - conv = iconv_open("UCS-2BE", "WCHAR_T"); - if (conv == (iconv_t)-1) { - free(wsrc_); - free(ret_); - return ISO_CHARSET_CONV_ERROR; - } - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - while (n == -1) { - /* The destination buffer is too small. Stops here. */ - if (errno == E2BIG) - break; - - /* An incomplete multi bytes sequence was found. We - * can't do anything here. That's quite unlikely. */ - if (errno == EINVAL) - break; - - /* The last possible error is an invalid multi bytes - * sequence. Just replace the character with a "_". - * Probably the character doesn't exist in UCS */ - set_ucsbe((uint16_t*) ret, '_'); - ret += sizeof(uint16_t); - outbytes -= sizeof(uint16_t); - - if (!outbytes) - break; - - /* There was an error with one character but some other remain - * to be converted. That's probably a multibyte character. - * See above comment. */ - src += sizeof(wchar_t); - inbytes -= sizeof(wchar_t); - - if (!inbytes) - break; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - } - - iconv_close(conv); - - /* close the ucs string */ - set_ucsbe((uint16_t*) ret, '\0'); - free(wsrc_); - - *output = (uint16_t*)ret_; - return ISO_SUCCESS; -} - -static int valid_d_char(char c) -{ - return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_'); -} - -static int valid_a_char(char c) -{ - return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?') || - (c >= 'A' && c <= 'Z') || (c == '_'); -} - -static int valid_j_char(uint16_t c) -{ - return cmp_ucsbe(&c, ' ') != -1 && cmp_ucsbe(&c, '*') && cmp_ucsbe(&c, '/') - && cmp_ucsbe(&c, ':') && cmp_ucsbe(&c, ';') && cmp_ucsbe(&c, '?') - && cmp_ucsbe(&c, '\\'); -} - -static -char *iso_dirid(const char *src, int size) -{ - size_t len, i; - char name[32]; - - len = strlen(src); - if (len > size) { - len = size; - } - for (i = 0; i < len; i++) { - char c= toupper(src[i]); - name[i] = valid_d_char(c) ? c : '_'; - } - - name[len] = '\0'; - return strdup(name); -} - -char *iso_1_dirid(const char *src) -{ - return iso_dirid(src, 8); -} - -char *iso_2_dirid(const char *src) -{ - return iso_dirid(src, 31); -} - -char *iso_1_fileid(const char *src) -{ - char *dot; /* Position of the last dot in the filename, will be used - * to calculate lname and lext. */ - int lname, lext, pos, i; - char dest[13]; /* 13 = 8 (name) + 1 (.) + 3 (ext) + 1 (\0) */ - - if (src == NULL) { - return NULL; - } - dot = strrchr(src, '.'); - - lext = dot ? strlen(dot + 1) : 0; - lname = strlen(src) - lext - (dot ? 1 : 0); - - /* If we can't build a filename, return NULL. */ - if (lname == 0 && lext == 0) { - return NULL; - } - - pos = 0; - - /* Convert up to 8 characters of the filename. */ - for (i = 0; i < lname && i < 8; i++) { - char c= toupper(src[i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - - /* This dot is mandatory, even if there is no extension. */ - dest[pos++] = '.'; - - /* Convert up to 3 characters of the extension, if any. */ - for (i = 0; i < lext && i < 3; i++) { - char c= toupper(src[lname + 1 + i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - - dest[pos] = '\0'; - return strdup(dest); -} - -char *iso_2_fileid(const char *src) -{ - char *dot; - int lname, lext, lnname, lnext, pos, i; - char dest[32]; /* 32 = 30 (name + ext) + 1 (.) + 1 (\0) */ - - if (src == NULL) { - return NULL; - } - - dot = strrchr(src, '.'); - - /* - * Since the maximum length can be divided freely over the name and - * extension, we need to calculate their new lengths (lnname and - * lnext). If the original filename is too long, we start by trimming - * the extension, but keep a minimum extension length of 3. - */ - if (dot == NULL || *(dot + 1) == '\0') { - lname = strlen(src); - lnname = (lname > 30) ? 30 : lname; - lext = lnext = 0; - } else { - lext = strlen(dot + 1); - lname = strlen(src) - lext - 1; - lnext = (strlen(src) > 31 && lext > 3) ? (lname < 27 ? 30 - lname : 3) - : lext; - lnname = (strlen(src) > 31) ? 30 - lnext : lname; - } - - if (lnname == 0 && lnext == 0) { - return NULL; - } - - pos = 0; - - /* Convert up to lnname characters of the filename. */ - for (i = 0; i < lnname; i++) { - char c= toupper(src[i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - dest[pos++] = '.'; - - /* Convert up to lnext characters of the extension, if any. */ - for (i = 0; i < lnext; i++) { - char c= toupper(src[lname + 1 + i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - dest[pos] = '\0'; - return strdup(dest); -} - -/** - * Create a dir name suitable for an ISO image with relaxed constraints. - * - * @param size - * Max len for the name - * @param relaxed - * 0 only allow d-characters, 1 allow also lowe case chars, - * 2 allow all characters - */ -char *iso_r_dirid(const char *src, int size, int relaxed) -{ - size_t len, i; - char *dest; - - len = strlen(src); - if (len > size) { - len = size; - } - dest = malloc(len + 1); - for (i = 0; i < len; i++) { - char c= src[i]; - if (relaxed == 2) { - /* all chars are allowed */ - dest[i] = c; - } else if (valid_d_char(c)) { - /* it is a valid char */ - dest[i] = c; - } else { - c= toupper(src[i]); - if (valid_d_char(c)) { - if (relaxed) { - /* lower chars are allowed */ - dest[i] = src[i]; - } else { - dest[i] = c; - } - } else { - dest[i] = '_'; - } - } - } - - dest[len] = '\0'; - return dest; -} - -/** - * Create a file name suitable for an ISO image with relaxed constraints. - * - * @param len - * Max len for the name, without taken the "." into account. - * @param relaxed - * 0 only allow d-characters, 1 allow also lowe case chars, - * 2 allow all characters - * @param forcedot - * Whether to ensure that "." is added - */ -char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot) -{ - char *dot; - int lname, lext, lnname, lnext, pos, i; - char *dest = alloca(len + 1 + 1); - - if (src == NULL) { - return NULL; - } - - dot = strrchr(src, '.'); - - /* - * Since the maximum length can be divided freely over the name and - * extension, we need to calculate their new lengths (lnname and - * lnext). If the original filename is too long, we start by trimming - * the extension, but keep a minimum extension length of 3. - */ - if (dot == NULL || *(dot + 1) == '\0') { - lname = strlen(src); - lnname = (lname > len) ? len : lname; - lext = lnext = 0; - } else { - lext = strlen(dot + 1); - lname = strlen(src) - lext - 1; - lnext = (strlen(src) > len + 1 && lext > 3) ? - (lname < len - 3 ? len - lname : 3) - : lext; - lnname = (strlen(src) > len + 1) ? len - lnext : lname; - } - - if (lnname == 0 && lnext == 0) { - return NULL; - } - - pos = 0; - - /* Convert up to lnname characters of the filename. */ - for (i = 0; i < lnname; i++) { - char c= src[i]; - if (relaxed == 2) { - /* all chars are allowed */ - dest[pos++] = c; - } else if (valid_d_char(c)) { - /* it is a valid char */ - dest[pos++] = c; - } else { - c= toupper(src[i]); - if (valid_d_char(c)) { - if (relaxed) { - /* lower chars are allowed */ - dest[pos++] = src[i]; - } else { - dest[pos++] = c; - } - } else { - dest[pos++] = '_'; - } - } - } - if (lnext > 0 || forcedot) { - dest[pos++] = '.'; - } - - /* Convert up to lnext characters of the extension, if any. */ - for (i = lname + 1; i < lname + 1 + lnext; i++) { - char c= src[i]; - if (relaxed == 2) { - /* all chars are allowed */ - dest[pos++] = c; - } else if (valid_d_char(c)) { - /* it is a valid char */ - dest[pos++] = c; - } else { - c= toupper(src[i]); - if (valid_d_char(c)) { - if (relaxed) { - /* lower chars are allowed */ - dest[pos++] = src[i]; - } else { - dest[pos++] = c; - } - } else { - dest[pos++] = '_'; - } - } - } - dest[pos] = '\0'; - return strdup(dest); -} - -uint16_t *iso_j_file_id(const uint16_t *src) -{ - uint16_t *dot; - size_t lname, lext, lnname, lnext, pos, i; - uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */ - - if (src == NULL) { - return NULL; - } - - dot = ucsrchr(src, '.'); - - /* - * Since the maximum length can be divided freely over the name and - * extension, we need to calculate their new lengths (lnname and - * lnext). If the original filename is too long, we start by trimming - * the extension, but keep a minimum extension length of 3. - */ - if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) { - lname = ucslen(src); - lnname = (lname > 64) ? 64 : lname; - lext = lnext = 0; - } else { - lext = ucslen(dot + 1); - lname = ucslen(src) - lext - 1; - lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3) - : lext; - lnname = (ucslen(src) > 65) ? 64 - lnext : lname; - } - - if (lnname == 0 && lnext == 0) { - return NULL; - } - - pos = 0; - - /* Convert up to lnname characters of the filename. */ - for (i = 0; i < lnname; i++) { - uint16_t c = src[i]; - if (valid_j_char(c)) { - dest[pos++] = c; - } else { - set_ucsbe(dest + pos, '_'); - pos++; - } - } - set_ucsbe(dest + pos, '.'); - pos++; - - /* Convert up to lnext characters of the extension, if any. */ - for (i = 0; i < lnext; i++) { - uint16_t c = src[lname + 1 + i]; - if (valid_j_char(c)) { - dest[pos++] = c; - } else { - set_ucsbe(dest + pos, '_'); - pos++; - } - } - set_ucsbe(dest + pos, '\0'); - return ucsdup(dest); -} - -uint16_t *iso_j_dir_id(const uint16_t *src) -{ - size_t len, i; - uint16_t dest[65]; /* 65 = 64 + 1 (\0) */ - - if (src == NULL) { - return NULL; - } - - len = ucslen(src); - if (len > 64) { - len = 64; - } - for (i = 0; i < len; i++) { - uint16_t c = src[i]; - if (valid_j_char(c)) { - dest[i] = c; - } else { - set_ucsbe(dest + i, '_'); - } - } - set_ucsbe(dest + len, '\0'); - return ucsdup(dest); -} - -size_t ucslen(const uint16_t *str) -{ - size_t i; - - for (i = 0; str[i]; i++) - ; - return i; -} - -uint16_t *ucsrchr(const uint16_t *str, char c) -{ - size_t len = ucslen(str); - - while (len-- > 0) { - if (cmp_ucsbe(str + len, c) == 0) { - return (uint16_t*)(str + len); - } - } - return NULL; -} - -uint16_t *ucsdup(const uint16_t *str) -{ - uint16_t *ret; - size_t len = ucslen(str); - - ret = malloc(2 * (len + 1)); - if (ret != NULL) { - memcpy(ret, str, 2 * (len + 1)); - } - return ret; -} - -/** - * Although each character is 2 bytes, we actually compare byte-by-byte - * (thats what the spec says). - */ -int ucscmp(const uint16_t *s1, const uint16_t *s2) -{ - const char *s = (const char*)s1; - const char *t = (const char*)s2; - size_t len1 = ucslen(s1); - size_t len2 = ucslen(s2); - size_t i, len = MIN(len1, len2) * 2; - - for (i = 0; i < len; i++) { - if (s[i] < t[i]) { - return -1; - } else if (s[i] > t[i]) { - return 1; - } - } - - if (len1 < len2) - return -1; - else if (len1 > len2) - return 1; - return 0; -} - -uint16_t *ucscpy(uint16_t *dest, const uint16_t *src) -{ - size_t n = ucslen(src) + 1; - memcpy(dest, src, n*2); - return dest; -} - -uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n) -{ - n = MIN(n, ucslen(src) + 1); - memcpy(dest, src, n*2); - return dest; -} - -int str2d_char(const char *icharset, const char *input, char **output) -{ - int ret; - char *ascii; - size_t len, i; - - if (output == NULL) { - return ISO_OUT_OF_MEM; - } - - /** allow NULL input */ - if (input == NULL) { - *output = NULL; - return 0; - } - - /* this checks for NULL parameters */ - ret = str2ascii(icharset, input, &ascii); - if (ret < 0) { - *output = NULL; - return ret; - } - - len = strlen(ascii); - - for (i = 0; i < len; ++i) { - char c= toupper(ascii[i]); - ascii[i] = valid_d_char(c) ? c : '_'; - } - - *output = ascii; - return ISO_SUCCESS; -} - -int str2a_char(const char *icharset, const char *input, char **output) -{ - int ret; - char *ascii; - size_t len, i; - - if (output == NULL) { - return ISO_OUT_OF_MEM; - } - - /** allow NULL input */ - if (input == NULL) { - *output = NULL; - return 0; - } - - /* this checks for NULL parameters */ - ret = str2ascii(icharset, input, &ascii); - if (ret < 0) { - *output = NULL; - return ret; - } - - len = strlen(ascii); - - for (i = 0; i < len; ++i) { - char c= toupper(ascii[i]); - ascii[i] = valid_a_char(c) ? c : '_'; - } - - *output = ascii; - return ISO_SUCCESS; -} - -void iso_lsb(uint8_t *buf, uint32_t num, int bytes) -{ - int i; - - for (i = 0; i < bytes; ++i) - buf[i] = (num >> (8 * i)) & 0xff; -} - -void iso_msb(uint8_t *buf, uint32_t num, int bytes) -{ - int i; - - for (i = 0; i < bytes; ++i) - buf[bytes - 1 - i] = (num >> (8 * i)) & 0xff; -} - -void iso_bb(uint8_t *buf, uint32_t num, int bytes) -{ - iso_lsb(buf, num, bytes); - iso_msb(buf+bytes, num, bytes); -} - -uint32_t iso_read_lsb(const uint8_t *buf, int bytes) -{ - int i; - uint32_t ret = 0; - - for (i=0; i 52 || tzoffset < -48 || always_gmt) { - /* absurd timezone offset, represent time in GMT */ - gmtime_r(&t, &tm); - tzoffset = 0; - } - buf[0] = tm.tm_year; - buf[1] = tm.tm_mon + 1; - buf[2] = tm.tm_mday; - buf[3] = tm.tm_hour; - buf[4] = tm.tm_min; - buf[5] = tm.tm_sec; - buf[6] = tzoffset; -} - -void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt) -{ - static int tzsetup = 0; - static int tzoffset; - struct tm tm; - - if (t == (time_t) - 1) { - /* unspecified time */ - memset(buf, '0', 16); - buf[16] = 0; - return; - } - - if (!tzsetup) { - tzset(); - tzsetup = 1; - } - - memset(&tm, 0, sizeof(tm)); - tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */ - localtime_r(&t, &tm); - - localtime_r(&t, &tm); - -#ifdef HAVE_TM_GMTOFF - tzoffset = tm.tm_gmtoff / 60 / 15; -#else - if (tm.tm_isdst < 0) - tm.tm_isdst = 0; - tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst; -#endif - - if (tzoffset > 52 || tzoffset < -48 || always_gmt) { - /* absurd timezone offset, represent time in GMT */ - gmtime_r(&t, &tm); - tzoffset = 0; - } - - sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900); - sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1); - sprintf((char*)&buf[6], "%02d", tm.tm_mday); - sprintf((char*)&buf[8], "%02d", tm.tm_hour); - sprintf((char*)&buf[10], "%02d", tm.tm_min); - sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec)); - memcpy(&buf[14], "00", 2); - buf[16] = tzoffset; - -} - -#ifndef HAVE_TIMEGM -static -time_t timegm(struct tm *tm) -{ - time_t ret; - char *tz; - - tz = getenv("TZ"); - setenv("TZ", "", 1); - tzset(); - ret = mktime(tm); - if (tz) - setenv("TZ", tz, 1); - else - unsetenv("TZ"); - tzset(); - return ret; -} -#endif - -time_t iso_datetime_read_7(const uint8_t *buf) -{ - struct tm tm; - - tm.tm_year = buf[0]; - tm.tm_mon = buf[1] - 1; - tm.tm_mday = buf[2]; - tm.tm_hour = buf[3]; - tm.tm_min = buf[4]; - tm.tm_sec = buf[5]; - return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15; -} - -time_t iso_datetime_read_17(const uint8_t *buf) -{ - struct tm tm; - - sscanf((char*)&buf[0], "%4d", &tm.tm_year); - sscanf((char*)&buf[4], "%2d", &tm.tm_mon); - sscanf((char*)&buf[6], "%2d", &tm.tm_mday); - sscanf((char*)&buf[8], "%2d", &tm.tm_hour); - sscanf((char*)&buf[10], "%2d", &tm.tm_min); - sscanf((char*)&buf[12], "%2d", &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15; -} - -/** - * Check whether the caller process has read access to the given local file. - * - * @return - * 1 on success (i.e, the process has read access), < 0 on error - * (including ISO_FILE_ACCESS_DENIED on access denied to the specified file - * or any directory on the path). - */ -int iso_eaccess(const char *path) -{ - int access; - - /* use non standard eaccess when available, open() otherwise */ -#ifdef HAVE_EACCESS - access = !eaccess(path, R_OK); -#else - int fd = open(path, O_RDONLY); - if (fd != -1) { - close(fd); - access = 1; - } else { - access = 0; - } -#endif - - if (!access) { - int err; - - /* error, choose an appropriate return code */ - switch (errno) { - case EACCES: - err = ISO_FILE_ACCESS_DENIED; - break; - case ENOTDIR: - case ENAMETOOLONG: - case ELOOP: - err = ISO_FILE_BAD_PATH; - break; - case ENOENT: - err = ISO_FILE_DOESNT_EXIST; - break; - case EFAULT: - case ENOMEM: - err = ISO_OUT_OF_MEM; - break; - default: - err = ISO_FILE_ERROR; - break; - } - return err; - } - return ISO_SUCCESS; -} - -char *strcopy(const char *buf, size_t len) -{ - char *str; - - str = malloc((len + 1) * sizeof(char)); - if (str == NULL) { - return NULL; - } - strncpy(str, buf, len); - str[len] = '\0'; - - /* remove trailing spaces */ - for (len = len-1; str[len] == ' ' && len > 0; --len) - str[len] = '\0'; - - return str; -} - -/** - * Copy up to \p max characters from \p src to \p dest. If \p src has less than - * \p max characters, we pad dest with " " characters. - */ -void strncpy_pad(char *dest, const char *src, size_t max) -{ - size_t len, i; - - if (src != NULL) { - len = MIN(strlen(src), max); - } else { - len = 0; - } - - for (i = 0; i < len; ++i) - dest[i] = src[i]; - for (i = len; i < max; ++i) - dest[i] = ' '; -} - -char *ucs2str(const char *buf, size_t len) -{ - size_t outbytes, inbytes; - char *str, *src, *out; - iconv_t conv; - size_t n; - - inbytes = len; - - outbytes = (inbytes+1) * MB_LEN_MAX; - - /* ensure enought space */ - out = alloca(outbytes); - - /* convert to local charset */ - setlocale(LC_CTYPE, ""); - conv = iconv_open(nl_langinfo(CODESET), "UCS-2BE"); - if (conv == (iconv_t)(-1)) { - return NULL; - } - src = (char *)buf; - str = (char *)out; - - n = iconv(conv, &src, &inbytes, &str, &outbytes); - if (n == -1) { - /* error */ - iconv_close(conv); - return NULL; - } - iconv_close(conv); - *str = '\0'; - - /* remove trailing spaces */ - for (len = strlen(out) - 1; out[len] == ' ' && len > 0; --len) - out[len] = '\0'; - return strdup(out); -} - -void iso_lib_version(int *major, int *minor, int *micro) -{ - *major = LIBISOFS_MAJOR_VERSION; - *minor = LIBISOFS_MINOR_VERSION; - *micro = LIBISOFS_MICRO_VERSION; -} - -int iso_lib_is_compatible(int major, int minor, int micro) -{ - int cmajor, cminor, cmicro; - - /* for now, the rule is that library is compitable if requested - * version is lower */ - iso_lib_version(&cmajor, &cminor, &cmicro); - - return cmajor > major - || (cmajor == major - && (cminor > minor - || (cminor == minor && cmicro >= micro))); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.h deleted file mode 100644 index 5a9616c5..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#ifndef LIBISO_UTIL_H_ -#define LIBISO_UTIL_H_ - -#include -#include - -#ifndef MAX -# define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -# define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#define DIV_UP(n,div) ((n + div - 1) / div) -#define ROUND_UP(n,mul) (DIV_UP(n, mul) * mul) - -int int_pow(int base, int power); - -/** - * Convert the charset encoding of a given string. - * - * @param input - * Input string - * @param icharset - * Input charset. Must be supported by iconv - * @param ocharset - * Output charset. Must be supported by iconv - * @param output - * Location where the pointer to the ouput string will be stored - * @return - * 1 on success, < 0 on error - */ -int strconv(const char *input, const char *icharset, const char *ocharset, - char **output); - -int strnconv(const char *str, const char *icharset, const char *ocharset, - size_t len, char **output); - -/** - * Convert a given string from any input charset to ASCII - * - * @param icharset - * Input charset. Must be supported by iconv - * @param input - * Input string - * @param output - * Location where the pointer to the ouput string will be stored - * @return - * 1 on success, < 0 on error - */ -int str2ascii(const char *icharset, const char *input, char **output); - -/** - * Convert a given string from any input charset to UCS-2BE charset, - * used for Joliet file identifiers. - * - * @param icharset - * Input charset. Must be supported by iconv - * @param input - * Input string - * @param output - * Location where the pointer to the ouput string will be stored - * @return - * 1 on success, < 0 on error - */ -int str2ucs(const char *icharset, const char *input, uint16_t **output); - -/** - * Create a level 1 directory identifier. - * - * @param src - * The identifier, in ASCII encoding. - */ -char *iso_1_dirid(const char *src); - -/** - * Create a level 2 directory identifier. - * - * @param src - * The identifier, in ASCII encoding. - */ -char *iso_2_dirid(const char *src); - -/** - * Create a dir name suitable for an ISO image with relaxed constraints. - * - * @param src - * The identifier, in ASCII encoding. - * @param size - * Max len for the name - * @param relaxed - * 0 only allow d-characters, 1 allow also lowe case chars, - * 2 allow all characters - */ -char *iso_r_dirid(const char *src, int size, int relaxed); - -/** - * Create a level 1 file identifier that consists of a name, in 8.3 - * format. - * Note that version number is not added to the file name - * - * @param src - * The identifier, in ASCII encoding. - */ -char *iso_1_fileid(const char *src); - -/** - * Create a level 2 file identifier. - * Note that version number is not added to the file name - * - * @param src - * The identifier, in ASCII encoding. - */ -char *iso_2_fileid(const char *src); - -/** - * Create a file name suitable for an ISO image with relaxed constraints. - * - * @param src - * The identifier, in ASCII encoding. - * @param len - * Max len for the name, without taken the "." into account. - * @param relaxed - * 0 only allow d-characters, 1 allow also lowe case chars, - * 2 allow all characters - * @param forcedot - * Whether to ensure that "." is added - */ -char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot); - -/** - * Create a Joliet file identifier that consists of name and extension. The - * combined name and extension length will not exceed 128 bytes, and the - * name and extension will be separated (.). All characters consist of - * 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL. - * - * Note that version number and (;1) is not appended. - * - * @return - * NULL if the original name and extension both are of length 0. - */ -uint16_t *iso_j_file_id(const uint16_t *src); - -/** - * Create a Joliet directory identifier that consists of name and optionally - * extension. The combined name and extension length will not exceed 128 bytes, - * and the name and extension will be separated (.). All characters consist of - * 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL. - * - * @return - * NULL if the original name and extension both are of length 0. - */ -uint16_t *iso_j_dir_id(const uint16_t *src); - -/** - * Like strlen, but for Joliet strings. - */ -size_t ucslen(const uint16_t *str); - -/** - * Like strrchr, but for Joliet strings. - */ -uint16_t *ucsrchr(const uint16_t *str, char c); - -/** - * Like strdup, but for Joliet strings. - */ -uint16_t *ucsdup(const uint16_t *str); - -/** - * Like strcmp, but for Joliet strings. - */ -int ucscmp(const uint16_t *s1, const uint16_t *s2); - -/** - * Like strcpy, but for Joliet strings. - */ -uint16_t *ucscpy(uint16_t *dest, const uint16_t *src); - -/** - * Like strncpy, but for Joliet strings. - * @param n - * Maximum number of characters to copy (2 bytes per char). - */ -uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n); - -/** - * Convert a given input string to d-chars. - * @return - * 1 on succes, < 0 error, 0 if input was null (output is set to null) - */ -int str2d_char(const char *icharset, const char *input, char **output); -int str2a_char(const char *icharset, const char *input, char **output); - -void iso_lsb(uint8_t *buf, uint32_t num, int bytes); -void iso_msb(uint8_t *buf, uint32_t num, int bytes); -void iso_bb(uint8_t *buf, uint32_t num, int bytes); - -uint32_t iso_read_lsb(const uint8_t *buf, int bytes); -uint32_t iso_read_msb(const uint8_t *buf, int bytes); - -/** - * if error != NULL it will be set to 1 if LSB and MSB integers don't match. - */ -uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error); - -/** - * Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5) - * - * @param buf - * Buffer where the date will be written - * @param t - * The time to be written - * @param always_gmt - * Always write the date in GMT and not in local time. - */ -void iso_datetime_7(uint8_t *buf, time_t t, int always_gmt); - -/** Records the date/time into a 17 byte buffer (ECMA-119, 8.4.26.1) */ -void iso_datetime_17(uint8_t *buf, time_t t, int always_gmt); - -time_t iso_datetime_read_7(const uint8_t *buf); -time_t iso_datetime_read_17(const uint8_t *buf); - -/** - * Check whether the caller process has read access to the given local file. - * - * @return - * 1 on success (i.e, the process has read access), < 0 on error - * (including ISO_FILE_ACCESS_DENIED on access denied to the specified file - * or any directory on the path). - */ -int iso_eaccess(const char *path); - -/** - * Copy up to \p len chars from \p buf and return this newly allocated - * string. The new string is null-terminated. - */ -char *strcopy(const char *buf, size_t len); - -/** - * Copy up to \p max characters from \p src to \p dest. If \p src has less than - * \p max characters, we pad dest with " " characters. - */ -void strncpy_pad(char *dest, const char *src, size_t max); - -/** - * Convert a Joliet string with a length of \p len bytes to a new string - * in local charset. - */ -char *ucs2str(const char *buf, size_t len); - -typedef struct iso_rbtree IsoRBTree; -typedef struct iso_htable IsoHTable; - -typedef unsigned int (*hash_funtion_t)(const void *key); -typedef int (*compare_function_t)(const void *a, const void *b); -typedef void (*hfree_data_t)(void *key, void *data); - -/** - * Create a new binary tree. libisofs binary trees allow you to add any data - * passing it as a pointer. You must provide a function suitable for compare - * two elements. - * - * @param compare - * A function to compare two keys. It takes a pointer to both keys - * and return 0, -1 or 1 if the first key is equal, less or greater - * than the second one. - * @param tree - * Location where the tree structure will be stored. - */ -int iso_rbtree_new(int (*compare)(const void*, const void*), IsoRBTree **tree); - -/** - * Destroy a given tree. - * - * Note that only the structure itself is deleted. To delete the elements, you - * should provide a valid free_data function. It will be called for each - * element of the tree, so you can use it to free any related data. - */ -void iso_rbtree_destroy(IsoRBTree *tree, void (*free_data)(void *)); - -/** - * Inserts a given element in a Red-Black tree. - * - * @param tree - * the tree where to insert - * @param data - * element to be inserted on the tree. It can't be NULL - * @param item - * if not NULL, it will point to a location where the tree element ptr - * will be stored. If data was inserted, *item == data. If data was - * already on the tree, *item points to the previously inserted object - * that is equal to data. - * @return - * 1 success, 0 element already inserted, < 0 error - */ -int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item); - -/** - * Get the number of elements in a given tree. - */ -size_t iso_rbtree_get_size(IsoRBTree *tree); - -/** - * Get an array view of the elements of the tree. - * - * @param include_item - * Function to select which elements to include in the array. It that takes - * a pointer to an element and returns 1 if the element should be included, - * 0 if not. If you want to add all elements to the array, you can pass a - * NULL pointer. - * @param size - * If not null, will be filled with the number of elements in the array, - * without counting the final NULL item. - * @return - * A sorted array with the contents of the tree, or NULL if there is not - * enought memory to allocate the array. You should free(3) the array when - * no more needed. Note that the array is NULL-terminated, and thus it - * has size + 1 length. - */ -void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *), - size_t *size); - -/** - * Create a new hash table. - * - * @param size - * Number of slots in table. - * @param hash - * Function used to generate - */ -int iso_htable_create(size_t size, hash_funtion_t hash, - compare_function_t compare, IsoHTable **table); - -/** - * Put an element in a Hash Table. The element will be identified by - * the given key, that you should use to retrieve the element again. - * - * This function allow duplicates, i.e., two items with the same key. In those - * cases, the value returned by iso_htable_get() is undefined. If you don't - * want to allow duplicates, use iso_htable_put() instead; - * - * Both the key and data pointers will be stored internally, so you should - * free the objects they point to. Use iso_htable_remove() to delete an - * element from the table. - */ -int iso_htable_add(IsoHTable *table, void *key, void *data); - -/** - * Like iso_htable_add(), but this doesn't allow dulpicates. - * - * @return - * 1 success, 0 if an item with the same key already exists, < 0 error - */ -int iso_htable_put(IsoHTable *table, void *key, void *data); - -/** - * Retrieve an element from the given table. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param data - * Will be filled with the element found. Remains untouched if no - * element with the given key is found. - * @return - * 1 if found, 0 if not, < 0 on error - */ -int iso_htable_get(IsoHTable *table, void *key, void **data); - -/** - * Remove an item with the given key from the table. In tables that allow - * duplicates, it is undefined the element that will be deleted. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param free_data - * Function that will be called passing as parameters both the key and - * the element that will be deleted. The user can use it to free the - * element. You can pass NULL if you don't want to delete the item itself. - * @return - * 1 success, 0 no element exists with the given key, < 0 error - */ -int iso_htable_remove(IsoHTable *table, void *key, hfree_data_t free_data); - -/** - * Like remove, but instead of checking for key equality using the compare - * function, it just compare the key pointers. If the table allows duplicates, - * and you provide different keys (i.e. different pointers) to elements - * with same key (i.e. same content), this function ensure the exact element - * is removed. - * - * It has the problem that you must provide the same key pointer, and not just - * a key whose contents are equal. Moreover, if you use the same key (same - * pointer) to identify several objects, what of those are removed is - * undefined. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param free_data - * Function that will be called passing as parameters both the key and - * the element that will be deleted. The user can use it to free the - * element. You can pass NULL if you don't want to delete the item itself. - * @return - * 1 success, 0 no element exists with the given key, < 0 error - */ -int iso_htable_remove_ptr(IsoHTable *table, void *key, hfree_data_t free_data); - -/** - * Destroy the given hash table. - * - * Note that you're responsible to actually destroy the elements by providing - * a valid free_data function. You can pass NULL if you only want to delete - * the hash structure. - */ -void iso_htable_destroy(IsoHTable *table, hfree_data_t free_data); - -/** - * Hash function suitable for keys that are char strings. - */ -unsigned int iso_str_hash(const void *key); - -#endif /*LIBISO_UTIL_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_htable.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_htable.c deleted file mode 100644 index 684ce6e9..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_htable.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "util.h" -#include "libisofs.h" - -#include -#include - -/* - * Hash table implementation - */ - -struct iso_hnode -{ - void *key; - void *data; - - /** next node for chaining */ - struct iso_hnode *next; -}; - -struct iso_htable -{ - struct iso_hnode **table; - - size_t size; /**< number of items in table */ - size_t cap; /**< number of slots in table */ - - hash_funtion_t hash; - compare_function_t compare; -}; - -static -struct iso_hnode *iso_hnode_new(void *key, void *data) -{ - struct iso_hnode *node = malloc(sizeof(struct iso_hnode)); - if (node == NULL) - return NULL; - - node->data = data; - node->key = key; - node->next = NULL; - return node; -} - -/** - * Put an element in a Hash Table. The element will be identified by - * the given key, that you should use to retrieve the element again. - * - * This function allow duplicates, i.e., two items with the same key. In those - * cases, the value returned by iso_htable_get() is undefined. If you don't - * want to allow duplicates, use iso_htable_put() instead; - * - * Both the key and data pointers will be stored internally, so you should - * free the objects they point to. Use iso_htable_remove() to delete an - * element from the table. - */ -int iso_htable_add(IsoHTable *table, void *key, void *data) -{ - struct iso_hnode *node; - struct iso_hnode *new; - unsigned int hash; - - if (table == NULL || key == NULL) { - return ISO_NULL_POINTER; - } - - new = iso_hnode_new(key, data); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - - hash = table->hash(key) % table->cap; - node = table->table[hash]; - - table->size++; - new->next = node; - table->table[hash] = new; - return ISO_SUCCESS; -} - -/** - * Like iso_htable_add(), but this doesn't allow dulpicates. - * - * @return - * 1 success, 0 if an item with the same key already exists, < 0 error - */ -int iso_htable_put(IsoHTable *table, void *key, void *data) -{ - struct iso_hnode *node; - struct iso_hnode *new; - unsigned int hash; - - if (table == NULL || key == NULL) { - return ISO_NULL_POINTER; - } - - hash = table->hash(key) % table->cap; - node = table->table[hash]; - - while (node) { - if (!table->compare(key, node->key)) { - return 0; - } - node = node->next; - } - - new = iso_hnode_new(key, data); - if (new == NULL) { - return ISO_OUT_OF_MEM; - } - - table->size++; - new->next = table->table[hash]; - table->table[hash] = new; - return ISO_SUCCESS; -} - -/** - * Retrieve an element from the given table. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param data - * Will be filled with the element found. Remains untouched if no - * element with the given key is found. - * @return - * 1 if found, 0 if not, < 0 on error - */ -int iso_htable_get(IsoHTable *table, void *key, void **data) -{ - struct iso_hnode *node; - unsigned int hash; - - if (table == NULL || key == NULL) { - return ISO_NULL_POINTER; - } - - hash = table->hash(key) % table->cap; - node = table->table[hash]; - while (node) { - if (!table->compare(key, node->key)) { - if (data) { - *data = node->data; - } - return 1; - } - node = node->next; - } - return 0; -} - -/** - * Remove an item with the given key from the table. In tables that allow - * duplicates, it is undefined the element that will be deleted. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param free_data - * Function that will be called passing as parameters both the key and - * the element that will be deleted. The user can use it to free the - * element. You can pass NULL if you don't want to delete the item itself. - * @return - * 1 success, 0 no element exists with the given key, < 0 error - */ -int iso_htable_remove(IsoHTable *table, void *key, hfree_data_t free_data) -{ - struct iso_hnode *node, *prev; - unsigned int hash; - - if (table == NULL || key == NULL) { - return ISO_NULL_POINTER; - } - - hash = table->hash(key) % table->cap; - node = table->table[hash]; - prev = NULL; - while (node) { - if (!table->compare(key, node->key)) { - if (free_data) - free_data(node->key, node->data); - if (prev) { - prev->next = node->next; - } else { - table->table[hash] = node->next; - } - free(node); - table->size--; - return 1; - } - prev = node; - node = node->next; - } - return 0; -} - -/** - * Like remove, but instead of checking for key equality using the compare - * function, it just compare the key pointers. If the table allows duplicates, - * and you provide different keys (i.e. different pointers) to elements - * with same key (i.e. same content), this function ensure the exact element - * is removed. - * - * It has the problem that you must provide the same key pointer, and not just - * a key whose contents are equal. Moreover, if you use the same key (same - * pointer) to identify several objects, what of those are removed is - * undefined. - * - * @param table - * Hash table - * @param key - * Key of the element that will be removed - * @param free_data - * Function that will be called passing as parameters both the key and - * the element that will be deleted. The user can use it to free the - * element. You can pass NULL if you don't want to delete the item itself. - * @return - * 1 success, 0 no element exists with the given key, < 0 error - */ -int iso_htable_remove_ptr(IsoHTable *table, void *key, hfree_data_t free_data) -{ - struct iso_hnode *node, *prev; - unsigned int hash; - - if (table == NULL || key == NULL) { - return ISO_NULL_POINTER; - } - - hash = table->hash(key) % table->cap; - node = table->table[hash]; - prev = NULL; - while (node) { - if (key == node->key) { - if (free_data) - free_data(node->key, node->data); - if (prev) { - prev->next = node->next; - } else { - table->table[hash] = node->next; - } - free(node); - table->size--; - return 1; - } - prev = node; - node = node->next; - } - return 0; -} - -/** - * Hash function suitable for keys that are char strings. - */ -unsigned int iso_str_hash(const void *key) -{ - int i, len; - const char *p = key; - unsigned int h = 2166136261u; - - len = strlen(p); - for (i = 0; i < len; i++) - h = (h * 16777619 ) ^ p[i]; - - return h; -} - -/** - * Destroy the given hash table. - * - * Note that you're responsible to actually destroy the elements by providing - * a valid free_data function. You can pass NULL if you only want to delete - * the hash structure. - */ -void iso_htable_destroy(IsoHTable *table, hfree_data_t free_data) -{ - size_t i; - struct iso_hnode *node, *tmp; - - if (table == NULL) { - return; - } - - for (i = 0; i < table->cap; ++i) { - node = table->table[i]; - while (node) { - tmp = node->next; - if (free_data) - free_data(node->key, node->data); - free(node); - node = tmp; - } - } - free(table->table); - free(table); -} - -/** - * Create a new hash table. - * - * @param size - * Number of slots in table. - * @param hash - * Function used to generate - */ -int iso_htable_create(size_t size, hash_funtion_t hash, - compare_function_t compare, IsoHTable **table) -{ - IsoHTable *t; - - if (table == NULL) { - return ISO_OUT_OF_MEM; - } - - t = malloc(sizeof(IsoHTable)); - if (t == NULL) { - return ISO_OUT_OF_MEM; - } - t->table = calloc(size, sizeof(void*)); - if (t->table == NULL) { - free(t); - return ISO_OUT_OF_MEM; - } - t->cap = size; - t->size = 0; - t->hash = hash; - t->compare = compare; - - *table = t; - return ISO_SUCCESS; -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_rbtree.c b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_rbtree.c deleted file mode 100644 index 7a30fc20..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/util_rbtree.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ - -#include "util.h" -#include "libisofs.h" - -#include - -/* - * This implementation of Red-Black tree is based on the public domain - * implementation of Julienne Walker. - */ - -struct iso_rbnode -{ - void *data; - struct iso_rbnode *ch[2]; - unsigned int red :1; -}; - -struct iso_rbtree -{ - struct iso_rbnode *root; - size_t size; - int (*compare)(const void *a, const void *b); -}; - -/** - * Create a new binary tree. libisofs binary trees allow you to add any data - * passing it as a pointer. You must provide a function suitable for compare - * two elements. - * - * @param compare - * A function to compare two elements. It takes a pointer to both elements - * and return 0, -1 or 1 if the first element is equal, less or greater - * than the second one. - * @param tree - * Location where the tree structure will be stored. - */ -int iso_rbtree_new(int (*compare)(const void*, const void*), IsoRBTree **tree) -{ - if (compare == NULL || tree == NULL) { - return ISO_NULL_POINTER; - } - *tree = calloc(1, sizeof(IsoRBTree)); - if (*tree == NULL) { - return ISO_OUT_OF_MEM; - } - (*tree)->compare = compare; - return ISO_SUCCESS; -} - -static -void rbtree_destroy_aux(struct iso_rbnode *root, void (*free_data)(void *)) -{ - if (root == NULL) { - return; - } - if (free_data != NULL) { - free_data(root->data); - } - rbtree_destroy_aux(root->ch[0], free_data); - rbtree_destroy_aux(root->ch[1], free_data); - free(root); -} - -/** - * Destroy a given tree. - * - * Note that only the structure itself is deleted. To delete the elements, you - * should provide a valid free_data function. It will be called for each - * element of the tree, so you can use it to free any related data. - */ -void iso_rbtree_destroy(IsoRBTree *tree, void (*free_data)(void *)) -{ - if (tree == NULL) { - return; - } - rbtree_destroy_aux(tree->root, free_data); - free(tree); -} - -static inline -int is_red(struct iso_rbnode *root) -{ - return root != NULL && root->red; -} - -static -struct iso_rbnode *iso_rbtree_single(struct iso_rbnode *root, int dir) -{ - struct iso_rbnode *save = root->ch[!dir]; - - root->ch[!dir] = save->ch[dir]; - save->ch[dir] = root; - - root->red = 1; - save->red = 0; - return save; -} - -static -struct iso_rbnode *iso_rbtree_double(struct iso_rbnode *root, int dir) -{ - root->ch[!dir] = iso_rbtree_single(root->ch[!dir], !dir); - return iso_rbtree_single(root, dir); -} - -static -struct iso_rbnode *iso_rbnode_new(void *data) -{ - struct iso_rbnode *rn = malloc(sizeof(struct iso_rbnode)); - - if (rn != NULL) { - rn->data = data; - rn->red = 1; - rn->ch[0] = NULL; - rn->ch[1] = NULL; - } - - return rn; -} - -/** - * Inserts a given element in a Red-Black tree. - * - * @param tree - * the tree where to insert - * @param data - * element to be inserted on the tree. It can't be NULL - * @param item - * if not NULL, it will point to a location where the tree element ptr - * will be stored. If data was inserted, *item == data. If data was - * already on the tree, *item points to the previously inserted object - * that is equal to data. - * @return - * 1 success, 0 element already inserted, < 0 error - */ -int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item) -{ - struct iso_rbnode *new; - int added = 0; /* has a new node been added? */ - - if (tree == NULL || data == NULL) { - return ISO_NULL_POINTER; - } - - if (tree->root == NULL) { - /* Empty tree case */ - tree->root = iso_rbnode_new(data); - if (tree->root == NULL) { - return ISO_OUT_OF_MEM; - } - new = data; - added = 1; - } else { - struct iso_rbnode head = { 0 }; /* False tree root */ - - struct iso_rbnode *g, *t; /* Grandparent & parent */ - struct iso_rbnode *p, *q; /* Iterator & parent */ - int dir = 0, last = 0; - int comp; - - /* Set up helpers */ - t = &head; - g = p = NULL; - q = t->ch[1] = tree->root; - - /* Search down the tree */ - while (1) { - if (q == NULL) { - /* Insert new node at the bottom */ - p->ch[dir] = q = iso_rbnode_new(data); - if (q == NULL) { - return ISO_OUT_OF_MEM; - } - added = 1; - } else if (is_red(q->ch[0]) && is_red(q->ch[1])) { - /* Color flip */ - q->red = 1; - q->ch[0]->red = 0; - q->ch[1]->red = 0; - } - - /* Fix red violation */ - if (is_red(q) && is_red(p)) { - int dir2 = (t->ch[1] == g); - - if (q == p->ch[last]) { - t->ch[dir2] = iso_rbtree_single(g, !last); - } else { - t->ch[dir2] = iso_rbtree_double(g, !last); - } - } - - comp = tree->compare(q->data, data); - - /* Stop if found */ - if (comp == 0) { - new = q->data; - break; - } - - last = dir; - dir = (comp < 0); - - /* Update helpers */ - if (g != NULL) - t = g; - g = p, p = q; - q = q->ch[dir]; - } - - /* Update root */ - tree->root = head.ch[1]; - } - - /* Make root black */ - tree->root->red = 0; - - if (item != NULL) { - *item = new; - } - if (added) { - /* a new element has been added */ - tree->size++; - return 1; - } else { - return 0; - } -} - -/** - * Get the number of elements in a given tree. - */ -size_t iso_rbtree_get_size(IsoRBTree *tree) -{ - return tree->size; -} - -static -size_t rbtree_to_array_aux(struct iso_rbnode *root, void **array, size_t pos, - int (*include_item)(void *)) -{ - if (root == NULL) { - return pos; - } - pos = rbtree_to_array_aux(root->ch[0], array, pos, include_item); - if (include_item == NULL || include_item(root->data)) { - array[pos++] = root->data; - } - pos = rbtree_to_array_aux(root->ch[1], array, pos, include_item); - return pos; -} - -/** - * Get an array view of the elements of the tree. - * - * @param include_item - * Function to select which elements to include in the array. It that takes - * a pointer to an element and returns 1 if the element should be included, - * 0 if not. If you want to add all elements to the array, you can pass a - * NULL pointer. - * @return - * A sorted array with the contents of the tree, or NULL if there is not - * enought memory to allocate the array. You should free(3) the array when - * no more needed. Note that the array is NULL-terminated, and thus it - * has size + 1 length. - */ -void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *), - size_t *size) -{ - size_t pos; - void **array; - - array = malloc((tree->size + 1) * sizeof(void*)); - if (array == NULL) { - return NULL; - } - - /* fill array */ - pos = rbtree_to_array_aux(tree->root, array, 0, include_item); - array[pos] = NULL; - - array = realloc(array, (pos + 1) * sizeof(void*)); - if (size) { - *size = pos; - } - return array; -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/writer.h b/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/writer.h deleted file mode 100644 index 8d357f8e..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/libisofs/writer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2007 Vreixo Formoso - * - * This file is part of the libisofs project; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See COPYING file for details. - */ -#ifndef LIBISO_IMAGE_WRITER_H_ -#define LIBISO_IMAGE_WRITER_H_ - -#include "ecma119.h" - -struct Iso_Image_Writer -{ - /** - * - */ - int (*compute_data_blocks)(IsoImageWriter *writer); - - int (*write_vol_desc)(IsoImageWriter *writer); - - int (*write_data)(IsoImageWriter *writer); - - int (*free_data)(IsoImageWriter *writer); - - void *data; - Ecma119Image *target; -}; - -/** - * This is the function all Writers shoudl call to write data to image. - * Currently, it is just a wrapper for write(2) Unix system call. - * - * It is implemented in ecma119.c - * - * @return - * 1 on sucess, < 0 error - */ -int iso_write(Ecma119Image *target, void *buf, size_t count); - -int ecma119_writer_create(Ecma119Image *target); - -#endif /*LIBISO_IMAGE_WRITER_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.c deleted file mode 100644 index 13c6b45d..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * - * - */ - -#include "fsource.h" -#include "mocked_fsrc.h" -#include "libisofs.h" - -#include -#include -#include -#include -#include -#include -#include - -static -struct mock_file *path_to_node(IsoFilesystem *fs, const char *path); - -static -char *get_path_aux(struct mock_file *file) -{ - if (file->parent == NULL) { - return strdup(""); - } else { - char *path = get_path_aux(file->parent); - int pathlen = strlen(path); - path = realloc(path, pathlen + strlen(file->name) + 2); - path[pathlen] = '/'; - path[pathlen + 1] = '\0'; - return strcat(path, file->name); - } -} - -static -char* mfs_get_path(IsoFileSource *src) -{ - struct mock_file *data; - data = src->data; - return get_path_aux(data); -} - -static -char* mfs_get_name(IsoFileSource *src) -{ - struct mock_file *data; - data = src->data; - return strdup(data->name); -} - -static -int mfs_lstat(IsoFileSource *src, struct stat *info) -{ - struct mock_file *data; - - if (src == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - data = src->data; - - *info = data->atts; - return ISO_SUCCESS; -} - -static -int mfs_stat(IsoFileSource *src, struct stat *info) -{ - struct mock_file *node; - if (src == NULL || info == NULL) { - return ISO_NULL_POINTER; - } - node = src->data; - - while ( S_ISLNK(node->atts.st_mode) ) { - /* the destination is stated */ - node = path_to_node(node->fs, (char *)node->content); - if (node == NULL) { - return ISO_FILE_ERROR; - } - } - - *info = node->atts; - return ISO_SUCCESS; -} - -static -int mfs_access(IsoFileSource *src) -{ - // TODO not implemented - return ISO_ERROR; -} - -static -int mfs_open(IsoFileSource *src) -{ - // TODO not implemented - return ISO_ERROR; -} - -static -int mfs_close(IsoFileSource *src) -{ - // TODO not implemented - return ISO_ERROR; -} - -static -int mfs_read(IsoFileSource *src, void *buf, size_t count) -{ - // TODO not implemented - return ISO_ERROR; -} - -static -int mfs_readdir(IsoFileSource *src, IsoFileSource **child) -{ - // TODO not implemented - return ISO_ERROR; -} - -static -int mfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz) -{ - struct mock_file *data; - - if (src == NULL || buf == NULL) { - return ISO_NULL_POINTER; - } - - if (bufsiz <= 0) { - return ISO_WRONG_ARG_VALUE; - } - data = src->data; - - if (!S_ISLNK(data->atts.st_mode)) { - return ISO_FILE_IS_NOT_SYMLINK; - } - strncpy(buf, data->content, bufsiz); - buf[bufsiz-1] = '\0'; - return ISO_SUCCESS; -} - -static -IsoFilesystem* mfs_get_filesystem(IsoFileSource *src) -{ - struct mock_file *data; - data = src->data; - return data->fs; -} - -static -void mfs_free(IsoFileSource *src) -{ - /* nothing to do */ -} - -IsoFileSourceIface mfs_class = { - 0, - mfs_get_path, - mfs_get_name, - mfs_lstat, - mfs_stat, - mfs_access, - mfs_open, - mfs_close, - mfs_read, - mfs_readdir, - mfs_readlink, - mfs_get_filesystem, - mfs_free -}; - -/** - * - * @return - * 1 success, < 0 error - */ -static -int mocked_file_source_new(struct mock_file *data, IsoFileSource **src) -{ - IsoFileSource *mocked_src; - - if (src == NULL || data == NULL) { - return ISO_NULL_POINTER; - } - - /* allocate memory */ - mocked_src = malloc(sizeof(IsoFileSource)); - if (mocked_src == NULL) { - free(data); - return ISO_OUT_OF_MEM; - } - - /* fill struct */ - mocked_src->refcount = 1; - mocked_src->data = data; - mocked_src->class = &mfs_class; - - /* take a ref to filesystem */ - //iso_filesystem_ref(fs); - - /* return */ - *src = mocked_src; - return ISO_SUCCESS; -} - -static -struct mock_file *path_to_node(IsoFilesystem *fs, const char *path) -{ - struct mock_file *node; - struct mock_file *dir; - char *ptr, *brk_info, *component; - - /* get the first child at the root of the volume - * that is "/" */ - dir = fs->data; - node = dir; - if (!strcmp(path, "/")) - return node; - - ptr = strdup(path); - - /* get the first component of the path */ - component = strtok_r(ptr, "/", &brk_info); - while (component) { - size_t i; - - if ( !S_ISDIR(node->atts.st_mode) ) { - node=NULL; - break; - } - dir = node; - - node=NULL; - if (!dir->content) { - break; - } - - i = 0; - while (((struct mock_file**)dir->content)[i]) { - if (!strcmp(component, ((struct mock_file**)dir->content)[i]->name)) { - node = ((struct mock_file**)dir->content)[i]; - break; - } - ++i; - } - - /* see if a node could be found */ - if (node==NULL) { - break; - } - component = strtok_r(NULL, "/", &brk_info); - } - free(ptr); - return node; -} - -static -void add_node(struct mock_file *parent, struct mock_file *node) -{ - int i; - - i = 0; - if (parent->content) { - while (((struct mock_file**)parent->content)[i]) { - ++i; - } - } - parent->content = realloc(parent->content, (i+2) * sizeof(void*)); - ((struct mock_file**)parent->content)[i] = node; - ((struct mock_file**)parent->content)[i+1] = NULL; -} - -struct mock_file *test_mocked_fs_get_root(IsoFilesystem *fs) -{ - return fs->data; -} - -int test_mocked_fs_add_dir(const char *name, struct mock_file *p, - struct stat atts, struct mock_file **node) -{ - struct mock_file *dir = calloc(1, sizeof(struct mock_file)); - dir->fs = p->fs; - dir->atts = atts; - dir->name = strdup(name); - dir->parent = p; - add_node(p, dir); - - *node = dir; - return ISO_SUCCESS; -} - -int test_mocked_fs_add_symlink(const char *name, struct mock_file *p, - struct stat atts, const char *dest, struct mock_file **node) -{ - struct mock_file *link = calloc(1, sizeof(struct mock_file)); - link->fs = p->fs; - link->atts = atts; - link->name = strdup(name); - link->parent = p; - add_node(p, link); - link->content = strdup(dest); - *node = link; - return ISO_SUCCESS; -} - -static -int mocked_get_root(IsoFilesystem *fs, IsoFileSource **root) -{ - if (fs == NULL || root == NULL) { - return ISO_NULL_POINTER; - } - return mocked_file_source_new(fs->data, root); -} - -static -int mocked_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file) -{ - struct mock_file *f; - if (fs == NULL || path == NULL || file == NULL) { - return ISO_NULL_POINTER; - } - f = path_to_node(fs, path); - return mocked_file_source_new(f, file); -} - -static -void free_mocked_file(struct mock_file *file) -{ - if (S_ISDIR(file->atts.st_mode)) { - if (file->content) { - int i = 0; - while (((struct mock_file**)file->content)[i]) { - free_mocked_file(((struct mock_file**)file->content)[i]); - ++i; - } - } - } - free(file->content); - free(file->name); - free(file); -} - -static -void mocked_fs_free(IsoFilesystem *fs) -{ - free_mocked_file((struct mock_file *)fs->data); -} - -int test_mocked_filesystem_new(IsoFilesystem **fs) -{ - struct mock_file *root; - IsoFilesystem *filesystem; - - if (fs == NULL) { - return ISO_NULL_POINTER; - } - - root = calloc(1, sizeof(struct mock_file)); - root->atts.st_atime = time(NULL); - root->atts.st_ctime = time(NULL); - root->atts.st_mtime = time(NULL); - root->atts.st_uid = 0; - root->atts.st_gid = 0; - root->atts.st_mode = S_IFDIR | 0777; - - filesystem = malloc(sizeof(IsoFilesystem)); - filesystem->refcount = 1; - root->fs = filesystem; - filesystem->data = root; - filesystem->get_root = mocked_get_root; - filesystem->get_by_path = mocked_get_by_path; - filesystem->free = mocked_fs_free; - *fs = filesystem; - return ISO_SUCCESS; -} - diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.h b/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.h deleted file mode 100644 index 8e92c61c..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/mocked_fsrc.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Mocked objects to simulate an input filesystem. - */ - -#ifndef MOCKED_FSRC_H_ -#define MOCKED_FSRC_H_ - -struct mock_file { - IsoFilesystem *fs; - struct mock_file *parent; - struct stat atts; - char *name; - - /* for links, link dest. For dirs, children */ - void *content; -}; - -/** - * A mocked fs. - */ -int test_mocked_filesystem_new(IsoFilesystem **fs); - -struct mock_file *test_mocked_fs_get_root(IsoFilesystem *fs); - -int test_mocked_fs_add_dir(const char *name, struct mock_file *parent, - struct stat atts, struct mock_file **dir); - -int test_mocked_fs_add_symlink(const char *name, struct mock_file *p, - struct stat atts, const char *dest, struct mock_file **node); - -#endif /*MOCKED_FSRC_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test.c deleted file mode 100644 index dd9d0a4f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "test.h" - -static void create_test_suite() -{ - add_node_suite(); - add_image_suite(); - add_tree_suite(); - add_util_suite(); - add_rockridge_suite(); - add_stream_suite(); -} - -int main(int argc, char **argv) -{ - /* initialize the CUnit test registry */ - if (CUE_SUCCESS != CU_initialize_registry()) - return CU_get_error(); - - create_test_suite(); - - /* Run all tests using the console interface */ - CU_basic_set_mode(CU_BRM_VERBOSE); - CU_basic_run_tests(); - CU_cleanup_registry(); - return CU_get_error(); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test.h b/libisofs/tags/ForXorrisoZeroOneTwo/test/test.h deleted file mode 100644 index 6e5e76a5..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef TEST_H_ -#define TEST_H_ - -#include -#include "libisofs.h" - -void add_node_suite(); -void add_image_suite(); -void add_tree_suite(); -void add_util_suite(); -void add_rockridge_suite(); -void add_stream_suite(); - -#endif /*TEST_H_*/ diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_image.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_image.c deleted file mode 100644 index fd0fef6c..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_image.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Unit test for image.h - */ - - -#include "libisofs.h" -#include "test.h" -#include "image.h" - -#include -#include -#include -#include -#include -#include - - -static void test_iso_image_new() -{ - int ret; - IsoImage *image; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NOT_NULL(image); - CU_ASSERT_EQUAL(image->refcount, 1); - CU_ASSERT_PTR_NOT_NULL(image->root); - - CU_ASSERT_STRING_EQUAL(image->volume_id, "volume_id"); - CU_ASSERT_STRING_EQUAL(image->volset_id, "volume_id"); - - CU_ASSERT_PTR_NULL(image->publisher_id); - CU_ASSERT_PTR_NULL(image->data_preparer_id); - CU_ASSERT_PTR_NULL(image->system_id); - CU_ASSERT_PTR_NULL(image->application_id); - CU_ASSERT_PTR_NULL(image->copyright_file_id); - CU_ASSERT_PTR_NULL(image->abstract_file_id); - CU_ASSERT_PTR_NULL(image->biblio_file_id); - - //CU_ASSERT_PTR_NULL(image->bootcat); - - iso_image_unref(image); -} - -static void test_iso_image_set_volume_id() -{ - int ret; - IsoImage *image; - char *volid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_STRING_EQUAL(image->volume_id, "volume_id"); - - volid = "new volume id"; - iso_image_set_volume_id(image, volid); - CU_ASSERT_STRING_EQUAL(image->volume_id, "new volume id"); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL(image->volume_id, volid); - iso_image_unref(image); -} - -static void test_iso_image_get_volume_id() -{ - int ret; - IsoImage *image; - char *volid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_STRING_EQUAL(iso_image_get_volume_id(image), "volume_id"); - - volid = "new volume id"; - iso_image_set_volume_id(image, volid); - CU_ASSERT_STRING_EQUAL( iso_image_get_volume_id(image), "new volume id" ); - - iso_image_unref(image); -} - -static void test_iso_image_set_publisher_id() -{ - int ret; - IsoImage *image; - char *pubid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->publisher_id); - - pubid = "new publisher id"; - iso_image_set_publisher_id(image, pubid); - CU_ASSERT_STRING_EQUAL( image->publisher_id, "new publisher id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->publisher_id, pubid ); - iso_image_unref(image); -} - -static void test_iso_image_get_publisher_id() -{ - int ret; - IsoImage *image; - char *pubid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->publisher_id); - - pubid = "new publisher id"; - iso_image_set_publisher_id(image, pubid); - CU_ASSERT_STRING_EQUAL(iso_image_get_publisher_id(image), "new publisher id"); - - iso_image_unref(image); -} - -static void test_iso_image_set_data_preparer_id() -{ - int ret; - IsoImage *image; - char *dpid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->data_preparer_id); - - dpid = "new data preparer id"; - iso_image_set_data_preparer_id(image, dpid); - CU_ASSERT_STRING_EQUAL(image->data_preparer_id, "new data preparer id"); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL(image->data_preparer_id, dpid); - iso_image_unref(image); -} - -static void test_iso_image_get_data_preparer_id() -{ - int ret; - IsoImage *image; - char *dpid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->data_preparer_id); - - dpid = "new data preparer id"; - iso_image_set_data_preparer_id(image, dpid); - CU_ASSERT_STRING_EQUAL( iso_image_get_data_preparer_id(image), "new data preparer id" ); - - iso_image_unref(image); -} - -static void test_iso_image_set_system_id() -{ - int ret; - IsoImage *image; - char *sysid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->system_id); - - sysid = "new system id"; - iso_image_set_system_id(image, sysid); - CU_ASSERT_STRING_EQUAL( image->system_id, "new system id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->system_id, sysid ); - iso_image_unref(image); -} - -static void test_iso_image_get_system_id() -{ - int ret; - IsoImage *image; - char *sysid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(iso_image_get_system_id(image)); - - sysid = "new system id"; - iso_image_set_system_id(image, sysid); - CU_ASSERT_STRING_EQUAL( iso_image_get_system_id(image), "new system id" ); - - iso_image_unref(image); -} - -static void test_iso_image_set_application_id() -{ - int ret; - IsoImage *image; - char *appid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->application_id); - - appid = "new application id"; - iso_image_set_application_id(image, appid); - CU_ASSERT_STRING_EQUAL( image->application_id, "new application id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->application_id, appid ); - iso_image_unref(image); -} - -static void test_iso_image_get_application_id() -{ - int ret; - IsoImage *image; - char *appid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(iso_image_get_application_id(image)); - - appid = "new application id"; - iso_image_set_application_id(image, appid); - CU_ASSERT_STRING_EQUAL( iso_image_get_application_id(image), "new application id" ); - - iso_image_unref(image); -} - -static void test_iso_image_set_copyright_file_id() -{ - int ret; - IsoImage *image; - char *copid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->copyright_file_id); - - copid = "new copyright id"; - iso_image_set_copyright_file_id(image, copid); - CU_ASSERT_STRING_EQUAL( image->copyright_file_id, "new copyright id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->copyright_file_id, copid ); - iso_image_unref(image); -} - -static void test_iso_image_get_copyright_file_id() -{ - int ret; - IsoImage *image; - char *copid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(iso_image_get_copyright_file_id(image)); - - copid = "new copyright id"; - iso_image_set_copyright_file_id(image, copid); - CU_ASSERT_STRING_EQUAL( iso_image_get_copyright_file_id(image), "new copyright id" ); - - iso_image_unref(image); -} - -static void test_iso_image_set_abstract_file_id() -{ - int ret; - IsoImage *image; - char *absid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->abstract_file_id); - - absid = "new abstract id"; - iso_image_set_abstract_file_id(image, absid); - CU_ASSERT_STRING_EQUAL( image->abstract_file_id, "new abstract id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->abstract_file_id, absid ); - iso_image_unref(image); -} - -static void test_iso_image_get_abstract_file_id() -{ - int ret; - IsoImage *image; - char *absid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(iso_image_get_abstract_file_id(image)); - - absid = "new abstract id"; - iso_image_set_abstract_file_id(image, absid); - CU_ASSERT_STRING_EQUAL(iso_image_get_abstract_file_id(image), "new abstract id"); - - iso_image_unref(image); -} - -static void test_iso_image_set_biblio_file_id() -{ - int ret; - IsoImage *image; - char *bibid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(image->biblio_file_id); - - bibid = "new biblio id"; - iso_image_set_biblio_file_id(image, bibid); - CU_ASSERT_STRING_EQUAL( image->biblio_file_id, "new biblio id" ); - - /* check string was strdup'ed */ - CU_ASSERT_PTR_NOT_EQUAL( image->biblio_file_id, bibid ); - iso_image_unref(image); -} - -static void test_iso_image_get_biblio_file_id() -{ - int ret; - IsoImage *image; - char *bibid; - - ret = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_PTR_NULL(iso_image_get_biblio_file_id(image)); - - bibid = "new biblio id"; - iso_image_set_biblio_file_id(image, bibid); - CU_ASSERT_STRING_EQUAL(iso_image_get_biblio_file_id(image), "new biblio id"); - - iso_image_unref(image); -} - -void add_image_suite() -{ - CU_pSuite pSuite = CU_add_suite("imageSuite", NULL, NULL); - - CU_add_test(pSuite, "iso_image_new()", test_iso_image_new); - CU_add_test(pSuite, "iso_image_set_volume_id()", test_iso_image_set_volume_id); - CU_add_test(pSuite, "iso_image_get_volume_id()", test_iso_image_get_volume_id); - CU_add_test(pSuite, "iso_image_set_publisher_id()", test_iso_image_set_publisher_id); - CU_add_test(pSuite, "iso_image_get_publisher_id()", test_iso_image_get_publisher_id); - CU_add_test(pSuite, "iso_image_set_data_preparer_id()", test_iso_image_set_data_preparer_id); - CU_add_test(pSuite, "iso_image_get_data_preparer_id()", test_iso_image_get_data_preparer_id); - CU_add_test(pSuite, "iso_image_set_system_id()", test_iso_image_set_system_id); - CU_add_test(pSuite, "iso_image_get_system_id()", test_iso_image_get_system_id); - CU_add_test(pSuite, "iso_image_set_application_id()", test_iso_image_set_application_id); - CU_add_test(pSuite, "iso_image_get_application_id()", test_iso_image_get_application_id); - CU_add_test(pSuite, "iso_image_set_copyright_file_id()", test_iso_image_set_copyright_file_id); - CU_add_test(pSuite, "iso_image_get_copyright_file_id()", test_iso_image_get_copyright_file_id); - CU_add_test(pSuite, "iso_image_set_abstract_file_id()", test_iso_image_set_abstract_file_id); - CU_add_test(pSuite, "iso_image_get_abstract_file_id()", test_iso_image_get_abstract_file_id); - CU_add_test(pSuite, "iso_image_set_biblio_file_id()", test_iso_image_set_biblio_file_id); - CU_add_test(pSuite, "iso_image_get_biblio_file_id()", test_iso_image_get_biblio_file_id); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_node.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_node.c deleted file mode 100644 index 6c2084a5..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_node.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Unit test for node.h - */ - -#include "libisofs.h" -#include "node.h" -#include "test.h" - -#include - -static -void test_iso_node_new_root() -{ - int ret; - IsoDir *dir; - - ret = iso_node_new_root(&dir); - CU_ASSERT_EQUAL(ret, ISO_SUCCESS); - - CU_ASSERT_EQUAL(dir->node.refcount, 1); - CU_ASSERT_EQUAL(dir->node.type, LIBISO_DIR); - CU_ASSERT_EQUAL(dir->node.mode, S_IFDIR | 0555); - CU_ASSERT_EQUAL(dir->node.uid, 0); - CU_ASSERT_EQUAL(dir->node.gid, 0); - CU_ASSERT_PTR_NULL(dir->node.name); - CU_ASSERT_EQUAL(dir->node.hidden, 0); - CU_ASSERT_PTR_EQUAL(dir->node.parent, dir); - CU_ASSERT_PTR_NULL(dir->node.next); - CU_ASSERT_EQUAL(dir->nchildren, 0); - CU_ASSERT_PTR_NULL(dir->children); - - iso_node_unref((IsoNode*)dir); -} - -static -void test_iso_node_new_dir() -{ - int ret; - IsoDir *dir; - char *name; - - name = strdup("name1"); - ret = iso_node_new_dir(name, &dir); - CU_ASSERT_EQUAL(ret, ISO_SUCCESS); - CU_ASSERT_EQUAL(dir->node.refcount, 1); - CU_ASSERT_EQUAL(dir->node.type, LIBISO_DIR); - CU_ASSERT_EQUAL(dir->node.mode, S_IFDIR); - CU_ASSERT_EQUAL(dir->node.uid, 0); - CU_ASSERT_EQUAL(dir->node.gid, 0); - CU_ASSERT_EQUAL(dir->node.atime, 0); - CU_ASSERT_EQUAL(dir->node.mtime, 0); - CU_ASSERT_EQUAL(dir->node.ctime, 0); - CU_ASSERT_STRING_EQUAL(dir->node.name, "name1"); - CU_ASSERT_EQUAL(dir->node.hidden, 0); - CU_ASSERT_PTR_NULL(dir->node.parent); - CU_ASSERT_PTR_NULL(dir->node.next); - CU_ASSERT_EQUAL(dir->nchildren, 0); - CU_ASSERT_PTR_NULL(dir->children); - - iso_node_unref((IsoNode*)dir); - - /* try with invalid names */ - ret = iso_node_new_dir("H/DHS/s", &dir); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); - ret = iso_node_new_dir(".", &dir); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); - ret = iso_node_new_dir("..", &dir); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); - ret = iso_node_new_dir(NULL, &dir); - CU_ASSERT_EQUAL(ret, ISO_NULL_POINTER); -} - -static -void test_iso_node_new_symlink() -{ - int ret; - IsoSymlink *link; - char *name, *dest; - - name = strdup("name1"); - dest = strdup("/home"); - ret = iso_node_new_symlink(name, dest, &link); - CU_ASSERT_EQUAL(ret, ISO_SUCCESS); - CU_ASSERT_EQUAL(link->node.refcount, 1); - CU_ASSERT_EQUAL(link->node.type, LIBISO_SYMLINK); - CU_ASSERT_EQUAL(link->node.mode, S_IFLNK); - CU_ASSERT_EQUAL(link->node.uid, 0); - CU_ASSERT_EQUAL(link->node.gid, 0); - CU_ASSERT_EQUAL(link->node.atime, 0); - CU_ASSERT_EQUAL(link->node.mtime, 0); - CU_ASSERT_EQUAL(link->node.ctime, 0); - CU_ASSERT_STRING_EQUAL(link->node.name, "name1"); - CU_ASSERT_EQUAL(link->node.hidden, 0); - CU_ASSERT_PTR_NULL(link->node.parent); - CU_ASSERT_PTR_NULL(link->node.next); - CU_ASSERT_STRING_EQUAL(link->dest, "/home"); - - iso_node_unref((IsoNode*)link); - - /* try with invalid names */ - ret = iso_node_new_symlink("H/DHS/s", "/home", &link); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); - ret = iso_node_new_symlink(".", "/home", &link); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); - ret = iso_node_new_symlink("..", "/home", &link); - CU_ASSERT_EQUAL(ret, ISO_WRONG_ARG_VALUE); -} - -static -void test_iso_node_set_permissions() -{ - IsoNode *node; - node = malloc(sizeof(IsoNode)); - - node->mode = S_IFDIR | 0777; - - /* set permissions propertly */ - iso_node_set_permissions(node, 0555); - CU_ASSERT_EQUAL(node->mode, S_IFDIR | 0555); - iso_node_set_permissions(node, 0640); - CU_ASSERT_EQUAL(node->mode, S_IFDIR | 0640); - - /* try to change file type via this call */ - iso_node_set_permissions(node, S_IFBLK | 0440); - CU_ASSERT_EQUAL(node->mode, S_IFDIR | 0440); - - free(node); -} - -static -void test_iso_node_get_permissions() -{ - IsoNode *node; - mode_t mode; - - node = malloc(sizeof(IsoNode)); - node->mode = S_IFDIR | 0777; - - mode = iso_node_get_permissions(node); - CU_ASSERT_EQUAL(mode, 0777); - - iso_node_set_permissions(node, 0640); - mode = iso_node_get_permissions(node); - CU_ASSERT_EQUAL(mode, 0640); - - iso_node_set_permissions(node, S_IFBLK | 0440); - mode = iso_node_get_permissions(node); - CU_ASSERT_EQUAL(mode, 0440); - - free(node); -} - -static -void test_iso_node_get_mode() -{ - IsoNode *node; - mode_t mode; - - node = malloc(sizeof(IsoNode)); - node->mode = S_IFDIR | 0777; - - mode = iso_node_get_mode(node); - CU_ASSERT_EQUAL(mode, S_IFDIR | 0777); - - iso_node_set_permissions(node, 0640); - mode = iso_node_get_mode(node); - CU_ASSERT_EQUAL(mode, S_IFDIR | 0640); - - iso_node_set_permissions(node, S_IFBLK | 0440); - mode = iso_node_get_mode(node); - CU_ASSERT_EQUAL(mode, S_IFDIR | 0440); - - free(node); -} - -static -void test_iso_node_set_uid() -{ - IsoNode *node; - node = malloc(sizeof(IsoNode)); - - node->uid = 0; - - iso_node_set_uid(node, 23); - CU_ASSERT_EQUAL(node->uid, 23); - iso_node_set_uid(node, 0); - CU_ASSERT_EQUAL(node->uid, 0); - - free(node); -} - -static -void test_iso_node_get_uid() -{ - IsoNode *node; - uid_t uid; - - node = malloc(sizeof(IsoNode)); - node->uid = 0; - - uid = iso_node_get_uid(node); - CU_ASSERT_EQUAL(uid, 0); - - iso_node_set_uid(node, 25); - uid = iso_node_get_uid(node); - CU_ASSERT_EQUAL(uid, 25); - - free(node); -} - -static -void test_iso_node_set_gid() -{ - IsoNode *node; - node = malloc(sizeof(IsoNode)); - - node->gid = 0; - - iso_node_set_gid(node, 23); - CU_ASSERT_EQUAL(node->gid, 23); - iso_node_set_gid(node, 0); - CU_ASSERT_EQUAL(node->gid, 0); - - free(node); -} - -static -void test_iso_node_get_gid() -{ - IsoNode *node; - gid_t gid; - - node = malloc(sizeof(IsoNode)); - node->gid = 0; - - gid = iso_node_get_gid(node); - CU_ASSERT_EQUAL(gid, 0); - - iso_node_set_gid(node, 25); - gid = iso_node_get_gid(node); - CU_ASSERT_EQUAL(gid, 25); - - free(node); -} - -static -void test_iso_dir_add_node() -{ - int result; - IsoDir *dir; - IsoNode *node1, *node2, *node3, *node4, *node5; - - /* init dir with default values, not all field need to be initialized */ - dir = malloc(sizeof(IsoDir)); - dir->children = NULL; - dir->nchildren = 0; - - /* 1st node to be added */ - node1 = calloc(1, sizeof(IsoNode)); - node1->name = "Node1"; - - /* addition of node to an empty dir */ - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(dir->nchildren, 1); - CU_ASSERT_PTR_EQUAL(dir->children, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, dir); - - /* addition of a node, to be inserted before */ - node2 = calloc(1, sizeof(IsoNode)); - node2->name = "A node to be added first"; - - result = iso_dir_add_node(dir, node2, 0); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(dir->nchildren, 2); - CU_ASSERT_PTR_EQUAL(dir->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node2->parent, dir); - - /* addition of a node, to be inserted last */ - node3 = calloc(1, sizeof(IsoNode)); - node3->name = "This node will be inserted last"; - - result = iso_dir_add_node(dir, node3, 0); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(dir->nchildren, 3); - CU_ASSERT_PTR_EQUAL(dir->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_EQUAL(node1->next, node3); - CU_ASSERT_PTR_NULL(node3->next); - CU_ASSERT_PTR_EQUAL(node3->parent, dir); - - /* force some failures */ - result = iso_dir_add_node(NULL, node3, 0); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_dir_add_node(dir, NULL, 0); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - - result = iso_dir_add_node(dir, (IsoNode*)dir, 0); - CU_ASSERT_EQUAL(result, ISO_WRONG_ARG_VALUE); - - /* a node with same name */ - node4 = calloc(1, sizeof(IsoNode)); - node4->name = "This node will be inserted last"; - result = iso_dir_add_node(dir, node4, 0); - CU_ASSERT_EQUAL(result, ISO_NODE_NAME_NOT_UNIQUE); - CU_ASSERT_EQUAL(dir->nchildren, 3); - CU_ASSERT_PTR_EQUAL(dir->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_EQUAL(node1->next, node3); - CU_ASSERT_PTR_NULL(node3->next); - CU_ASSERT_PTR_NULL(node4->parent); - - /* a node already added to another dir should fail */ - node5 = calloc(1, sizeof(IsoNode)); - node5->name = "other node"; - node5->parent = (IsoDir*)node4; - result = iso_dir_add_node(dir, node5, 0); - CU_ASSERT_EQUAL(result, ISO_NODE_ALREADY_ADDED); - - free(node1); - free(node2); - free(node3); - free(node4); - free(node5); - free(dir); -} - -static -void test_iso_dir_get_node() -{ - int result; - IsoDir *dir; - IsoNode *node1, *node2, *node3; - IsoNode *node; - - /* init dir with default values, not all field need to be initialized */ - dir = malloc(sizeof(IsoDir)); - dir->children = NULL; - dir->nchildren = 0; - - /* try to find a node in an empty dir */ - result = iso_dir_get_node(dir, "a inexistent name", &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - - /* add a node */ - node1 = calloc(1, sizeof(IsoNode)); - node1->name = "Node1"; - result = iso_dir_add_node(dir, node1, 0); - - /* try to find a node not existent */ - result = iso_dir_get_node(dir, "a inexistent name", &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - - /* and an existing one */ - result = iso_dir_get_node(dir, "Node1", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - - /* add another node */ - node2 = calloc(1, sizeof(IsoNode)); - node2->name = "A node to be added first"; - result = iso_dir_add_node(dir, node2, 0); - - /* try to find a node not existent */ - result = iso_dir_get_node(dir, "a inexistent name", &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - - /* and the two existing */ - result = iso_dir_get_node(dir, "Node1", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - result = iso_dir_get_node(dir, "A node to be added first", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node2); - - /* insert another node */ - node3 = calloc(1, sizeof(IsoNode)); - node3->name = "This node will be inserted last"; - result = iso_dir_add_node(dir, node3, 0); - - /* get again */ - result = iso_dir_get_node(dir, "a inexistent name", &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - result = iso_dir_get_node(dir, "This node will be inserted last", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node3); - - /* force some failures */ - result = iso_dir_get_node(NULL, "asas", &node); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_dir_get_node(dir, NULL, &node); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - - /* and try with null node */ - result = iso_dir_get_node(dir, "asas", NULL); - CU_ASSERT_EQUAL(result, 0); - result = iso_dir_get_node(dir, "This node will be inserted last", NULL); - CU_ASSERT_EQUAL(result, 1); - - free(node1); - free(node2); - free(node3); - free(dir); -} - -void test_iso_dir_get_children() -{ - int result; - IsoDirIter *iter; - IsoDir *dir; - IsoNode *node, *node1, *node2, *node3; - - /* init dir with default values, not all field need to be initialized */ - dir = malloc(sizeof(IsoDir)); - dir->children = NULL; - dir->nchildren = 0; - - result = iso_dir_get_children(dir, &iter); - CU_ASSERT_EQUAL(result, 1); - - /* item should have no items */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 0); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - iso_dir_iter_free(iter); - - /* 1st node to be added */ - node1 = calloc(1, sizeof(IsoNode)); - node1->name = "Node1"; - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(dir->nchildren, 1); - - /* test iteration again */ - result = iso_dir_get_children(dir, &iter); - CU_ASSERT_EQUAL(result, 1); - - /* iter should have a single item... */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - - /* ...and no more */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 0); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - iso_dir_iter_free(iter); - - /* add another node */ - node2 = calloc(1, sizeof(IsoNode)); - node2->name = "A node to be added first"; - result = iso_dir_add_node(dir, node2, 0); - CU_ASSERT_EQUAL(result, 2); - - result = iso_dir_get_children(dir, &iter); - CU_ASSERT_EQUAL(result, 1); - - /* iter should have two items... */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node2); - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - - /* ...and no more */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 0); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - iso_dir_iter_free(iter); - - /* addition of a 3rd node, to be inserted last */ - node3 = calloc(1, sizeof(IsoNode)); - node3->name = "This node will be inserted last"; - result = iso_dir_add_node(dir, node3, 0); - CU_ASSERT_EQUAL(result, 3); - - result = iso_dir_get_children(dir, &iter); - CU_ASSERT_EQUAL(result, 1); - - /* iter should have 3 items... */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node2); - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 1); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node3); - - /* ...and no more */ - result = iso_dir_iter_has_next(iter); - CU_ASSERT_EQUAL(result, 0); - result = iso_dir_iter_next(iter, &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - iso_dir_iter_free(iter); - - free(node1); - free(node2); - free(node3); - free(dir); -} - -void test_iso_node_take() -{ - int result; - IsoDir *dir; - IsoNode *node1, *node2, *node3; - - /* init dir with default values, not all field need to be initialized */ - dir = malloc(sizeof(IsoDir)); - dir->children = NULL; - dir->nchildren = 0; - - /* 1st node to be added */ - node1 = calloc(1, sizeof(IsoNode)); - node1->name = "Node1"; - - /* addition of node to an empty dir */ - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(result, 1); - - /* and take it */ - result = iso_node_take(node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(dir->nchildren, 0); - CU_ASSERT_PTR_NULL(dir->children); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_NULL(node1->parent); - - /* insert it again */ - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(result, 1); - - /* addition of a 2nd node, to be inserted before */ - node2 = calloc(1, sizeof(IsoNode)); - node2->name = "A node to be added first"; - result = iso_dir_add_node(dir, node2, 0); - CU_ASSERT_EQUAL(result, 2); - - /* take first child */ - result = iso_node_take(node2); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(dir->nchildren, 1); - CU_ASSERT_PTR_EQUAL(dir->children, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, dir); - CU_ASSERT_PTR_NULL(node2->next); - CU_ASSERT_PTR_NULL(node2->parent); - - /* insert node 2 again */ - result = iso_dir_add_node(dir, node2, 0); - CU_ASSERT_EQUAL(result, 2); - - /* now take last child */ - result = iso_node_take(node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(dir->nchildren, 1); - CU_ASSERT_PTR_EQUAL(dir->children, node2); - CU_ASSERT_PTR_NULL(node2->next); - CU_ASSERT_PTR_EQUAL(node2->parent, dir); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_NULL(node1->parent); - - /* insert again node1... */ - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(result, 2); - - /* ...and a 3rd child, to be inserted last */ - node3 = calloc(1, sizeof(IsoNode)); - node3->name = "This node will be inserted last"; - result = iso_dir_add_node(dir, node3, 0); - CU_ASSERT_EQUAL(result, 3); - - /* and take the node in the middle */ - result = iso_node_take(node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(dir->nchildren, 2); - CU_ASSERT_PTR_EQUAL(dir->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node3); - CU_ASSERT_PTR_EQUAL(node2->parent, dir); - CU_ASSERT_PTR_NULL(node3->next); - CU_ASSERT_PTR_EQUAL(node3->parent, dir); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_NULL(node1->parent); - - free(node1); - free(node2); - free(node3); - free(dir); -} - -static -void test_iso_node_set_name() -{ - int result; - IsoDir *dir; - IsoNode *node1, *node2; - - /* init dir with default values, not all field need to be initialized */ - dir = malloc(sizeof(IsoDir)); - dir->children = NULL; - dir->nchildren = 0; - - /* cretae a node */ - node1 = calloc(1, sizeof(IsoNode)); - node1->name = strdup("Node1"); - - /* check name change */ - result = iso_node_set_name(node1, "New name"); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_STRING_EQUAL(node1->name, "New name"); - - /* add node dir */ - result = iso_dir_add_node(dir, node1, 0); - CU_ASSERT_EQUAL(result, 1); - - /* check name change */ - result = iso_node_set_name(node1, "Another name"); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_STRING_EQUAL(node1->name, "Another name"); - - /* addition of a 2nd node */ - node2 = calloc(1, sizeof(IsoNode)); - node2->name = strdup("A node to be added first"); - result = iso_dir_add_node(dir, node2, 0); - CU_ASSERT_EQUAL(result, 2); - - result = iso_node_set_name(node2, "New name"); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_STRING_EQUAL(node2->name, "New name"); - - /* and now try to give an existing name */ - result = iso_node_set_name(node2, "Another name"); - CU_ASSERT_EQUAL(result, ISO_NODE_NAME_NOT_UNIQUE); - CU_ASSERT_STRING_EQUAL(node2->name, "New name"); - - free(node1->name); - free(node2->name); - free(node1); - free(node2); - free(dir); -} - -void add_node_suite() -{ - CU_pSuite pSuite = CU_add_suite("Node Test Suite", NULL, NULL); - - CU_add_test(pSuite, "iso_node_new_root()", test_iso_node_new_root); - CU_add_test(pSuite, "iso_node_new_dir()", test_iso_node_new_dir); - CU_add_test(pSuite, "iso_node_new_symlink()", test_iso_node_new_symlink); - CU_add_test(pSuite, "iso_node_set_permissions()", test_iso_node_set_permissions); - CU_add_test(pSuite, "iso_node_get_permissions()", test_iso_node_get_permissions); - CU_add_test(pSuite, "iso_node_get_mode()", test_iso_node_get_mode); - CU_add_test(pSuite, "iso_node_set_uid()", test_iso_node_set_uid); - CU_add_test(pSuite, "iso_node_get_uid()", test_iso_node_get_uid); - CU_add_test(pSuite, "iso_node_set_gid()", test_iso_node_set_gid); - CU_add_test(pSuite, "iso_node_get_gid()", test_iso_node_get_gid); - CU_add_test(pSuite, "iso_dir_add_node()", test_iso_dir_add_node); - CU_add_test(pSuite, "iso_dir_get_node()", test_iso_dir_get_node); - CU_add_test(pSuite, "iso_dir_get_children()", test_iso_dir_get_children); - CU_add_test(pSuite, "iso_node_take()", test_iso_node_take); - CU_add_test(pSuite, "iso_node_set_name()", test_iso_node_set_name); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_rockridge.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_rockridge.c deleted file mode 100644 index 0a3d411f..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_rockridge.c +++ /dev/null @@ -1,1395 +0,0 @@ -/* - * Unit test for util.h - * - * This test utiliy functions - */ -#include "test.h" -#include "ecma119_tree.h" -#include "rockridge.h" -#include "node.h" - -#include - -static void test_rrip_calc_len_file() -{ - IsoFile *file; - Ecma119Node *node; - Ecma119Image t; - size_t sua_len = 0, ce_len = 0; - - memset(&t, 0, sizeof(Ecma119Image)); - t.input_charset = "UTF-8"; - t.output_charset = "UTF-8"; - - file = malloc(sizeof(IsoFile)); - CU_ASSERT_PTR_NOT_NULL_FATAL(file); - file->msblock = 0; - file->sort_weight = 0; - file->stream = NULL; /* it is not needed here */ - file->node.type = LIBISO_FILE; - - node = malloc(sizeof(Ecma119Node)); - CU_ASSERT_PTR_NOT_NULL_FATAL(node); - node->node = (IsoNode*)file; - node->parent = (Ecma119Node*)0x55555555; /* just to make it not NULL */ - node->info.file = NULL; /* it is not needed here */ - node->type = ECMA119_FILE; - - /* Case 1. Name fit in System Use field */ - file->node.name = "a small name.txt"; - node->iso_name = "A_SMALL_.TXT"; - - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 0); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 16) + (5 + 3*7) + 1); - - /* Case 2. Name fits exactly */ - file->node.name = "a big name, with 133 characters, that it is the max " - "that fits in System Use field of the directory record " - "PADPADPADADPADPADPADPAD.txt"; - node->iso_name = "A_BIG_NA.TXT"; - - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 0); - /* note that 254 is the max length of a directory record, as it needs to - * be an even number */ - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* case 3. A name just 1 character too big to fit in SUA */ - file->node.name = "a big name, with 133 characters, that it is the max " - "that fits in System Use field of the directory record " - "PADPADPADADPADPADPADPAD1.txt"; - node->iso_name = "A_BIG_NA.TXT"; - - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - /* 28 (the chars moved to include the CE entry) + 5 (header of NM in CE) + - * 1 (the char that originally didn't fit) */ - CU_ASSERT_EQUAL(ce_len, 28 + 5 + 1); - /* note that 254 is the max length of a directory record, as it needs to - * be an even number */ - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* case 4. A 255 characters name */ - file->node.name = "a big name, with 255 characters, that it is the max " - "that a POSIX filename can have. PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"; - node->iso_name = "A_BIG_NA.TXT"; - - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - /* 150 + 5 (header + characters that don't fit in sua) */ - CU_ASSERT_EQUAL(ce_len, 150 + 5); - /* note that 254 is the max length of a directory record, as it needs to - * be an even number */ - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - free(node); - free(file); -} - -static void test_rrip_calc_len_symlink() -{ - IsoSymlink *link; - Ecma119Node *node; - Ecma119Image t; - size_t sua_len = 0, ce_len = 0; - - memset(&t, 0, sizeof(Ecma119Image)); - t.input_charset = "UTF-8"; - t.output_charset = "UTF-8"; - - link = malloc(sizeof(IsoSymlink)); - CU_ASSERT_PTR_NOT_NULL_FATAL(link); - link->node.type = LIBISO_SYMLINK; - - node = malloc(sizeof(Ecma119Node)); - CU_ASSERT_PTR_NOT_NULL_FATAL(node); - node->node = (IsoNode*)link; - node->parent = (Ecma119Node*)0x55555555; /* just to make it not NULL */ - node->type = ECMA119_SYMLINK; - - /* Case 1. Name and dest fit in System Use field */ - link->node.name = "a small name.txt"; - link->dest = "/three/components"; - node->iso_name = "A_SMALL_.TXT"; - - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 0); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 16) + (5 + 3*7) + 1 + - (5 + 2 + (2+5) + (2+10)) ); - - /* case 2. name + dest fits exactly */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 0); - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* case 3. name fits, dest is one byte larger to fit */ - /* 3.a extra byte in dest */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./big/destination/with/10/componentsk"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 60); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* 3.b extra byte in name */ - link->node.name = "this name will have 75 characters as it is the max " - "that fits in the SUx.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 59); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 75) + (5 + 3*7) + 28); - - /* case 4. name seems to fit, but SL no, and when CE is added NM - * doesn't fit too */ - /* 4.a it just fits */ - link->node.name = "this name will have 105 characters as it is just the " - "max that fits in the SU once we add the CE entry.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 59); - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* 4.b it just fits, the the component ends in '/' */ - link->node.name = "this name will have 105 characters as it is just the " - "max that fits in the SU once we add the CE entry.txt"; - link->dest = "./and/../a/./big/destination/with/10/components/"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 59); - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* 4.c extra char in name, that forces it to be divided */ - link->node.name = "this name will have 105 characters as it is just the " - "max that fits in the SU once we add the CE entryc.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 59 + 6); - CU_ASSERT_EQUAL(sua_len, 254 - 46); - - /* 5 max destination length to fit in a single SL entry (250) */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./very/big/destination/with/10/components/that/" - "conforms/the/max/that/fits/in/a/single/SL/as/it/takes/" - "just/two/hundred/and/fifty/bytes/bytes/bytes/bytes/bytes" - "/bytes/bytes/bytes/bytes/bytes/bytes/../bytes"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 255); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* 6 min destination length to need two SL entries (251) */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./very/big/destination/with/10/components/that/" - "conforms/the/max/that/fits/in/a/single/SL/as/it/takes/" - "just/two/hundred/and/fifty/bytes/bytes/bytes/bytes/bytes" - "/bytes/bytes/bytes/bytes/bytes/bytes/../bytess"; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 261); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* 7 destination with big component that need to be splited - * in two SL entries */ - /* 7.a just fits in one */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "very big component with 248 characters, that is the max that" - " fits in a single SL entry. Take care that SL header takes 5 " - "bytes, and component header another 2, one for size, another" - " for flags. This last characters are just padding to get 248 " - "bytes."; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 255); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* 7.b doesn't fits by one character */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "very big component with 249 characters, that is the min that" - " doesn't fit in a single SL entry. Take care that SL header " - "takes 5 bytes, and component header another 2, one for size," - " another for flags. This last characters are just padding to" - " get 249."; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 255 + (5+2+1)); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* 7.c several components before, such as it has just the right len - * to fit in the SL entry plus another one */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "the/first/components/take just 245 characters/and thus the " - "first SL entry will have/255 - 5 - 245 - 2 (component " - "header) = 3/ just the space for another component with a " - "single character/This makes that last component fit in exactly 2 " - "SLs/very big component with 249 characters, that is the min " - "that doesn't fit in a single SL entry. Take care that SL " - "header takes 5 bytes, and component header another 2, one " - "for size, another for flags. This last characters are just " - "padding to get 249."; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 255 + 255); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* - * 7.d several components before, and then a big component that doesn't - * fit in the 1st SL entry and another one. That case needs a 3rd SL entry, - * but instead of divide the component in 2 entries, we put it in 2, - * without completelly fill the first one. - */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "the/first/components/take just 245 characters/and thus the " - "first SL entry will have/255 - 5 - 245 - 2 (component " - "header) = 3/ just the space for another component with a " - "single character/This makes that last component fit in exactly 2 " - "SLs/very big component with 250 characters, that is the min " - "that does not fit in a single SL entry. Take care that SL " - "header takes 5 bytes, and component header another 2, one " - "for size, another for flags. This last characters are just " - "padding to get 249."; - node->iso_name = "THIS_NAM.TXT"; - sua_len = rrip_calc_len(&t, node, 0, 255 - 46, &ce_len); - CU_ASSERT_EQUAL(ce_len, 252 + 255 + 9); - CU_ASSERT_EQUAL(sua_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - free(link); - free(node); -} - -static -void susp_info_free(struct susp_info *susp) -{ - size_t i; - - for (i = 0; i < susp->n_susp_fields; ++i) { - free(susp->susp_fields[i]); - } - free(susp->susp_fields); - - for (i = 0; i < susp->n_ce_susp_fields; ++i) { - free(susp->ce_susp_fields[i]); - } - free(susp->ce_susp_fields); -} - -static -void test_rrip_get_susp_fields_file() -{ - IsoFile *file; - Ecma119Node *node; - int ret; - struct susp_info susp; - Ecma119Image t; - uint8_t *entry; - - memset(&t, 0, sizeof(Ecma119Image)); - t.input_charset = "UTF-8"; - t.output_charset = "UTF-8"; - - file = malloc(sizeof(IsoFile)); - CU_ASSERT_PTR_NOT_NULL_FATAL(file); - file->msblock = 0; - file->sort_weight = 0; - file->stream = NULL; /* it is not needed here */ - file->node.type = LIBISO_FILE; - file->node.mode = S_IFREG | 0555; - file->node.uid = 235; - file->node.gid = 654; - file->node.mtime = 675757578; - file->node.atime = 546462546; - file->node.ctime = 323245342; - - node = malloc(sizeof(Ecma119Node)); - CU_ASSERT_PTR_NOT_NULL_FATAL(node); - node->node = (IsoNode*)file; - node->parent = (Ecma119Node*)0x55555555; /* just to make it not NULL */ - node->info.file = NULL; /* it is not needed here */ - node->type = ECMA119_FILE; - node->nlink = 1; - node->ino = 0x03447892; - - /* Case 1. Name fit in System Use field */ - file->node.name = "a small name.txt"; - node->iso_name = "A_SMALL_.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 0); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 0); - CU_ASSERT_EQUAL(susp.n_susp_fields, 3); /* PX + TF + NM */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 16) + (5 + 3*7) + 1); - - /* PX is the first entry */ - entry = susp.susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'P'); - CU_ASSERT_EQUAL(entry[1], 'X'); - CU_ASSERT_EQUAL(entry[2], 44); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), S_IFREG | 0555); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), S_IFREG | 0555); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 1); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 235); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 235); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 28, 4), 654); - CU_ASSERT_EQUAL(iso_read_msb(entry + 32, 4), 654); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 36, 4), 0x03447892); - CU_ASSERT_EQUAL(iso_read_msb(entry + 40, 4), 0x03447892); - - /* TF is the second entry */ - entry = susp.susp_fields[1]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'T'); - CU_ASSERT_EQUAL(entry[1], 'F'); - CU_ASSERT_EQUAL(entry[2], 5 + 3*7); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0x0E); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 5), 675757578); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 12), 546462546); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 19), 323245342); - - /* NM is the last entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 16); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "a small name.txt", 16); - - susp_info_free(&susp); - - /* Case 2. Name fits exactly */ - file->node.name = "a big name, with 133 characters, that it is the max " - "that fits in System Use field of the directory record " - "PADPADPADADPADPADPADPAD.txt"; - node->iso_name = "A_BIG_NA.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 0); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 0); - CU_ASSERT_EQUAL(susp.suf_len, 254 - 46); - - CU_ASSERT_EQUAL(susp.n_susp_fields, 3); /* PX + TF + NM */ - - /* NM is the last entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 133); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "a big name, with 133 characters, that " - "it is the max that fits in System Use field of the " - "directory record PADPADPADADPADPADPADPAD.txt", 133); - - susp_info_free(&susp); - - /* case 3. A name just 1 character too big to fit in SUA */ - file->node.name = "a big name, with 133 characters, that it is the max " - "that fits in System Use field of the directory record " - "PADPADPADADPADPADPADPAD1.txt"; - node->iso_name = "A_BIG_NA.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 28 + 5 + 1); - CU_ASSERT_EQUAL(susp.suf_len, 254 - 46); - - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* NM */ - - /* test NM entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 105); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 1); /* CONTINUE */ - CU_ASSERT_NSTRING_EQUAL(entry + 5, "a big name, with 133 characters, that " - "it is the max that fits in System Use field of the " - "directory record", 105); - - /* and CE entry */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 34); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 34); - - /* and check Continuation area */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 29); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, " PADPADPADADPADPADPADPAD1.txt", 29); - - susp_info_free(&susp); - - /* case 4. A 255 characters name */ - file->node.name = "a big name, with 255 characters, that it is the max " - "that a POSIX filename can have. PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"; - node->iso_name = "A_BIG_NA.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - susp.ce_block = 12; - susp.ce_len = 456; - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 150 + 5 + 456); - CU_ASSERT_EQUAL(susp.suf_len, 254 - 46); - - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* NM */ - - /* test NM entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 105); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 1); /* CONTINUE */ - CU_ASSERT_NSTRING_EQUAL(entry + 5, "a big name, with 255 characters, that " - "it is the max that a POSIX filename can have. PPP" - "PPPPPPPPPPPPPPPPPP", 105); - - /* and CE entry */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - - /* block, offset, size */ - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 12); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 12); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 456); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 456); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 155); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 155); - - /* and check Continuation area */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 150); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" - "PPPPPPPPPPPPPP", 150); - - susp_info_free(&susp); - - free(node); - free(file); -} - -static void test_rrip_get_susp_fields_symlink() -{ - IsoSymlink *link; - Ecma119Node *node; - Ecma119Image t; - int ret; - struct susp_info susp; - uint8_t *entry; - - memset(&t, 0, sizeof(Ecma119Image)); - t.input_charset = "UTF-8"; - t.output_charset = "UTF-8"; - - link = malloc(sizeof(IsoSymlink)); - CU_ASSERT_PTR_NOT_NULL_FATAL(link); - link->node.type = LIBISO_SYMLINK; - link->node.mode = S_IFREG | 0555; - link->node.uid = 235; - link->node.gid = 654; - link->node.mtime = 675757578; - link->node.atime = 546462546; - link->node.ctime = 323245342; - - node = malloc(sizeof(Ecma119Node)); - CU_ASSERT_PTR_NOT_NULL_FATAL(node); - node->node = (IsoNode*)link; - node->parent = (Ecma119Node*)0x55555555; /* just to make it not NULL */ - node->type = ECMA119_SYMLINK; - node->nlink = 1; - node->ino = 0x03447892; - - /* Case 1. Name and dest fit in System Use field */ - link->node.name = "a small name.txt"; - link->dest = "/three/components"; - node->iso_name = "A_SMALL_.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 0); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 0); - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + SL */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 16) + (5 + 3*7) + 1 - + (5 + 2 + (2 + 5) + (2 + 10))); - - /* PX is the first entry */ - entry = susp.susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'P'); - CU_ASSERT_EQUAL(entry[1], 'X'); - CU_ASSERT_EQUAL(entry[2], 44); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), S_IFREG | 0555); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), S_IFREG | 0555); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 1); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 235); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 235); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 28, 4), 654); - CU_ASSERT_EQUAL(iso_read_msb(entry + 32, 4), 654); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 36, 4), 0x03447892); - CU_ASSERT_EQUAL(iso_read_msb(entry + 40, 4), 0x03447892); - - /* TF is the second entry */ - entry = susp.susp_fields[1]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'T'); - CU_ASSERT_EQUAL(entry[1], 'F'); - CU_ASSERT_EQUAL(entry[2], 5 + 3*7); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0x0E); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 5), 675757578); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 12), 546462546); - CU_ASSERT_EQUAL(iso_datetime_read_7(entry + 19), 323245342); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 16); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "a small name.txt", 16); - - /* SL is the last entry */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 5 + 2 + (2 + 5) + (2 + 10)); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x8); /* root */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 5); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "three", 5); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 16, "components", 10); - - susp_info_free(&susp); - - /* case 2. name + dest fits exactly */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 0); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 0); - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + SL */ - CU_ASSERT_EQUAL(susp.suf_len, 254 - 46); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 74); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 74 characters as " - "it is the max that fits in the SU.txt", 74); - - /* SL is the last entry */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 5 + 2 + 5 + 2 + 3 + 2 + 5 + 13 + 6 + 4 + 12); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "components", 10); - - susp_info_free(&susp); - - /* case 3. name fits, dest is one byte larger to fit */ - /* 3.a extra byte in dest */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./big/destination/with/10/componentsk"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 60); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 74) + (5 + 3*7) + 1 + 28); - - /* PX is the first entry */ - entry = susp.susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'P'); - CU_ASSERT_EQUAL(entry[1], 'X'); - CU_ASSERT_EQUAL(entry[2], 44); - - /* TF is the second entry */ - entry = susp.susp_fields[1]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'T'); - CU_ASSERT_EQUAL(entry[1], 'F'); - CU_ASSERT_EQUAL(entry[2], 5 + 3*7); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 74); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 74 characters as " - "it is the max that fits in the SU.txt", 74); - - /* and CE entry is last */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 60); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 60); - - - /* finally, SL is the single entry in CE */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 60); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "componentsk", 11); - - susp_info_free(&susp); - - /* 3.b extra byte in name */ - link->node.name = "this name will have 75 characters as it is the max " - "that fits in the SUx.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 59); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 75) + (5 + 3*7) + 28); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 75); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 75 characters as it " - "is the max that fits in the SUx.txt", 75); - - /* and CE entry is last */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 59); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 59); - - - /* finally, SL is the single entry in CE */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 59); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "components", 10); - - susp_info_free(&susp); - - /* case 4. name seems to fit, but SL no, and when CE is added NM - * doesn't fit too */ - /* 4.a it just fits */ - link->node.name = "this name will have 105 characters as it is just the " - "max that fits in the SU once we add the CE entry.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 59); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 3*7) + (5 + 105) + 28); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 105); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 105 characters as " - "it is just the max that fits in the SU once we " - "add the CE entry.txt", 105); - - /* and CE entry is last */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 59); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 59); - - /* finally, SL is the single entry in CE */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 59); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "components", 10); - - susp_info_free(&susp); - - /* 4.b it just fits, the the component ends in '/' */ - link->node.name = "this name will have 105 characters as it is just the " - "max that fits in the SU once we add the CE entry.txt"; - link->dest = "./and/../a/./big/destination/with/10/components/"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 59); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 3*7) + (5 + 105) + 28); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 105); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 105 characters as " - "it is just the max that fits in the SU once we " - "add the CE entry.txt", 105); - - /* and CE entry is last */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 59); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 59); - - /* finally, SL is the single entry in CE */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 59); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "components", 10); - - susp_info_free(&susp); - - /* 4.c extra char in name, that forces it to be divided */ - link->node.name = "this name will have 106 characters as it is just the " - "max that fits in the SU once we add the CE entryc.txt"; - link->dest = "./and/../a/./big/destination/with/10/components"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 6 + 59); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 2); /* NM + SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 3*7) + (5 + 105) + 28); - - /* NM is the 3rd entry */ - entry = susp.susp_fields[2]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 105); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0x1); /* continue */ - CU_ASSERT_NSTRING_EQUAL(entry + 5, "this name will have 106 characters as " - "it is just the max that fits in the SU once we " - "add the CE entryc.tx", 105); - - /* and CE entry is last */ - entry = susp.susp_fields[3]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'C'); - CU_ASSERT_EQUAL(entry[1], 'E'); - CU_ASSERT_EQUAL(entry[2], 28); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 4, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 8, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 12, 4), 0); - CU_ASSERT_EQUAL(iso_read_msb(entry + 16, 4), 0); - CU_ASSERT_EQUAL(iso_read_lsb(entry + 20, 4), 59 + 6); - CU_ASSERT_EQUAL(iso_read_msb(entry + 24, 4), 59 + 6); - - /* NM is the 1st entry in CE */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'N'); - CU_ASSERT_EQUAL(entry[1], 'M'); - CU_ASSERT_EQUAL(entry[2], 5 + 1); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - CU_ASSERT_EQUAL(entry[5], 't'); - - /* finally, SL is the single entry in CE */ - entry = susp.ce_susp_fields[1]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 59); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "big", 3); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[24], 0); - CU_ASSERT_EQUAL(entry[25], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 26, "destination", 11); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[37], 0); - CU_ASSERT_EQUAL(entry[38], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 39, "with", 4); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "10", 2); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[47], 0); - CU_ASSERT_EQUAL(entry[48], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 49, "components", 10); - - susp_info_free(&susp); - - /* 5 max destination length to fit in a single SL entry (250) */ - link->node.name = "this name will have 74 characters as it is the max " - "that fits in the SU.txt"; - link->dest = "./and/../a/./very/big/destination/with/10/components/that/" - "conforms/the/max/that/fits/in/a single SL/entry as it takes " - "just two hundred and/fifty bytes bytes bytes bytes/bytes" - " bytes bytes bytes bytes bytes bytes bytes bytes/../bytes"; - node->iso_name = "THIS_NAM.TXT"; - - memset(&susp, 0, sizeof(struct susp_info)); - ret = rrip_get_susp_fields(&t, node, 0, 255 - 46, &susp); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_EQUAL(susp.ce_len, 255); - CU_ASSERT_EQUAL(susp.n_ce_susp_fields, 1); /* SL */ - CU_ASSERT_EQUAL(susp.n_susp_fields, 4); /* PX + TF + NM + CE */ - CU_ASSERT_EQUAL(susp.suf_len, 44 + (5 + 3*7) + (5 + 74) + 1 + 28); - - /* just check the SL entry */ - entry = susp.ce_susp_fields[0]; - CU_ASSERT_PTR_NOT_NULL(entry); - CU_ASSERT_EQUAL(entry[0], 'S'); - CU_ASSERT_EQUAL(entry[1], 'L'); - CU_ASSERT_EQUAL(entry[2], 255); - CU_ASSERT_EQUAL(entry[3], 1); - CU_ASSERT_EQUAL(entry[4], 0); - - /* first component */ - CU_ASSERT_EQUAL(entry[5], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[6], 0); - - /* 2nd component */ - CU_ASSERT_EQUAL(entry[7], 0); - CU_ASSERT_EQUAL(entry[8], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 9, "and", 3); - - /* 3rd component */ - CU_ASSERT_EQUAL(entry[12], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[13], 0); - - /* 4th component */ - CU_ASSERT_EQUAL(entry[14], 0); - CU_ASSERT_EQUAL(entry[15], 1); - CU_ASSERT_EQUAL(entry[16], 'a'); - - /* 5th component */ - CU_ASSERT_EQUAL(entry[17], 0x2); /* current */ - CU_ASSERT_EQUAL(entry[18], 0); - - /* 6th component */ - CU_ASSERT_EQUAL(entry[19], 0); - CU_ASSERT_EQUAL(entry[20], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 21, "very", 4); - - /* 7th component */ - CU_ASSERT_EQUAL(entry[25], 0); - CU_ASSERT_EQUAL(entry[26], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 27, "big", 3); - - /* 8th component */ - CU_ASSERT_EQUAL(entry[30], 0); - CU_ASSERT_EQUAL(entry[31], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 32, "destination", 11); - - /* 9th component */ - CU_ASSERT_EQUAL(entry[43], 0); - CU_ASSERT_EQUAL(entry[44], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 45, "with", 4); - - /* 10th component */ - CU_ASSERT_EQUAL(entry[49], 0); - CU_ASSERT_EQUAL(entry[50], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 51, "10", 2); - - /* 11th component */ - CU_ASSERT_EQUAL(entry[53], 0); - CU_ASSERT_EQUAL(entry[54], 10); - CU_ASSERT_NSTRING_EQUAL(entry + 55, "components", 10); - - /* 12th component */ - CU_ASSERT_EQUAL(entry[65], 0); - CU_ASSERT_EQUAL(entry[66], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 67, "that", 4); - - /* 13th component */ - CU_ASSERT_EQUAL(entry[71], 0); - CU_ASSERT_EQUAL(entry[72], 8); - CU_ASSERT_NSTRING_EQUAL(entry + 73, "conforms", 8); - - /* 14th component */ - CU_ASSERT_EQUAL(entry[81], 0); - CU_ASSERT_EQUAL(entry[82], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 83, "the", 3); - - /* 15th component */ - CU_ASSERT_EQUAL(entry[86], 0); - CU_ASSERT_EQUAL(entry[87], 3); - CU_ASSERT_NSTRING_EQUAL(entry + 88, "max", 3); - - /* 16th component */ - CU_ASSERT_EQUAL(entry[91], 0); - CU_ASSERT_EQUAL(entry[92], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 93, "that", 4); - - /* 17th component */ - CU_ASSERT_EQUAL(entry[97], 0); - CU_ASSERT_EQUAL(entry[98], 4); - CU_ASSERT_NSTRING_EQUAL(entry + 99, "fits", 4); - - /* 18th component */ - CU_ASSERT_EQUAL(entry[103], 0); - CU_ASSERT_EQUAL(entry[104], 2); - CU_ASSERT_NSTRING_EQUAL(entry + 105, "in", 2); - - /* 19th component */ - CU_ASSERT_EQUAL(entry[107], 0); - CU_ASSERT_EQUAL(entry[108], 11); - CU_ASSERT_NSTRING_EQUAL(entry + 109, "a single SL", 11); - - /* 20th component */ - CU_ASSERT_EQUAL(entry[120], 0); - CU_ASSERT_EQUAL(entry[121], 38); - CU_ASSERT_NSTRING_EQUAL(entry + 122, "entry as it takes " - "just two hundred and", 38); - - /* 21th component */ - CU_ASSERT_EQUAL(entry[160], 0); - CU_ASSERT_EQUAL(entry[161], 29); - CU_ASSERT_NSTRING_EQUAL(entry + 162, "fifty bytes bytes bytes bytes", 29); - - /* 22th component */ - CU_ASSERT_EQUAL(entry[191], 0); - CU_ASSERT_EQUAL(entry[192], 53); - CU_ASSERT_NSTRING_EQUAL(entry + 193, "bytes bytes bytes bytes bytes bytes" - " bytes bytes bytes", 53); - - /* 23th component */ - CU_ASSERT_EQUAL(entry[246], 0x4); /* parent */ - CU_ASSERT_EQUAL(entry[247], 0); - - /* 24th component */ - CU_ASSERT_EQUAL(entry[248], 0); - CU_ASSERT_EQUAL(entry[249], 5); - CU_ASSERT_NSTRING_EQUAL(entry + 250, "bytes", 5); - - susp_info_free(&susp); - - free(node); - free(link); -} - -void add_rockridge_suite() -{ - CU_pSuite pSuite = CU_add_suite("RockRidge Suite", NULL, NULL); - - CU_add_test(pSuite, "rrip_calc_len(file)", test_rrip_calc_len_file); - CU_add_test(pSuite, "rrip_calc_len(symlink)", test_rrip_calc_len_symlink); - CU_add_test(pSuite, "rrip_get_susp_fields(file)", test_rrip_get_susp_fields_file); - CU_add_test(pSuite, "rrip_get_susp_fields(symlink)", test_rrip_get_susp_fields_symlink); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_stream.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_stream.c deleted file mode 100644 index 35e14666..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_stream.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Unit test for util.h - * - * This test utiliy functions - */ -#include "test.h" -#include "stream.h" - -#include - -static -void test_mem_new() -{ - int ret; - IsoStream *stream; - unsigned char *buf; - - buf = malloc(3000); - ret = iso_memory_stream_new(buf, 3000, &stream); - CU_ASSERT_EQUAL(ret, 1); - iso_stream_unref(stream); - - ret = iso_memory_stream_new(NULL, 3000, &stream); - CU_ASSERT_EQUAL(ret, ISO_NULL_POINTER); - - ret = iso_memory_stream_new(buf, 3000, NULL); - CU_ASSERT_EQUAL(ret, ISO_NULL_POINTER); -} - -static -void test_mem_open() -{ - int ret; - IsoStream *stream; - unsigned char *buf; - - buf = malloc(3000); - ret = iso_memory_stream_new(buf, 3000, &stream); - CU_ASSERT_EQUAL(ret, 1); - - ret = iso_stream_open(stream); - CU_ASSERT_EQUAL(ret, 1); - - /* try to open an already opened stream */ - ret = iso_stream_open(stream); - CU_ASSERT_EQUAL(ret, ISO_FILE_ALREADY_OPENNED); - - ret = iso_stream_close(stream); - CU_ASSERT_EQUAL(ret, 1); - - ret = iso_stream_close(stream); - CU_ASSERT_EQUAL(ret, ISO_FILE_NOT_OPENNED); - - iso_stream_unref(stream); -} - -static -void test_mem_read() -{ - int ret; - IsoStream *stream; - unsigned char *buf; - unsigned char rbuf[3000]; - - buf = malloc(3000); - memset(buf, 2, 200); - memset(buf + 200, 3, 300); - memset(buf + 500, 5, 500); - memset(buf + 1000, 10, 1000); - memset(buf + 2000, 56, 48); - memset(buf + 2048, 137, 22); - memset(buf + 2070, 13, 130); - memset(buf + 2200, 88, 800); - - ret = iso_memory_stream_new(buf, 3000, &stream); - CU_ASSERT_EQUAL(ret, 1); - - /* test 1: read full buf */ - ret = iso_stream_open(stream); - CU_ASSERT_EQUAL(ret, 1); - - ret = iso_stream_read(stream, rbuf, 3000); - CU_ASSERT_EQUAL(ret, 3000); - CU_ASSERT_NSTRING_EQUAL(rbuf, buf, 3000); - - /* read again is EOF */ - ret = iso_stream_read(stream, rbuf, 20); - CU_ASSERT_EQUAL(ret, 0); - - ret = iso_stream_close(stream); - CU_ASSERT_EQUAL(ret, 1); - - /* test 2: read more than available bytes */ - ret = iso_stream_open(stream); - CU_ASSERT_EQUAL(ret, 1); - - ret = iso_stream_read(stream, rbuf, 3050); - CU_ASSERT_EQUAL(ret, 3000); - CU_ASSERT_NSTRING_EQUAL(rbuf, buf, 3000); - - /* read again is EOF */ - ret = iso_stream_read(stream, rbuf, 20); - CU_ASSERT_EQUAL(ret, 0); - - ret = iso_stream_close(stream); - CU_ASSERT_EQUAL(ret, 1); - - /* test 3: read in block size */ - ret = iso_stream_open(stream); - CU_ASSERT_EQUAL(ret, 1); - - ret = iso_stream_read(stream, rbuf, 2048); - CU_ASSERT_EQUAL(ret, 2048); - CU_ASSERT_NSTRING_EQUAL(rbuf, buf, 2048); - - ret = iso_stream_read(stream, rbuf, 2048); - CU_ASSERT_EQUAL(ret, 3000 - 2048); - CU_ASSERT_NSTRING_EQUAL(rbuf, buf + 2048, 3000 - 2048); - - ret = iso_stream_read(stream, rbuf, 20); - CU_ASSERT_EQUAL(ret, 0); - - ret = iso_stream_close(stream); - CU_ASSERT_EQUAL(ret, 1); - - iso_stream_unref(stream); -} - -static -void test_mem_size() -{ - int ret; - off_t size; - IsoStream *stream; - unsigned char *buf; - - buf = malloc(3000); - ret = iso_memory_stream_new(buf, 3000, &stream); - CU_ASSERT_EQUAL(ret, 1); - - size = iso_stream_get_size(stream); - CU_ASSERT_EQUAL(size, 3000); - - iso_stream_unref(stream); -} - -void add_stream_suite() -{ - CU_pSuite pSuite = CU_add_suite("IsoStreamSuite", NULL, NULL); - - CU_add_test(pSuite, "iso_memory_stream_new()", test_mem_new); - CU_add_test(pSuite, "MemoryStream->open()", test_mem_open); - CU_add_test(pSuite, "MemoryStream->read()", test_mem_read); - CU_add_test(pSuite, "MemoryStream->get_size()", test_mem_size); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_tree.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_tree.c deleted file mode 100644 index 8379439c..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_tree.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Unit test for node.h - */ - -#include "libisofs.h" -#include "node.h" -#include "image.h" - -#include "test.h" -#include "mocked_fsrc.h" - -#include - -static -void test_iso_tree_add_new_dir() -{ - int result; - IsoDir *root; - IsoDir *node1, *node2, *node3, *node4; - IsoImage *image; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - result = iso_tree_add_new_dir(root, "Dir1", &node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(root->nchildren, 1); - CU_ASSERT_PTR_EQUAL(root->children, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node1->node.parent, root); - CU_ASSERT_EQUAL(node1->node.type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node1->node.name, "Dir1"); - - /* creation of a second dir, to be inserted before */ - result = iso_tree_add_new_dir(root, "A node to be added first", &node2); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(root->nchildren, 2); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node2->node.parent, root); - CU_ASSERT_EQUAL(node2->node.type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node2->node.name, "A node to be added first"); - - /* creation of a 3rd node, to be inserted last */ - result = iso_tree_add_new_dir(root, "This node will be inserted last", &node3); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_EQUAL(node3->node.parent, root); - CU_ASSERT_EQUAL(node3->node.type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node3->node.name, "This node will be inserted last"); - - /* force some failures */ - result = iso_tree_add_new_dir(NULL, "dsadas", &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_tree_add_new_dir(root, NULL, &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - - /* try to insert a new dir with same name */ - result = iso_tree_add_new_dir(root, "This node will be inserted last", &node4); - CU_ASSERT_EQUAL(result, ISO_NODE_NAME_NOT_UNIQUE); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_NULL(node4); - - /* but pointer to new dir can be null */ - result = iso_tree_add_new_dir(root, "Another node", NULL); - CU_ASSERT_EQUAL(result, 4); - CU_ASSERT_EQUAL(root->nchildren, 4); - CU_ASSERT_PTR_EQUAL(node2->node.next->next, node1); - CU_ASSERT_STRING_EQUAL(node2->node.next->name, "Another node"); - - iso_image_unref(image); -} - -static -void test_iso_tree_add_new_symlink() -{ - int result; - IsoDir *root; - IsoSymlink *node1, *node2, *node3, *node4; - IsoImage *image; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - result = iso_tree_add_new_symlink(root, "Link1", "/path/to/dest", &node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(root->nchildren, 1); - CU_ASSERT_PTR_EQUAL(root->children, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node1->node.parent, root); - CU_ASSERT_EQUAL(node1->node.type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node1->node.name, "Link1"); - CU_ASSERT_STRING_EQUAL(node1->dest, "/path/to/dest"); - - /* creation of a second link, to be inserted before */ - result = iso_tree_add_new_symlink(root, "A node to be added first", "/home/me", &node2); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(root->nchildren, 2); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node2->node.parent, root); - CU_ASSERT_EQUAL(node2->node.type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node2->node.name, "A node to be added first"); - CU_ASSERT_STRING_EQUAL(node2->dest, "/home/me"); - - /* creation of a 3rd node, to be inserted last */ - result = iso_tree_add_new_symlink(root, "This node will be inserted last", - "/path/to/dest", &node3); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_EQUAL(node3->node.parent, root); - CU_ASSERT_EQUAL(node3->node.type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node3->node.name, "This node will be inserted last"); - CU_ASSERT_STRING_EQUAL(node3->dest, "/path/to/dest"); - - /* force some failures */ - result = iso_tree_add_new_symlink(NULL, "dsadas", "/path/to/dest", &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_tree_add_new_symlink(root, NULL, "/path/to/dest", &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_tree_add_new_symlink(root, "dsadas", NULL, &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - - /* try to insert a new link with same name */ - result = iso_tree_add_new_symlink(root, "This node will be inserted last", "/", &node4); - CU_ASSERT_EQUAL(result, ISO_NODE_NAME_NOT_UNIQUE); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_NULL(node4); - - /* but pointer to new link can be null */ - result = iso_tree_add_new_symlink(root, "Another node", ".", NULL); - CU_ASSERT_EQUAL(result, 4); - CU_ASSERT_EQUAL(root->nchildren, 4); - CU_ASSERT_PTR_EQUAL(node2->node.next->next, node1); - CU_ASSERT_EQUAL(node2->node.next->type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(((IsoSymlink*)(node2->node.next))->dest, "."); - CU_ASSERT_STRING_EQUAL(node2->node.next->name, "Another node"); - - iso_image_unref(image); -} - -static -void test_iso_tree_add_new_special() -{ - int result; - IsoDir *root; - IsoSpecial *node1, *node2, *node3, *node4; - IsoImage *image; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - result = iso_tree_add_new_special(root, "Special1", S_IFSOCK | 0644, 0, &node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(root->nchildren, 1); - CU_ASSERT_PTR_EQUAL(root->children, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node1->node.parent, root); - CU_ASSERT_EQUAL(node1->node.type, LIBISO_SPECIAL); - CU_ASSERT_STRING_EQUAL(node1->node.name, "Special1"); - CU_ASSERT_EQUAL(node1->dev, 0); - CU_ASSERT_EQUAL(node1->node.mode, S_IFSOCK | 0644); - - /* creation of a block dev, to be inserted before */ - result = iso_tree_add_new_special(root, "A node to be added first", S_IFBLK | 0640, 34, &node2); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(root->nchildren, 2); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_NULL(node1->node.next); - CU_ASSERT_PTR_EQUAL(node2->node.parent, root); - CU_ASSERT_EQUAL(node2->node.type, LIBISO_SPECIAL); - CU_ASSERT_STRING_EQUAL(node2->node.name, "A node to be added first"); - CU_ASSERT_EQUAL(node2->dev, 34); - CU_ASSERT_EQUAL(node2->node.mode, S_IFBLK | 0640); - - /* creation of a 3rd node, to be inserted last */ - result = iso_tree_add_new_special(root, "This node will be inserted last", - S_IFCHR | 0440, 345, &node3); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_EQUAL(node3->node.parent, root); - CU_ASSERT_EQUAL(node3->node.type, LIBISO_SPECIAL); - CU_ASSERT_STRING_EQUAL(node3->node.name, "This node will be inserted last"); - CU_ASSERT_EQUAL(node3->dev, 345); - CU_ASSERT_EQUAL(node3->node.mode, S_IFCHR | 0440); - - /* force some failures */ - result = iso_tree_add_new_special(NULL, "dsadas", S_IFBLK | 0440, 345, &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_tree_add_new_special(root, NULL, S_IFBLK | 0440, 345, &node4); - CU_ASSERT_EQUAL(result, ISO_NULL_POINTER); - result = iso_tree_add_new_special(root, "dsadas", S_IFDIR | 0666, 0, &node4); - CU_ASSERT_EQUAL(result, ISO_WRONG_ARG_VALUE); - result = iso_tree_add_new_special(root, "dsadas", S_IFREG | 0666, 0, &node4); - CU_ASSERT_EQUAL(result, ISO_WRONG_ARG_VALUE); - result = iso_tree_add_new_special(root, "dsadas", S_IFLNK | 0666, 0, &node4); - CU_ASSERT_EQUAL(result, ISO_WRONG_ARG_VALUE); - - /* try to insert a new special file with same name */ - result = iso_tree_add_new_special(root, "This node will be inserted last", S_IFIFO | 0666, 0, &node4); - CU_ASSERT_EQUAL(result, ISO_NODE_NAME_NOT_UNIQUE); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->node.next, node1); - CU_ASSERT_PTR_EQUAL(node1->node.next, node3); - CU_ASSERT_PTR_NULL(node3->node.next); - CU_ASSERT_PTR_NULL(node4); - - /* but pointer to new special can be null */ - result = iso_tree_add_new_special(root, "Another node", S_IFIFO | 0666, 0, NULL); - CU_ASSERT_EQUAL(result, 4); - CU_ASSERT_EQUAL(root->nchildren, 4); - CU_ASSERT_PTR_EQUAL(node2->node.next->next, node1); - CU_ASSERT_EQUAL(node2->node.next->type, LIBISO_SPECIAL); - CU_ASSERT_EQUAL(((IsoSpecial*)(node2->node.next))->dev, 0); - CU_ASSERT_EQUAL(node2->node.next->mode, S_IFIFO | 0666); - CU_ASSERT_STRING_EQUAL(node2->node.next->name, "Another node"); - - iso_image_unref(image); -} - -static -void test_iso_tree_add_node_dir() -{ - int result; - IsoDir *root; - IsoNode *node1, *node2, *node3, *node4; - IsoImage *image; - IsoFilesystem *fs; - struct stat info; - struct mock_file *mroot, *dir1, *dir2; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - /* replace image filesystem with out mockep one */ - iso_filesystem_unref(image->fs); - result = test_mocked_filesystem_new(&fs); - CU_ASSERT_EQUAL(result, 1); - image->fs = fs; - mroot = test_mocked_fs_get_root(fs); - - /* add some files to the filesystem */ - info.st_mode = S_IFDIR | 0550; - info.st_uid = 20; - info.st_gid = 21; - info.st_atime = 234523; - info.st_ctime = 23432432; - info.st_mtime = 1111123; - result = test_mocked_fs_add_dir("dir", mroot, info, &dir1); - CU_ASSERT_EQUAL(result, 1); - - info.st_mode = S_IFDIR | 0555; - info.st_uid = 30; - info.st_gid = 31; - info.st_atime = 3234523; - info.st_ctime = 3234432; - info.st_mtime = 3111123; - result = test_mocked_fs_add_dir("a child node", dir1, info, &dir2); - CU_ASSERT_EQUAL(result, 1); - - info.st_mode = S_IFDIR | 0750; - info.st_uid = 40; - info.st_gid = 41; - info.st_atime = 4234523; - info.st_ctime = 4234432; - info.st_mtime = 4111123; - result = test_mocked_fs_add_dir("another one", dir1, info, &dir2); - CU_ASSERT_EQUAL(result, 1); - - info.st_mode = S_IFDIR | 0755; - info.st_uid = 50; - info.st_gid = 51; - info.st_atime = 5234523; - info.st_ctime = 5234432; - info.st_mtime = 5111123; - result = test_mocked_fs_add_dir("zzzz", mroot, info, &dir2); - CU_ASSERT_EQUAL(result, 1); - - /* and now insert those files to the image */ - result = iso_tree_add_node(image, root, "/dir", &node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(root->nchildren, 1); - CU_ASSERT_PTR_EQUAL(root->children, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_EQUAL(node1->type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node1->name, "dir"); - CU_ASSERT_EQUAL(node1->mode, S_IFDIR | 0550); - CU_ASSERT_EQUAL(node1->uid, 20); - CU_ASSERT_EQUAL(node1->gid, 21); - CU_ASSERT_EQUAL(node1->atime, 234523); - CU_ASSERT_EQUAL(node1->ctime, 23432432); - CU_ASSERT_EQUAL(node1->mtime, 1111123); - CU_ASSERT_PTR_NULL(((IsoDir*)node1)->children); - CU_ASSERT_EQUAL(((IsoDir*)node1)->nchildren, 0); - - result = iso_tree_add_node(image, root, "/dir/a child node", &node2); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(root->nchildren, 2); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_PTR_EQUAL(node2->parent, root); - CU_ASSERT_EQUAL(node2->type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node2->name, "a child node"); - CU_ASSERT_EQUAL(node2->mode, S_IFDIR | 0555); - CU_ASSERT_EQUAL(node2->uid, 30); - CU_ASSERT_EQUAL(node2->gid, 31); - CU_ASSERT_EQUAL(node2->atime, 3234523); - CU_ASSERT_EQUAL(node2->ctime, 3234432); - CU_ASSERT_EQUAL(node2->mtime, 3111123); - CU_ASSERT_PTR_NULL(((IsoDir*)node2)->children); - CU_ASSERT_EQUAL(((IsoDir*)node2)->nchildren, 0); - - result = iso_tree_add_node(image, root, "/dir/another one", &node3); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node3); - CU_ASSERT_PTR_EQUAL(node3->next, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_PTR_EQUAL(node2->parent, root); - CU_ASSERT_PTR_EQUAL(node3->parent, root); - CU_ASSERT_EQUAL(node3->type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node3->name, "another one"); - CU_ASSERT_EQUAL(node3->mode, S_IFDIR | 0750); - CU_ASSERT_EQUAL(node3->uid, 40); - CU_ASSERT_EQUAL(node3->gid, 41); - CU_ASSERT_EQUAL(node3->atime, 4234523); - CU_ASSERT_EQUAL(node3->ctime, 4234432); - CU_ASSERT_EQUAL(node3->mtime, 4111123); - CU_ASSERT_PTR_NULL(((IsoDir*)node3)->children); - CU_ASSERT_EQUAL(((IsoDir*)node3)->nchildren, 0); - - result = iso_tree_add_node(image, root, "/zzzz", &node4); - CU_ASSERT_EQUAL(result, 4); - CU_ASSERT_EQUAL(root->nchildren, 4); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node3); - CU_ASSERT_PTR_EQUAL(node3->next, node1); - CU_ASSERT_PTR_EQUAL(node1->next, node4); - CU_ASSERT_PTR_NULL(node4->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_PTR_EQUAL(node2->parent, root); - CU_ASSERT_PTR_EQUAL(node3->parent, root); - CU_ASSERT_PTR_EQUAL(node4->parent, root); - CU_ASSERT_EQUAL(node4->type, LIBISO_DIR); - CU_ASSERT_STRING_EQUAL(node4->name, "zzzz"); - CU_ASSERT_EQUAL(node4->mode, S_IFDIR | 0755); - CU_ASSERT_EQUAL(node4->uid, 50); - CU_ASSERT_EQUAL(node4->gid, 51); - CU_ASSERT_EQUAL(node4->atime, 5234523); - CU_ASSERT_EQUAL(node4->ctime, 5234432); - CU_ASSERT_EQUAL(node4->mtime, 5111123); - CU_ASSERT_PTR_NULL(((IsoDir*)node4)->children); - CU_ASSERT_EQUAL(((IsoDir*)node4)->nchildren, 0); - - iso_image_unref(image); -} - -static -void test_iso_tree_add_node_link() -{ - int result; - IsoDir *root; - IsoNode *node1, *node2, *node3; - IsoImage *image; - IsoFilesystem *fs; - struct stat info; - struct mock_file *mroot, *link; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - /* replace image filesystem with out mockep one */ - iso_filesystem_unref(image->fs); - result = test_mocked_filesystem_new(&fs); - CU_ASSERT_EQUAL(result, 1); - image->fs = fs; - mroot = test_mocked_fs_get_root(fs); - - /* add some files to the filesystem */ - info.st_mode = S_IFLNK | 0777; - info.st_uid = 12; - info.st_gid = 13; - info.st_atime = 123444; - info.st_ctime = 123555; - info.st_mtime = 123666; - result = test_mocked_fs_add_symlink("link1", mroot, info, "/home/me", &link); - CU_ASSERT_EQUAL(result, 1); - - info.st_mode = S_IFLNK | 0555; - info.st_uid = 22; - info.st_gid = 23; - info.st_atime = 223444; - info.st_ctime = 223555; - info.st_mtime = 223666; - result = test_mocked_fs_add_symlink("another link", mroot, info, "/", &link); - CU_ASSERT_EQUAL(result, 1); - - info.st_mode = S_IFLNK | 0750; - info.st_uid = 32; - info.st_gid = 33; - info.st_atime = 323444; - info.st_ctime = 323555; - info.st_mtime = 323666; - result = test_mocked_fs_add_symlink("this will be the last", mroot, info, "/etc", &link); - CU_ASSERT_EQUAL(result, 1); - - /* and now insert those files to the image */ - result = iso_tree_add_node(image, root, "/link1", &node1); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_EQUAL(root->nchildren, 1); - CU_ASSERT_PTR_EQUAL(root->children, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_EQUAL(node1->type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node1->name, "link1"); - CU_ASSERT_EQUAL(node1->mode, S_IFLNK | 0777); - CU_ASSERT_EQUAL(node1->uid, 12); - CU_ASSERT_EQUAL(node1->gid, 13); - CU_ASSERT_EQUAL(node1->atime, 123444); - CU_ASSERT_EQUAL(node1->ctime, 123555); - CU_ASSERT_EQUAL(node1->mtime, 123666); - CU_ASSERT_STRING_EQUAL(((IsoSymlink*)node1)->dest, "/home/me"); - - result = iso_tree_add_node(image, root, "/another link", &node2); - CU_ASSERT_EQUAL(result, 2); - CU_ASSERT_EQUAL(root->nchildren, 2); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_NULL(node1->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_PTR_EQUAL(node2->parent, root); - CU_ASSERT_EQUAL(node2->type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node2->name, "another link"); - CU_ASSERT_EQUAL(node2->mode, S_IFLNK | 0555); - CU_ASSERT_EQUAL(node2->uid, 22); - CU_ASSERT_EQUAL(node2->gid, 23); - CU_ASSERT_EQUAL(node2->atime, 223444); - CU_ASSERT_EQUAL(node2->ctime, 223555); - CU_ASSERT_EQUAL(node2->mtime, 223666); - CU_ASSERT_STRING_EQUAL(((IsoSymlink*)node2)->dest, "/"); - - result = iso_tree_add_node(image, root, "/this will be the last", &node3); - CU_ASSERT_EQUAL(result, 3); - CU_ASSERT_EQUAL(root->nchildren, 3); - CU_ASSERT_PTR_EQUAL(root->children, node2); - CU_ASSERT_PTR_EQUAL(node2->next, node1); - CU_ASSERT_PTR_EQUAL(node1->next, node3); - CU_ASSERT_PTR_NULL(node3->next); - CU_ASSERT_PTR_EQUAL(node1->parent, root); - CU_ASSERT_PTR_EQUAL(node2->parent, root); - CU_ASSERT_PTR_EQUAL(node3->parent, root); - CU_ASSERT_EQUAL(node3->type, LIBISO_SYMLINK); - CU_ASSERT_STRING_EQUAL(node3->name, "this will be the last"); - CU_ASSERT_EQUAL(node3->mode, S_IFLNK | 0750); - CU_ASSERT_EQUAL(node3->uid, 32); - CU_ASSERT_EQUAL(node3->gid, 33); - CU_ASSERT_EQUAL(node3->atime, 323444); - CU_ASSERT_EQUAL(node3->ctime, 323555); - CU_ASSERT_EQUAL(node3->mtime, 323666); - CU_ASSERT_STRING_EQUAL(((IsoSymlink*)node3)->dest, "/etc"); - - iso_image_unref(image); -} - -static -void test_iso_tree_path_to_node() -{ - int result; - IsoDir *root; - IsoDir *node1, *node2, *node11; - IsoNode *node; - IsoImage *image; - IsoFilesystem *fs; - - result = iso_image_new("volume_id", &image); - CU_ASSERT_EQUAL(result, 1); - root = iso_image_get_root(image); - CU_ASSERT_PTR_NOT_NULL(root); - - /* replace image filesystem with out mockep one */ - iso_filesystem_unref(image->fs); - result = test_mocked_filesystem_new(&fs); - CU_ASSERT_EQUAL(result, 1); - image->fs = fs; - - /* add some files */ - result = iso_tree_add_new_dir(root, "Dir1", &node1); - CU_ASSERT_EQUAL(result, 1); - result = iso_tree_add_new_dir(root, "Dir2", (IsoDir**)&node2); - CU_ASSERT_EQUAL(result, 2); - result = iso_tree_add_new_dir((IsoDir*)node1, "Dir11", (IsoDir**)&node11); - CU_ASSERT_EQUAL(result, 1); - - /* retrive some items */ - result = iso_tree_path_to_node(image, "/", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, root); - result = iso_tree_path_to_node(image, "/Dir1", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node1); - result = iso_tree_path_to_node(image, "/Dir2", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node2); - result = iso_tree_path_to_node(image, "/Dir1/Dir11", &node); - CU_ASSERT_EQUAL(result, 1); - CU_ASSERT_PTR_EQUAL(node, node11); - - /* some failtures */ - result = iso_tree_path_to_node(image, "/Dir2/Dir11", &node); - CU_ASSERT_EQUAL(result, 0); - CU_ASSERT_PTR_NULL(node); - - iso_image_unref(image); -} - -void add_tree_suite() -{ - CU_pSuite pSuite = CU_add_suite("Iso Tree Suite", NULL, NULL); - - CU_add_test(pSuite, "iso_tree_add_new_dir()", test_iso_tree_add_new_dir); - CU_add_test(pSuite, "iso_tree_add_new_symlink()", test_iso_tree_add_new_symlink); - CU_add_test(pSuite, "iso_tree_add_new_special()", test_iso_tree_add_new_special); - CU_add_test(pSuite, "iso_tree_add_node() [1. dir]", test_iso_tree_add_node_dir); - CU_add_test(pSuite, "iso_tree_add_node() [2. symlink]", test_iso_tree_add_node_link); - CU_add_test(pSuite, "iso_tree_path_to_node()", test_iso_tree_path_to_node); - -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_util.c b/libisofs/tags/ForXorrisoZeroOneTwo/test/test_util.c deleted file mode 100644 index 0852e926..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/test/test_util.c +++ /dev/null @@ -1,1072 +0,0 @@ -/* - * Unit test for util.h - * - * This test utiliy functions - */ -#include "test.h" -#include "util.h" - -#include -#include -#include - -static void test_int_pow() -{ - CU_ASSERT_EQUAL(int_pow(1, 2), 1); - CU_ASSERT_EQUAL(int_pow(2, 2), 4); - CU_ASSERT_EQUAL(int_pow(0, 2), 0); - CU_ASSERT_EQUAL(int_pow(-1, 2), 1); - CU_ASSERT_EQUAL(int_pow(-1, 3), -1); - CU_ASSERT_EQUAL(int_pow(3, 2), 9); - CU_ASSERT_EQUAL(int_pow(3, 10), 59049); -} - -static void test_strconv() -{ - int ret; - char *out; - - /* Prova de cadeia com codificação ISO-8859-15 */ - unsigned char in1[45] = - {0x50, 0x72, 0x6f, 0x76, 0x61, 0x20, 0x64, 0x65, 0x20, 0x63, 0x61, - 0x64, 0x65, 0x69, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x20, 0x63, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0xe7, 0xe3, 0x6f, 0x20, 0x49, - 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, 0x35, 0x0a, - 0x00}; /* encoded in ISO-8859-15 */ - unsigned char out1[47] = - {0x50, 0x72, 0x6f, 0x76, 0x61, 0x20, 0x64, 0x65, 0x20, 0x63, 0x61, - 0x64, 0x65, 0x69, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x20, 0x63, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0xc3, 0xa7, 0xc3, 0xa3, 0x6f, - 0x20, 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, 0x31, - 0x35, 0x0a, 0x00}; /* encoded in UTF-8 */ - unsigned char in2[45] = - {0x50, 0x72, 0x6f, 0x76, 0x61, 0x20, 0x64, 0x65, 0x20, 0x63, 0x61, - 0x64, 0x65, 0x69, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x20, 0x63, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0xe7, 0xe3, 0x6f, 0x20, 0x49, - 0x53, 0x4f, 0x2d, 0x38, 0x38, 0xff, 0xff, 0x2d, 0x31, 0x35, 0x0a, - 0x00}; /* incorrect encoding */ - - /* ISO-8859-15 to UTF-8 */ - ret = strconv((char*)in1, "ISO-8859-15", "UTF-8", &out); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_STRING_EQUAL(out, (char*)out1); - free(out); - - /* UTF-8 to ISO-8859-15 */ - ret = strconv((char*)out1, "UTF-8", "ISO-8859-15", &out); - CU_ASSERT_EQUAL(ret, 1); - CU_ASSERT_STRING_EQUAL(out, (char*)in1); - free(out); - - /* try with an incorrect input */ - ret = strconv((char*)in2, "UTF-8", "ISO-8859-15", &out); - CU_ASSERT_EQUAL(ret, ISO_CHARSET_CONV_ERROR); -} - -static void test_div_up() -{ - CU_ASSERT_EQUAL( DIV_UP(1, 2), 1 ); - CU_ASSERT_EQUAL( DIV_UP(2, 2), 1 ); - CU_ASSERT_EQUAL( DIV_UP(0, 2), 0 ); - CU_ASSERT_EQUAL( DIV_UP(-1, 2), 0 ); - CU_ASSERT_EQUAL( DIV_UP(3, 2), 2 ); -} - -static void test_round_up() -{ - CU_ASSERT_EQUAL( ROUND_UP(1, 2), 2 ); - CU_ASSERT_EQUAL( ROUND_UP(2, 2), 2 ); - CU_ASSERT_EQUAL( ROUND_UP(0, 2), 0 ); - CU_ASSERT_EQUAL( ROUND_UP(-1, 2), 0 ); - CU_ASSERT_EQUAL( ROUND_UP(3, 2), 4 ); - CU_ASSERT_EQUAL( ROUND_UP(15, 7), 21 ); - CU_ASSERT_EQUAL( ROUND_UP(13, 7), 14 ); - CU_ASSERT_EQUAL( ROUND_UP(14, 7), 14 ); -} - -static void test_iso_lsb_msb() -{ - uint8_t buf[4]; - uint32_t num; - - num = 0x01020304; - iso_lsb(buf, num, 4); - CU_ASSERT_EQUAL( buf[0], 0x04 ); - CU_ASSERT_EQUAL( buf[1], 0x03 ); - CU_ASSERT_EQUAL( buf[2], 0x02 ); - CU_ASSERT_EQUAL( buf[3], 0x01 ); - - iso_msb(buf, num, 4); - CU_ASSERT_EQUAL( buf[0], 0x01 ); - CU_ASSERT_EQUAL( buf[1], 0x02 ); - CU_ASSERT_EQUAL( buf[2], 0x03 ); - CU_ASSERT_EQUAL( buf[3], 0x04 ); - - iso_lsb(buf, num, 2); - CU_ASSERT_EQUAL( buf[0], 0x04 ); - CU_ASSERT_EQUAL( buf[1], 0x03 ); - - iso_msb(buf, num, 2); - CU_ASSERT_EQUAL( buf[0], 0x03 ); - CU_ASSERT_EQUAL( buf[1], 0x04 ); -} - -static void test_iso_read_lsb_msb() -{ - uint8_t buf[4]; - uint32_t num; - - buf[0] = 0x04; - buf[1] = 0x03; - buf[2] = 0x02; - buf[3] = 0x01; - - num = iso_read_lsb(buf, 4); - CU_ASSERT_EQUAL(num, 0x01020304); - - num = iso_read_msb(buf, 4); - CU_ASSERT_EQUAL(num, 0x04030201); - - num = iso_read_lsb(buf, 2); - CU_ASSERT_EQUAL(num, 0x0304); - - num = iso_read_msb(buf, 2); - CU_ASSERT_EQUAL(num, 0x0403); -} - -static void test_iso_bb() -{ - uint8_t buf[8]; - uint32_t num; - - num = 0x01020304; - iso_bb(buf, num, 4); - CU_ASSERT_EQUAL( buf[0], 0x04 ); - CU_ASSERT_EQUAL( buf[1], 0x03 ); - CU_ASSERT_EQUAL( buf[2], 0x02 ); - CU_ASSERT_EQUAL( buf[3], 0x01 ); - CU_ASSERT_EQUAL( buf[4], 0x01 ); - CU_ASSERT_EQUAL( buf[5], 0x02 ); - CU_ASSERT_EQUAL( buf[6], 0x03 ); - CU_ASSERT_EQUAL( buf[7], 0x04 ); - - iso_bb(buf, num, 2); - CU_ASSERT_EQUAL( buf[0], 0x04 ); - CU_ASSERT_EQUAL( buf[1], 0x03 ); - CU_ASSERT_EQUAL( buf[2], 0x03 ); - CU_ASSERT_EQUAL( buf[3], 0x04 ); -} - -static void test_iso_datetime_7() -{ - uint8_t buf[7]; - time_t t1, t2, tr; - char *tz; - struct tm tp; - - tz = getenv("TZ"); - - setenv("TZ", "", 1); - tzset(); - - strptime("01-03-1976 13:27:45", "%d-%m-%Y %T", &tp); - t1 = mktime(&tp); /* t1 in GMT */ - - strptime("01-07-2007 13:27:45", "%d-%m-%Y %T", &tp); - t2 = mktime(&tp); /* t1 in GMT (summer time) */ - - /* ----------------- European Timezones ----------------------*/ - setenv("TZ", "Europe/Madrid", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 14); /* hour (GMT+1) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 4); /* GMT+1 hour for CET */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - iso_datetime_7(buf, t2, 0); - CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 7); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 15); /* hour (GMT+2, summer time) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 8); /* GMT+2 hour for CEST */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Europe/London", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 13); /* hour (GMT+0) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 0); /* GMT+0 */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - iso_datetime_7(buf, t2, 0); - CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 7); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 14); /* hour (GMT+1, summer time) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 4); /* GMT+1 */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - /* ----------------- American Timezones ----------------------*/ - setenv("TZ", "America/New_York", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 8); /* hour */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], -5*4); /* GMT-5 for EST */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - /* ----------------- Asia Timezones ----------------------*/ - setenv("TZ", "Asia/Hong_Kong", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 21); /* hour */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 8*4); /* GMT+8 */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - /* read from another timestamp */ - setenv("TZ", "Europe/Madrid", 1); - tzset(); - - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - /* ----------------- Africa Timezones ----------------------*/ - - /* Africa country without Daylight saving time */ - setenv("TZ", "Africa/Luanda", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 14); /* hour (GMT+1) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 4); /* GMT+1 hour */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - iso_datetime_7(buf, t2, 0); - CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 7); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 14); /* hour (GMT+1, no summer time) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 4); /* GMT+1 hour */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - /* ----------------- Australia Timezones ----------------------*/ - - /* this is GMT+9:30 (note that in South summer is winter in North) */ - setenv("TZ", "Australia/Broken_Hill", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 23); /* hour GMT+9+1 (summer time!!) */ - CU_ASSERT_EQUAL(buf[4], 57); /* minute + 30 */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 42); /* GMT+9:30 hour + 1 (summer time) */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - iso_datetime_7(buf, t2, 0); - CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 7); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 22); /* hour (GMT+9) */ - CU_ASSERT_EQUAL(buf[4], 57); /* minute +30 */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 38); /* GMT+9:30 */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - /* ----------------- Pacific Timezones ----------------------*/ - - /* this is GMT+13, the max supported */ - setenv("TZ", "Pacific/Tongatapu", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 2); /* day */ - CU_ASSERT_EQUAL(buf[3], 2); /* hour (GMT+13) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], 52); /* GMT+13 hour */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - /* this is GMT-11, I can't found a -12 timezone */ - setenv("TZ", "Pacific/Pago_Pago", 1); - tzset(); - - iso_datetime_7(buf, t1, 0); - CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */ - CU_ASSERT_EQUAL(buf[1], 3); /* month */ - CU_ASSERT_EQUAL(buf[2], 1); /* day */ - CU_ASSERT_EQUAL(buf[3], 2); /* hour (GMT-11) */ - CU_ASSERT_EQUAL(buf[4], 27); /* minute */ - CU_ASSERT_EQUAL(buf[5], 45); /* second */ - CU_ASSERT_EQUAL((int8_t)buf[6], -44); /* GMT-11 hour */ - - /* check that reading returns the same time */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - - /* --- and now test from several zones, just for write/read compatibilty */ - setenv("TZ", "Pacific/Kiritimati", 1); - tzset(); - iso_datetime_7(buf, t1, 1); /* this needs GMT */ - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "America/Argentina/La_Rioja", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "America/Argentina/La_Rioja", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "America/Caracas", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Asia/Bangkok", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Asia/Tehran", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Pacific/Pitcairn", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Antarctica/McMurdo", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "EET", 1); /* Eastern European Time */ - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Europe/Moscow", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Asia/Novosibirsk", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Asia/Vladivostok", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Asia/Anadyr", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Atlantic/Canary", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "Indian/Mauritius", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - setenv("TZ", "America/Los_Angeles", 1); - tzset(); - iso_datetime_7(buf, t1, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t1); - iso_datetime_7(buf, t2, 0); - tr = iso_datetime_read_7(buf); - CU_ASSERT_EQUAL(tr, t2); - - if (tz) - setenv("TZ", tz, 1); - else - unsetenv("TZ"); - tzset(); -} - -static void test_iso_1_dirid() -{ - char *dir; - dir = iso_1_dirid("dir1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_1_dirid("dIR1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_1_dirid("DIR1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_1_dirid("dirwithbigname"); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITHB"); - free(dir); - dir = iso_1_dirid("dirwith8"); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITH8"); - free(dir); - dir = iso_1_dirid("dir.1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR_1"); - free(dir); - dir = iso_1_dirid("4f<0KmM::xcvf"); - CU_ASSERT_STRING_EQUAL(dir, "4F_0KMM_"); - free(dir); -} - -static void test_iso_2_dirid() -{ - char *dir; - dir = iso_2_dirid("dir1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_2_dirid("dIR1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_2_dirid("DIR1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_2_dirid("dirwithbigname"); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITHBIGNAME"); - free(dir); - dir = iso_2_dirid("dirwith8"); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITH8"); - free(dir); - dir = iso_2_dirid("dir.1"); - CU_ASSERT_STRING_EQUAL(dir, "DIR_1"); - free(dir); - dir = iso_2_dirid("4f<0KmM::xcvf"); - CU_ASSERT_STRING_EQUAL(dir, "4F_0KMM__XCVF"); - free(dir); - dir = iso_2_dirid("directory with 31 characters ok"); - CU_ASSERT_STRING_EQUAL(dir, "DIRECTORY_WITH_31_CHARACTERS_OK"); - free(dir); - dir = iso_2_dirid("directory with more than 31 characters"); - CU_ASSERT_STRING_EQUAL(dir, "DIRECTORY_WITH_MORE_THAN_31_CHA"); - free(dir); -} - -static void test_iso_1_fileid() -{ - char *file; - file = iso_1_fileid("file1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_1_fileid("fILe1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_1_fileid("FILE1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_1_fileid(".EXT"); - CU_ASSERT_STRING_EQUAL(file, ".EXT"); - free(file); - file = iso_1_fileid("file.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_1_fileid("fiLE.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_1_fileid("file.EXt"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_1_fileid("FILE.EXT"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_1_fileid("bigfilename"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILEN."); - free(file); - file = iso_1_fileid("bigfilename.ext"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILEN.EXT"); - free(file); - file = iso_1_fileid("bigfilename.e"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILEN.E"); - free(file); - file = iso_1_fileid("file.bigext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.BIG"); - free(file); - file = iso_1_fileid(".bigext"); - CU_ASSERT_STRING_EQUAL(file, ".BIG"); - free(file); - file = iso_1_fileid("bigfilename.bigext"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILEN.BIG"); - free(file); - file = iso_1_fileid("file<:a.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.EXT"); - free(file); - file = iso_1_fileid("file.<:a"); - CU_ASSERT_STRING_EQUAL(file, "FILE.__A"); - free(file); - file = iso_1_fileid("file<:a.--a"); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.__A"); - free(file); - file = iso_1_fileid("file.ex1.ex2"); - CU_ASSERT_STRING_EQUAL(file, "FILE_EX1.EX2"); - free(file); - file = iso_1_fileid("file.ex1.ex2.ex3"); - CU_ASSERT_STRING_EQUAL(file, "FILE_EX1.EX3"); - free(file); - file = iso_1_fileid("fil.ex1.ex2.ex3"); - CU_ASSERT_STRING_EQUAL(file, "FIL_EX1_.EX3"); - free(file); -} - -static void test_iso_2_fileid() -{ - char *file; - file = iso_2_fileid("file1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_2_fileid("fILe1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_2_fileid("FILE1"); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_2_fileid(".EXT"); - CU_ASSERT_STRING_EQUAL(file, ".EXT"); - free(file); - file = iso_2_fileid("file.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_2_fileid("fiLE.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_2_fileid("file.EXt"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_2_fileid("FILE.EXT"); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_2_fileid("bigfilename"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILENAME."); - free(file); - file = iso_2_fileid("bigfilename.ext"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILENAME.EXT"); - free(file); - file = iso_2_fileid("bigfilename.e"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILENAME.E"); - free(file); - file = iso_2_fileid("31 characters filename.extensio"); - CU_ASSERT_STRING_EQUAL(file, "31_CHARACTERS_FILENAME.EXTENSIO"); - free(file); - file = iso_2_fileid("32 characters filename.extension"); - CU_ASSERT_STRING_EQUAL(file, "32_CHARACTERS_FILENAME.EXTENSIO"); - free(file); - file = iso_2_fileid("more than 30 characters filename.extension"); - CU_ASSERT_STRING_EQUAL(file, "MORE_THAN_30_CHARACTERS_FIL.EXT"); - free(file); - file = iso_2_fileid("file.bigext"); - CU_ASSERT_STRING_EQUAL(file, "FILE.BIGEXT"); - free(file); - file = iso_2_fileid(".bigext"); - CU_ASSERT_STRING_EQUAL(file, ".BIGEXT"); - free(file); - file = iso_2_fileid("bigfilename.bigext"); - CU_ASSERT_STRING_EQUAL(file, "BIGFILENAME.BIGEXT"); - free(file); - file = iso_2_fileid("file<:a.ext"); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.EXT"); - free(file); - file = iso_2_fileid("file.<:a"); - CU_ASSERT_STRING_EQUAL(file, "FILE.__A"); - free(file); - file = iso_2_fileid("file<:a.--a"); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.__A"); - free(file); - file = iso_2_fileid("file.ex1.ex2"); - CU_ASSERT_STRING_EQUAL(file, "FILE_EX1.EX2"); - free(file); - file = iso_2_fileid("file.ex1.ex2.ex3"); - CU_ASSERT_STRING_EQUAL(file, "FILE_EX1_EX2.EX3"); - free(file); - file = iso_2_fileid("fil.ex1.ex2.ex3"); - CU_ASSERT_STRING_EQUAL(file, "FIL_EX1_EX2.EX3"); - free(file); - file = iso_2_fileid(".file.bigext"); - CU_ASSERT_STRING_EQUAL(file, "_FILE.BIGEXT"); - free(file); -} - -static void test_iso_r_dirid() -{ - char *dir; - - dir = iso_r_dirid("dir1", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - - dir = iso_r_dirid("dIR1", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - - /* allow lowercase */ - dir = iso_r_dirid("dIR1", 31, 1); - CU_ASSERT_STRING_EQUAL(dir, "dIR1"); - free(dir); - dir = iso_r_dirid("dIR1", 31, 2); - CU_ASSERT_STRING_EQUAL(dir, "dIR1"); - free(dir); - - dir = iso_r_dirid("DIR1", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIR1"); - free(dir); - dir = iso_r_dirid("dirwithbigname", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITHBIGNAME"); - free(dir); - dir = iso_r_dirid("dirwith8", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIRWITH8"); - free(dir); - - /* dot is not allowed */ - dir = iso_r_dirid("dir.1", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIR_1"); - free(dir); - dir = iso_r_dirid("dir.1", 31, 1); - CU_ASSERT_STRING_EQUAL(dir, "dir_1"); - free(dir); - dir = iso_r_dirid("dir.1", 31, 2); - CU_ASSERT_STRING_EQUAL(dir, "dir.1"); - free(dir); - - dir = iso_r_dirid("4f<0KmM::xcvf", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "4F_0KMM__XCVF"); - free(dir); - dir = iso_r_dirid("4f<0KmM::xcvf", 31, 1); - CU_ASSERT_STRING_EQUAL(dir, "4f_0KmM__xcvf"); - free(dir); - dir = iso_r_dirid("4f<0KmM::xcvf", 31, 2); - CU_ASSERT_STRING_EQUAL(dir, "4f<0KmM::xcvf"); - free(dir); - - dir = iso_r_dirid("directory with 31 characters ok", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIRECTORY_WITH_31_CHARACTERS_OK"); - free(dir); - dir = iso_r_dirid("directory with more than 31 characters", 31, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIRECTORY_WITH_MORE_THAN_31_CHA"); - free(dir); - dir = iso_r_dirid("directory with more than 31 characters", 35, 0); - CU_ASSERT_STRING_EQUAL(dir, "DIRECTORY_WITH_MORE_THAN_31_CHARACT"); - free(dir); -} - -static void test_iso_r_fileid() -{ - char *file; - - /* force dot */ - file = iso_r_fileid("file1", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - - /* and not */ - file = iso_r_fileid("file1", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE1"); - free(file); - - /* allow lowercase */ - file = iso_r_fileid("file1", 30, 1, 0); - CU_ASSERT_STRING_EQUAL(file, "file1"); - free(file); - file = iso_r_fileid("file1", 30, 2, 0); - CU_ASSERT_STRING_EQUAL(file, "file1"); - free(file); - - /* force d-char and dot */ - file = iso_r_fileid("fILe1", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - /* force d-char but not dot */ - file = iso_r_fileid("fILe1", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE1"); - free(file); - /* allow lower case but force dot */ - file = iso_r_fileid("fILe1", 30, 1, 1); - CU_ASSERT_STRING_EQUAL(file, "fILe1."); - free(file); - - file = iso_r_fileid("FILE1", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE1."); - free(file); - file = iso_r_fileid(".EXT", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, ".EXT"); - free(file); - file = iso_r_fileid(".EXT", 30, 1, 0); - CU_ASSERT_STRING_EQUAL(file, ".EXT"); - free(file); - - file = iso_r_fileid("file.ext", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - - /* not force dot is the same in this case */ - file = iso_r_fileid("fiLE.ext", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_r_fileid("fiLE.ext", 30, 2, 0); - CU_ASSERT_STRING_EQUAL(file, "fiLE.ext"); - free(file); - - file = iso_r_fileid("file.EXt", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - file = iso_r_fileid("FILE.EXT", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "FILE.EXT"); - free(file); - - file = iso_r_fileid("31 characters filename.extensio", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "31_CHARACTERS_FILENAME.EXTENSIO"); - free(file); - file = iso_r_fileid("32 characters filename.extension", 30, 0, 1); - CU_ASSERT_STRING_EQUAL(file, "32_CHARACTERS_FILENAME.EXTENSIO"); - free(file); - - /* allow lowercase */ - file = iso_r_fileid("31 characters filename.extensio", 30, 1, 1); - CU_ASSERT_STRING_EQUAL(file, "31_characters_filename.extensio"); - free(file); - - /* and all characters */ - file = iso_r_fileid("31 characters filename.extensio", 30, 2, 1); - CU_ASSERT_STRING_EQUAL(file, "31 characters filename.extensio"); - free(file); - - file = iso_r_fileid("more than 30 characters filename.extension", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "MORE_THAN_30_CHARACTERS_FIL.EXT"); - free(file); - - /* incrementing the size... */ - file = iso_r_fileid("more than 30 characters filename.extension", 35, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "MORE_THAN_30_CHARACTERS_FILENAME.EXT"); - free(file); - - file = iso_r_fileid("more than 30 characters filename.extension", 36, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "MORE_THAN_30_CHARACTERS_FILENAME.EXTE"); - free(file); - - file = iso_r_fileid("file.bigext", 30, 1, 0); - CU_ASSERT_STRING_EQUAL(file, "file.bigext"); - free(file); - - file = iso_r_fileid(".bigext", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, ".BIGEXT"); - free(file); - - /* "strange" characters */ - file = iso_r_fileid("file<:a.ext", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.EXT"); - free(file); - file = iso_r_fileid("file<:a.ext", 30, 1, 0); - CU_ASSERT_STRING_EQUAL(file, "file__a.ext"); - free(file); - file = iso_r_fileid("file<:a.ext", 30, 2, 0); - CU_ASSERT_STRING_EQUAL(file, "file<:a.ext"); - free(file); - - /* multiple dots */ - file = iso_r_fileid("fi.le.a.ext", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FI_LE_A.EXT"); - free(file); - file = iso_r_fileid("fi.le.a.ext", 30, 1, 0); - CU_ASSERT_STRING_EQUAL(file, "fi_le_a.ext"); - free(file); - file = iso_r_fileid("fi.le.a.ext", 30, 2, 0); - CU_ASSERT_STRING_EQUAL(file, "fi.le.a.ext"); - free(file); - - file = iso_r_fileid("file.<:a", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE.__A"); - free(file); - file = iso_r_fileid("file<:a.--a", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "FILE__A.__A"); - free(file); - - file = iso_r_fileid(".file.bigext", 30, 0, 0); - CU_ASSERT_STRING_EQUAL(file, "_FILE.BIGEXT"); - free(file); - - file = iso_r_fileid(".file.bigext", 30, 2, 0); - CU_ASSERT_STRING_EQUAL(file, ".file.bigext"); - free(file); -} - -static void test_iso_rbtree_insert() -{ - int res; - IsoRBTree *tree; - char *str1, *str2, *str3, *str4, *str5; - void *str; - - res = iso_rbtree_new((compare_function_t)strcmp, &tree); - CU_ASSERT_EQUAL(res, 1); - - /* ok, insert one str */ - str1 = "first str"; - res = iso_rbtree_insert(tree, str1, &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str1); - - str2 = "second str"; - res = iso_rbtree_insert(tree, str2, &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str2); - - /* an already inserted string */ - str3 = "second str"; - res = iso_rbtree_insert(tree, str3, &str); - CU_ASSERT_EQUAL(res, 0); - CU_ASSERT_PTR_EQUAL(str, str2); - - /* an already inserted string */ - str3 = "first str"; - res = iso_rbtree_insert(tree, str3, &str); - CU_ASSERT_EQUAL(res, 0); - CU_ASSERT_PTR_EQUAL(str, str1); - - str4 = "a string to be inserted first"; - res = iso_rbtree_insert(tree, str4, &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str4); - - str5 = "this to be inserted last"; - res = iso_rbtree_insert(tree, str5, &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str5); - - /* - * TODO write a really good test to check all possible estrange - * behaviors of a red-black tree - */ - - iso_rbtree_destroy(tree, NULL); -} - -void test_iso_htable_put_get() -{ - int res; - IsoHTable *table; - char *str1, *str2, *str3, *str4, *str5; - void *str; - - res = iso_htable_create(4, iso_str_hash, (compare_function_t)strcmp, &table); - CU_ASSERT_EQUAL(res, 1); - - /* try to get str from empty table */ - res = iso_htable_get(table, "first str", &str); - CU_ASSERT_EQUAL(res, 0); - - /* ok, insert one str */ - str1 = "first str"; - res = iso_htable_put(table, str1, str1); - CU_ASSERT_EQUAL(res, 1); - - /* and now get str from table */ - res = iso_htable_get(table, "first str", &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str1); - res = iso_htable_get(table, "second str", &str); - CU_ASSERT_EQUAL(res, 0); - - str2 = "second str"; - res = iso_htable_put(table, str2, str2); - CU_ASSERT_EQUAL(res, 1); - - str = NULL; - res = iso_htable_get(table, "first str", &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str1); - res = iso_htable_get(table, "second str", &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str2); - - /* insert again, with same key but other data */ - res = iso_htable_put(table, str2, str1); - CU_ASSERT_EQUAL(res, 0); - - res = iso_htable_get(table, "second str", &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str2); - - str3 = "third str"; - res = iso_htable_put(table, str3, str3); - CU_ASSERT_EQUAL(res, 1); - - str4 = "four str"; - res = iso_htable_put(table, str4, str4); - CU_ASSERT_EQUAL(res, 1); - - str5 = "fifth str"; - res = iso_htable_put(table, str5, str5); - CU_ASSERT_EQUAL(res, 1); - - /* some searches */ - res = iso_htable_get(table, "sixth str", &str); - CU_ASSERT_EQUAL(res, 0); - - res = iso_htable_get(table, "fifth str", &str); - CU_ASSERT_EQUAL(res, 1); - CU_ASSERT_PTR_EQUAL(str, str5); - - iso_htable_destroy(table, NULL); -} - -void add_util_suite() -{ - CU_pSuite pSuite = CU_add_suite("UtilSuite", NULL, NULL); - - CU_add_test(pSuite, "strconv()", test_strconv); - CU_add_test(pSuite, "int_pow()", test_int_pow); - CU_add_test(pSuite, "DIV_UP()", test_div_up); - CU_add_test(pSuite, "ROUND_UP()", test_round_up); - CU_add_test(pSuite, "iso_bb()", test_iso_bb); - CU_add_test(pSuite, "iso_lsb/msb()", test_iso_lsb_msb); - CU_add_test(pSuite, "iso_read_lsb/msb()", test_iso_read_lsb_msb); - CU_add_test(pSuite, "iso_datetime_7()", test_iso_datetime_7); - CU_add_test(pSuite, "iso_1_dirid()", test_iso_1_dirid); - CU_add_test(pSuite, "iso_2_dirid()", test_iso_2_dirid); - CU_add_test(pSuite, "iso_1_fileid()", test_iso_1_fileid); - CU_add_test(pSuite, "iso_2_fileid()", test_iso_2_fileid); - CU_add_test(pSuite, "iso_r_dirid()", test_iso_r_dirid); - CU_add_test(pSuite, "iso_r_fileid()", test_iso_r_fileid); - CU_add_test(pSuite, "iso_rbtree_insert()", test_iso_rbtree_insert); - CU_add_test(pSuite, "iso_htable_put/get()", test_iso_htable_put_get); -} diff --git a/libisofs/tags/ForXorrisoZeroOneTwo/version.h.in b/libisofs/tags/ForXorrisoZeroOneTwo/version.h.in deleted file mode 100644 index f903ff0a..00000000 --- a/libisofs/tags/ForXorrisoZeroOneTwo/version.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#define LIBISOFS_MAJOR_VERSION @LIBISOFS_MAJOR_VERSION@ -#define LIBISOFS_MINOR_VERSION @LIBISOFS_MINOR_VERSION@ -#define LIBISOFS_MICRO_VERSION @LIBISOFS_MICRO_VERSION@