diff options
Diffstat (limited to 'iso/libisofs')
-rw-r--r-- | iso/libisofs/COPYING | 280 | ||||
-rw-r--r-- | iso/libisofs/ChangeLog | 6 | ||||
-rw-r--r-- | iso/libisofs/Makefile.am | 18 | ||||
-rw-r--r-- | iso/libisofs/README | 24 | ||||
-rw-r--r-- | iso/libisofs/bswap.h | 94 | ||||
-rw-r--r-- | iso/libisofs/el_torito.h | 63 | ||||
-rw-r--r-- | iso/libisofs/iso_fs.h | 219 | ||||
-rw-r--r-- | iso/libisofs/isofs.c | 876 | ||||
-rw-r--r-- | iso/libisofs/isofs.h | 161 | ||||
-rw-r--r-- | iso/libisofs/rock.h | 127 |
10 files changed, 1868 insertions, 0 deletions
diff --git a/iso/libisofs/COPYING b/iso/libisofs/COPYING new file mode 100644 index 0000000..c7aea18 --- /dev/null +++ b/iso/libisofs/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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/iso/libisofs/ChangeLog b/iso/libisofs/ChangeLog new file mode 100644 index 0000000..fb46b80 --- /dev/null +++ b/iso/libisofs/ChangeLog @@ -0,0 +1,6 @@ +0.1 -> 0.2 + +- Critical directory parsing bug fixed +- Call backs only if some sanity checks on the directory entry succeeds + (length checks to avoid buffer overrun if received corrupt data) +- Preliminary El Torito boot specification support (No multiple boot entries yet) diff --git a/iso/libisofs/Makefile.am b/iso/libisofs/Makefile.am new file mode 100644 index 0000000..a1278ff --- /dev/null +++ b/iso/libisofs/Makefile.am @@ -0,0 +1,18 @@ +noinst_LTLIBRARIES = libisofs.la + + +INCLUDES = $(all_includes) + + +#LDFLAGS = + +libisofs_la_METASOURCES=AUTO + +libisofs_la_SOURCES = isofs.c +#libisofs_la_LIBADD = $(LIB_KIO) + +#libisofs_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN) + + + +noinst_HEADERS = bswap.h el_torito.h iso_fs.h isofs.h rock.h diff --git a/iso/libisofs/README b/iso/libisofs/README new file mode 100644 index 0000000..45d3bff --- /dev/null +++ b/iso/libisofs/README @@ -0,0 +1,24 @@ +This is the 0.2 release of libisofs. For changes, see the ChangeLog. + +Libisofs implements the reading of the famous ISO-9660 (ECMA-119) file system, +found on CD-ROM media. It also supports the Rock Ridge Interchange Protocol and +Microsoft Joliet extensions. It allows user-mode programs to query the +filesystem volume descriptors and traverse through the directory structure. +Preliminary support for El-Torito boot CDs are added in version 0.2. + +To use it in your project, I recommend to copy bswap.h, isofs.h, iso_fs.h, +el_torito.h rock.h and isofs.c to your sources, and include isofs.h in the +appropriate places. + +Currently only the directory tables are parsed, the path tables are not. +(The path tables contain redundant information.) + +Also a sample program can be compiled with the supplied Makefile. Simply +execute 'make', it should create the executable file isofs. + +On big-endian systems, you need to define WORDS_BIGENDIAN (either in the +compiler command-line, or if you defined HAVE_CONFIG_H, in config.h) + + +Gy�rgy Szombathelyi <[email protected]> +http://libcdrom.sourceforge.net/libisofs.html diff --git a/iso/libisofs/bswap.h b/iso/libisofs/bswap.h new file mode 100644 index 0000000..95520c6 --- /dev/null +++ b/iso/libisofs/bswap.h @@ -0,0 +1,94 @@ +/* From the mplayer project (www.mplayerhq.hu) */ + +#ifndef __BSWAP_H__ +#define __BSWAP_H__ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_BYTESWAP_H +#include <byteswap.h> +#else + +#ifdef ARCH_X86 +inline static unsigned short ByteSwap16(unsigned short x) +{ + __asm("xchgb %b0,%h0" : + "=q" (x) : + "0" (x)); + return x; +} +#define bswap_16(x) ByteSwap16(x) + +inline static unsigned int ByteSwap32(unsigned int x) +{ +#if __CPU__ > 386 + __asm("bswap %0": + "=r" (x) : +#else + __asm("xchgb %b0,%h0\n" + " rorl $16,%0\n" + " xchgb %b0,%h0": + "=q" (x) : +#endif + "0" (x)); + return x; +} +#define bswap_32(x) ByteSwap32(x) + +inline static unsigned long long int ByteSwap64(unsigned long long int x) +{ + register union { __extension__ unsigned long long int __ll; + unsigned int __l[2]; } __x; + asm("xchgl %0,%1": + "=r"(__x.__l[0]),"=r"(__x.__l[1]): + "0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32)))); + return __x.__ll; +} +#define bswap_64(x) ByteSwap64(x) + +#else + +#define bswap_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8) + + +/* code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc. */ +#define bswap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#define bswap_64(x) \ + (__extension__ \ + ({ union { __extension__ unsigned long long int __ll; \ + unsigned int __l[2]; } __w, __r; \ + __w.__ll = (x); \ + __r.__l[0] = bswap_32 (__w.__l[1]); \ + __r.__l[1] = bswap_32 (__w.__l[0]); \ + __r.__ll; })) +#endif /* !ARCH_X86 */ + +#endif /* !HAVE_BYTESWAP_H */ + +/* + be2me ... BigEndian to MachineEndian + le2me ... LittleEndian to MachineEndian +*/ + +#ifdef WORDS_BIGENDIAN +#define be2me_16(x) (x) +#define be2me_32(x) (x) +#define be2me_64(x) (x) +#define le2me_16(x) bswap_16(x) +#define le2me_32(x) bswap_32(x) +#define le2me_64(x) bswap_64(x) +#else +#define be2me_16(x) bswap_16(x) +#define be2me_32(x) bswap_32(x) +#define be2me_64(x) bswap_64(x) +#define le2me_16(x) (x) +#define le2me_32(x) (x) +#define le2me_64(x) (x) +#endif + +#endif diff --git a/iso/libisofs/el_torito.h b/iso/libisofs/el_torito.h new file mode 100644 index 0000000..cba83f7 --- /dev/null +++ b/iso/libisofs/el_torito.h @@ -0,0 +1,63 @@ +#ifndef ELTORITO_H +#define ELTORITO_H 1 + +#include "iso_fs.h" + +#define EL_TORITO_ID "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0" + +struct el_torito_boot_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char system_id [ISODCL ( 8, 39)]; /* achars */ + char unused [ISODCL ( 40, 71)]; + char boot_catalog [ISODCL ( 72, 75)]; /* 731 */ +}; + +struct validation_entry { + char type [ISODCL ( 1, 1)]; /* 1 */ + char platform [ISODCL ( 2, 2)]; + char unused [ISODCL ( 3, 4)]; + char id [ISODCL ( 5, 28)]; + char cheksum [ISODCL ( 29, 30)]; + char key [ISODCL ( 31, 31)]; /* 0x55 */ + char key2 [ISODCL ( 32, 32)]; /* 0xaa */ +}; + +struct default_entry { + char bootid [ISODCL ( 1, 1)]; + char media [ISODCL ( 2, 2)]; + char loadseg [ISODCL ( 3, 4)]; + char systype [ISODCL ( 5, 5)]; + char unused [ISODCL ( 6, 6)]; + char seccount [ISODCL ( 7, 8)]; + char start [ISODCL ( 9, 12)]; + char unused2 [ISODCL ( 13, 32)]; +}; + +struct section_header { + char headerid [ISODCL ( 1, 1)]; + char platform [ISODCL ( 2, 2)]; + char entries [ISODCL ( 3, 4)]; + char id [ISODCL ( 5, 32)]; +}; + +struct section_entry { + char bootid [ISODCL ( 1, 1)]; + char media [ISODCL ( 2, 2)]; + char loadseg [ISODCL ( 3, 4)]; + char systype [ISODCL ( 5, 5)]; + char unused [ISODCL ( 6, 6)]; + char seccount [ISODCL ( 7, 8)]; + char start [ISODCL ( 9, 12)]; + char selcrit [ISODCL ( 13, 13)]; + char vendor_selcrit [ISODCL ( 14, 32)]; +}; + +struct section_entry_ext { + char extid [ISODCL ( 1, 1)]; + char extrec [ISODCL ( 2, 2)]; + char vendor_selcrit [ISODCL ( 3, 32)]; +}; + +#endif diff --git a/iso/libisofs/iso_fs.h b/iso/libisofs/iso_fs.h new file mode 100644 index 0000000..43353b0 --- /dev/null +++ b/iso/libisofs/iso_fs.h @@ -0,0 +1,219 @@ +/* From the linux kernel */ + +#ifndef _ISO_FS_H +#define _ISO_FS_H 1 + +#include "bswap.h" + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type[ISODCL(1,1)]; /* 711 */ + char id[ISODCL(2,6)]; + char version[ISODCL(7,7)]; + char data[ISODCL(8,2048)]; +}; + +/* volume descriptor types */ +#define ISO_VD_BOOT 0 +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +struct iso_primary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char unused1 [ISODCL ( 8, 8)]; + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char unused3 [ISODCL ( 89, 120)]; + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + +/* Almost the same as the primary descriptor but two fields are specified */ +struct iso_supplementary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char flags [ISODCL ( 8, 8)]; /* 853 */ + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char escape [ISODCL ( 89, 120)]; /* 856 */ + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + +#define HS_STANDARD_ID "CDROM" + +struct hs_volume_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char data[ISODCL(16,2048)]; +}; + + +struct hs_primary_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char unused1 [ISODCL ( 16, 16)]; /* 711 */ + char system_id [ISODCL ( 17, 48)]; /* achars */ + char volume_id [ISODCL ( 49, 80)]; /* dchars */ + char unused2 [ISODCL ( 81, 88)]; /* 733 */ + char volume_space_size [ISODCL ( 89, 96)]; /* 733 */ + char unused3 [ISODCL ( 97, 128)]; /* 733 */ + char volume_set_size [ISODCL (129, 132)]; /* 723 */ + char volume_sequence_number [ISODCL (133, 136)]; /* 723 */ + char logical_block_size [ISODCL (137, 140)]; /* 723 */ + char path_table_size [ISODCL (141, 148)]; /* 733 */ + char type_l_path_table [ISODCL (149, 152)]; /* 731 */ + char unused4 [ISODCL (153, 180)]; /* 733 */ + char root_directory_record [ISODCL (181, 214)]; /* 9.1 */ +}; + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table{ + char name_len[1]; /* 711 */ + char ext_attr_length[1]; /* 711 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[1]; +}; + +/* high sierra is identical to iso, except that the date is only 6 bytes, and + there is an extra reserved byte after the flags */ + +struct iso_directory_record { + char length [ISODCL (1, 1)]; /* 711 */ + char ext_attr_length [ISODCL (2, 2)]; /* 711 */ + char extent [ISODCL (3, 10)]; /* 733 */ + char size [ISODCL (11, 18)]; /* 733 */ + char date [ISODCL (19, 25)]; /* 7 by 711 */ + char flags [ISODCL (26, 26)]; + char file_unit_size [ISODCL (27, 27)]; /* 711 */ + char interleave [ISODCL (28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ + char name_len [ISODCL (33, 33)]; /* 711 */ + char name [1]; +}; + +/* 8 bit numbers */ +__inline unsigned char isonum_711(char *p); +__inline char isonum_712(char *p); + +/* 16 bit numbers */ +__inline unsigned short isonum_721(char *p); +__inline unsigned short isonum_722(char *p); +__inline unsigned short isonum_723(char *p); + +/* 32 bit numbers */ +__inline unsigned int isonum_731(char *p); +__inline unsigned int isonum_732(char *p); +__inline unsigned int isonum_733(char *p); + + +/* 8 bit numbers */ +__inline unsigned char isonum_711(char *p) +{ + return *(unsigned char *)p; +} +__inline char isonum_712(char *p) +{ + return *p; +} + +/* 16 bit numbers */ +__inline unsigned short isonum_721(char *p) +{ + return le2me_16(*(unsigned short *)p); +} +__inline unsigned short isonum_722(char *p) +{ + return be2me_16(*(unsigned short *)p); +} +__inline unsigned short isonum_723(char *p) +{ + /* Ignore bigendian datum due to broken mastering programs */ + return le2me_16(*(unsigned short *)p); +} + +/* 32 bit numbers */ +__inline unsigned int isonum_731(char *p) +{ + return le2me_32(*(unsigned int *)p); +} + +__inline unsigned int isonum_732(char *p) +{ + return be2me_32(*(unsigned int *)p); +} + +__inline unsigned int isonum_733(char *p) +{ + /* Ignore bigendian datum due to broken mastering programs */ + return le2me_32(*(unsigned int *)p); +} + +#endif /*_ISOFS_H*/ + diff --git a/iso/libisofs/isofs.c b/iso/libisofs/isofs.c new file mode 100644 index 0000000..ab13d9e --- /dev/null +++ b/iso/libisofs/isofs.c @@ -0,0 +1,876 @@ +/*************************************************************************** + isofs.c - libisofs + implementation + ------------------- + begin : Oct 25 2002 + copyright : (C) 2002 by Szombathelyi Gy�gy + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include "isofs.h" + +/**************************************************************/ + + +/* internal function from the linux kernel (isofs fs) */ +static time_t getisotime(int year,int month,int day,int hour, + int minute,int second,int tz) { + + int days, i; + time_t crtime; + + year-=1970; + + if (year < 0) { + crtime = 0; + } else { + int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; + + days = year * 365; + if (year > 2) + days += (year+1) / 4; + for (i = 1; i < month; i++) + days += monlen[i-1]; + if (((year+2) % 4) == 0 && month > 2) + days++; + days += day - 1; + crtime = ((((days * 24) + hour) * 60 + minute) * 60) + + second; + + /* sign extend */ + if (tz & 0x80) + tz |= (-1 << 8); + + /* + * The timezone offset is unreliable on some disks, + * so we make a sanity check. In no case is it ever + * more than 13 hours from GMT, which is 52*15min. + * The time is always stored in localtime with the + * timezone offset being what get added to GMT to + * get to localtime. Thus we need to subtract the offset + * to get to true GMT, which is what we store the time + * as internally. On the local system, the user may set + * their timezone any way they wish, of course, so GMT + * gets converted back to localtime on the receiving + * system. + * + * NOTE: mkisofs in versions prior to mkisofs-1.10 had + * the sign wrong on the timezone offset. This has now + * been corrected there too, but if you are getting screwy + * results this may be the explanation. If enough people + * complain, a user configuration option could be added + * to add the timezone offset in with the wrong sign + * for 'compatibility' with older discs, but I cannot see how + * it will matter that much. + * + * Thanks to [email protected] (Volker Kuhlmann) + * for pointing out the sign error. + */ + if (-52 <= tz && tz <= 52) + crtime -= tz * 15 * 60; + } + return crtime; + +} + +/** + * Returns the Unix from the ISO9660 9.1.5 time format + */ +time_t isodate_915(char * p, int hs) { + + return getisotime(1900+p[0],p[1],p[2],p[3],p[4],p[5],hs==0 ? p[6] : 0); +} + +/** + * Returns the Unix from the ISO9660 8.4.26.1 time format + * BUG: hundredth of seconds are ignored, because Unix time_t has one second + * resolution (I think it's no problem at all) + */ +time_t isodate_84261(char * p, int hs) { + int year,month,day,hour,minute,second; + year=(p[0]-'0')*1000 + (p[1]-'0')*100 + (p[2]-'0')*10 + p[3]-'0'; + month=(p[4]-'0')*10 + (p[5]-'0'); + day=(p[6]-'0')*10 + (p[7]-'0'); + hour=(p[8]-'0')*10 + (p[9]-'0'); + minute=(p[10]-'0')*10 + (p[11]-'0'); + second=(p[12]-'0')*10 + (p[13]-'0'); + return getisotime(year,month,day,hour,minute,second,hs==0 ? p[16] : 0); +} + +void FreeBootTable(boot_head *boot) { + boot_entry *be,*next; + + be=boot->defentry; + while (be) { + next=be->next; + free(be); + be=next; + } + boot->defentry=NULL; +} + +int BootImageSize(int media,int len) { + int ret; + + switch(media & 0xf) { + case 0: + ret=len; /* No emulation */ + break; + case 1: + ret=80*2*15; /* 1.2 MB */ + break; + case 2: + ret=80*2*18; /* 1.44 MB */ + break; + case 3: + ret=80*2*36; /* 2.88 MB */ + break; + case 4: + /* FIXME!!! */ + ret=len; /* Hard Disk */ + break; + default: + ret=len; + } + return ret; +} + +static boot_entry *CreateBootEntry(char *be) { + boot_entry *entry; + + entry = (boot_entry*) malloc(sizeof(boot_entry)); + if (!entry) return NULL; + memset(entry, 0, sizeof(boot_entry)); + memcpy(entry->data,be,0x20); + return entry; +} + +int ReadBootTable(readfunc *read,int sector, boot_head *head, void *udata) { + + char buf[2048], *c, *be; + int i,end=0; + unsigned short sum; + boot_entry *defcur=NULL,*deflast=NULL; + register struct validation_entry *ventry=NULL; + + head->sections=NULL; + head->defentry=NULL; + while (1) { + be = (char*) &buf; + if ( read(be, sector, 1, udata) != 1 ) goto err; + + /* first entry needs to be a validation entry */ + if (!ventry) { + ventry=(struct validation_entry *) be; + if ( isonum_711(ventry->type) !=1 ) goto err; + sum=0; + c = (char*) ventry; + for (i=0;i<16;i++) { sum += isonum_721(c); c+=2; } + if (sum) goto err; + memcpy(&head->ventry,be,0x20); + be += 0x20; + } + + while (!end && (be < (char *)(&buf+1))) { + switch (isonum_711(be)) { + case 0x88: + defcur=CreateBootEntry(be); + if (!defcur) goto err; + if (deflast) + deflast->next=defcur; + else + head->defentry=defcur; + defcur->prev=deflast; + deflast=defcur; + break; + case 0x90: + case 0x91: + break; + default: + end=1; + break; + } + be += 0x20; + } + if (end) break; + + sector ++; + } + + return 0; + +err: + FreeBootTable(head); + return -1; +} + + +/** + * Creates the linked list of the volume descriptors + */ +iso_vol_desc *ReadISO9660(readfunc *read,int sector,void *udata) { + + int i; + struct iso_volume_descriptor buf; + iso_vol_desc *first=NULL,*current=NULL,*prev=NULL; + + for (i=0;i<100;i++) { + if (read( (char*) &buf, sector+i+16, 1, udata) != 1 ) { + FreeISO9660(first); + return NULL; + } + if (!memcmp(ISO_STANDARD_ID,&buf.id,5)) { + switch ( isonum_711(&buf.type[0]) ) { + + case ISO_VD_BOOT: + case ISO_VD_PRIMARY: + case ISO_VD_SUPPLEMENTARY: + current=(iso_vol_desc*) malloc(sizeof(iso_vol_desc)); + if (!current) { + FreeISO9660(first); + return NULL; + } + current->prev=prev; + current->next=NULL; + if (prev) prev->next=current; + memcpy(&(current->data),&buf,2048); + if (!first) first=current; + prev=current; + break; + + case ISO_VD_END: + return first; + break; + } + } else if (!memcmp(HS_STANDARD_ID,(struct hs_volume_descriptor*) &buf,5)) { + /* High Sierra format not supported (yet) */ + } + } + + return first; +} + +/** + * Frees the linked list of volume descriptors + */ +void FreeISO9660(iso_vol_desc *data) { + + iso_vol_desc *current; + + + while (data) { + current=data; + data=current->next; + free(current); + } +} + +/** + * Frees the strings in 'rrentry' + */ +void FreeRR(rr_entry *rrentry) { + if (rrentry->name) { + free(rrentry->name); + rrentry->name=NULL; + } + if (rrentry->sl) { + free(rrentry->sl); + rrentry->name=NULL; + } +} + +static int str_nappend(char **d,char *s,int n) { + int i=0; + char *c; + +/* i=strnlen(s,n)+1; */ + while (i<n && s[i]) i++; + i++; + if (*d) i+=(strlen(*d)+1); + c=(char*) malloc(i); + if (!c) return -ENOMEM; + if (*d) { + strcpy(c,*d); + strncat(c,s,n); + + free(*d); + } else + strncpy(c,s,n); + c[i-1]=0; + *d=c; + return 0; +} + +static int str_append(char **d,char *s) { + int i; + char *c; + + i=strlen(s)+1; + if (*d) i+=(strlen(*d)+1); + c=(char*) malloc(i); + if (!c) return -ENOMEM; + if (*d) { + strcpy(c,*d); + strcat(c,s); + free(*d); + } else + strcpy(c,s); + c[i-1]=0; + *d=c; + return 0; +} + +#define rrtlen(c) (((unsigned char) c & 0x80) ? 17 : 7) +#define rrctime(f,c) ((unsigned char) f & 0x80) ? isodate_84261(c,0) : isodate_915(c,0) +/** + * Parses the System Use area and fills rr_entry with values + */ +int ParseRR(struct iso_directory_record *idr, rr_entry *rrentry) { + + int suspoffs,susplen,i,f,ret=0; + char *r, *c; + struct rock_ridge *rr; + + suspoffs=33+isonum_711(idr->name_len); + if (!(isonum_711(idr->name_len) & 1)) suspoffs++; + susplen=isonum_711(idr->length)-suspoffs; + r= & (((char*) idr)[suspoffs]); + rr = (struct rock_ridge*) r; + + memset(rrentry,0,sizeof(rr_entry)); + rrentry->len = sizeof(rr_entry); + + while (susplen > 0) { + if (isonum_711(&rr->len) > susplen || rr->len == 0) break; + if (rr->signature[0]=='N' && rr->signature[1]=='M') { + if (!(rr->u.NM.flags & 0x26) && rr->len>5 && !rrentry->name) { + + if (str_nappend(&rrentry->name,rr->u.NM.name,isonum_711(&rr->len)-5)) { + FreeRR(rrentry); return -ENOMEM; + } + ret++; + } + } else if (rr->signature[0]=='P' && rr->signature[1]=='X' && + (isonum_711(&rr->len)==44 || isonum_711(&rr->len)==36)) { + rrentry->mode=isonum_733(rr->u.PX.mode); + rrentry->nlink=isonum_733(rr->u.PX.n_links); + rrentry->uid=isonum_733(rr->u.PX.uid); + rrentry->gid=isonum_733(rr->u.PX.gid); + if (isonum_711(&rr->len)==44) rrentry->serno=isonum_733(rr->u.PX.serno); + ret++; + } else if (rr->signature[0]=='P' && rr->signature[1]=='N' && + isonum_711(&rr->len)==20) { + rrentry->dev_major=isonum_733(rr->u.PN.dev_high); + rrentry->dev_minor=isonum_733(rr->u.PN.dev_low); + ret++; + } else if (rr->signature[0]=='P' && rr->signature[1]=='L' && + isonum_711(&rr->len)==12) { + rrentry->pl=isonum_733(rr->u.PL.location); + ret++; + } else if (rr->signature[0]=='C' && rr->signature[1]=='L' && + isonum_711(&rr->len)==12) { + rrentry->cl=isonum_733(rr->u.CL.location); + ret++; + } else if (rr->signature[0]=='R' && rr->signature[1]=='E' && + isonum_711(&rr->len)==4) { + rrentry->re=1; + ret++; + } else if (rr->signature[0]=='S' && rr->signature[1]=='L' && + isonum_711(&rr->len)>7) { + i = isonum_711(&rr->len)-5; + c = (char*) rr; + c += 5; + while (i>0) { + switch(c[0] & ~1) { + case 0x2: + if (str_append(&rrentry->sl,(char *)".")) { + FreeRR(rrentry); return -ENOMEM; + } + break; + case 0x4: + if (str_append(&rrentry->sl,(char *)"..")) { + FreeRR(rrentry); return -ENOMEM; + } + break; + } + if ( (c[0] & 0x08) == 0x08 || (c[1] && rrentry->sl && + strlen(rrentry->sl)>1) ) { + if (str_append(&rrentry->sl,(char *)"/")) { + FreeRR(rrentry); return -ENOMEM; + } + } + + if ((unsigned char)c[1]>0) { + if (str_nappend(&rrentry->sl,c+2,(unsigned char)c[1])) { + FreeRR(rrentry); return -ENOMEM; + } + } + i -= ((unsigned char)c[1] + 2); + c += ((unsigned char)c[1] + 2); + } + ret++; + } else if (rr->signature[0]=='T' && rr->signature[1]=='F' && + isonum_711(&rr->len)>5) { + + i = isonum_711(&rr->len)-5; + f = rr->u.TF.flags; + c = (char*) rr; + c += 5; + + while (i >= rrtlen(f)) { + if (f & 1) { + rrentry->t_creat=rrctime(f,c); + f &= ~1; + } else if (f & 2) { + rrentry->t_mtime=rrctime(f,c); + f &= ~2; + } else if (f & 4) { + rrentry->t_atime=rrctime(f,c); + f &= ~4; + } else if (f & 8) { + rrentry->t_ctime=rrctime(f,c); + f &= ~8; + } else if (f & 16) { + rrentry->t_backup=rrctime(f,c); + f &= ~16; + } else if (f & 32) { + rrentry->t_expire=rrctime(f,c); + f &= ~32; + } else if (f & 64) { + rrentry->t_effect=rrctime(f,c); + f &= ~64; + } + + i -= rrtlen(f); + c += rrtlen(f); + } + ret++; + + } else if (rr->signature[0]=='Z' && rr->signature[1]=='F' && + isonum_711(&rr->len)==16) { + /* Linux-specific extension: transparent decompression */ + rrentry->z_algo[0]=rr->u.ZF.algorithm[0]; + rrentry->z_algo[1]=rr->u.ZF.algorithm[1]; + rrentry->z_params[0]=rr->u.ZF.parms[0]; + rrentry->z_params[1]=rr->u.ZF.parms[1]; + rrentry->z_size=isonum_733(rr->u.ZF.real_size); + ret++; + } else { +/* printf("SUSP sign: %c%c\n",rr->signature[0],rr->signature[1]); */ + } + + susplen -= isonum_711(&rr->len); + r += isonum_711(&rr->len); + rr = (struct rock_ridge*) r; + } + + return ret; +} + +/** + * Iterates over the directory entries. The directory is in 'buf', + * the size of the directory is 'size'. 'callback' is called for each + * directory entry with the parameter 'udata'. + */ +int ProcessDir(readfunc *read,int extent,int size,dircallback *callback,void *udata) { + + int pos=0,ret=0,siz; + char *buf; + struct iso_directory_record *idr; + + if (size & 2047) { + siz=((size>>11)+1)<<11; + } else { + siz=size; + } + + buf=(char*) malloc(siz); + if (!buf) return -ENOMEM; + if (read(buf,extent,siz>>11,udata)!=siz>>11) { + free(buf); + return -EIO; + } + + while (size>0) { + idr=(struct iso_directory_record*) &buf[pos]; + if (isonum_711(idr->length)==0) { + + size-=(2048 - (pos & 0x7ff)); + if (size<=2) break; + pos+=0x800; + pos&=0xfffff800; + idr=(struct iso_directory_record*) &buf[pos]; + } + pos+=isonum_711(idr->length); + pos+=isonum_711(idr->ext_attr_length); + size-=isonum_711(idr->length); + size-=isonum_711(idr->ext_attr_length); + if (size<0) break; + + if (isonum_711(idr->length) +<33 || + isonum_711(idr->length)<33+isonum_711(idr->name_len)) { + /* Invalid directory entry */ + continue; + } + if ((ret=callback(idr,udata))) break; + } + + free(buf); + return ret; +} + +/** + * returns the joliet level from the volume descriptor + */ +int JolietLevel(struct iso_volume_descriptor *ivd) { + int ret=0; + register struct iso_supplementary_descriptor *isd; + + isd = (struct iso_supplementary_descriptor *) ivd; + + if (isonum_711(ivd->type)==ISO_VD_SUPPLEMENTARY) { + if (isd->escape[0]==0x25 && + isd->escape[1]==0x2f) { + + switch (isd->escape[2]) { + case 0x40: + ret=1; + break; + case 0x43: + ret=2; + break; + case 0x45: + ret=3; + break; + } + } + } + return ret; +} + +/********************************************************************/ +#ifdef ISOFS_MAIN + +#include <time.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <iconv.h> + +int level=0,joliet=0,dirs,files; +iconv_t iconv_d; +int fd; + +int readf(char *buf, int start, int len,void *udata) { + int ret; + + if ((ret=lseek(fd, start << 11, SEEK_SET))<0) return ret; + ret=read(fd, buf, len << 11); + if (ret<0) return ret; + return (ret >> 11); +} + +void dumpchars(char *c,int len) { + while (len>0) { + printf("%c",*c); + len--; + c++; + } +} + +void sp(int num) { + int i; + for (i=0;i<num*5;i++) { printf(" "); }; +} + +void dumpflags(char flags) { + if (flags & 1) printf("HIDDEN "); + if (flags & 2) printf("DIR "); + if (flags & 4) printf("ASF "); +} + +void dumpjoliet(char *c,int len) { + + char outbuf[255]; + size_t out; + int ret; + char *outptr; + + outptr=(char*) &outbuf; + out=255; + if ((iconv(iconv_d,&c,&len,&outptr,&out))<0) { + printf("conversion error=%d",errno); + return; + } + ret=255-out; + dumpchars((char*) &outbuf,ret); +} + +void dumpchardesc(char *c,int len) { + + if (joliet) + dumpjoliet(c,len); + else { + dumpchars(c,len); + } +} + +void dumpiso915time(char *t, int hs) { + + time_t time; + char *c; + + time=isodate_915(t,hs); + c=(char*) ctime(&time); + if (c && c[strlen(c)-1]==0x0a) c[strlen(c)-1]=0; + if (c) printf("%s",c); +} + +void dumpiso84261time(char *t, int hs) { + + time_t time; + char *c; + + time=isodate_84261(t,hs); + c=(char*) ctime(&time); + if (c && c[strlen(c)-1]==0x0a) c[strlen(c)-1]=0; + if (c) printf("%s",c); +} + +void dumpdirrec(struct iso_directory_record *dir) { + + if (isonum_711(dir->name_len)==1) { + switch (dir->name[0]) { + case 0: + printf("."); + break; + case 1: + printf(".."); + break; + default: + printf("%c",dir->name[0]); + break; + } + } + dumpchardesc(dir->name,isonum_711(dir->name_len)); + printf(" size=%d",isonum_733(dir->size)); + printf(" extent=%d ",isonum_733(dir->extent)); + dumpflags(isonum_711(dir->flags)); + dumpiso915time((char*) &(dir->date),0); +} + +void dumprrentry(rr_entry *rr) { + printf(" NM=[%s] uid=%d gid=%d nlink=%d mode=%o ", + rr->name,rr->uid,rr->gid,rr->nlink,rr->mode); + if (S_ISCHR(rr->mode) || S_ISBLK(rr->mode)) + printf("major=%d minor=%d ",rr->dev_major,rr->dev_minor); + if (rr->mode & S_IFLNK && rr->sl) printf("slink=%s ",rr->sl); +/* + printf("\n"); + if (rr->t_creat) printf("t_creat: %s",ctime(&rr->t_creat)); + if (rr->st_mtime) printf("st_mtime: %s",ctime(&rr->st_mtime)); + if (rr->st_atime) printf("st_atime: %s",ctime(&rr->st_atime)); + if (rr->st_ctime) printf("st_ctime: %s",ctime(&rr->st_ctime)); + if (rr->t_backup) printf("t_backup: %s",ctime(&rr->t_backup)); + if (rr->t_expire) printf("t_expire: %s",ctime(&rr->t_expire)); + if (rr->t_effect) printf("t_effect: %s",ctime(&rr->t_effect)); +*/ +} + +void dumpsusp(char *c, int len) { + dumpchars(c,len); +} + +void dumpboot(struct el_torito_boot_descriptor *ebd) { + printf("version: %d\n",isonum_711(ebd->version)); + printf("system id: ");dumpchars(ebd->system_id,ISODCL(8,39));printf("\n"); + printf("boot catalog start: %d\n",isonum_731(ebd->boot_catalog)); +} + +void dumpdefentry(struct default_entry *de) { + printf("Default entry: \n"); + printf(" bootid=%x\n",isonum_711(de->bootid)); + printf(" media emulation=%d (",isonum_711(de->media)); + switch(isonum_711(de->media) & 0xf) { + case 0: + printf("No emulation"); + break; + case 1: + printf("1.2 Mb floppy"); + break; + case 2: + printf("1.44 Mb floppy"); + break; + case 3: + printf("2.88 Mb floppy"); + break; + case 4: + printf("Hard Disk"); + break; + default: + printf("Unknown/Invalid"); + break; + } + printf(")\n"); + printf(" loadseg=%d\n",isonum_721(de->loadseg)); + printf(" systype=%d\n",isonum_711(de->systype)); + printf(" start lba=%d count=%d\n",isonum_731(de->start), + isonum_721(de->seccount)); +} + +void dumpbootcat(boot_head *bh) { + boot_entry *be; + + printf("System id: ");dumpchars(bh->ventry.id,ISODCL(28,5));printf("\n"); + be=bh->defentry; + while (be) { + dumpdefentry(be->data); + be=be->next; + } +} + +void dumpdesc(struct iso_primary_descriptor *ipd) { + + printf("system id: ");dumpchardesc(ipd->system_id,ISODCL(9,40));printf("\n"); + printf("volume id: ");dumpchardesc(ipd->volume_id,ISODCL(41,72));printf("\n"); + printf("volume space size: %d\n",isonum_733(ipd->volume_space_size)); + printf("volume set size: %d\n",isonum_723(ipd->volume_set_size)); + printf("volume seq num: %d\n",isonum_723(ipd->volume_set_size)); + printf("logical block size: %d\n",isonum_723(ipd->logical_block_size)); + printf("path table size: %d\n",isonum_733(ipd->path_table_size)); + printf("location of type_l path table: %d\n",isonum_731(ipd->type_l_path_table)); + printf("location of optional type_l path table: %d\n",isonum_731(ipd->opt_type_l_path_table)); + printf("location of type_m path table: %d\n",isonum_732(ipd->type_m_path_table)); + printf("location of optional type_m path table: %d\n",isonum_732(ipd->opt_type_m_path_table)); +/* + printf("Root dir record:\n");dumpdirrec((struct iso_directory_record*) &ipd->root_directory_record); +*/ + printf("Volume set id: ");dumpchardesc(ipd->volume_set_id,ISODCL(191,318));printf("\n"); + printf("Publisher id: ");dumpchardesc(ipd->publisher_id,ISODCL(319,446));printf("\n"); + printf("Preparer id: ");dumpchardesc(ipd->preparer_id,ISODCL(447,574));printf("\n"); + printf("Application id: ");dumpchardesc(ipd->application_id,ISODCL(575,702));printf("\n"); + printf("Copyright id: ");dumpchardesc(ipd->copyright_file_id,ISODCL(703,739));printf("\n"); + printf("Abstract file id: ");dumpchardesc(ipd->abstract_file_id,ISODCL(740,776));printf("\n"); + printf("Bibliographic file id: ");dumpchardesc(ipd->bibliographic_file_id,ISODCL(777,813));printf("\n"); + printf("Volume creation date: ");dumpiso84261time(ipd->creation_date,0);printf("\n"); + printf("Volume modification date: ");dumpiso84261time(ipd->modification_date,0);printf("\n"); + printf("Volume expiration date: ");dumpiso84261time(ipd->expiration_date,0);printf("\n"); + printf("Volume effective date: ");dumpiso84261time(ipd->effective_date,0);printf("\n"); + printf("File structure version: %d\n",isonum_711(ipd->file_structure_version)); +} + +int mycallb(struct iso_directory_record *idr,void *udata) { + rr_entry rrentry; + + sp(level);dumpdirrec(idr); + if (level==0) printf(" (Root directory) "); + printf("\n"); + + if (ParseRR(idr,&rrentry)>0) { + sp(level);printf(" ");dumprrentry(&rrentry);printf("\n"); + } + FreeRR(&rrentry); + if ( !(idr->flags[0] & 2) ) files++; + if ( (idr->flags[0] & 2) && (level==0 || isonum_711(idr->name_len)>1) ) { + level++; + dirs++; + ProcessDir(&readf,isonum_733(idr->extent),isonum_733(idr->size),&mycallb,udata); + level--; + } + return 0; +} + +/************************************************/ + +int main(int argc, char *argv[]) { + + int i=1,sector=0; + iso_vol_desc *desc; + boot_head boot; + + if (argc<2) { + fprintf(stderr,"\nUsage: %s iso-file-name or device [starting sector]\n\n",argv[0]); + return 0; + } + if (argc>=3) { + sector=atoi(argv[2]); + printf("Using starting sector number %d\n",sector); + } + fd=open(argv[1],O_RDONLY); + if (fd<0) { + fprintf(stderr,"open error\n"); + return -1; + } + iconv_d=iconv_open("ISO8859-2","UTF16BE"); + if (iconv_d==0) { + fprintf(stderr,"iconv open error\n"); + return -1; + } + + desc=ReadISO9660(&readf,sector,NULL); + if (!desc) { + printf("No volume descriptors\n"); + return -1; + } + while (desc) { + + printf("\n\n--------------- Volume descriptor (%d.) type %d: ---------------\n\n", + i,isonum_711(desc->data.type)); + switch (isonum_711(desc->data.type)) { + case ISO_VD_BOOT: { + + struct el_torito_boot_descriptor* bootdesc; + bootdesc=&(desc->data); + dumpboot(bootdesc); + if ( !memcmp(EL_TORITO_ID,bootdesc->system_id,ISODCL(8,39)) ) { + + if (ReadBootTable(&readf,isonum_731(bootdesc->boot_catalog),&boot,NULL)) { + printf("Boot Catalog Error\n"); + } else { + dumpbootcat(&boot); + FreeBootTable(&boot); + } + } + } + break; + + case ISO_VD_PRIMARY: + case ISO_VD_SUPPLEMENTARY: + joliet=0; + joliet = JolietLevel(&desc->data); + printf("Joliet level: %d\n",joliet); + dumpdesc((struct iso_primary_descriptor*) &desc->data); + printf("\n\n--------------- Directory structure: -------------------\n\n"); + dirs=0;files=0; + mycallb( &( ((struct iso_primary_descriptor*) &desc->data)->root_directory_record), NULL ); + printf("\nnumber of directories: %d\n",dirs); + printf("\nnumber of files: %d\n",files); + break; + + } + desc=desc->next; + i++; + } + iconv_close(iconv_d); + close(fd); + FreeISO9660(desc); + return 0; +} + +#endif /* ISOFS_MAIN */ diff --git a/iso/libisofs/isofs.h b/iso/libisofs/isofs.h new file mode 100644 index 0000000..52190e6 --- /dev/null +++ b/iso/libisofs/isofs.h @@ -0,0 +1,161 @@ +/*************************************************************************** + isofs.h - include this file to use libisofs + ------------------- + begin : Oct 25 2002 + copyright : (C) 2002 by Szombathelyi Gy�gy + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef ISOFS_H +#define ISOFS_H + +#include <sys/time.h> +#ifdef __cplusplus +extern "C" { +#endif + +#include "iso_fs.h" +#include "el_torito.h" +#include "rock.h" + +typedef struct _rr_entry { + int len; /* length of structure */ + char *name; /* Name from 'NM' */ + char *sl; /* symbolic link data */ + time_t t_creat; + time_t t_mtime; + time_t t_atime; + time_t t_ctime; + time_t t_backup; + time_t t_expire; + time_t t_effect; + int mode; /* POSIX file modes */ + int nlink; + int uid; + int gid; + int serno; + int dev_major; + int dev_minor; + int pl; /* parent location */ + int cl; /* child location */ + int re; /* relocated */ + char z_algo[2]; /* zizofs algorithm */ + char z_params[2]; /* zizofs parameters */ + int z_size; /* zizofs real_size */ +} rr_entry; + +typedef struct _iso_vol_desc { + struct _iso_vol_desc *next; + struct _iso_vol_desc *prev; + struct iso_volume_descriptor data; +} iso_vol_desc; + +typedef struct _boot_entry { + struct _boot_entry *next; + struct _boot_entry *prev; + struct _boot_entry *parent; + struct _boot_entry *child; + char data[32]; +} + boot_entry; + +typedef struct _boot_head { + struct validation_entry ventry; + struct _boot_entry *defentry; + struct _boot_entry *sections; +} + boot_head; + +/** + * this callback function needs to read 'len' sectors from 'start' into 'buf' + */ +typedef int readfunc(char *buf,int start, int len,void *); + +/** + * ProcessDir uses this callback + */ +typedef int dircallback(struct iso_directory_record *,void *); + +/** + * Returns the Unix from the ISO9660 9.1.5 (7 bytes) time format + * This function is from the linux kernel. + * Set 'hs' to non-zero if it's a HighSierra volume + */ +time_t isodate_915(char * p, int hs); + +/** + * Returns the Unix time from the ISO9660 8.4.26.1 (17 bytes) time format + * BUG: hundredth of seconds are ignored, because time_t has one second + * resolution (I think it's no problem at all) + * Set 'hs' to non-zero if it's a HighSierra volume + */ +time_t isodate_84261(char * p, int hs); + +/** + * Creates the linked list of the volume descriptors + * 'sector' is the starting sector number of where the filesystem start + * (starting sector of a session on a CD-ROM) + * If the function fails, returns NULL + * Don't forget to call FreeISO9660 after using the volume descriptor list! + */ +iso_vol_desc *ReadISO9660(readfunc *read,int sector,void *udata); + +/** + * Frees the linked list of volume descriptors +. + */ +void FreeISO9660(iso_vol_desc *data); + +/** + * Iterates over the directory entries. The directory is in 'buf', + * the size of the directory is 'size'. 'callback' is called for each + * directory entry with the parameter 'udata'. + */ +int ProcessDir(readfunc *read,int extent,int size,dircallback *callback,void *udata); + +/** + * Parses the System Use area and fills rr_entry with values + */ +int ParseRR(struct iso_directory_record *idr, rr_entry *rrentry); + +/** + * Frees the strings in 'rrentry' + */ +void FreeRR(rr_entry *rrentry); + +/** + * returns the joliet level from the volume descriptor + */ +int JolietLevel(struct iso_volume_descriptor *ivd); + +/** + * Returns the size of the boot image (in 512 byte sectors) + */ +int BootImageSize(int media,int len); + +/** + * Frees the boot catalog entries in 'boot'. If you ever called ReadBootTable, + * then don't forget to call FreeBootTable! + */ +void FreeBootTable(boot_head *boot); + +/** + * Reads the boot catalog into 'head'. Don't forget to call FreeBootTable! + */ +int ReadBootTable(readfunc *read,int sector, boot_head *head, void *udata); + +#ifdef __cplusplus +} //extern "C" +#endif + +#endif + diff --git a/iso/libisofs/rock.h b/iso/libisofs/rock.h new file mode 100644 index 0000000..e859192 --- /dev/null +++ b/iso/libisofs/rock.h @@ -0,0 +1,127 @@ +/* this header is from the linux kernel */ + +#ifndef ROCK_H +#define ROCK_H 1 + +/* These structs are used by the system-use-sharing protocol, in which the + Rock Ridge extensions are embedded. It is quite possible that other + extensions are present on the disk, and this is fine as long as they + all use SUSP */ + +struct SU_SP{ + unsigned char magic[2]; + unsigned char skip; +}; + +struct SU_CE{ + char extent[8]; + char offset[8]; + char size[8]; +}; + +struct SU_ER{ + unsigned char len_id; + unsigned char len_des; + unsigned char len_src; + unsigned char ext_ver; + char data[1]; +}; + +struct RR_RR{ + char flags[1]; +}; + +struct RR_PX{ + char mode[8]; + char n_links[8]; + char uid[8]; + char gid[8]; + char serno[8]; +}; + +struct RR_PN{ + char dev_high[8]; + char dev_low[8]; +}; + + +struct SL_component{ + unsigned char flags; + unsigned char len; + char text[1]; +}; + +struct RR_SL{ + unsigned char flags; + struct SL_component link; +}; + +struct RR_NM{ + unsigned char flags; + char name[1]; +}; + +struct RR_CL{ + char location[8]; +}; + +struct RR_PL{ + char location[8]; +}; + +struct stamp{ + char time[7]; +}; + +struct RR_TF{ + char flags; + struct stamp times[1]; /* Variable number of these beasts */ +}; + +/* Linux-specific extension for transparent decompression */ +struct RR_ZF{ + char algorithm[2]; + char parms[2]; + char real_size[8]; +}; + +/* These are the bits and their meanings for flags in the TF structure. */ +#define TF_CREATE 1 +#define TF_MODIFY 2 +#define TF_ACCESS 4 +#define TF_ATTRIBUTES 8 +#define TF_BACKUP 16 +#define TF_EXPIRATION 32 +#define TF_EFFECTIVE 64 +#define TF_LONG_FORM 128 + +struct rock_ridge{ + char signature[2]; + char len; /* 711 */ + char version; /* 711 */ + union{ + struct SU_SP SP; + struct SU_CE CE; + struct SU_ER ER; + struct RR_RR RR; + struct RR_PX PX; + struct RR_PN PN; + struct RR_SL SL; + struct RR_NM NM; + struct RR_CL CL; + struct RR_PL PL; + struct RR_TF TF; + struct RR_ZF ZF; + } u; +}; + +#define RR_PX 1 /* POSIX attributes */ +#define RR_PN 2 /* POSIX devices */ +#define RR_SL 4 /* Symbolic link */ +#define RR_NM 8 /* Alternate Name */ +#define RR_CL 16 /* Child link */ +#define RR_PL 32 /* Parent link */ +#define RR_RE 64 /* Relocation directory */ +#define RR_TF 128 /* Timestamps */ + +#endif /* ROCK_H */ |