Import mkhybrid from OpenBSD 7.3 to create ISO9660/HFS hybrid ISO images.

- files in libfile except proto.h prepared by OpenBSD are not imported
  due to non-standard license
  (newer BSD Licensed versions will be imported later)
- unnecessary files for tools build are not imported
- RCSId strings are trimmed to avoid unintended substitutions

Proposed on tech-toolchain@:
 https://mail-index.netbsd.org/tech-toolchain/2024/05/25/msg004355.html
This commit is contained in:
tsutsui 2024-05-31 19:49:02 +00:00
parent 942f913628
commit ddaa4e7dfc
80 changed files with 29558 additions and 0 deletions

23
external/gpl2/mkhybrid/bin/Makefile vendored Normal file
View File

@ -0,0 +1,23 @@
# $OpenBSD: Makefile,v 1.8 2022/07/11 03:11:49 daniel Exp $
# NOTE: The mkhybrid distrib also makes an "mkisofs" which is the same binary
# linked. When we know mkhybrid makes distrib CDs ok we should modify this
# to make mkisofs as a link to this, rather than the (earlier) version in
# the tree.
PROG= mkhybrid
MAN= mkhybrid.8
BINDIR= /usr/sbin
.PATH: ${.CURDIR}/../src ${.CURDIR}/../src/libhfs_iso ${.CURDIR}/../src/libfile
SRCS= data.c block.c low.c lfile.c btree.c node.c record.c lvolume.c \
hfs.c file.c apprentice.c softmagic.c mkisofs.c tree.c write.c \
hash.c rock.c multi.c joliet.c match.c name.c eltorito.c \
apple.c volume.c desktop.c mac_label.c
CFLAGS+=-DSYSTEM_ID_DEFAULT=\"OpenBSD\" -DAPPLE_HYB -DVANILLA_AUTOCONF \
-I${.CURDIR}/../src -I${.CURDIR}/../src/include \
-I${.CURDIR}/../src/libhfs_iso \
-I${.CURDIR}/../src/libfile
.include <bsd.prog.mk>

349
external/gpl2/mkhybrid/dist/COPYING vendored Normal file
View File

@ -0,0 +1,349 @@
The GPL below is copyrighted by the Free Software
Foundation, but the instance of code that it refers to
(the mkisofs utility is copyrighted by Yggdrasil Computing, Incorporated.
HFS hybrid code Copyright (C) James Pearson 1997, 1998, 1999.
libhfs code Copyright (C) 1996, 1997 Robert Leslie
libfile code Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991,
1992, 1994, 1995.)
----------------------------------------
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
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

863
external/gpl2/mkhybrid/dist/ChangeLog vendored Normal file
View File

@ -0,0 +1,863 @@
Wed Nov 5 10:46:29 1997 Andreas Buschmann US/EC4 60/1F/110 #40409 <buschman@lts.sel.alcatel.de>
Circumvent a bug in the SunOS / Solaris CD-ROM driver (and maybe HP/UX, too).
* mkisofs.8 (-S): Document switch.
* mkisofs.c (split_SL_field): new Variable, new switch -S.
* mkisofs.h (split_SL_field): new Variable.
* rock.c (generate_rock_ridge_attributes): only split SL field,
when split_SL_field is set.
Tue Jun 3 15:32:21 1997 Andreas Buschmann <buschman@lts.sel.alcatel.de>
Circumvent a bug in the SunOS CD-ROM driver (and maybee HP/UX, too).
* mkisofs.8 (-s): Document switch.
* mkisofs.c (split_SL_component): new Variable, new switch -s.
* mkisofs.h (split_SL_component): new Variable.
* rock.c (generate_rock_ridge_attributes): only split SL
components, when split_SL_component is set.
* defaults.h: Added SunOS string.
Wed Mar 19 16:50:17 1997 Fred Fish <fnf@ninemoons.com>
* Makefile.in (CFLAGS): Let configure set basic flags. Move
compilation option -c to actual CC commands.
(LDFLAGS): Let configure set basic flags.
(Makefile): Depends upon config.status, not configure.
Regenerate if necessary from Makefile.in using config.status.
(configure): Cd to srcdir before running autoconf.
* acconfig.h: New file to hold nonstandard entries used in
config.h.in. Used by autoheader to generate config.h.in.
* config.h.in: Regenerated with autoheader.
* configure.in: Check for existance of sbrk() function.
* configure: Regenerated with autoconf 2.12.
* fnmatch.c (FMN_FILE_NAME): Define if not already defined.
(FNM_LEADING_DIR): Ditto.
(FNM_CASEFOLD): Ditto.
* mkisofs.c (main): Only use sbrk() if system supports it.
Fri Mar 14 21:54:37 1997 Eric Youngdale <eric@andante.jic.com>
* Bump version number to 1.10, public release.
* Put entire thing under RCS. History is buried there now.
* Fix bug involving empty directories, translation tables and
malloc(0).
Mon Feb 17 12:44:03 1997 Eric Youngdale <eric@andante.jic.com>
* Bump version number to 1.10b7.
* Makefile.in, configure.in, config.in: Change to use GNU autoconf.
* Configure: Delete old configuration script.
* tree.c: Fix bug where we had a rename limit of 1000 files
instead of 0x1000.
* mkisofs.c: Fix sign of timezone offset. Linux iso filesystem
also need to be fixed, unfortunately.
Tue Dec 3 22:21:21 1996 Eric Youngdale <eric@sub2317.jic.com>
Fixed a couple of multi-session bugs. Discs now seem to
work on both Solaris and Windows-NT.
* Bump version number to 1.10b6.
Tue Dec 3 22:21:21 1996 Eric Youngdale <eric@sub2317.jic.com>
Multi-session stuff *almost* there. Discs seem to work
under Linux without any problem, but under DOS only
the first session is seen. The patch to write.c
inspired by disc written by Windows generated multi-session
disc, which will hopefully make the discs usable under
DOS as well.
* Bump version number to 1.10b5.
* write.c: use size of new session, not total of all sessions
in volume_space_size field.
* mkisofs.8: Update with current location of cdwrite.
Mon Nov 4 23:45:01 1996 Eric Youngdale <eric@sub2317.jic.com>
* Bump version number to 1.10b4.
* Add cdwrite.c.diff file, which provides a very crude, minimal
interface between mkisofs and cdwrite. It should be enough to
generate a multi-session disc, but it hasn't been tested yet.
Thu Oct 17 00:39:52 1996 Eric Youngdale <eric@sub2317.jic.com>
* Bump version number to 1.10b3.
Wed Oct 16 23:40:44 1996 Michael Fulbright <msf@redhat.com>
Add support for 'El Torito' specification which allows for bootable
cdroms.
* Makefile.in: Add eltorito.[c,o].
* defaults.h: Add default settings for El Torito related things.
* iso9660.h: Add structure definitions for El Torito.
* mkisofs.8: Document new options.
* mkisofs.c: Add support for new options related to El Torito.
* mkisofs.h: Add definitions, prototypes as required.
* tree.c: Add search_tree_file function to search for a specified
file.
* write.c: Add support for writing special records for El Torito.
* eltorito.c: New file.
Wed Oct 16 23:40:44 1996 Eric Youngdale <eric@sub2317.jic.com>
* rock.c: Fix bug whereby we made assumptions about how
dev_t was split into major/minor. Use major() and minor()
macros to do this for us, since each system should
do this correctly.
* write.c: Fix bug whereby abstract, copyright and appid
strings were not properly filled if application ID weren't
in use.
Sun Sep 29 10:05:10 1996 Eric Youngdale <eric@sub2317.jic.com>
* Bump version number to 1.10b2. Minor bug fixes here
and there.
Sun Sep 15 18:54:05 1996 Eric Youngdale <eric@sub2317.jic.com>
* Bump version number to 1.10b1. Major new functionality is
support for multi-session. Still a bit preliminary, but
most of the pieces are there now.
Wed Dec 20 16:44:44 1995 Eric Youngdale (eric@andante.aib.com)
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.05.
* rock.c: Bugfix for cases where sizeof(int) == 4 and
sizeof(dev_t) > 4.
* rock.c: Bugfix for long symbolic links ('/' characters were
being dropped).
Patches from Peter Miller <pmiller@agso.gov.au>:
* mkisofs.8: Documentation fix (some versions of nroff don't
like '.' in column 1 if it is not a nroff command).
* mkisofs.c: Add support for 'rationalize' option.
Similar to rock ridge, except echos of development environment
are removed.
* write.c Status indicator now indicates percent finished, and
estimated time of completion.
Sun Feb 26 01:52:06 1995 Eric Youngdale (eric@largo)
* Add patches from Ross Biro to allow you to merge arbitrary
trees into the image. This is not compiled in by default but
you need to add -DADD_FILES when compiling.
Fri Feb 17 02:29:03 1995 Paul Eggert <eggert@twinsun.com>
* tree.c: Port to Solaris 2.4. Prefer <sys/mkdev.h> if
HASMKDEV. Cast unknown integer types to unsigned long and
print them with %lu or %lx.
Thu Jan 26 15:25:00 1995 H. Peter Anvin (hpa@yggdrasil.com)
* mkisofs.c: Substitute underscore for leading dot in non-Rock
Ridge filenames, since MS-DOS cannot read files whose names
begin with a period.
Mon Jan 16 18:31:41 1995 Eric Youngdale (eric@aib.com)
* rock.c (generate_rock_ridge_attributes): Only use ROOT
record for symlinks if we are at the start of the symlink.
Otherwise just generate an empty entry.
Mon Jan 16 16:19:50 1995 Eric Youngdale (eric@aib.com)
* diag/isodump.c: Use isonum_733 instead of trying to dereference
pointers when trying to decode 733 numbers in the iso9660 image.
* diag/isovfy.c: Likewise.
* write.c: Always assign an extent number, even for zero length
files. A zero length file with a NULL extent is apparently dropped
by many readers.
Wed Jan 11 13:46:50 1995 Eric Youngdale (eric@aib.com)
* mkisofs.c: Modify extension record to conform to IEEE P1282
specifications. This is commented out right now, but a trivial
change to a #define enables this. I need to see the specs
to see whether anything else changed before this becomes final.
* write.c (FDECL4): Fix so that we properly determine error
conditions.
* mkisofs.h: Change rr_attributes to unsigned.
* tree.c(increment_nlink): Change pnt since rr_attributes is now
unsigned.
Ultrix patches from petav@argon.e20.physik.tu-muenchen.de (Peter Averkamp)
* rock.c: Fix for ultrix systems, we have 64 bit device numbers.
Type cast when generating file size. Change rr_attributes to
unsigned.
* mkisofs.c: For ultrix systems, define our own function
for strdup.
* mkisofs.c: Fix usage() since some compilers do not concatenate
strings properly (i.e. ultrix).
Bugs found with Sentinel II:
* write.c: Fix a couple of memory leaks.
* mkisofs.c: Bugfix - always put a zero byte at end of name
for ".." entry.
* tree.c: Set isorec.date from fstatbuf.st_ctime, not current_time,
since current_time might not be set.
Sat Dec 3 14:55:42 1994 Eric Youngdale (eric@andante)
* mkisofs.c: When returning entry for ".." file, set second byte
to 0.
* write.c: Free name and rr_attributes fields when writing.
Mon Nov 28 13:36:27 1994 Eric Youngdale (eric@andante)
* mkisofs.h: Change rr_attributes to unsigned.
* rock.c: Ditto. Work around >>32 bug in ultrix for 64 bit data types.
* mkisofs.c (usage): Fix for ultrix - use continuation lines
instead of assuming that strings are catenated by the compiler.
Mon Jun 20 20:25:26 1994 Eric Youngdale (eric@esp22)
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to pre-1.02.
* mkisofs.h: Fix declaration of e_malloc to use DECL macros.
* tree.c: Fix bug in previous change.
* diag/*.c: Add appropriate copyright notices.
Sat Apr 9 13:30:46 1994 Eric Youngdale (ericy@cais.com)
* Configure: New file - shell script that determines a bunch of
things to properly build mkisofs.
* Makefile.in: New file - copy of Makefile, but Configure sets a
few things up for it.
* tree.c: Do not depend upon opendir to return NULL if we cannot
open a directory - actually try and read the first entry. The
foibles of NFS seem to require this.
* write.c: Fix definition of xfwrite (Use FDECL4)
Add some changes to allow more configurability of some of the
volume header fields:
* mkisofs.8: Document new configuration options.
* mkisofs.c: Add variables to hold new fields. Add function to
read .mkisofsrc files.
* defaults.h: Another way of configuring the same things.
Add some changes from Leo Weppelman leo@ahwau.ahold.nl.
* mkisofs.c: Allow -A to specify application ID. Fix usage(),
getopt and add case switch.
* rock.c: Fix handling of device numbers (dev_t high should only
be used when sizeof(dev_t) > 32 bits).
Add a bunch of changes from Manuel Bouyer.
* diag/Makefile: New file.
* diag/dump.c, diag/isodump.c: Use termios if system supports it.
* (throughout): Replace all occurences of "malloc" with e_malloc.
* mkisofs.c: For NetBSD, attempt to increase the rlimit for
the size of the data segment to about 33 Mb.
* mkisofs.c (e_malloc): New function. Calls malloc, and prints
nice error message and exits if NULL is returned.
Sun Jan 23 19:23:57 1994 Eric Youngdale (eric@esp22)
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.01.
Add a bunch of stuff so that mkisofs will work on a VMS system.
* (ALL): Change any direct use of the "st_ino" field from
the statbuf to use a macro.
* mkisofs.h: Define appropriate macros for both VMS and unix.
* (ALL): Add type casts whenever we use the UNCACHED_DEV macro.
* rock.c: Wrap a #ifndef VMS around block and character device
stuff.
* write.c: Add prototype for strdup if VMS is defined.
* make.com: Script for building mkisofs on a VMS system.
* Makefile: Include make.com in the distribution.
* mkisofs.c: Include <sys/type.h> on VMS systems.
* tree.c: Include <sys/file.h> and "vms.h" on VMS systems.
* mkisofs.h (PATH_SEPARATOR, SPATH_SEPARATOR): New macros
that define the ascii character that separates the last directory
component from the filename.
* tree.c, mkisofs.c: Use them.
* vms.c: New file. Contains version of getopt, strdup, opendir,
readdir and closedir.
* vms.h: New file. Defines S_IS* macros. Define gmtime as
localtime, since gmtime under VMS returns NULL.
Sat Jan 15 13:57:42 1994 Eric Youngdale (eric@esp22)
* mkisofs.h (transparent_compression): New prototype.
* mkisofs.c (transparent_compression): Declare, use
'-z' option to turn on.
* tree.c: Change TRANS.TBL;1 to TRANS.TBL (version gets
added later, if required).
* rock.c: If transparent compression requested, verify
file is really suitable (check magic numbers), and extract
correct file length to store in SUSP record.
Sat Jan 15 01:57:42 1994 Eric Youngdale (eric@esp22)
* write.c (compare_dirs): Bugfix for patch from Jan 6.
* mkisofs.h (struct directory_entry): Add element total_rr_attr_size.
(struct file_hash): Add element ce_bytes.
* write.c (iso_write): Update last_extent_written, as required,
and check it against last_extent as a sanity check.
(generate_one_directory): If ce_bytes is non-zero, allocate
a buffer and fill it with the CE records. Also, update
the extent and offset entries in the CE SUSP field and
output after directory is written.
(assign_directory_addresses): Allow for CE sectors after each
directory.
* tree.c (sort_n_finish): Set field ce_bytes by summing
the sizes of all CE blocks in each files RR attributes.
Do not count these bytes for main directory.
* rock.c (generate_rock_ridge_attributes): Generate
CE entries to break up large records into manageable sizes.
Allow long names to be split, and allow long symlinks to be split.
Allow splitting before each SUSP field as well, to make
sure we do not screw outselves.
Thu Jan 6 21:47:43 1994 Eric Youngdale (eric@esp22)
Bugfix.
* write.c (compare_dirs): Only compare directory names up to
the ';' for the version number.
Add four new options: (1) Full 31 character filenames,
(2) Omit version number, (3) Omit trailing period from filenames,
(4) Skip deep directory relocation.
* iso9660.h: Allow 34 characters for filename.
* mkisofs.8: Update for new options.
* mkisofs.c: Add flag variables for new options.
Mention new options in usage(), tell getopt about
new options, and set appropriate flags when
new options are specified.
* mkisofs.c (iso9660_file_length): Implement new options.
* mkisofs.h: Declare flag variables for new options.
* tree.c (sort_n_finish): Increase declaration of newname and
rootname to 34 characters. If full_iso9660_filenames in effect,
use different rules for making unique names.
* tree.c (scan_directory_tree): Use RR_relocation_depth instead of
constant for threshold for starting deep directory relocation.
Wed Jan 5 01:32:34 1994 John Brezak (brezak@ch.hp.com)
* Makefile.bsd: New file. For NetBSD.
* rock.c, tree.c: Do not include sys/sysmacros.h for NetBSD.
Fri Dec 31 13:22:52 1993 Eric Youngdale (eric@esp22)
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.00.
* tree.c (scan_directory_tree): Handle case where we do not
have permissions to open a directory.
* write.c (xfwrite): New function - wrapper for fwrite,
except that we print message and punt if write fails.
* write.c: Move include of mkisofs.h and iso9660.h until after
string.h and stdlib.h is included.
* write.c: Do not attempt to use strerror on sun systems.
Thu Dec 9 13:17:28 1993 R.-D. Marzusch (marzusch@odiehh.hanse.de)
* exclude.c, exclude.h: New files. Contains list of files to
exclude from consideration.
* Makefile: Compile exclude.c, add dependencies to other files.
* mkisofs.8: Describe -x option.
* mkisofs.c: Include exclude.h, handle -x option.
Fri Dec 10 01:07:43 1993 Peter van der Veen (peterv@qnx.com)
* mkisofs.c, mkisofs.h: Moved declaration of root_record.
* mkisofs.h: Added prototype for get_733().
* write.c(iso_write), tree.c, rock.c(generate_rock_ridge_attributes):
Added defines for QNX operation system
* rock.c(generate_rock_ridge_attributes): symbolic links should
not have CONTINUE component flag set unless there are multiple
component records, and mkisofs does not generate these.
st_ctime was stored as the creation time, changed to attribute time.
QNX has a creation time, so that is stored as well under QNX.
Thu Oct 28 19:54:38 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.99.
* write.c(iso_write): Put hour, minute, second into date fields in
volume descriptor.
* write.c (iso_write): Set file_structure_version to 1, instead of
' ' (Seems to screw up Macs).
Sun Oct 17 01:13:36 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.98.
Increment nlink in root directory when rr_moved directory is present.
* tree.c (increment_nlink): New function.
* tree.c (finish_cl_pl_entries): Call increment_nlink for all
references to the root directory.
* tree.c (root_statbuf): New variable.
* tree.c (scan_directory_tree): Initialize root_statbuf when we
stat the root directory.
* tree.c (generate_reloc_directory): Use root_statbuf when
generating the Rock Ridge stuff for the ".." entry in the
reloc_dir.
* tree.c (scan_directory_tree): Use root_statbuf when generating
the ".." entry in the root directory.
Sat Oct 16 10:28:30 1993 Eric Youngdale (eric@kafka)
Fix path tables so that they are sorted.
* tree.c (assign_directory_addresses): Move to write.c
* write.c (generate_path_tables): Create an array of pointers to
the individual directories, and sort it based upon the name and
the parent path table index. Then update all of the indexes and
repeat the sort until the path table indexes no longer need to be
changed, and then write the path table.
Fix problem where hard links were throwing off the total extent count.
* write.c (iso_write): Call assign_file_addresses, and then
use last_extent to determine how big the volume is.
* write.c (generate_one_directory): Decrement n_data_extents
for hard links to non-directories so that the expected number
of extents is written correctly.
* write.c(assign_file_addresses): New function.
Fri Oct 15 22:35:43 1993 Eric Youngdale (eric@kafka)
The standard says we should do these things:
* tree.c (generate_reloc_directory): Add RR attributes to
the rr_moved directory.
* mkisofs.c(main): Change ER text strings back to recommended
values.
Tue Oct 12 21:07:38 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.97.
* tree.c (scan_directory_tree): Do not insert PL entry into
root directory record (i.e. !parent)
* tree.c (finish_cl_pl_entries): Do not rely upon name
comparison to locate parent - use d_entry->self instead,
which is guaranteed to be correct.
* mkisofs.h: New variable n_data_extents.
* tree.c: Declare and initialize n_data_extents to 0.
(scan_directory_tree) for non-directories, add
ROUND_UP(statbuf.st_size) to n_data_extents.
(sort_n_finish): Increment n_data_extents for translation tables,
as appropriate.
* write.c(iso_write): Add n_data_extents to the
volume_space_size field.
* hash.c(add_hash): If size != 0 and extent == 0, or
if size == 0 and extent != 0, then complain about
inserting this into the hash table. Kind of a sanity check.
Sat Oct 9 16:39:15 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.96.
Numerous bugfixes, thanks to a one-off disc from rab@cdrom.com.
* write.c(generate_one_directory): Wait until after we have
filled in the starting_extent field to s_entry before calling
add_hash. This fixes a problem where the hash table gets an
extent of 0 for all regular files, and this turns up when you have
hard links on the disc. (The hash table allows us to have each
hard link point to the same extent on the cdrom, thereby saving
some space).
* tree.c(scan_directory_tree): Set statbuf.st_dev and
statbuf.st_ino to the UNCACHED numbers for symlinks that we
are not following. This prevents the function find_hash from
returning an inode that cooresponds to the file the symlink points
to, which in turn prevents generate_one_directory from filling in
a bogus file length (should be zero for symlinks).
* tree.c(scan_directory_tree): Always call lstat for the file
so that non-RockRidge discs get correct treatment of symlinks.
Improve error message when we ignore a symlink on a non-RR disc.
* write.c(generate_one_directory): Set fields for starting_extent
and size in the "." and ".." entries before we add them to the
file hash. Fixes problems with incorrect backlinks for second
level directories.
Wed Oct 6 19:53:40 1993 Eric Youngdale (eric@kafka)
* write.c (write_one_file): Print message and punt if we are
unable to open the file.
* tree.c(scan_directory_tree): For regular files, use the access
function to verify that the file is readable in the first place.
If not, issue a warning and skip it. For directories, it probably
does not matter, since we would not be able to descend into them
in the first place.
Wed Sep 29 00:02:47 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.95.
* write.c, tree.c: Cosmetic changes to printed information.
* tree.c(scan_directory_tree): Set size to zero for
special stub entries that correspond to the
relocated directories. Hopefully last big bug.
* mkisofs.h: Change TABLE_INODE, UNCACHED_* macros
to be 0x7fff... to be compatible with signed datatypes.
Mon Sep 27 20:14:49 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.94.
* write.c (write_path_tables): Actually search the
directory for the matching entry in case we renamed
the directory because of a name conflict.
* tree.c(scan_directory_tree): Take directory_entry pointer
as second argument so that we can create a backpointer
in the directory structure that points back to the original
dir.
* mkisofs.c: Fix call to scan_directory_tree to use new calling
sequence.
* write.c(generate_one_directory): Punt if the last_extent counter
ever exceeds 700Mb/2048. Print name of responsible file,
extent counter, and starting extent. Perhaps we can catch it in
the act.
Sun Sep 26 20:58:05 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.93.
* tree.c(scan_directory_tree): Handle symlinks better. Either
leave them as symlinks, or erase any trace that they were a
symlink but do not do it 1/2 way as before. Also, watch for
directory loops created with symlinks.
* mkisofs.h: Add new flag follow_links.
* mkisofs.c: Add command line switch "-f" to toggle follow_links.
* mkisofs.8: Document new switch.
* tree.c: Add code to handle symlinks using new flag.
* hash.c: Add add_directory_hash, find_directory_hash functions.
* mkisofs.h: Add prototypes.
Sat Sep 25 14:26:31 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.92.
* mkisofs.c: Make sure path is an actual directory before trying
to scan it.
* mkisofs.h: Add DECL and FDECL? macros for sparc like systems.
Do proper define of optind and optarg under SVr4.
* tree.c: Change translation table name from YMTRANS.TBL to TRANS.TBL.
* mkisofs.c: Neaten up message in extension record when RRIP is
in use.
* Throughout - change all function declarations so that
traditional C compilers (i.e. sparc) will work.
* Makefile: Change to use system default C compiler.
* mkisofs.c: Add some stuff so that this will compile under VMS.
Many things missing for VMS still.
* iso9660.h: Do not use zero length array in struct definition.
* tree.c (sort_n_finish): Account for this.
* Change copyright notice.
Wed Aug 25 08:06:51 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.91.
* mkisofs.h: Only include sys/dir.h for linux. Other systems
will need other things.
* mkisofs.c, tree.c: Include unistd.h.
* Makefile: Use OBJS to define list of object files.
Sun Aug 22 20:55:17 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.9.
* write.c (iso_7*): Fix so that they work properly on Motorola
systems.
Fri Aug 20 00:14:36 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.8.
* rock.c: Do not mask off write permissions from posix file modes.
Wed Aug 18 09:02:12 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.7.
* rock.c: Do not write NM field for . and .. (redundant and a
waste of space).
* mkisofs.c: Take -P and -p options for publisher and preparer id
fields.
* write.c: Store publisher and preparer id in volume
descriptor.
* rock.c: Write optional SP field to identify SUSP. Write
optional CE field to point to the extension header.
* tree.c: Request SP and CE fields be added to root directory.
* tree.c: Fix bug in name conflict resolution.
* write.c: Fill in date fields in the colume descriptor.
* write.c (write_one_file): If the file is large enough, write in
chunks of 16 sectors to improve performance.
* hash.c (add_hash, find_hash, etc): Do not hash s_entry, instead
store relevant info in hash structure (we free s_entry structs as
we write files, and we need to have access to the hash table the
whole way through.
* write.c: Add a few statistics about directory sizes, RR sizes,
translation table sizes, etc.
* tree.c: Use major, not MAJOR. Same for minor. Define S_ISSOCK
and S_ISLNK if not defined.
* rock.c: Define S_ISLNK if not defined.
* mkisofs.c: Print out max memory usage. Fix bug in call to getopt.
* mkisofs.c, Makefile (version_string): Bump to 0.6.
* tree.c: Simplify the calculation of isorec.len, isorec.name_len
and the calculation of the path table sizes by doing it all at
one point after conflict resolution is done.
* tree.c: scan_directory_tree is now responsible for generating
the line that goes into the YMTRANS.TBL file. These lines are
collected later on into something that will be dumped to the
file. Correctly handle all of the special file types.
Mon Aug 16 21:59:47 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.5.
* mkisofs.c: Add -a option (to force all files to be
transferred). Remove find_file_hash stuff.
* write.c: Pad length even if Rock Ridge is not in use.
* hash.c: Rewrite hash_file_* stuff so that it can be used to
easily detect (and look up) filenames that have been accepted
for use in this directory. Used for name collision detection.
* tree.c (sort_n_finish): If two names collide, generate a unique
one (verified with the hash routines). Change the lower priority
name if there is a difference.
Sat Aug 14 13:18:21 1993 Eric Youngdale (eric@kafka)
* mkisofs.c, Makefile (version_string): Bump to 0.4.
* tree.c (load_translation_table): New function - read
YMTRANS.TBL. (scan_directory_tree) Call it.
* mkisofs.c (iso9660_file_length): Call find_file_hash to see
if translated name is specified. If so, use it.
* hash.c (name_hash, add_file_hash, find_file_hash,
flush_file_hash): New functions for hashing stuff from
YMTRANS.TBL.
* mkisofs.h: Add a bunch of prototypes for the new functions.
* mkisofs.8: Update.
* mkisofs.c, Makefile (version_string): Bump to 0.3.
* Makefile: Add version number to tar file in dist target.
* mkisofs.c: Call finish_cl_pl_entries() after directories have
been generated, and extent numbers assigned.
* write.c (generate_one_directory): Update s_entry->size for
directories (as well as isorec.size).
* rock.c: Add code to generate CL, PL, and RE entries. The
extent numbers for the CL and PL entries are NULL, and these
are filled in later once we know where they actually belong.
* mkisofs.h: Add parent_rec to directory_entry. Used to fix CL/PL
stuff.
* tree.c (scan_directory_tree): Set flag to generate CL/PL/RE
entries as required, update sizes as well.
Fri Aug 13 19:49:30 1993 Eric Youngdale (eric@kafka)
* mkisofs.c (version_string): Bump to 0.2.
* hash.c: Do not use entries with inode == 0xffffffff or dev ==
0xffff.
* write.c (write_path_tables): Strip leading directory specifications.
* mkisofs.h: Add definition for reloc_dir symbol. Add prototype
for sort_n_finish, add third parameter to scan_directory_tree
(for true parent, when directories are relocated).
* mkisofs.c (main): Modify call to scan_directory_tree. Call
sort_n_finish for reloc_dir.
* tree.c (sort_n_finish): New function - moved code from
scan_directory_tree.
* tree.c (generate_reloc_directory): New function. Generate
directory to hold relocated directories.
* tree.c (scan_directory_tree): Strip leading directories when
generating this_dir->name. If depth is too great, then move
directory to reloc_dir (creating if it does not exist, and leave
a dummy (non-directory) entry in the regular directory so that
we can eventually add the required Rock Ridge record.
* tree.c (scan_directory_tree): Use s_entry instead of sort_dir,
assign to this_dir->contents sooner.
Thu Aug 12 22:38:17 1993 Eric Youngdale (eric@kafka)
* mkisofs.c (usage): Fix syntax.
* mkisofs.c (main): Add new argument to scan_directory_tree
* tree.c (scan_directory_tree): If directory is at depth 8 or
more, create rr_moved directory in main directory.
Mon Jul 26 19:45:47 1993 Eric Youngdale (eric@kafka)
* mkisofs v 0.1 released.

View File

@ -0,0 +1,369 @@
Thu Apr 7 20:29:04 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12b5.1
Fixed bugs with MacBinary names and symbolic links to HFS files
when using the -f option
Re-introduced some minor changes "lost" from v1.12b4.8
Forgot to add -hide-hfs-list option in previous version ...
Tue Mar 30 08:31:13 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12b5.0
Now based on mkisofs v1.12b5
Option -mac-name now only uses the HFS name if the file is one
of the known HFS file types
Added -hide-list, -hide-joliet-list, -hide-hfs-list, -exclude-list
and -path-list options. Allows a list of filenames to be excluded or
hidden to be given in a file instead of on the command line.
Added option -hfs-volid to give the HFS volume its own name (not
using the ISO9660 volume name).
Tue Jan 5 15:44:24 GMT 1999 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12b4.8
Fixed an AppleDouble bug and added better support for more Unix
flavours.
Fixed -hide-hfs bug that corrupted some HFS hidden files
Made the verbose output less verbose.
Added initial support for the AutoStart feature.
HFS partition maps can now be added without having to create
a bootable HFS CD (as pre-v1.12a4.7).
Added option to specify the PC Exchange "cluster size".
Mon Aug 24 23:18:38 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.7
Fixed SGI/XINET and PC Exchange bugs
By default, the output image no longer has an HFS partition map
(as pre-v1.12a3.4). Partition maps are only added if making a
bootable HFS CD
Fixed possible bug with odd-length structure alignment with gcc on
some architectures
Tue Aug 4 23:09:17 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.6
Made a couple of Netatalk changes
Altered way Apple/Unix associated files are excluded - e.g.
if just --cap is selected, then files associated with the other
Apple/Unix encodings are processed as normal files. Previously they
would have been ignored
Added option (-no-desktop) to prevent the (empty) HFS desktop files
being created. These will be created when the CD is used on a
Macintosh (and stored in the System Folder).
Sun Jul 26 09:44:50 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.5
Fixed serious bug that could cause corrupt output when used with
the -J option
Tue Jul 21 14:33:20 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.4
HFS file/directory names that share the first 31 characters have
'_N' (N == decimal number) substituted for the last few characters
to generate unique names.
1 year since the first release ...
Sat Jul 11 12:57:04 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.3
Added options to "hide" (options -hide and -hide-joliet) files
or directories from the ISO9660/RockRidge and/or Joliet directory
trees.
Renamed the -hfs-exclude option to -hide-hfs to be compatible
with the above options.
Fixed a bug with the -hide-hfs option (very rare case ...)
Thu Jun 25 20:02:20 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.2
Fixed an HFS bug introduced with v1.12a3.4 that created some
corrupt HFS volumes over about 400Mb
Tighten up checking for MacBinary files to prevent false matches
Sun Jun 21 11:55:09 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.1
Default TYPE and CREATOR can now be set via the .mkisofsrc file
Order of magic and mapping file on the command line is now
important. This defines the order in which TYPE and CREATOR are set.
Apple/Unix file types found are logged as part of the verbose output
(need to give -v twice)
Added option (-log-file) to redirect stderr messages
Added option (-hfs-exclude) to exclude files/directories from
the HFS part of the CD.
Fixed a couple of MacBinary/AppleSingle bugs.
Thu Jun 8 23:40:56 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a4.0
Resource fork file names not added to TRANS.TBL
Re-enabled support of non-regular Win32 files. GNU-Win32 can
create symbolic links etc. These are now recognised.
mkhybrid man page added.
Based on mkisofs v1.12b4
Wed May 20 12:54:36 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.5
Added support for using a "magic" file to set CREATOR/TYPE for
a file - see README.hfs_magic for details.
Mon May 18 16:22:32 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.4
Added possible support for bootable Mac CDs - see README.hfs_boot
or details.
Fixed -x bug (mkisofs v1.12 bug)
Mon May 4 14:23:46 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.3
Added support for UShare Mac/Unix files
Individual Mac/Unix file types can now be selected instead
of searching for all possible types. See README.mkhybrid for
details.
Fri May 1 10:34:29 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.2
Various bug fixes to Mac file names
Tue Mar 10 14:42:03 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.1
Added -no-hfs-files option that assumes there are no Unix/Mac
files (CAP, Netatalk, etc) - speeds up processing in these cases
Case insensitive HFS file/folder names that are the same are now
allowed - one or more '_' characters are added to one or more of
the filenames.
(Changed -macname option to -mac-name option)
Mon Feb 23 16:09:27 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a3.0
Based on mkisofs v1.12b3
Fixed serious HFS bug that crept in from v1.11 -> v1.12
Tue Feb 17 16:20:12 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a2.0
Based on mkisofs v1.12b2
Improved Win32 support: using -r now makes all files executable
when run under Win95/NT4
Tue Feb 3 10:30:18 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a1.2
Fixed memory bug when used without any HFS options
Improved PC Exchange support (although still needs testing)
Tue Jan 27 10:32:26 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a1.1
Can now handle multiple hard linked source files with the -hfs option
(multiple hard linked source files are handled as separate files)
configure script changed to check for ranlib
Fixed a couple of AppleSingle bugs.
Added option to use Mac names as starting point for ISO9660, Joliet
and RockRidge names
Wed Jan 21 14:00:56 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.12a1
See README.mkhybrid for details
Fri Jan 16 17:09:48 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 1.11
Changed version numbering to be the same as mkisofs
Code no longer considered beta level
Minor changes to allow the code to be complied and run
on Win95/NT using Cygnus' GNU-Win32 (available from
http://www.cygnus.com/misc/gnu-win32/)
Thu Dec 4 17:17:45 GMT 1997 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 0.49b
Fixed an HFS bug that caused a failure with directory names that
had special AUFS characters
Fixed mkisofs bug in eltorito.c that wrote warning messages
to stdout not stderr
Code no longer considered alpha level
Thu Nov 27 19:00:02 GMT 1997 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 0.48a
Added Apple's extensions to ISO9660 that can be used instead of
the HFS options (see README.mkhybrid for more details).
Added more verbose HFS error messages.
Changed the Joliet option flag to -J (-j still works) to be
compatible the with next release of mkisofs (v1.12)
Wed Oct 15 11:16:21 BST 1997 James Pearson <j.pearson@ge.ucl.ac.uk>
Version 0.47a
Fixed bug that prevented volume_space_size not being set in the
PVD (or SVD)
Mon Oct 6 15:46:24 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.46a
Small Joliet bug fix - source directories that are not readable
are set to empty ordinary files in the ISO9660 filesystem - this
is now true for the Joliet directory (partially responsible
for NT4 having problems with CDs where this happened)
Minor documentation updates.
Mon Sep 15 14:15:11 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.45a
Attempt to prevent the HFS Catalog file growing (see
"Implementation" in README.mkhybrid for more details)
This is only likely to be a problem where folders have lots
of small files.
Mon Aug 18 12:00:24 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.44a
If the directories were deeper than 8 and the -D flag was not
used, then the "rr_moved" directory was not added to the Joliet
directory tree. This has now been fixed - but one day, the deep
Joliet directories may not have to be relocated ...
Fixed memcmp problem with possible uninitialised memory in
j_compare_paths(), which *might* cause incorrect Joliet directory
sort order
Wed Aug 13 14:58:56 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.43a
Fixed bug for incorrect Joliet path table size
Fixed some old minor mkisofs bugs (TRANS.TBL not having a
version number by default and incorrect date in the PVD).
Mon Aug 11 17:17:07 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.42a
Now will not try to create the HFS "Desktop DB" and "Desktop DF"
if they already exist when used with the HFS options.
Fixed a serious bug in the hfs code that truncated some files.
"TRANS.TBL" was missed out of the Joliet directory if the -T
option was given (previously an empty file with no name was used
which could cause problems on NT 4)
Fri Aug 8 10:19:46 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.41a
Fixed bug which created invalid HFS/ISO9660 volumes if the -j (Joliet)
option was not used
Mon Aug 4 15:08:43 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.4a
Added (partial?) Joliet support.
Now based on mkisofs v1.11
Tue Jul 29 11:57:14 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.32a
Allocation sizes improved to cut down on wasted space. Now uses
the HFS "allocation" size rounded up to the nearest 2048 bytes.
Savings can be significant with a large volume containing lots
of smallish files.
Wed Jul 23 15:36:08 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.31a
Deep directories (greater than RR_relocation_depth) cause core
dump in "copy_to_mac_volume" as the relocated directory was not
marked as an HFS folder. Fixed by putting deep HFS folders in
their correct location.
Mon Jul 21 15:50:05 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk>
Version 0.3a, first public release.

149
external/gpl2/mkhybrid/dist/Makefile.in vendored Normal file
View File

@ -0,0 +1,149 @@
#
# Id: Makefile.in,v 1.3 2008/03/08 15:36:12 espie Exp
#
## Makefile for mkhybrid - based on mkisofs v1.12
# James Pearson 16/3/1999
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
LIBS = @LIBS@ -lhfs -lfile
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
RANLIB = @RANLIB@
libhfsdir = libhfs_iso
LIBHFS = $(libhfsdir)/libhfs.a
INCHFS = $(libhfsdir)/hfs.h
libfiledir = libfile
LIBFILE = $(libfiledir)/libfile.a
DEFINES = -DAPPLE_HYB
COPTS=@CFLAGS@
# Where to put the manual pages.
mandir = $(prefix)/man/man8
# Extension (not including `.') for the manual page filenames.
manext = 8
#### End of system configuration section. ####
CFLAGS=$(COPTS) $(DEFINES) -I. -Iinclude -I$(libhfsdir) -DVANILLA_AUTOCONF
LDFLAGS=@LDFLAGS@ -L$(libhfsdir) -L$(libfiledir)
OBJS=mkisofs.o tree.o write.o hash.o rock.o multi.o \
joliet.o match.o name.o eltorito.o \
apple.o volume.o desktop.o mac_label.o
World: mkhybrid
Makefile: Makefile.in config.status
CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
config.status: configure
$(SHELL) config.status --recheck
configure: configure.in
cd $(srcdir) && autoconf
mkhybrid: Makefile $(OBJS) $(LIBHFS) $(LIBFILE)
$(CC) $(LDFLAGS) -o mkhybrid $(OBJS) $(LIBS)
mkisofs: Makefile $(OBJS) $(LIBHFS) $(LIBFILE)
$(CC) $(LDFLAGS) -o mkisofs $(OBJS) $(LIBS)
apple_driver: apple_driver.o
$(CC) $(LDFLAGS) -o apple_driver apple_driver.o
apple_driver.o: apple_driver.c mac_label.h
$(CC) -c $(CFLAGS) $(srcdir)/apple_driver.c
install: mkisofs mkisofs.8
[ -d $(bindir) ] || mkdir $(bindir)
[ -d $(mandir) ] || mkdir $(mandir)
$(INSTALL_PROGRAM) mkhybrid $(bindir)/mkhybrid
-$(INSTALL_DATA) $(srcdir)/mkhybrid.8 $(mandir)/mkhybrid.$(manext)
tree.o: tree.c mkisofs.h iso9660.h exclude.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/tree.c
write.o: write.c mkisofs.h iso9660.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/write.c
hash.o: hash.c mkisofs.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/hash.c
rock.o: rock.c mkisofs.h iso9660.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/rock.c
joliet.o: joliet.c mkisofs.h iso9660.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/joliet.c
match.o: match.c match.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/match.c
multi.o: multi.c iso9660.h mkisofs.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/multi.c
name.o: name.c iso9660.h mkisofs.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/name.c
mkisofs.o: mkisofs.c iso9660.h mkisofs.h exclude.h config.h Makefile $(LIBHFS) $(INCHFS) $(LIBFILE)
$(CC) -c $(CFLAGS) $(srcdir)/mkisofs.c
eltorito.o: eltorito.c iso9660.h mkisofs.h config.h Makefile
$(CC) -c $(CFLAGS) $(srcdir)/eltorito.c
apple.o: apple.c apple.h Makefile mkisofs.h
$(CC) -c $(CFLAGS) $(srcdir)/apple.c
volume.o: volume.c mkisofs.h config.h Makefile $(LIBHFS) $(INCHFS)
$(CC) -c $(CFLAGS) $(srcdir)/volume.c
desktop.o: desktop.c mkisofs.h config.h Makefile $(LIBHFS) $(INCHFS)
$(CC) -c $(CFLAGS) $(srcdir)/desktop.c
mac_label.o: mac_label.c mac_label.h Makefile config.h mkisofs.h
$(CC) -c $(CFLAGS) $(srcdir)/mac_label.c
$(LIBHFS) ::
cd $(libhfsdir) && $(MAKE) CC="$(CC)" COPTS="$(COPTS)" DEFINES="$(DEFINES)" RANLIB="$(RANLIB)"
$(LIBFILE) ::
cd $(libfiledir) && $(MAKE) CC="$(CC)" COPTS="$(COPTS)" DEFINES="$(DEFINES)" RANLIB="$(RANLIB)"
clean:
/bin/rm -f *.o core mkhybrid apple_driver *~ #*#
/bin/rm -f config.status config.log config.cache config.h
(cd diag/; make clean)
(cd $(libhfsdir); make clean)
(cd $(libfiledir); make clean)
#
# All .h files except for config.h get copied.
#
dist: Makefile
(mydir=`basename \`pwd\``;\
cd .. && tar -cvvf - $$mydir/README $$mydir/README.eltorito \
$$mydir/configure.in $$mydir/configure $$mydir/config.h.in \
$$mydir/Makefile.in $$mydir/make.com $$mydir/TODO \
$$mydir/COPYING $$mydir/ChangeLog $$mydir/*.8 $$mydir/*.c \
$$mydir/mkisofs.spec $$mydir/acconfig.h \
$$mydir/install-sh $$mydir/[d-z]*.h \
$$mydir/README.session $$mydir/diag/Makefile.in \
$$mydir/diag/README $$mydir/diag/*.c $$mydir/diag/isoinfo.8 \
$$mydir/include/*.h | gzip -9 > $${mydir}.tar.gz)

3
external/gpl2/mkhybrid/dist/README vendored Normal file
View File

@ -0,0 +1,3 @@
Please start by reading the file README.mkhybrid
[The original README file for mkisofs is README.mkisofs]

View File

@ -0,0 +1,97 @@
# Id: README.eltorito,v 1.1 2000/10/10 20:40:10 beck Exp
What is El Torito?
------------------
Simply put, El Torito is a specification that says how a cdrom should
be formatted such that you can directly boot from it.
The "El Torito" spec says that ANY cdrom drive should work (scsi/eide)
as long as the BIOS supports El Torito. So far this has only been
tested with EIDE drives because none of the scsi controllers that has
been tested so far appears to support El Torito. The motherboard
definately has to support El Torito. The ones that do let you choose
booting from HD, Floppy, Network or CDROM.
How To Make Bootable CDs
------------------------
For the x86 platform, many BIOS's have begun to support bootable CDs.
The standard my patches for mkisofs is based on is called "El Torito".
The "El Torito" standard works by making the CD drive appear, through BIOS
calls, to be a normal floppy drive. This way you simply put an floppy
size image (exactly 1440k for a 1.44 meg floppy) somewhere in the
iso fs. In the headers of the iso fs you place a pointer to this image.
The BIOS will then grab this image from the CD and for all purposes it
acts as if it were booting from the floppy drive. This allows a working
LILO boot disk, for example, to simply be used as is.
It is simple then to make a bootable CD. First create a file, say "boot.img"
which is an exact image of the boot floppu currently in use. There is
at least one HOWTO on making bootable floppies. If you have a bootable
floppy handy, you can make a boot image with the command
dd if=/dev/fd0 of=boot.img bs=10k count=144
assuming the floppy is in the A: drive.
Place this image somewhere in the hierarchy which will be the source
for the iso9660 filesystem. It is a good idea to put all boot related
files in their own directory ("boot/" under the root of the iso9660 fs,
for example), but this is not necessary.
One caveat - Your boot floppy MUST load any initial ramdisk via LILO,
not the kernel ramdisk driver! This is because once the linux kernel
starts up, the BIOS emulation of the CD as a floppy disk is circumvented
and will fail miserably. LILO will load the initial ramdisk using BIOS
disk calls, so the emulation works as designed.
The "El Torito" specification requires a "boot catalog" to be created as
ll.
This is a 2048 byte file which is of no interest except it is required.
My patches to mkisofs will cause it to automatically create the
boot catalog. You must specify where the boot catalog will go in the
iso9660 filesystem. Usually it is a good idea to put it the same place
as the boot image, and a name like "boot.catalog" seems appropriate.
So we have our boot image in the file "boot.image", and we are going to
put it in the directory "boot/" under the root of the iso9660 filesystem.
We will have the boot catalog go in the same directory with the name
"boot.catalog". The command to create the iso9660 fs in the file
bootcd.iso is then
mkisofs -b boot/boot.imh -c boot/boot.catalog -o bootcd.iso .
The -b option specifies the boot image to be used (note the path is
relative to the root of the iso9660 disc), and the -c option is
for the boot catalog file.
Now burn the CD and its ready to boot!
CAVEATS
-------
I don't think this will work with multisession CDs.
If your bootable floppy image needs to access the boot floppy, it has
to do so through BIOS calls. This is because if your O/S tries to talk to
the floppy directly it will bypass the "floppy emulation" the El Torito spec
creates through BIOS. For example, under Linux it is possible to
have an initial RAM disk loaded when the kernel starts up. If you let the
kernel try to read in the initial RAM disk from floppy, it will fail
miserably because Linux is not using BIOS calls to access the floppy drive.
Instead of seeing the floppy image on the CD, Linux will be looking at
the actually floppy drive.
The solution is to have the initial boot loader, called LILO, load your
initial RAM disk for you. LILO uses BIOS calls entirely for these
operations, so it can grab it from the emulated floppy image.
I don't think making a CD bootable renders it unreadable by non-El Torito
machines. The El Torito spec uses parts of the iso9660 filesystem which
were reserved for future use, so no existing code should care what it does.
Mkisofs currently stores identification records in the iso9660 filesystem
saying that the system is a x86 system. The El Torito spec also allows
one to write PowerPC or Mac id's instead. If you look at the code in write.c
you could figure out how to change what is written.

View File

@ -0,0 +1,66 @@
Making HFS bootable CDs
It *may* be possible to make the hybrid CD bootable on a Mac. As I do not
have easy access to a CD-R (nor a Mac) at the moment, I have not actually
created and written a bootable hybrid to CD - however, I *think* it will work!
A bootable HFS CD requires an Apple CD-ROM (or compatible) driver, a bootable
HFS partition and the necessary System, Finder, etc. files.
A driver can be obtained from any other Mac bootable CD-ROM using the
"apple_driver" utility (to make, type "make apple_driver"). This file can
then be used with the -boot-hfs-file option. See below for usage.
The HFS partition (i.e. the hybrid disk in our case) must contain a
suitable System Folder, again from another CD-ROM or disk.
For a partition to be bootable, it must have it's "boot block" set. The boot
block is in the first two blocks of a partition. For a non-bootable partition
the boot block is full of zeros. Normally, when a System file is copied to
partition on a Mac disk, the boot block is filled with a number of required
settings - unfortunately I don't know the full spec for the boot block ...
I'm guessing that this will work OK ...
Therefore, the utility "apple_driver" also extracts the boot block from the
first HFS partition it finds on the given CD-ROM and this is used for the
HFS partition created by mkhybrid.
To extract the driver and boot block:
apple_driver CDROM_device > HFS_driver_file
where CDROM_device is the device name used by the CD-ROM (e.g. /dev/cdrom)
The format of the HFS driver file is:
HFS CD Label Block 512 bytes
Driver Partition Map (for 2048 byte blocks) 512 bytes
Driver Partition Map (for 512 byte blocks) 512 bytes
Empty 512 bytes
Driver Partition N x 2048 bytes
HFS Partition Boot Block 1024 bytes
The Perl script "hdisk.pl" can be used to give a listing of what's on
a Mac CD. hdisk.pl is part of hfsutils.
A hybrid CD is made using the option "-boot-hfs-file" e.g.
mkhybrid -boot-hfs-file HFS_driver_file -o hfs.raw src_files/
The -boot-hfs-file implies the -hfs option.
PLEASE NOTE:
By using a driver from an Apple CD and copying Apple software to your CD,
you become liable to obey Apple Computer, Inc. Software License Agreements.
The driver code (both extracting the driver and creating partitions etc.
is based on code from "mkisofs 1.05 PLUS" by Andy Polyakov
<appro@fy.chalmers.se> (see http://fy.chalmers.se/~appro/mkisofs_plus.html)
Any comments, bug reports/fixes to the address below
James Pearson (j.pearson@ge.ucl.ac.uk)
18/5/98

View File

@ -0,0 +1,69 @@
Find file types by using a modified "magic" file
Based on file v3.22 by Ian F. Darwin (see libfile/LEGAL.NOTICE and
libfile/README.dist - File v3.22 can be found at many archive sites)
For each entry in the magic file, the "message" for the initial offset MUST
be 4 characters for the CREATOR and 4 characters for the TYPE - white space is
optional between them. Any other characters on this line are ignored.
Continuation lines (starting with a '>') are also ignored i.e. only the initial
offset lines are used.
e.g magic entry for a GIF file:
# off type test message
#
# GIF image
0 string GIF8 8BIM GIFf
>4 string 7a \b, version 8%s,
>4 string 9a \b, version 8%s,
>6 leshort >0 %hd x
>8 leshort >0 %hd,
#>10 byte &0x80 color mapped,
#>10 byte&0x07 =0x00 2 colors
#>10 byte&0x07 =0x01 4 colors
#>10 byte&0x07 =0x02 8 colors
#>10 byte&0x07 =0x03 16 colors
#>10 byte&0x07 =0x04 32 colors
#>10 byte&0x07 =0x05 64 colors
#>10 byte&0x07 =0x06 128 colors
#>10 byte&0x07 =0x07 256 colors
Just the "8BIM" "GIFf" will be used whatever the type of GIF file it is.
The continuation lines are used by the "file" command, but ignored by
mkhybrid. They could be left out completely.
The complete format of the magic file is given in the magic man page (magic.5).
See the file "magic" for other examples
Use with the -magic magic_file option, where magic_file is a file
described above.
The magic file can be used with the mapping file (option -map) - the order
these options appear on the command line is important. mkhybrid will try to
detect if the file is one of the Unix/Mac files (e.g. a CAP or Netatalk
file) first. If that fails, it will then use the magic and/or mapping
file e.g:
mkhybrid -o output.raw -map mapping -magic magic src_dir
The above will check filename extensions first, if that fails to set the
CREATOR/TYPE, the magic file will be used. To check the magic file
before the filename extensions, use:
mkhybrid -o output.raw -magic magic -map mapping src_dir
Using just a magic file - filename extensions will not be checked e.g:
mkhybrid -o output.raw -magic magic src_dir
For the magic method to work, each file must be opened and read twice
(once to find it's CREATOR/TYPE, and a second time to actually copy the
file to the CD image). Therefore the -magic option may significantly
increase processing time.
If a file's CREATOR/TYPE is not set via the magic and mapping matches,
then the file is given the default CREATOR/TYPE.

View File

@ -0,0 +1,108 @@
mkhybrid v1.12b5.1 - make ISO9660/HFS shared hybrid CD volume
HFS hybrid code Copyright (C) James Pearson 1997, 1998, 1999
libhfs code Copyright (C) 1996, 1997 Robert Leslie
libfile code Copyright (c) Ian F. Darwin 1986, 1987, 1989,
1990, 1991, 1992, 1994, 1995
mkisofs code Copyright 1993 Yggdrasil Computing, Incorporated
WARNING - this is Beta release code - please use with care!
If you find a bug, please report it to the address given below.
This code is based on a Beta release of mkisofs, so there may be
problems unrelated to my additions. However, I have found mkisofs
v1.12b5 to be very stable.
However, many people are using v1.12, so although it's called a "beta"
release, I would encourage people to use it ...
Most of the HFS features work fine, however, some are not fully tested.
These are marked as "Alpha" in the man page.
Please read the man page (mkhybrid.8, or mkhybrid_man.html) for information
on how to use mkhybrid.
Also see "ChangeLog.mkhybrid" for any minor changes/bug fixes
DESCRIPTION
mkhybrid is a pre-mastering utility that creates ISO9660/ROCKRIDGE/JOLIET/HFS
hybrid CDROM images. You will have to use some other CD-R package to write
the image to a CD.
INSTALLATION
To make/install, type "./configure", make any changes to the Makefile
and type "make"
This has been tested with gcc on SunOS 4.1.3 (see below), gcc on Linux
(Redhat v5.1), cc on IRIX 5.3/6.2 and gcc on Win95/WinNT4 using Cygnus'
cygwin (see README.win32)
If you are using SunOS 4.1.[34], then you need the following patches
to read CDs with associated files:
SunOS 4.1.3: Patch 101832-05
SunOS 4.1.3_U1: Patch 101833-02
SunOS 4.1.4: Patch 102583-02
EXAMPLES
To create a HFS hybrid CD with the Joliet and Rock Ridge extensions or
the source directory cd_dir:
% mkhybrid -o cd.iso -r -J -hfs cd_dir
To create a HFS hybrid CD from the source directory cd_dir that contains
Netatalk Apple/Unix files:
% mkhybrid -o cd.iso --netatalk cd_dir
To create a HFS hybrid CD from the source directory cd_dir, giving all files
CREATOR and TYPES based on just their filename extensions listed in the file
"mapping".:
% mkhybrid -o cd.iso -no-mac-files -map mapping cd_dir
To create a CD with the 'Apple Extensions to ISO9660', from the source
direcories cd_dir and another_dir. Files in all the known Apple/Unix format
are decoded and any other files are given CREATOR and TYPE based on their
magic number given in the file "magic":
% mkhybird -o cd.iso -magic -apple cd_dir another_dir
The following example puts different files on the CD that all have
the name README, but have different contents when seen as a
ISO9660/RockRidge Joliet or HFS CD.
Current directory contains
% ls -F
README.hfs README.joliet README.unix cd_dir/
The following command puts the contents of the directory "cd_dir" on the
CD along with the three README files - but only one will be seen from
each of the three filesystems:
% mkhybrid -o cd.iso -hfs -J -r \
-hide README.hfs -hide README.joliet \
-hide-joliet README.hfs -hide-joliet README.unix \
-hide-hfs README.joliet -hide-hfs README.unix \
README=README.hfs README=README.joliet README=README.unix \
cd_dir
i.e. the file README.hfs will be seen as README on the HFS CD and the
other two README files will be hidden. Similarly for the Joliet and
ISO9660/RockRidge CD.
There are probably all sorts of stange results possible with
combinations of the hide options ...
Any comments, bug reports/fixes to the address below.
Please state the version, platform and command line used when submitting
a bug report - the output from "-log-file -v" would help.
James Pearson (j.pearson@ge.ucl.ac.uk)

View File

@ -0,0 +1,145 @@
# Id: README.mkisofs,v 1.1 2000/10/10 20:40:11 beck Exp
Note:
This program requires a lot of virtual memory to run since it
builds all of the directories in memory. The exact requirements
depend upon a lot of things, but for Rock Ridge discs 12Mb would not
be unreasonable. Without RockRidge and without the translation
tables, the requirements would be considerably less.
The cdwrite utility is maintained separately from mkisofs by
yggdrasil.com. It is enclosed here as a convenience, since the two programs
are often useful together.
*****************************
Notes for version 1.12
Joliet support is now complete. See the -J option.
The file scanning code is much improved - mkisofs can use multiple
sources of input files and merge them together to form the output
image. In addition, each source can be grafted at any point in the
iso9660 image.
The image writing code has been cleaned up to make it much easier
to add custom extensions.
The ADD_FILES feature has been removed as it didn't work well,
and it was hard to figure out. The recent rearrangements in the
file scanning code would tend to solve these issues.
*****************************
Notes for version 1.11
There is a feature which can be optionally compiled into
mkisofs that allows you to merge arbitrary directory trees into the
image you are creating. You need to compile with -DADD_FILES for my
changes to take effect. Thanks to Ross Biro biro@yggdrasil.com.
*****************************
Notes for version 1.10b1
Big news is that multi-session capability is very close to being
done. There is still a missing interface to cdwrite that is
used to determine the next writable address and the sector number
of the last existing session. Until we get the interface to cdwrite
done, this is a beta version.
Bug involving DST fixed (dates are always calculated, since some
files may be DST and other ones would not be).
Unfortunately the notes on some of the small patches got lost.
*****************************
Notes for version 1.06
Jan-Piet Mens <jpm@mens.de> added support for the '-m' switch. This
allows exclusion of shell-style globs from the CDROM.
See manual mkisofs.8 for more information.
*****************************
Notes for version 1.05
Added support for '-r' switch. This is very similar to -R for
Rock Ridge, but echos of the development environment are removed
(i.e. uid/gid set to 0, and permissions of the files are canonicalized).
Useful in applications where a distribution medium is being produced.
*****************************
Notes for version 1.04
No notes for 1.04.
*****************************
Notes for version 1.03
No notes for 1.03.
*****************************
Notes for version 1.02.
Minor bugfixes here and there. Support for compiled in
defaults for many of the text fields in the volume header are now
present, and there is also support for a file ".mkisofsrc" that can
also read settings for these parameters.
A short script "Configure" was added to allow us to set up special
compile options that depend upon the system that we are running on.
This should help stamp out the sphaghetti-isms that were starting to grow
up in various places in the code.
You should get more meaningful error messages if you run out of
memory.
*****************************
Notes for version 1.1.
The big news is that SUSP CE entries are now generated for
extremely long filenames and symlink names. This virtually guarantees
that there is no limit (OK, well, about 600Mb) for file name lengths.
I have tested this as well as I can, and it seems to work with linux.
This would only be used very rarely I suspect.
Also, I believe that support for VMS is done. You must be
careful, because only Stream-LF and FIxed length record files can be
recorded. The rest are rejected with error messages. Perhaps I am
being too severe here.
There is a bugfix in the sorting of entries on the disc - we
need to stop comparing once we reach the ';' character.
There are four new options -z -d -D -l -V. Some of these tell
mkisofs to relax some of the iso9660 restrictions, and many systems
apparently do not really seem to mind. Use these with caution.
Some diagnostic programs to scan disc images are in the diag
directory. These are not as portable as mkisofs, and may have some
bugs. Still they are useful because they can check for bugs that I might
have introduced as I add new features.
*****************************
Notes for version 1.0.
In version 1.0, the date fields in the TF fields were fixed -
previously I was storing st_ctime as the file creation time instead of
the file attribute change time. Thanks to Peter van der Veen for
pointing this out. I have one slight concern with this change,
however. The Young Minds software is definitely supplying 3 dates
(creation, modification and access), and I would strongly suspect that
they are incorrectly putting the file attribute change time in the
file creation slot. I would be curious to see how the different RRIP
filesystems treat this. Anyway, this is something to keep in the back
of your mind.
The symlink handling was not quite correct in 0.99 - this is
now fixed. Only some systems seemed to have been affected by this bug.
A command line option is now present to allow you to
specifically exclude certain files from the distribution.
The case where you do not have permissions to read a directory
is now handled better by mkisofs. The directory that cannot be opened
is converted into a zero-length file, and processing continues normally.
A few portability things have been fixed (hopefully).

View File

@ -0,0 +1,48 @@
# Id: README.session,v 1.1 2000/10/10 20:40:11 beck Exp
This release of mkisofs has basic support completed for
multiple sessions. However, we still need some interaction
between cdrecord and mkisofs for this to work correctly. This is needed as
only cdrecord knows the different ways to gather these numbers for all
different drives. It may be that future versions of mkisofs will include
the needed support for MMC compliant drives.
There are a few new options to mkisofs to allow for this.
The first one is "-M /dev/scd0", and is used so that mkisofs can examine
the entirety of the previous image so that it can figure out what additional
files need to be written in the new session. Note that there are operating
systems that don't allow to read from CD drives with a sector size
of 2048 bytes per sector. To use mkisofs on such an operating system, you
will need a version of mkisofs that includes the SCSI transport library
from cdrecord. Simply use the dev= syntax from cdrecord with -M in
such a case. It will tell mkisofs to use the SCSI transport library to
read from the CD instead of using the standard read() OS interface.
There is also a temporary hack in mkisofs in the form of a '-C' option.
The -C option takes two numbers as input, which are delimited by commas.
For example, you could specify "-C 1000,1020", but you should never just
make up numbers to use here. These numbers are determined from cdrecord.
Note that if you use -C and omit -M, it effectively means that
you are writing a new session, starting at a non-zero block number,
and you are effectively ignoring all of the previous session contents.
When this session is sent to the writer, the new session effectively
"erases" the previous session.
In practice you should be able to do something like:
mkisofs [other options] -C `cdrecord dev=b,t,l -msinfo` \
-M /dev/cdblkdev
Replace 'b,t,l' by the aproriate numbers for SCSIbus, target and lun
of your drive.
Note: As of the 1.12b5 release, the multi-session technology has
matured quite significantly. It is entirely possible that bugs
exists, or that further tweaks will be required somewhere along the
way to get things working correctly. The data gathering mode of
cdrecord has been tested, and I believe it works correctly. Caveat
Emptor.
[Mar 1, 1999].

View File

@ -0,0 +1,38 @@
mkhybrid can be compiled on Win9X/NT4 using Cygnus' cygwin
available from:
http://sourceware.cygnus.com/cygwin/
To build, start a "bash" shell (open a DOS/Command window, cd to the required
directory and type "bash"), and type "./configure" and "make"
A pre-compiled current Win32 binary is available from:
ftp://ftp.ge.ucl.ac.uk/pub/mkhfs/win32
To use the pre-compiled binary, extract the files from the Zip archive, put
the files cygwin1.dll, mount.exe and mkhybrid.exe in your WINDOWS directory
and from a Command/MS-DOS window type mkhybrid for usage (also see
mkhybrid_man.html).
mkhybrid is a Unix command line utility and knows nothing about DOS/WIN.
Therefore all directory names are given in Unix format (i.e. use '/' for a
directory separator, not '\'). To access files on another disk (i.e.
floppy, CDROM and network disk), you need to use the supplied "mount"
command e.g.
mount a: /a
mount d: /cdrom
i.e. files on the floppy disk are accessed as being in directory /a and
files on the CDROM are accessed as /cdrom (assuming your CDROM is drive d:)
e.g. the following command creates a CD image in the current directory
using a source directories on the CDROM drive, a sub-directory and the
floppy drive:
mkhybrid -o hfs.iso -h -J -r /cdrom/subdir dir1 /a
Please note: Starting with v1.12b5.0 the Win32 executable uses the b20.1
version of the cygwin DLL. If you are using an earlier version of mkhybrid,
then you will need this DLL as well.

6
external/gpl2/mkhybrid/dist/TODO vendored Normal file
View File

@ -0,0 +1,6 @@
# Id: TODO,v 1.1 2000/10/10 20:40:11 beck Exp
1) Finish multiple paths. Update nlink count on directories if it is
different than what stat returned. Save the nlink count that we store in
the rock ridge attributes so know when we don't have to adjust it.

View File

@ -0,0 +1,7 @@
/* Definitions for mkisofs processed by autoheader. */
#undef NODIR /* none -- don't make numbered backup files */
/* This shows us where to find the major()/minor() macros */
#undef MAJOR_IN_MKDEV
#undef MAJOR_IN_SYSMACROS

1813
external/gpl2/mkhybrid/dist/apple.c vendored Normal file

File diff suppressed because it is too large Load Diff

371
external/gpl2/mkhybrid/dist/apple.h vendored Normal file
View File

@ -0,0 +1,371 @@
/*
** apple.h: cut down macfile.h from CAP distribution
*/
#ifndef _APPLE_H
#include <sys/param.h>
#include <mactypes.h>
#ifdef __sgi /* bit of a hack ... need to investigate further */
#define __svr4__ /* maybe there's a "configure" solution ? */
#endif /* __sgi */
#ifdef __svr4__
#include <sys/statvfs.h>
#else
#if defined(__FreeBSD__) || defined(__bsdi__) || defined(__OpenBSD__)
#include <sys/mount.h>
#else
#if defined(_IBMR2)
#include <sys/statfs.h>
#else
#include <sys/vfs.h>
#endif /* _IBMR2 */
#endif /* __FreeBSD__ || __bsdi__ */
#endif /* __svr4__ */
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#ifdef _WIN32_TEST
#undef UNICODE
#include <windows.h>
#endif /* _WIN32 */
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif /* MIN */
#define CT_SIZE 4 /* Size of type/creator */
#define NUMMAP 512 /* initial number of maps */
#define BLANK " " /* blank type/creator */
#define DEFMATCH "*" /* default mapping extension */
typedef struct {
char *extn; /* filename extension */
int elen; /* length of extension */
char type[CT_SIZE+1]; /* extension type */
char creator[CT_SIZE+1]; /* extension creator */
unsigned short fdflags; /* finder flags */
} afpmap;
/* from "data.h" - libhfs routines */
unsigned long d_toutime(unsigned long);
long d_getl(unsigned char *);
short d_getw(unsigned char *);
#include "libfile/proto.h"
/****** TYPE_CAP ******/
/*
* taken from the CAP distribution:
* macfile.h - header file with Macintosh file definitions
*
* AppleTalk package for UNIX (4.2 BSD).
*
* Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the
* City of New York.
*
* Edit History:
*
* Sept 1987 Created by Charlie
*
*/
#ifndef USE_MAC_DATES
#define USE_MAC_DATES
#endif /* USE_MAC_DATES */
typedef unsigned char byte;
typedef char sbyte;
typedef unsigned short word;
typedef short sword;
typedef unsigned int dword;
typedef int sdword;
/*
typedef unsigned long dword;
typedef long sdword;
*/
#define MAXCLEN 199 /* max size of a comment string */
#define FINFOLEN 32 /* Finder info is 32 bytes */
#define MAXMACFLEN 31 /* max Mac file name length */
typedef struct {
/* base finder information */
byte fdType[4]; /* File type [4]*/
byte fdCreator[4]; /* File creator [8]*/
word fdFlags; /* Finder flags [10]*/
word fdLocation[2]; /* File's location [14] */
word fdFldr; /* File's window [16] */
/* extended finder information */
word fdIconID; /* Icon ID [18] */
word fdUnused[4]; /* Unused [26] */
word fdComment; /* Comment ID [28] */
dword fdPutAway; /* Home directory ID [32] */
word fi_attr; /* attributes */
#define FI_MAGIC1 255
byte fi_magic1; /* was: length of comment */
#define FI_VERSION 0x10 /* version major 1, minor 0 */
/* if we have more than 8 versions wer're */
/* doiong something wrong anyway */
byte fi_version; /* version number */
#define FI_MAGIC 0xda
byte fi_magic; /* magic word check */
byte fi_bitmap; /* bitmap of included info */
#define FI_BM_SHORTFILENAME 0x1 /* is this included? */
#define FI_BM_MACINTOSHFILENAME 0x2 /* is this included? */
byte fi_shortfilename[12+1]; /* possible short file name */
byte fi_macfilename[32+1]; /* possible macintosh file name */
byte fi_comln; /* comment length */
byte fi_comnt[MAXCLEN+1]; /* comment string */
#ifdef USE_MAC_DATES
byte fi_datemagic; /* sanity check */
#define FI_MDATE 0x01 /* mtime & utime are valid */
#define FI_CDATE 0x02 /* ctime is valid */
byte fi_datevalid; /* validity flags */
byte fi_ctime[4]; /* mac file create time */
byte fi_mtime[4]; /* mac file modify time */
byte fi_utime[4]; /* (real) time mtime was set */
#endif /* USE_MAC_DATES */
} FileInfo;
/* Atribute flags */
#define FI_ATTR_SETCLEAR 0x8000 /* set-clear attributes */
#define FI_ATTR_READONLY 0x20 /* file is read-only */
#define FI_ATTR_ROPEN 0x10 /* resource fork in use */
#define FI_ATTR_DOPEN 0x80 /* data fork in use */
#define FI_ATTR_MUSER 0x2 /* multi-user */
#define FI_ATTR_INVISIBLE 0x1 /* invisible */
/**** MAC STUFF *****/
/* Flags */
#define FNDR_fOnDesk 0x1
#define FNDR_fHasBundle 0x2000
#define FNDR_fInvisible 0x4000
/* locations */
#define FNDR_fTrash -3 /* File in Trash */
#define FNDR_fDesktop -2 /* File on desktop */
#define FNDR_fDisk 0 /* File in disk window */
/****** TYPE_ESHARE ******/
/*
** Information supplied by Jens-Uwe Mager (jum@helios.de)
*/
#define ES_VERSION 0x0102
#define ES_MAGIC 0x3681093
#define ES_INFOLEN 32
#define ES_INFO_SIZE 512
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef struct {
uint32 magic;
uint32 serno; /* written only, never read */
uint16 version;
uint16 attr; /* invisible... */
uint16 openMax; /* max number of opens */
uint16 filler0;
uint32 backupCleared; /* time backup bit cleared */
uint32 id; /* dir/file id */
uint32 createTime; /* unix format */
uint32 backupTime; /* unix format */
/* uint8 finderInfo[INFOLEN];*/
/* base finder information (compatible with CAP) */
uint8 fdType[4]; /* File type [4]*/
uint8 fdCreator[4]; /* File creator [8]*/
uint16 fdFlags; /* Finder flags [10]*/
uint16 fdLocation[2]; /* File's location [14] */
uint16 fdFldr; /* File's window [16] */
/* extended finder information */
uint16 fdIconID; /* Icon ID [18] */
uint16 fdUnused[4]; /* Unused [26] */
uint16 fdComment; /* Comment ID [28] */
uint32 fdPutAway; /* Home directory ID [32] */
} es_FileInfo;
/****** TYPE_USHARE ******/
/* similar to the EtherShare layout, but the finder info stuff is different
info provided by: Phil Sylvester <psylvstr@interaccess.com> */
typedef struct {
uint8 fdType[4]; /* File type [4]*/
uint8 fdCreator[4]; /* File creator [8]*/
uint16 fdFlags; /* Finder flags [10]*/
uint8 unknown1[22]; /* ignore [32] */
uint32 btime; /* mac file backup time [36]*/
uint8 unknown2[4]; /* ignore [40] */
uint32 ctime; /* mac file create time [44]*/
uint8 unknown3[8]; /* ignore [52] */
uint32 mtime; /* mac file modify time [56]*/
uint8 unknown4[456]; /* ignore [512] */
} us_FileInfo;
/****** TYPE_DOUBLE, TYPE_SINGLE ******/
/*
** Taken from cvt2cap (c) May 1988, Paul Campbell
*/
typedef struct {
dword id;
dword offset;
dword length;
} a_entry;
typedef struct {
dword magic;
dword version;
char home[16];
word nentries;
a_entry entries[1];
} a_hdr;
#define A_HDR_SIZE 26
#define A_ENTRY_SIZE sizeof(a_entry)
#define A_VERSION 0x00010000
#define APPLE_SINGLE 0x00051600
#define APPLE_DOUBLE 0x00051607
#define ID_DATA 1
#define ID_RESOURCE 2
#define ID_NAME 3
#define ID_FINDER 9
/****** TYPE_MACBIN ******/
/*
** taken from capit.c by Nigel Perry, np@doc.ic.ac.uk which is adapted
** from unmacbin by John M. Sellens, jmsellens@watdragon.uwaterloo.ca
*/
#define MB_NAMELEN 63 /* maximum legal Mac file name length */
#define MB_SIZE 128
/* Format of a bin file:
A bin file is composed of 128 byte blocks. The first block is the
info_header (see below). Then comes the data fork, null padded to fill the
last block. Then comes the resource fork, padded to fill the last block. A
proposal to follow with the text of the Get Info box has not been implemented,
to the best of my knowledge. Version, zero1 and zero2 are what the receiving
program looks at to determine if a MacBinary transfer is being initiated.
*/
typedef struct { /* info file header (128 bytes). Unfortunately, these
longs don't align to word boundaries */
byte version; /* there is only a version 0 at this time */
byte nlen; /* Length of filename. */
byte name[MB_NAMELEN]; /* Filename */
byte type[4]; /* File type. */
byte auth[4]; /* File creator. */
byte flags; /* file flags: LkIvBnSyBzByChIt */
byte zero1; /* Locked, Invisible,Bundle, System */
/* Bozo, Busy, Changed, Init */
byte icon_vert[2]; /* Vertical icon position within window */
byte icon_horiz[2]; /* Horizontal icon postion in window */
byte window_id[2]; /* Window or folder ID. */
byte protect; /* = 1 for protected file, 0 otherwise */
byte zero2;
byte dflen[4]; /* Data Fork length (bytes) - most sig. */
byte rflen[4]; /* Resource Fork length byte first */
byte cdate[4]; /* File's creation date. */
byte mdate[4]; /* File's "last modified" date. */
byte ilen[2]; /* GetInfo message length */
byte flags2; /* Finder flags, bits 0-7 */
byte unused[14];
byte packlen[4]; /* length of total files when unpacked */
byte headlen[2]; /* length of secondary header */
byte uploadvers; /* Version of MacBinary II that the uploading program is written for */
byte readvers; /* Minimum MacBinary II version needed to read this file */
byte crc[2]; /* CRC of the previous 124 bytes */
byte padding[2]; /* two trailing unused bytes */
} mb_info;
/*
** An array useful for CRC calculations that use 0x1021 as the "seed"
** taken from mcvert.c modified by Jim Van Verth.
*/
static unsigned short mb_magic[] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/****** TYPE_FE ******/
/* Information provided by Mark Weinstein <mrwesq@earthlink.net> */
typedef struct {
byte nlen;
byte name[31];
byte type[4];
byte creator[4];
byte flags[2];
byte location[4];
byte fldr[2];
byte xinfo[16];
byte cdate[4];
byte mdate[4];
byte bdate[4];
byte fileid[4];
byte sname[8];
byte ext[3];
byte pad;
} fe_info;
#define FE_SIZE 92
/****** TYPE_SGI ******/
typedef struct {
char unknown1[8];
char type[4];
char creator[4];
char unknown2[238];
char name[32];
char unknown3[14];
} sgi_info;
#define SGI_SIZE 300
#define _APPLE_H
#endif /* _APPLE_H */

View File

@ -0,0 +1,35 @@
/* apple_proto.h */
/* $OpenBSD: apple_proto.h,v 1.1 2008/03/08 15:36:12 espie Exp $ */
/*
* Copyright (c) 2008 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef APPLE_PROTO_H
#define APPLE_PROTO_H
struct directory_entry;
struct hfs_info;
extern void hfs_init(char *, unsigned short, int, int, unsigned int);
extern void clean_hfs(void);
extern int hfs_exclude(char *);
extern int get_hfs_rname(char *, char *, char *);
extern int get_hfs_dir(char *, char *, struct directory_entry *);
extern int get_hfs_info(char *, char *, struct directory_entry *);
extern void print_hfs_info(struct directory_entry *);
extern void delete_rsrc_ent(struct directory_entry *);
extern void del_hfs_info(struct hfs_info *);
#endif

67
external/gpl2/mkhybrid/dist/config.h vendored Normal file
View File

@ -0,0 +1,67 @@
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
/* #undef MAJOR_IN_MKDEV */
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
/* #undef MAJOR_IN_SYSMACROS */
/* #undef NODIR */ /* none -- don't make numbered backup files */
/* This shows us where to find the major()/minor() macros */
/* #undef MAJOR_IN_MKDEV */
/* #undef MAJOR_IN_SYSMACROS */
/* Define if you have the memmove function. */
#define HAVE_MEMMOVE 1
/* Define if you have the sbrk function. */
#define HAVE_SBRK 1
/* Define if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
/* Define if you have the <malloc.h> header file. */
/* #undef HAVE_MALLOC_H */
/* Define if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/dir.h> header file. */
/* #undef HAVE_SYS_DIR_H */
/* Define if you have the <sys/fcntl.h> header file. */
#define HAVE_SYS_FCNTL_H 1
/* Define if you have the <sys/mkdev.h> header file. */
/* #undef HAVE_SYS_MKDEV_H */
/* Define if you have the <sys/ndir.h> header file. */
/* #undef HAVE_SYS_NDIR_H */
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/sysmacros.h> header file. */
/* #undef HAVE_SYS_SYSMACROS_H */
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
#define HAVE_FLOCK 1

64
external/gpl2/mkhybrid/dist/config.h.in vendored Normal file
View File

@ -0,0 +1,64 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
#undef MAJOR_IN_MKDEV
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS
#undef NODIR /* none -- don't make numbered backup files */
/* This shows us where to find the major()/minor() macros */
#undef MAJOR_IN_MKDEV
#undef MAJOR_IN_SYSMACROS
/* Define if you have the memmove function. */
#undef HAVE_MEMMOVE
/* Define if you have the sbrk function. */
#undef HAVE_SBRK
/* Define if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <ndir.h> header file. */
#undef HAVE_NDIR_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/dir.h> header file. */
#undef HAVE_SYS_DIR_H
/* Define if you have the <sys/fcntl.h> header file. */
#undef HAVE_SYS_FCNTL_H
/* Define if you have the <sys/mkdev.h> header file. */
#undef HAVE_SYS_MKDEV_H
/* Define if you have the <sys/ndir.h> header file. */
#undef HAVE_SYS_NDIR_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/sysmacros.h> header file. */
#undef HAVE_SYS_SYSMACROS_H
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

1662
external/gpl2/mkhybrid/dist/configure vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
dnl Id: configure.in,v 1.1 2000/10/10 20:40:13 beck Exp
dnl Modified for mkhybrid James Pearson 22/1/98
dnl Process this file with autoconf to produce a configure script.
AC_INIT(mkisofs.c)
AC_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_CONST
AC_HEADER_MAJOR
AC_HEADER_DIRENT
if test -z "$ac_header_dirent"; then
AC_DEFINE(NODIR)
fi
AC_CHECK_FUNCS(memmove sbrk strdup)
AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h)
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_OUTPUT(Makefile diag/Makefile)

87
external/gpl2/mkhybrid/dist/defaults.h vendored Normal file
View File

@ -0,0 +1,87 @@
/*
* Header file defaults.h - assorted default values for character strings in
* the volume descriptor.
*
* Id: defaults.h,v 1.1 2000/10/10 20:40:13 beck Exp
*/
#define PREPARER_DEFAULT NULL
#define PUBLISHER_DEFAULT NULL
#ifndef APPID_DEFAULT
#define APPID_DEFAULT "MKHYBRID ISO9660/HFS FILESYSTEM BUILDER"
#endif
#define COPYRIGHT_DEFAULT NULL
#define BIBLIO_DEFAULT NULL
#define ABSTRACT_DEFAULT NULL
#define VOLSET_ID_DEFAULT NULL
#define VOLUME_ID_DEFAULT "CDROM"
#define BOOT_CATALOG_DEFAULT "boot.catalog"
#define BOOT_IMAGE_DEFAULT NULL
#ifdef APPLE_HYB
#define DEFTYPE "TEXT" /* default Apple TYPE */
#define DEFCREATOR "unix" /* default Apple CREATOR */
#endif /* APPLE_HYB */
#ifdef __QNX__
#define SYSTEM_ID_DEFAULT "QNX"
#endif
#ifdef __osf__
#define SYSTEM_ID_DEFAULT "OSF"
#endif
#ifdef __sun
#ifdef __SVR4
#define SYSTEM_ID_DEFAULT "Solaris"
#else
#define SYSTEM_ID_DEFAULT "SunOS"
#endif
#endif
#ifdef __hpux
#define SYSTEM_ID_DEFAULT "HP-UX"
#endif
#ifdef __sgi
#define SYSTEM_ID_DEFAULT "SGI"
#endif
#ifdef _AIX
#define SYSTEM_ID_DEFAULT "AIX"
#endif
#ifdef _WIN
#define SYSTEM_ID_DEFAULT "Win32"
#endif /* _WIN */
#ifdef __FreeBSD__
#define SYSTEM_ID_DEFAULT "FreeBSD"
#endif
#ifdef __OpenBSD__
#define SYSTEM_ID_DEFAULT "OpenBSD"
#endif
#ifdef __NetBSD__
#define SYSTEM_ID_DEFAULT "NetBSD"
#endif
#ifdef __linux__
#define SYSTEM_ID_DEFAULT "LINUX"
#endif
#ifdef __FreeBSD__
#define SYSTEM_ID_DEFAULT "FreeBSD"
#endif
#ifdef __OpenBSD__
#define SYSTEM_ID_DEFAULT "OpenBSD"
#endif
#ifdef __NetBSD__
#define SYSTEM_ID_DEFAULT "NetBSD"
#endif
#ifndef SYSTEM_ID_DEFAULT
#define SYSTEM_ID_DEFAULT "Unknown"
#endif

134
external/gpl2/mkhybrid/dist/desktop.c vendored Normal file
View File

@ -0,0 +1,134 @@
/*
** make_desktop: create "Desktop DB" and "Desktop DF" files.
**
** These are set up to prevent the Mac "rebuilding the desktop"
** when the CD is inserted ???
**
** I don't know if these files should be populated, but I've just
** created these files in their initial states:
**
** Desktop DB: Initial size == volume's clump size
** first block contents found by using od ...
** rest of file seems to be padding
** No resource fork
**
** Desktop DF: Empty
**
** If the files already exist, then set correct type/creator/flags
**
** James Pearson 11/8/97
** Adapted from mkhfs routines for mkhybrid
*/
#ifdef APPLE_HYB
#include <string.h>
#include <err.h>
#include "hfs.h"
#define DB "Desktop DB"
#define DBFC "DMGR"
#define DBT "BTFL"
#define DF "Desktop DF"
#define DFT "DTFL"
/* from "data.h" - libhfs routines */
void d_putw(unsigned char *, short);
void d_putl(unsigned char *, long);
extern hce_mem *hce; /* libhfs/mkisofs extras */
int
make_desktop(hfsvol *vol, int end)
/* hfsvol *vol; Mac volume */
{
hfsfile *hfp; /* Mac file */
hfsdirent ent; /* Mac finderinfo */
unsigned short clps; /* clump size */
unsigned short blks; /* blocks in a clump */
unsigned char *blk; /* user data */
/* set up default directory entries - not all these fields
are needed, but we'll set them up anyway ... */
ent.rsize = 0; /* resource size == 0 */
strcpy(ent.creator, DBFC); /* creator */
strcpy(ent.type, DBT); /* type */
ent.crdate = ent.mddate = time(0); /* date is now */
ent.fdflags = HFS_FNDR_ISINVISIBLE; /* invisible files */
/* clear the DB file */
blk = hce->hfs_ce + hce->hfs_ce_size*HFS_BLOCKSZ;
blks = hce->hfs_dt_size;
clps = blks*HFS_BLOCKSZ;
memset(blk, 0, clps);
/* create "Desktop DB" (if it doesn't exist) */
if(hfs_create(vol, DB, ent.type, ent.creator) == 0)
{
/* DB file size from hce_mem info */
/* set up "Desktop DB" data - following found by od'ing
the "Desktop DB" file */
d_putw(blk+8, 0x100);
d_putw(blk+10, 0x3);
d_putw(blk+32, 0x200);
d_putw(blk+34, 0x25);
d_putl(blk+36, blks);
d_putl(blk+40, blks - 1);
d_putw(blk+48, clps);
d_putw(blk+50, 0xff);
d_putw(blk+120, 0x20a);
d_putw(blk+122, 0x100);
d_putw(blk+248, 0x8000);
d_putl(blk+504, 0x1f800f8);
d_putl(blk+508, 0x78000e);
/* entries for "Desktop DB" */
ent.dsize = clps; /* size = clump size */
/* open file */
if((hfp = hfs_open(vol, DB)) == 0)
err(1, hfs_error);
/* "write" file */
write_fork(hfp, clps);
/* set DB file attributes */
if (hfs_fsetattr(hfp, &ent) < 0)
err(1, hfs_error);
/* find the real start of the file */
end += hce->hfs_ce_size;
/* close DB file */
if (hfs_close(hfp, end, 0) < 0)
err(1, hfs_error);
}
else
{
/* if it already exists, then make sure it has the correct
type/creator and flags */
if(hfs_setattr(vol, DB, &ent) < 0)
err(1, hfs_error);
}
/* setup "Desktop DF" file as an empty file */
strcpy(ent.type, DFT); /* type */
ent.dsize = 0; /* empty */
/* create DF file (if it doesn't exist) - no need to open it */
hfs_create(vol, DF, ent.type, ent.creator);
/* set DB file attributes */
if (hfs_setattr(vol, DF, &ent) < 0)
err(1, hfs_error);
return 0;
}
#endif /* APPLE_HYB */

316
external/gpl2/mkhybrid/dist/eltorito.c vendored Normal file
View File

@ -0,0 +1,316 @@
/*
* Program eltorito.c - Handle El Torito specific extensions to iso9660.
*
Written by Michael Fulbright <msf@redhat.com> (1996).
Copyright 1996 RedHat Software, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include "config.h"
#include "mkisofs.h"
#include "iso9660.h"
/* used by Win32 for opening binary file - not used by Unix */
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#undef MIN
#define MIN(a, b) (((a) < (b))? (a): (b))
static struct eltorito_validation_entry valid_desc;
static struct eltorito_defaultboot_entry default_desc;
static struct eltorito_boot_descriptor gboot_desc;
static int tvd_write __PR((FILE * outfile));
/*
* Check for presence of boot catalog. If it does not exist then make it
*/
void FDECL1(init_boot_catalog, const char *, path)
{
int bcat;
char * bootpath; /* filename of boot catalog */
char * buf;
struct stat statbuf;
bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
strcpy(bootpath, path);
if (bootpath[strlen(bootpath)-1] != '/')
{
strcat(bootpath,"/");
}
strcat(bootpath, boot_catalog);
/*
* check for the file existing
*/
#ifdef DEBUG_TORITO
fprintf(stderr,"Looking for boot catalog file %s\n",bootpath);
#endif
if (!stat_filter(bootpath, &statbuf))
{
/*
* make sure its big enough to hold what we want
*/
if (statbuf.st_size == 2048)
{
/*
* printf("Boot catalog exists, so we do nothing\n");
*/
free(bootpath);
return;
}
else
{
fprintf(stderr, "A boot catalog exists and appears corrupted.\n");
fprintf(stderr, "Please check the following file: %s.\n",bootpath);
fprintf(stderr, "This file must be removed before a bootable CD can be done.\n");
free(bootpath);
exit(1);
}
}
/*
* file does not exist, so we create it
* make it one CD sector long
*/
bcat = open(bootpath, O_WRONLY | O_CREAT | O_BINARY, S_IROTH | S_IRGRP | S_IRWXU );
if (bcat == -1)
{
fprintf(stderr, "Error creating boot catalog, exiting...\n");
perror("");
exit(1);
}
buf = (char *) e_malloc( 2048 );
write(bcat, buf, 2048);
close(bcat);
free(bootpath);
} /* init_boot_catalog(... */
void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
{
int bootcat;
int checksum;
unsigned char * checksum_ptr;
struct directory_entry * de;
struct directory_entry * de2;
int i;
int nsectors;
memset(boot_desc, 0, sizeof(*boot_desc));
boot_desc->id[0] = 0;
memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID) - 1);
boot_desc->version[0] = 1;
memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));
/*
* search from root of iso fs to find boot catalog
*/
de2 = search_tree_file(root, boot_catalog);
if (!de2)
{
fprintf(stderr,"Uh oh, I cant find the boot catalog!\n");
exit(1);
}
set_731(boot_desc->bootcat_ptr,
(unsigned int) get_733(de2->isorec.extent));
/*
* now adjust boot catalog
* lets find boot image first
*/
de=search_tree_file(root, boot_image);
if (!de)
{
fprintf(stderr,"Uh oh, I cant find the boot image!\n");
exit(1);
}
/*
* we have the boot image, so write boot catalog information
* Next we write out the primary descriptor for the disc
*/
memset(&valid_desc, 0, sizeof(valid_desc));
valid_desc.headerid[0] = 1;
valid_desc.arch[0] = EL_TORITO_ARCH_x86;
/*
* we'll shove start of publisher id into id field, may get truncated
* but who really reads this stuff!
*/
if (publisher)
memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher)));
valid_desc.key1[0] = 0x55;
valid_desc.key2[0] = 0xAA;
/*
* compute the checksum
*/
checksum=0;
checksum_ptr = (unsigned char *) &valid_desc;
for (i=0; i<sizeof(valid_desc); i+=2)
{
/*
* skip adding in ckecksum word, since we dont have it yet!
*/
if (i == 28)
{
continue;
}
checksum += (unsigned int)checksum_ptr[i];
checksum += ((unsigned int)checksum_ptr[i+1])*256;
}
/*
* now find out the real checksum
*/
checksum = -checksum;
set_721(valid_desc.cksum, (unsigned int) checksum);
/*
* now make the initial/default entry for boot catalog
*/
memset(&default_desc, 0, sizeof(default_desc));
default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
/*
* use default BIOS loadpnt
*/
set_721(default_desc.loadseg, 0);
default_desc.arch[0] = EL_TORITO_ARCH_x86;
/*
* figure out size of boot image in sectors, for now hard code to
* assume 512 bytes/sector on a bootable floppy
*/
nsectors = ((de->size + 511) & ~(511))/512;
#ifdef APPLE_HYB
/* NON-HFS change */
if (verbose > 0 )
#endif /* APPLE_HYB */
fprintf(stderr, "\nSize of boot image is %d sectors -> ", nsectors);
/*
* choose size of emulated floppy based on boot image size
*/
if (nsectors == 2880 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
#ifdef APPLE_HYB
/* NON-HFS change */
if (verbose > 0 )
#endif /* APPLE_HYB */
fprintf(stderr, "Emulating a 1.44 meg floppy\n");
}
else if (nsectors == 5760 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
#ifdef APPLE_HYB
/* NON-HFS change */
if (verbose > 0 )
#endif /* APPLE_HYB */
fprintf(stderr,"Emulating a 2.88 meg floppy\n");
}
else if (nsectors == 2400 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
#ifdef APPLE_HYB
/* NON-HFS change */
if (verbose > 0 )
#endif /* APPLE_HYB */
fprintf(stderr,"Emulating a 1.2 meg floppy\n");
}
else if (nsectors == 4 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL;
#ifdef APPLE_HYB
/* NON-HFS change */
if (verbose > 0 )
#endif /* APPLE_HYB */
fprintf(stderr,"No-emulation CD boot sector\n");
}
else
{
fprintf(stderr,"\nError - boot image is not the an allowable size.\n");
exit(1);
}
/*
* FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT, unless it's no-emulation
* boot.
*/
if (default_desc.boot_media[0] != EL_TORITO_MEDIA_NOEMUL)
nsectors = 1;
set_721(default_desc.nsect, (unsigned int) nsectors );
#ifdef DEBUG_TORITO
fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent));
#endif
set_731(default_desc.bootoff,
(unsigned int) get_733(de->isorec.extent));
/*
* now write it to disk
*/
bootcat = open(de2->whole_name, O_RDWR | O_BINARY);
if (bootcat == -1)
{
fprintf(stderr,"Error opening boot catalog for update.\n");
perror("");
exit(1);
}
/*
* write out
*/
write(bootcat, &valid_desc, 32);
write(bootcat, &default_desc, 32);
close(bootcat);
} /* get_torito_desc(... */
/*
* Function to write the EVD for the disc.
*/
static int FDECL1(tvd_write, FILE *, outfile)
{
/*
* Next we write out the boot volume descriptor for the disc
*/
get_torito_desc(&gboot_desc);
xfwrite(&gboot_desc, 1, 2048, outfile);
last_extent_written ++;
return 0;
}
struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write};

760
external/gpl2/mkhybrid/dist/getopt.c vendored Normal file
View File

@ -0,0 +1,760 @@
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95
Free Software Foundation, Inc.
This file is part of the libiberty library. This library is free
software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option)
any later version.
This library 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, if you link this library with files
compiled with a GNU compiler to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#ifndef __STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
/* Many versions of the Linux C library include older, broken versions
of these routines, which will break the linker's command-line
parsing. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#if defined(__GNU_LIBRARY__) || defined(__OpenBSD__)
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#include <stdlib.h>
#endif /* GNU C library. */
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "getopt.h"
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* XXX 1003.2 says this must be 1 before any call. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own getopt implementation. */
int optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
#if defined(__GNU_LIBRARY__) || defined(__OpenBSD__)
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
#include <string.h>
#define my_index strchr
#else
/* Avoid depending on library functions or files
whose names are inconsistent. */
char *getenv ();
static char *
my_index (str, chr)
const char *str;
int chr;
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
#ifndef __STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void
exchange (argv)
char **argv;
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Initialize the internal data when the first call is made. */
static const char *
_getopt_initialize (optstring)
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = optind = 1;
nextchar = NULL;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (getenv ("POSIXLY_CORRECT") != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
{
optarg = NULL;
if (optind == 0)
optstring = _getopt_initialize (optstring);
if (argc == 0)
return EOF;
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
optind++;
last_nonopt = optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if (nameend - nextchar == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, "%s: option `%s' is ambiguous\n",
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
optind++;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (opterr)
{
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
"%s: option `--%s' doesn't allow an argument\n",
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
"%s: option `%c%s' doesn't allow an argument\n",
argv[0], argv[optind - 1][0], pfound->name);
}
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (opterr)
fprintf (stderr, "%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, "%s: unrecognized option `--%s'\n",
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
optind++;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
if (temp == NULL || c == ':')
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
}
optopt = c;
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
optarg = nextchar;
optind++;
}
else
optarg = NULL;
nextchar = NULL;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: option requires an argument -- %c\n",
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = NULL;
}
}
return c;
}
}
int
getopt (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
if (c == EOF)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

129
external/gpl2/mkhybrid/dist/getopt.h vendored Normal file
View File

@ -0,0 +1,129 @@
/* Declarations for getopt.
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if __STDC__
#if defined(__GNU_LIBRARY__)
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* not __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* not __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* _GETOPT_H */

190
external/gpl2/mkhybrid/dist/getopt1.c vendored Normal file
View File

@ -0,0 +1,190 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include "getopt.h"
#ifndef __STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
/* Many versions of the Linux C library include older, broken versions
of these routines, which will break the linker's command-line
parsing. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#else
char *getenv ();
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == EOF)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

244
external/gpl2/mkhybrid/dist/hash.c vendored Normal file
View File

@ -0,0 +1,244 @@
/*
* File hash.c - generate hash tables for iso9660 filesystem.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdlib.h>
#include "config.h"
#include "mkisofs.h"
#define NR_HASH 1024
#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH)
static struct file_hash * hash_table[NR_HASH] = {0,};
void FDECL1(add_hash, struct directory_entry *, spnt){
struct file_hash * s_hash;
unsigned int hash_number;
if(spnt->size == 0 || spnt->starting_block == 0)
if(spnt->size != 0 || spnt->starting_block != 0) {
fprintf(stderr,"Non zero-length file assigned zero extent.\n");
exit(1);
};
if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return;
hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode);
#if 0
if (verbose > 1) fprintf(stderr,"%s ",spnt->name);
#endif
s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
s_hash->next = hash_table[hash_number];
s_hash->inode = spnt->inode;
s_hash->dev = spnt->dev;
s_hash->starting_block = spnt->starting_block;
s_hash->size = spnt->size;
hash_table[hash_number] = s_hash;
}
struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){
unsigned int hash_number;
struct file_hash * spnt;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
spnt = hash_table[hash_number];
while(spnt){
if(spnt->inode == inode && spnt->dev == dev) return spnt;
spnt = spnt->next;
};
return NULL;
}
#ifdef APPLE_HYB
/* based on flush_file_hash() below - needed as we wnat to re-use the
file hash table */
void flush_hash(){
struct file_hash * fh, *fh1;
int i;
for(i=0; i<NR_HASH; i++) {
fh = hash_table[i];
while(fh) {
fh1 = fh->next;
free(fh);
fh = fh1;
}
hash_table[i] = NULL;
}
}
#endif /* APPLE_HYB */
static struct file_hash * directory_hash_table[NR_HASH] = {0,};
void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){
struct file_hash * s_hash;
unsigned int hash_number;
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
s_hash->next = directory_hash_table[hash_number];
s_hash->inode = inode;
s_hash->dev = dev;
directory_hash_table[hash_number] = s_hash;
}
struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){
unsigned int hash_number;
struct file_hash * spnt;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
spnt = directory_hash_table[hash_number];
while(spnt){
if(spnt->inode == inode && spnt->dev == dev) return spnt;
spnt = spnt->next;
};
return NULL;
}
struct name_hash
{
struct name_hash * next;
struct directory_entry * de;
};
#define NR_NAME_HASH 128
static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
/*
* Find the hash bucket for this name.
*/
static unsigned int FDECL1(name_hash, const char *, name)
{
unsigned int hash = 0;
const char * p;
p = name;
while (*p)
{
/*
* Don't hash the iso9660 version number. This way
* we can detect duplicates in cases where we have
* directories (i.e. foo) and non-directories
* (i.e. foo;1).
*/
if( *p == ';' )
{
break;
}
hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
}
return hash % NR_NAME_HASH;
}
void FDECL1(add_file_hash, struct directory_entry *, de){
struct name_hash * new;
int hash;
new = (struct name_hash *) e_malloc(sizeof(struct name_hash));
new->de = de;
new->next = NULL;
hash = name_hash(de->isorec.name);
/* Now insert into the hash table */
new->next = name_hash_table[hash];
name_hash_table[hash] = new;
}
struct directory_entry * FDECL1(find_file_hash, char *, name)
{
struct name_hash * nh;
char * p1;
char * p2;
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
{
p1 = name;
p2 = nh->de->isorec.name;
/*
* Look for end of string, or a mismatch.
*/
while(1==1)
{
if( (*p1 == '\0' || *p1 == ';')
|| (*p2 == '\0' || *p2 == ';')
|| (*p1 != *p2) )
{
break;
}
p1++;
p2++;
}
/*
* If we are at the end of both strings, then
* we have a match.
*/
if( (*p1 == '\0' || *p1 == ';')
&& (*p2 == '\0' || *p2 == ';') )
{
return nh->de;
}
}
return NULL;
}
int FDECL1(delete_file_hash, struct directory_entry *, de){
struct name_hash * nh, *prev;
int hash;
prev = NULL;
hash = name_hash(de->isorec.name);
for(nh = name_hash_table[hash]; nh; nh = nh->next) {
if(nh->de == de) break;
prev = nh;
}
if(!nh) return 1;
if(!prev)
name_hash_table[hash] = nh->next;
else
prev->next = nh->next;
free(nh);
return 0;
}
void flush_file_hash(){
struct name_hash * nh, *nh1;
int i;
for(i=0; i<NR_NAME_HASH; i++) {
nh = name_hash_table[i];
while(nh) {
nh1 = nh->next;
free(nh);
nh = nh1;
}
name_hash_table[i] = NULL;
}
}

View File

@ -0,0 +1,57 @@
/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */
/*
* Generic header for users of open(), creat() and chmod()
*
* Copyright (c) 1996 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _FCTLDEFS_H
#define _FCTLDEFS_H
#ifndef _MCONFIG_H
#include <mconfig.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else /* HAVE_FCNTL_H */
# include <sys/file.h>
#endif /* HAVE_FCNTL_H */
/*
* Do not define more than O_RDONLY / O_WRONLY / O_RDWR
* The values may differ.
*/
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#ifndef O_WRONLY
#define O_WRONLY 1
#endif
#ifndef O_RDWR
#define O_RDWR 2
#endif
#endif /* _FCTLDEFS_H */

View File

@ -0,0 +1,268 @@
/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */
/*
* definitions for machine configuration
*
* Copyright (c) 1995 J. Schilling
*
* This file must be included before any other file.
* Use only cpp instructions.
*
* NOTE: SING: (Schily Is Not Gnu)
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _MCONFIG_H
#define _MCONFIG_H
/*
* This hack that is needed as long as VMS has no POSIX shell.
*/
#ifdef VMS
# define USE_STATIC_CONF
#endif
#ifdef VANILLA_AUTOCONF
#include <config.h>
#else
#ifdef USE_STATIC_CONF
#include <xmconfig.h> /* This is the current static autoconf stuff */
#else
#include <xconfig.h> /* This is the current dynamic autoconf stuff */
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(unix) || defined(__unix) || defined(__unix__)
# define IS_UNIX
#endif
#ifdef __MSDOS__
# define IS_MSDOS
#endif
#if defined(tos) || defined(__tos)
# define IS_TOS
#endif
#ifdef THINK_C
# define IS_MAC
#endif
#if defined(sun) || defined(__sun) || defined(__sun__)
# define IS_SUN
#endif
#if defined(__CYGWIN32__)
# define IS_GCC_WIN32
#endif
/*--------------------------------------------------------------------------*/
/*
* Some magic that cannot (yet) be figured out with autoconf.
*/
#ifdef sparc
# ifndef HAVE_LDSTUB
# define HAVE_LDSTUB
# endif
# ifndef HAVE_SCANSTACK
# define HAVE_SCANSTACK
# endif
#endif
#if defined(__i386_) || defined(i386)
# ifndef HAVE_XCHG
# define HAVE_XCHG
# endif
# ifndef HAVE_SCANSTACK
# define HAVE_SCANSTACK
# endif
#endif
#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \
|| defined(SVR4)
# ifndef __SVR4
# define __SVR4
# endif
#endif
#ifdef __SVR4
# ifndef SVR4
# define SVR4
# endif
#endif
/*
* SunOS 4.x / SunOS 5.x
*/
#if defined(IS_SUN)
# define HAVE_GETAV0
#endif
/*
* AIX
*/
#if defined(_IBMR2) || defined(_AIX)
# define IS_UNIX /* ??? really ??? */
#endif
/*
* Silicon Graphics (must be before SVR4)
*/
#if defined(sgi) || defined(__sgi)
# define __NOT_SVR4__ /* Not a real SVR4 implementation */
#endif
/*
* Data General
*/
#if defined(__DGUX__)
#ifdef XXXXXXX
# undef HAVE_MTGET_DSREG
# undef HAVE_MTGET_RESID
# undef HAVE_MTGET_FILENO
# undef HAVE_MTGET_BLKNO
#endif
# define mt_type mt_model
# define mt_dsreg mt_status1
# define mt_erreg mt_status2
/*
* DGUX hides its flock as dg_flock.
*/
# define HAVE_FLOCK
# define flock dg_flock
/*
* Use the BSD style wait on DGUX to get the resource usages of child
* processes.
*/
# define _BSD_WAIT_FLAVOR
#endif
/*
* Apple Rhapsody
*/
#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody
# define HAVE_OSDEF /* prevent later definitions to overwrite current */
#endif
/*
* NextStep
*/
#if defined(__NeXT__) && !defined(HAVE_OSDEF)
#define NO_PRINT_OVR
#undef HAVE_USG_STDIO /*
* NeXT Step 3.x uses __flsbuf(unsigned char , FILE *)
* instead of __flsbuf(int, FILE *)
*/
#endif
/*
* NextStep 3.x has a broken linker that does not allow us to override
* these functions.
*/
#ifndef __OPRINTF__
#ifdef NO_PRINT_OVR
# define printf Xprintf
# define fprintf Xfprintf
# define sprintf Xsprintf
#endif
#endif /* __OPRINTF__ */
/*--------------------------------------------------------------------------*/
/*
* If there is no flock defined by the system, use emulation
* through fcntl record locking.
*/
#ifndef HAVE_FLOCK
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* don't block when locking */
#define LOCK_UN 8 /* unlock */
#endif
#include <prototyp.h>
/*
* gcc 2.x generally implements the long long type.
*/
#ifdef __GNUC__
# if __GNUC__ > 1
# ifndef HAVE_LONGLONG
# define HAVE_LONGLONG
# endif
# endif
#endif
/*
* Convert to GNU name
*/
#ifdef HAVE_STDC_HEADERS
# ifndef STDC_HEADERS
# define STDC_HEADERS
# endif
#endif
/*
* Convert to SCHILY name
*/
#ifdef STDC_HEADERS
# ifndef HAVE_STDC_HEADERS
# define HAVE_STDC_HEADERS
# endif
#endif
#ifdef IS_UNIX
# define PATH_DELIM '/'
# define PATH_DELIM_STR "/"
# define far
# define near
#endif
#ifdef IS_GCC_WIN32
# define PATH_DELIM '/'
# define PATH_DELIM_STR "/"
# define far
# define near
#endif
#ifdef IS_MSDOS
# define PATH_DELIM '\\'
# define PATH_DELIM_STR "\\"
#endif
#ifdef IS_TOS
# define PATH_DELIM '\\'
# define PATH_DELIM_STR "\\"
# define far
# define near
#endif
#ifdef IS_MAC
# define PATH_DELIM ':'
# define PATH_DELIM_STR ":"
# define far
# define near
#endif
#ifdef __cplusplus
}
#endif
#endif /* _MCONFIG_H */

View File

@ -0,0 +1,74 @@
/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */
/*
* Definitions for dealing with ANSI / KR C-Compilers
*
* Copyright (c) 1995 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _PROTOTYP_H
#define _PROTOTYP_H
#ifndef PROTOTYPES
/*
* If this has already been defined,
* someone else knows better than us...
*/
# ifdef __STDC__
# if __STDC__ /* ANSI C */
# define PROTOTYPES
# endif
# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */
# define PROTOTYPES
# endif
# endif
#endif /* PROTOTYPES */
/*
* If we have prototypes, we should have stdlib.h string.h stdarg.h
*/
#ifdef PROTOTYPES
#if !(defined(SABER) && defined(sun))
# ifndef HAVE_STDARG_H
# define HAVE_STDARG_H
# endif
#endif
# ifndef HAVE_STDLIB_H
# define HAVE_STDLIB_H
# endif
# ifndef HAVE_STRING_H
# define HAVE_STRING_H
# endif
# ifndef HAVE_STDC_HEADERS
# define HAVE_STDC_HEADERS
# endif
# ifndef STDC_HEADERS
# define STDC_HEADERS /* GNU name */
# endif
#endif
#ifdef NO_PROTOTYPES /* Force not to use prototypes */
# undef PROTOTYPES
#endif
#ifdef PROTOTYPES
# define __PR(a) a
#else
# define __PR(a) ()
#endif
#endif /* _PROTOTYP_H */

View File

@ -0,0 +1,139 @@
/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */
/*
* Definitions for stat() file mode
*
* Copyright (c) 1998 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _STATDEFS_H
#define _STATDEFS_H
#ifndef _MCONFIG_H
#include <mconfig.h>
#endif
#ifdef STAT_MACROS_BROKEN
#undef S_ISFIFO /* Named pipe */
#undef S_ISCHR /* Character special */
#undef S_ISMPC /* UNUSED multiplexed c */
#undef S_ISDIR /* Directory */
#undef S_ISNAM /* Named file (XENIX) */
#undef S_ISBLK /* Block special */
#undef S_ISMPB /* UNUSED multiplexed b */
#undef S_ISREG /* Regular file */
#undef S_ISCNT /* Contiguous file */
#undef S_ISLNK /* Symbolic link */
#undef S_ISSHAD /* Solaris shadow inode */
#undef S_ISSOCK /* UNIX domain socket */
#undef S_ISDOOR /* Solaris DOOR */
#endif
#ifndef S_ISFIFO /* Named pipe */
# ifdef S_IFIFO
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
# else
# define S_ISFIFO(m) (0)
# endif
#endif
#ifndef S_ISCHR /* Character special */
# ifdef S_IFCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
# else
# define S_ISCHR(m) (0)
# endif
#endif
#ifndef S_ISMPC /* UNUSED multiplexed c */
# ifdef S_IFMPC
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
# else
# define S_ISMPC(m) (0)
# endif
#endif
#ifndef S_ISDIR /* Directory */
# ifdef S_IFDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# else
# define S_ISDIR(m) (0)
# endif
#endif
#ifndef S_ISNAM /* Named file (XENIX) */
# ifdef S_IFNAM
# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
# else
# define S_ISNAM(m) (0)
# endif
#endif
#ifndef S_ISBLK /* Block special */
# ifdef S_IFBLK
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
# else
# define S_ISBLK(m) (0)
# endif
#endif
#ifndef S_ISMPB /* UNUSED multiplexed b */
# ifdef S_IFMPB
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
# else
# define S_ISMPB(m) (0)
# endif
#endif
#ifndef S_ISREG /* Regular file */
# ifdef S_IFREG
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
# else
# define S_ISREG(m) (0)
# endif
#endif
#ifndef S_ISCNT /* Contiguous file */
# ifdef S_IFCNT
# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT)
# else
# define S_ISCNT(m) (0)
# endif
#endif
#ifndef S_ISLNK /* Symbolic link */
# ifdef S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
# else
# define S_ISLNK(m) (0)
# endif
#endif
#ifndef S_ISSHAD /* Solaris shadow inode */
# ifdef S_IFSHAD
# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD)
# else
# define S_ISSHAD(m) (0)
# endif
#endif
#ifndef S_ISSOCK /* UNIX domain socket */
# ifdef S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
# else
# define S_ISSOCK(m) (0)
# endif
#endif
#ifndef S_ISDOOR /* Solaris DOOR */
# ifdef S_IFDOOR
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
# else
# define S_ISDOOR(m) (0)
# endif
#endif
#endif /* _STATDEFS_H */

238
external/gpl2/mkhybrid/dist/install-sh vendored Normal file
View File

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

158
external/gpl2/mkhybrid/dist/iso9660.h vendored Normal file
View File

@ -0,0 +1,158 @@
/*
* Header file iso9660.h - assorted structure definitions and typecasts.
* specific to iso9660 filesystem.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* Id: iso9660.h,v 1.1 2000/10/10 20:40:16 beck Exp
*/
#ifndef _ISOFS_FS_H
#define _ISOFS_FS_H
/*
* The isofs filesystem constants/structures
*/
/* This part borrowed from the bsd386 isofs */
#define ISODCL(from, to) (to - from + 1)
struct iso_volume_descriptor {
char type[ISODCL(1,1)]; /* 711 */
char id[ISODCL(2,6)];
char version[ISODCL(7,7)];
char data[ISODCL(8,2048)];
};
/* volume descriptor types */
#define ISO_VD_PRIMARY 1
#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */
#define ISO_VD_END 255
#define ISO_STANDARD_ID "CD001"
#define EL_TORITO_ID "EL TORITO SPECIFICATION"
#define EL_TORITO_ARCH_x86 0
#define EL_TORITO_ARCH_PPC 1
#define EL_TORITO_ARCH_MAC 2
#define EL_TORITO_BOOTABLE 0x88
#define EL_TORITO_MEDIA_NOEMUL 0
#define EL_TORITO_MEDIA_12FLOP 1
#define EL_TORITO_MEDIA_144FLOP 2
#define EL_TORITO_MEDIA_288FLOP 3
#define EL_TORITO_MEDIA_HD 4
struct iso_primary_descriptor {
char type [ISODCL ( 1, 1)]; /* 711 */
char id [ISODCL ( 2, 6)];
char version [ISODCL ( 7, 7)]; /* 711 */
char unused1 [ISODCL ( 8, 8)];
char system_id [ISODCL ( 9, 40)]; /* achars */
char volume_id [ISODCL ( 41, 72)]; /* dchars */
char unused2 [ISODCL ( 73, 80)];
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
char escape_sequences [ISODCL ( 89, 120)];
char volume_set_size [ISODCL (121, 124)]; /* 723 */
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
char logical_block_size [ISODCL (129, 132)]; /* 723 */
char path_table_size [ISODCL (133, 140)]; /* 733 */
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
char volume_set_id [ISODCL (191, 318)]; /* dchars */
char publisher_id [ISODCL (319, 446)]; /* achars */
char preparer_id [ISODCL (447, 574)]; /* achars */
char application_id [ISODCL (575, 702)]; /* achars */
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
char file_structure_version [ISODCL (882, 882)]; /* 711 */
char unused4 [ISODCL (883, 883)];
char application_data [ISODCL (884, 1395)];
char unused5 [ISODCL (1396, 2048)];
};
/* El Torito Boot Record Volume Descriptor */
struct eltorito_boot_descriptor {
char id [ISODCL ( 1, 1)]; /* 711 */
char id2 [ISODCL ( 2, 6)];
char version [ISODCL ( 7, 7)]; /* 711 */
char system_id [ISODCL ( 8, 39)];
char unused2 [ISODCL ( 40, 71)];
char bootcat_ptr [ISODCL ( 72 , 75)];
char unused5 [ISODCL ( 76, 2048)];
};
/* Validation entry for El Torito */
struct eltorito_validation_entry {
char headerid [ISODCL ( 1, 1)]; /* 711 */
char arch [ISODCL ( 2, 2)];
char pad1 [ISODCL ( 3, 4)]; /* 711 */
char id [ISODCL ( 5, 28)];
char cksum [ISODCL ( 29, 30)];
char key1 [ISODCL ( 31, 31)];
char key2 [ISODCL ( 32, 32)];
};
/* El Torito initial/default entry in boot catalog */
struct eltorito_defaultboot_entry {
char boot_id [ISODCL ( 1, 1)]; /* 711 */
char boot_media [ISODCL ( 2, 2)];
char loadseg [ISODCL ( 3, 4)]; /* 711 */
char arch [ISODCL ( 5, 5)];
char pad1 [ISODCL ( 6, 6)];
char nsect [ISODCL ( 7, 8)];
char bootoff [ISODCL ( 9, 12)];
char pad2 [ISODCL ( 13, 32)];
};
/* We use this to help us look up the parent inode numbers. */
struct iso_path_table{
unsigned char name_len[2]; /* 721 */
char extent[4]; /* 731 */
char parent[2]; /* 721 */
char name[1];
};
struct iso_directory_record {
unsigned char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
char extent [ISODCL (3, 10)]; /* 733 */
char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
char name [34]; /* Not really, but we need something here */
};
#endif

1074
external/gpl2/mkhybrid/dist/joliet.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
/* proto.h */
/* $OpenBSD: proto.h,v 1.1 2008/03/08 15:36:12 espie Exp $ */
/*
* Copyright (c) 2008 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIBFILE_PROTO_H
#define LIBFILE_PROTO_H
extern int init_magic(char *);
extern char *get_magic_match(const char *);
extern void clean_magic(void);
#endif

View File

@ -0,0 +1,75 @@
###############################################################################
#
# hfsutils - tools for reading and writing Macintosh HFS volumes
# Copyright (C) 1996, 1997 Robert Leslie
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
###############################################################################
CC = gcc
INCLUDES =
LIBS =
DEFINES =
COPTS = -g -Wall -pedantic
CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES)
ARFLAGS = rc
RANLIB = ranlib
###############################################################################
TARGET = libhfs.a
OBJS = data.o block.o low.o file.o btree.o node.o record.o volume.o \
hfs.o
###############################################################################
all :: $(TARGET)
again :: depend clean all
depend ::
( sed -n '1,/^### DEPEND/p' Makefile; \
echo; \
$(CC) -MM $(CFLAGS) *.c; \
) > Makefile.new
mv -f Makefile.new Makefile
clean ::
rm -f $(TARGET) *.o core
###############################################################################
$(TARGET): $(OBJS)
ar $(ARFLAGS) $@ \
$(OBJS)
$(RANLIB) $@
### DEPENDENCIES FOLLOW #######################################################
block.o: block.c internal.h hfs.h data.h block.h low.h
btree.o: btree.c internal.h hfs.h data.h block.h file.h btree.h node.h
data.o: data.c internal.h hfs.h data.h btree.h
file.o: file.c internal.h hfs.h data.h block.h file.h btree.h record.h \
volume.h
hfs.o: hfs.c internal.h hfs.h data.h block.h low.h file.h btree.h \
node.h record.h volume.h
low.o: low.c internal.h hfs.h data.h block.h low.h file.h
node.o: node.c internal.h hfs.h data.h btree.h node.h
record.o: record.c internal.h hfs.h data.h record.h
volume.o: volume.c internal.h hfs.h data.h low.h btree.h record.h \
volume.h

View File

@ -0,0 +1,29 @@
Modified version of libhfs (v2.0) to work with mkhybrid.
To complile for mkhybrid, use the #define -DAPPLE_HYB
The libhfs.a created with this option must not be used with other
hfsutils routines.
James Pearson 18/7/97
Copyright information from hfsutils:
hfsutils - tools for reading and writing Macintosh HFS volumes
Copyright (C) 1996, 1997 Robert Leslie
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., 675 Mass Ave, Cambridge, MA 02139, USA.

View File

@ -0,0 +1,205 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <string.h>
# include <sys/types.h>
# include <unistd.h>
# include <errno.h>
# include <time.h>
# include "internal.h"
# include "data.h"
# include "block.h"
# include "low.h"
#ifdef DEBUG
#include <stdio.h>
#endif /* DEBUG */
/*
* NAME: block->readlb()
* DESCRIPTION: read a logical block from a volume
*/
int b_readlb(hfsvol *vol, unsigned long num, block *bp)
{
#ifdef APPLE_HYB
block *b;
hce_mem *hce;
#ifdef DEBUG
fprintf(stderr,"b_readlb: start block = %d\n", vol->vstart + num);
#endif /* DEBUG */
hce = vol->hce;
/* Check to see if requested block is in the HFS header or catalog/exents
files. If it is, read info from memory copy. If not, then something
has gone horribly wrong ... */
if (num < hce->hfs_hdr_size)
b = (block *)hce->hfs_hdr + num;
else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
else
{
ERROR(EIO, "should not happen!");
return -1;
}
memcpy(bp, b, HFS_BLOCKSZ);
#else
int bytes;
if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
{
ERROR(errno, "error seeking device");
return -1;
}
bytes = read(vol->fd, bp, HFS_BLOCKSZ);
if (bytes < 0)
{
ERROR(errno, "error reading from device");
return -1;
}
else if (bytes == 0)
{
ERROR(EIO, "read EOF on volume");
return -1;
}
else if (bytes != HFS_BLOCKSZ)
{
ERROR(EIO, "read incomplete block");
return -1;
}
#endif /* APPLE_HYB */
return 0;
}
/*
* NAME: block->writelb()
* DESCRIPTION: write a logical block to a volume
*/
int b_writelb(hfsvol *vol, unsigned long num, block *bp)
{
#ifdef APPLE_HYB
block *b;
hce_mem *hce;
#ifdef DEBUG
fprintf(stderr,"b_writelb: start block = %d\n", vol->vstart + num);
#endif /* DEBUG */
hce = vol->hce;
/* Check to see if requested block is in the HFS header or catalog/exents
files. If it is, write info to memory copy. If not, then it's a block
for an ordinary file - and as we are writing the files later, then just
ignore and return OK */
if (num < hce->hfs_hdr_size)
b = (block *)hce->hfs_hdr + num;
else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
else
{
#ifdef DEBUG
fprintf(stderr,"b_writelb: ignoring\n");
#endif /* DEBUG */
return 0;
}
memcpy(b, bp, HFS_BLOCKSZ);
#else
int bytes;
if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
{
ERROR(errno, "error seeking device");
return -1;
}
bytes = write(vol->fd, bp, HFS_BLOCKSZ);
if (bytes < 0)
{
ERROR(errno, "error writing to device");
return -1;
}
else if (bytes != HFS_BLOCKSZ)
{
ERROR(EIO, "wrote incomplete block");
return -1;
}
#endif /* APPLE_HYB */
return 0;
}
/*
* NAME: block->readab()
* DESCRIPTION: read a block from an allocation block from a volume
*/
int b_readab(hfsvol *vol,
unsigned int anum, unsigned int index, block *bp)
{
/* verify the allocation block exists and is marked as in-use */
if (anum >= vol->mdb.drNmAlBlks)
{
ERROR(EIO, "read nonexistent block");
return -1;
}
else if (vol->vbm && ! BMTST(vol->vbm, anum))
{
ERROR(EIO, "read unallocated block");
return -1;
}
return b_readlb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + index, bp);
}
/*
* NAME: b->writeab()
* DESCRIPTION: write a block to an allocation block to a volume
*/
int b_writeab(hfsvol *vol,
unsigned int anum, unsigned int index, block *bp)
{
/* verify the allocation block exists and is marked as in-use */
if (anum >= vol->mdb.drNmAlBlks)
{
ERROR(EIO, "write nonexistent block");
return -1;
}
else if (vol->vbm && ! BMTST(vol->vbm, anum))
{
ERROR(EIO, "write unallocated block");
return -1;
}
vol->mdb.drAtrb &= ~HFS_ATRB_UMOUNTED;
vol->mdb.drLsMod = d_tomtime(time(0));
++vol->mdb.drWrCnt;
vol->flags |= HFS_UPDATE_MDB;
return b_writelb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + index, bp);
}

View File

@ -0,0 +1,24 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int b_readlb(hfsvol *, unsigned long, block *);
int b_writelb(hfsvol *, unsigned long, block *);
int b_readab(hfsvol *, unsigned int, unsigned int, block *);
int b_writeab(hfsvol *, unsigned int, unsigned int, block *);

View File

@ -0,0 +1,719 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include "internal.h"
# include "data.h"
# include "block.h"
# include "file.h"
# include "btree.h"
# include "node.h"
/*
* NAME: btree->getnode()
* DESCRIPTION: retrieve a numbered node from a B*-tree file
*/
int bt_getnode(node *np)
{
btree *bt = np->bt;
block *bp = &np->data;
unsigned char *ptr;
int i;
/* verify the node exists and is marked as in-use */
if (np->nnum < 0 || (np->nnum > 0 && np->nnum >= bt->hdr.bthNNodes))
{
ERROR(EIO, "read nonexistent b*-tree node");
return -1;
}
if (bt->map && ! BMTST(bt->map, np->nnum))
{
ERROR(EIO, "read unallocated b*-tree node");
return -1;
}
if (f_getblock(&bt->f, np->nnum, bp) < 0)
return -1;
ptr = *bp;
d_fetchl(&ptr, (long *) &np->nd.ndFLink);
d_fetchl(&ptr, (long *) &np->nd.ndBLink);
d_fetchb(&ptr, (char *) &np->nd.ndType);
d_fetchb(&ptr, (char *) &np->nd.ndNHeight);
d_fetchw(&ptr, (short *) &np->nd.ndNRecs);
d_fetchw(&ptr, &np->nd.ndResv2);
if (np->nd.ndNRecs > HFS_MAXRECS)
{
ERROR(EIO, "too many b*-tree node records");
return -1;
}
i = np->nd.ndNRecs + 1;
ptr = *bp + HFS_BLOCKSZ - (2 * i);
while (i--)
d_fetchw(&ptr, (short *) &np->roff[i]);
return 0;
}
/*
* NAME: btree->putnode()
* DESCRIPTION: store a numbered node into a B*-tree file
*/
int bt_putnode(node *np)
{
btree *bt = np->bt;
block *bp = &np->data;
unsigned char *ptr;
int i;
/* verify the node exists and is marked as in-use */
if (np->nnum && np->nnum >= bt->hdr.bthNNodes)
{
ERROR(EIO, "write nonexistent b*-tree node");
return -1;
}
else if (bt->map && ! BMTST(bt->map, np->nnum))
{
ERROR(EIO, "write unallocated b*-tree node");
return -1;
}
ptr = *bp;
d_storel(&ptr, np->nd.ndFLink);
d_storel(&ptr, np->nd.ndBLink);
d_storeb(&ptr, np->nd.ndType);
d_storeb(&ptr, np->nd.ndNHeight);
d_storew(&ptr, np->nd.ndNRecs);
d_storew(&ptr, np->nd.ndResv2);
if (np->nd.ndNRecs > HFS_MAXRECS)
{
ERROR(EIO, "too many b*-tree node records");
return -1;
}
i = np->nd.ndNRecs + 1;
ptr = *bp + HFS_BLOCKSZ - (2 * i);
while (i--)
d_storew(&ptr, np->roff[i]);
if (f_putblock(&bt->f, np->nnum, bp) < 0)
return -1;
return 0;
}
/*
* NAME: btree->readhdr()
* DESCRIPTION: read the header node of a B*-tree
*/
int bt_readhdr(btree *bt)
{
unsigned char *ptr;
char *map;
int i;
unsigned long nnum;
bt->hdrnd.bt = bt;
bt->hdrnd.nnum = 0;
if (bt_getnode(&bt->hdrnd) < 0)
return -1;
if (bt->hdrnd.nd.ndType != ndHdrNode ||
bt->hdrnd.nd.ndNRecs != 3 ||
bt->hdrnd.roff[0] != 0x00e ||
bt->hdrnd.roff[1] != 0x078 ||
bt->hdrnd.roff[2] != 0x0f8 ||
bt->hdrnd.roff[3] != 0x1f8)
{
ERROR(EIO, "malformed b*-tree header node");
return -1;
}
/* read header record */
ptr = HFS_NODEREC(bt->hdrnd, 0);
d_fetchw(&ptr, (short *) &bt->hdr.bthDepth);
d_fetchl(&ptr, (long *) &bt->hdr.bthRoot);
d_fetchl(&ptr, (long *) &bt->hdr.bthNRecs);
d_fetchl(&ptr, (long *) &bt->hdr.bthFNode);
d_fetchl(&ptr, (long *) &bt->hdr.bthLNode);
d_fetchw(&ptr, (short *) &bt->hdr.bthNodeSize);
d_fetchw(&ptr, (short *) &bt->hdr.bthKeyLen);
d_fetchl(&ptr, (long *) &bt->hdr.bthNNodes);
d_fetchl(&ptr, (long *) &bt->hdr.bthFree);
for (i = 0; i < 76; ++i)
d_fetchb(&ptr, (char *) &bt->hdr.bthResv[i]);
if (bt->hdr.bthNodeSize != HFS_BLOCKSZ)
{
ERROR(EINVAL, "unsupported b*-tree node size");
return -1;
}
/* read map record; construct btree bitmap */
/* don't set bt->map until we're done, since getnode() checks it */
map = ALLOC(char, HFS_MAP1SZ);
if (map == 0)
{
ERROR(ENOMEM, 0);
return -1;
}
memcpy(map, HFS_NODEREC(bt->hdrnd, 2), HFS_MAP1SZ);
bt->mapsz = HFS_MAP1SZ;
/* read continuation map records, if any */
nnum = bt->hdrnd.nd.ndFLink;
while (nnum)
{
node n;
char *newmap;
n.bt = bt;
n.nnum = nnum;
if (bt_getnode(&n) < 0)
{
FREE(map);
return -1;
}
if (n.nd.ndType != ndMapNode ||
n.nd.ndNRecs != 1 ||
n.roff[0] != 0x00e ||
n.roff[1] != 0x1fa)
{
FREE(map);
ERROR(EIO, "malformed b*-tree map node");
return -1;
}
newmap = REALLOC(map, char, bt->mapsz + HFS_MAPXSZ);
if (newmap == 0)
{
FREE(map);
ERROR(ENOMEM, 0);
return -1;
}
map = newmap;
memcpy(map + bt->mapsz, HFS_NODEREC(n, 0), HFS_MAPXSZ);
bt->mapsz += HFS_MAPXSZ;
nnum = n.nd.ndFLink;
}
bt->map = map;
return 0;
}
/*
* NAME: btree->writehdr()
* DESCRIPTION: write the header node of a B*-tree
*/
int bt_writehdr(btree *bt)
{
unsigned char *ptr;
char *map;
unsigned long mapsz, nnum;
int i;
if (bt->hdrnd.bt != bt ||
bt->hdrnd.nnum != 0 ||
bt->hdrnd.nd.ndType != ndHdrNode ||
bt->hdrnd.nd.ndNRecs != 3)
abort();
ptr = HFS_NODEREC(bt->hdrnd, 0);
d_storew(&ptr, bt->hdr.bthDepth);
d_storel(&ptr, bt->hdr.bthRoot);
d_storel(&ptr, bt->hdr.bthNRecs);
d_storel(&ptr, bt->hdr.bthFNode);
d_storel(&ptr, bt->hdr.bthLNode);
d_storew(&ptr, bt->hdr.bthNodeSize);
d_storew(&ptr, bt->hdr.bthKeyLen);
d_storel(&ptr, bt->hdr.bthNNodes);
d_storel(&ptr, bt->hdr.bthFree);
for (i = 0; i < 76; ++i)
d_storeb(&ptr, bt->hdr.bthResv[i]);
memcpy(HFS_NODEREC(bt->hdrnd, 2), bt->map, HFS_MAP1SZ);
if (bt_putnode(&bt->hdrnd) < 0)
return -1;
map = bt->map + HFS_MAP1SZ;
mapsz = bt->mapsz - HFS_MAP1SZ;
nnum = bt->hdrnd.nd.ndFLink;
while (mapsz)
{
node n;
if (nnum == 0)
{
ERROR(EIO, "truncated b*-tree map");
return -1;
}
n.bt = bt;
n.nnum = nnum;
if (bt_getnode(&n) < 0)
return -1;
if (n.nd.ndType != ndMapNode ||
n.nd.ndNRecs != 1 ||
n.roff[0] != 0x00e ||
n.roff[1] != 0x1fa)
{
ERROR(EIO, "malformed b*-tree map node");
return -1;
}
memcpy(HFS_NODEREC(n, 0), map, HFS_MAPXSZ);
if (bt_putnode(&n) < 0)
return -1;
map += HFS_MAPXSZ;
mapsz -= HFS_MAPXSZ;
nnum = n.nd.ndFLink;
}
bt->flags &= ~HFS_UPDATE_BTHDR;
return 0;
}
/* High-Level B*-Tree Routines ============================================= */
/*
* NAME: btree->space()
* DESCRIPTION: assert space for new records, or extend the file
*/
int bt_space(btree *bt, unsigned int nrecs)
{
unsigned int nnodes;
int space;
nnodes = nrecs * (bt->hdr.bthDepth + 1);
if (nnodes <= bt->hdr.bthFree)
return 0;
/* make sure the extents tree has room too */
if (bt != &bt->f.vol->ext)
{
if (bt_space(&bt->f.vol->ext, 1) < 0)
return -1;
}
space = f_alloc(&bt->f);
if (space < 0)
return -1;
nnodes = space * (bt->f.vol->mdb.drAlBlkSiz / bt->hdr.bthNodeSize);
bt->hdr.bthNNodes += nnodes;
bt->hdr.bthFree += nnodes;
bt->flags |= HFS_UPDATE_BTHDR;
bt->f.vol->flags |= HFS_UPDATE_ALTMDB;
while (bt->hdr.bthNNodes > bt->mapsz * 8)
{
char *newmap;
node mapnd;
/* extend tree map */
newmap = REALLOC(bt->map, char, bt->mapsz + HFS_MAPXSZ);
if (newmap == 0)
{
ERROR(ENOMEM, 0);
return -1;
}
memset(newmap + bt->mapsz, 0, HFS_MAPXSZ);
bt->map = newmap;
bt->mapsz += HFS_MAPXSZ;
n_init(&mapnd, bt, ndMapNode, 0);
if (n_new(&mapnd) < 0)
return -1;
/* link the new map node */
if (bt->hdrnd.nd.ndFLink == 0)
{
bt->hdrnd.nd.ndFLink = mapnd.nnum;
mapnd.nd.ndBLink = 0;
}
else
{
node n;
n.bt = bt;
n.nnum = bt->hdrnd.nd.ndFLink;
while (1)
{
if (bt_getnode(&n) < 0)
return -1;
if (n.nd.ndFLink == 0)
break;
n.nnum = n.nd.ndFLink;
}
n.nd.ndFLink = mapnd.nnum;
mapnd.nd.ndBLink = n.nnum;
if (bt_putnode(&n) < 0)
return -1;
}
mapnd.nd.ndNRecs = 1;
mapnd.roff[1] = 0x1fa;
if (bt_putnode(&mapnd) < 0)
return -1;
}
return 0;
}
/*
* NAME: btree->insertx()
* DESCRIPTION: recursively locate a node and insert a record
*/
int bt_insertx(node *np, unsigned char *record, int *reclen)
{
node child;
unsigned char *rec;
if (n_search(np, record))
{
ERROR(EIO, "b*-tree record already exists");
return -1;
}
switch ((unsigned char) np->nd.ndType)
{
case ndIndxNode:
if (np->rnum < 0)
rec = HFS_NODEREC(*np, 0);
else
rec = HFS_NODEREC(*np, np->rnum);
child.bt = np->bt;
child.nnum = d_getl(HFS_RECDATA(rec));
if (bt_getnode(&child) < 0 ||
bt_insertx(&child, record, reclen) < 0)
return -1;
if (np->rnum < 0)
{
n_index(np->bt, HFS_NODEREC(child, 0), child.nnum, rec, 0);
if (*reclen == 0)
return bt_putnode(np);
}
return *reclen ? n_insert(np, record, reclen) : 0;
case ndLeafNode:
return n_insert(np, record, reclen);
default:
ERROR(EIO, "unexpected b*-tree node");
return -1;
}
}
/*
* NAME: btree->insert()
* DESCRIPTION: insert a new node record into a tree
*/
int bt_insert(btree *bt, unsigned char *record, int reclen)
{
node root;
if (bt->hdr.bthRoot == 0)
{
/* create root node */
n_init(&root, bt, ndLeafNode, 1);
if (n_new(&root) < 0 ||
bt_putnode(&root) < 0)
return -1;
bt->hdr.bthDepth = 1;
bt->hdr.bthRoot = root.nnum;
bt->hdr.bthFNode = root.nnum;
bt->hdr.bthLNode = root.nnum;
bt->flags |= HFS_UPDATE_BTHDR;
}
else
{
root.bt = bt;
root.nnum = bt->hdr.bthRoot;
if (bt_getnode(&root) < 0)
return -1;
}
if (bt_insertx(&root, record, &reclen) < 0)
return -1;
if (reclen)
{
unsigned char oroot[HFS_MAXRECLEN];
int orootlen;
/* root node was split; create a new root */
n_index(bt, HFS_NODEREC(root, 0), root.nnum, oroot, &orootlen);
n_init(&root, bt, ndIndxNode, root.nd.ndNHeight + 1);
if (n_new(&root) < 0)
return -1;
++bt->hdr.bthDepth;
bt->hdr.bthRoot = root.nnum;
bt->flags |= HFS_UPDATE_BTHDR;
/* insert index records for new root */
n_search(&root, oroot);
n_insertx(&root, oroot, orootlen);
n_search(&root, record);
n_insertx(&root, record, reclen);
if (bt_putnode(&root) < 0)
return -1;
}
++bt->hdr.bthNRecs;
bt->flags |= HFS_UPDATE_BTHDR;
return 0;
}
/*
* NAME: btree->deletex()
* DESCRIPTION: recursively locate a node and delete a record
*/
int bt_deletex(node *np, unsigned char *key, unsigned char *record, int *flag)
{
node child;
unsigned char *rec;
int found;
found = n_search(np, key);
switch ((unsigned char) np->nd.ndType)
{
case ndIndxNode:
if (np->rnum < 0)
{
ERROR(EIO, "b*-tree record not found");
return -1;
}
rec = HFS_NODEREC(*np, np->rnum);
child.bt = np->bt;
child.nnum = d_getl(HFS_RECDATA(rec));
if (bt_getnode(&child) < 0 ||
bt_deletex(&child, key, rec, flag) < 0)
return -1;
if (*flag)
{
*flag = 0;
if (HFS_RECKEYLEN(rec) == 0)
return n_delete(np, record, flag);
if (np->rnum == 0)
{
n_index(np->bt, HFS_NODEREC(*np, 0), np->nnum, record, 0);
*flag = 1;
}
return bt_putnode(np);
}
return 0;
case ndLeafNode:
if (found == 0)
{
ERROR(EIO, "b*-tree record not found");
return -1;
}
return n_delete(np, record, flag);
default:
ERROR(EIO, "unexpected b*-tree node");
return -1;
}
}
/*
* NAME: btree->delete()
* DESCRIPTION: remove a node record from a tree
*/
int bt_delete(btree *bt, unsigned char *key)
{
node root;
unsigned char record[HFS_MAXRECLEN];
int flag = 0;
root.bt = bt;
root.nnum = bt->hdr.bthRoot;
if (root.nnum == 0)
{
ERROR(EIO, "empty b*-tree");
return -1;
}
if (bt_getnode(&root) < 0 ||
bt_deletex(&root, key, record, &flag) < 0)
return -1;
if (bt->hdr.bthDepth > 1 && root.nd.ndNRecs == 1)
{
unsigned char *rec;
/* chop the root */
rec = HFS_NODEREC(root, 0);
--bt->hdr.bthDepth;
bt->hdr.bthRoot = d_getl(HFS_RECDATA(rec));
n_free(&root);
}
else if (bt->hdr.bthDepth == 1 && root.nd.ndNRecs == 0)
{
/* delete the root node */
bt->hdr.bthDepth = 0;
bt->hdr.bthRoot = 0;
bt->hdr.bthFNode = 0;
bt->hdr.bthLNode = 0;
n_free(&root);
}
--bt->hdr.bthNRecs;
bt->flags |= HFS_UPDATE_BTHDR;
return 0;
}
/*
* NAME: btree->search()
* DESCRIPTION: locate a data record given a search key
*/
int bt_search(btree *bt, unsigned char *key, node *np)
{
np->bt = bt;
np->nnum = bt->hdr.bthRoot;
if (np->nnum == 0)
{
ERROR(ENOENT, 0);
return 0;
}
while (1)
{
int found;
unsigned char *rec;
if (bt_getnode(np) < 0)
return -1;
found = n_search(np, key);
switch ((unsigned char) np->nd.ndType)
{
case ndIndxNode:
if (np->rnum < 0)
{
ERROR(ENOENT, 0);
return 0;
}
rec = HFS_NODEREC(*np, np->rnum);
np->nnum = d_getl(HFS_RECDATA(rec));
break;
case ndLeafNode:
if (! found)
ERROR(ENOENT, 0);
return found;
default:
ERROR(EIO, "unexpected b*-tree node");
return -1;
}
}
}

View File

@ -0,0 +1,34 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int bt_getnode(node *);
int bt_putnode(node *);
int bt_readhdr(btree *);
int bt_writehdr(btree *);
int bt_space(btree *, unsigned int);
int bt_insertx(node *, unsigned char *, int *);
int bt_insert(btree *, unsigned char *, int);
int bt_deletex(node *, unsigned char *, unsigned char *, int *);
int bt_delete(btree *, unsigned char *);
int bt_search(btree *, unsigned char *, node *);

View File

@ -0,0 +1,319 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <string.h>
# include <time.h>
# include "internal.h"
# include "data.h"
# include "btree.h"
# define MUTDIFF 2082844800L
static
unsigned long tzdiff = -1;
unsigned char hfs_charorder[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x22, 0x23, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69,
0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f,
0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1,
0xa3, 0xa5, 0xa8, 0xaa, 0xab, 0xac, 0xad, 0xae,
0x54, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69,
0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f,
0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1,
0xa3, 0xa5, 0xa8, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0x4c, 0x50, 0x5c, 0x62, 0x7d, 0x81, 0x9a, 0x55,
0x4a, 0x56, 0x4c, 0x4e, 0x50, 0x5c, 0x62, 0x64,
0x65, 0x66, 0x6f, 0x70, 0x71, 0x72, 0x7d, 0x89,
0x8a, 0x8b, 0x81, 0x83, 0x9c, 0x9d, 0x9e, 0x9a,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0x95,
0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0x52, 0x85,
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc9, 0xca, 0xcb, 0x57, 0x8c, 0xcc, 0x52, 0x85,
0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0x26,
0x27, 0xd4, 0x20, 0x4a, 0x4e, 0x83, 0x87, 0x87,
0xd5, 0xd6, 0x24, 0x25, 0x2d, 0x2e, 0xd7, 0xd8,
0xa7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
/*
* NAME: data->getb()
* DESCRIPTION: marshal 1 byte into local host format
*/
char d_getb(unsigned char *ptr)
{
return (char) ptr[0];
}
/*
* NAME: data->getw()
* DESCRIPTION: marshal 2 bytes into local host format
*/
short d_getw(unsigned char *ptr)
{
return (short)
((ptr[0] << 8) |
(ptr[1] << 0));
}
/*
* NAME: data->getl()
* DESCRIPTION: marshal 4 bytes into local host format
*/
long d_getl(unsigned char *ptr)
{
return (long)
((ptr[0] << 24) |
(ptr[1] << 16) |
(ptr[2] << 8) |
(ptr[3] << 0));
}
/*
* NAME: data->putb()
* DESCRIPTION: marshal 1 byte out to Macintosh (big-endian) format
*/
void d_putb(unsigned char *ptr, char data)
{
ptr[0] = (unsigned char) data;
}
/*
* NAME: data->putw()
* DESCRIPTION: marshal 2 bytes out to Macintosh (big-endian) format
*/
void d_putw(unsigned char *ptr, short data)
{
ptr[0] = ((unsigned short) data & 0xff00) >> 8;
ptr[1] = ((unsigned short) data & 0x00ff) >> 0;
}
/*
* NAME: data->putl()
* DESCRIPTION: marshal 4 bytes out to Macintosh (big-endian) format
*/
void d_putl(unsigned char *ptr, long data)
{
ptr[0] = ((unsigned long) data & 0xff000000) >> 24;
ptr[1] = ((unsigned long) data & 0x00ff0000) >> 16;
ptr[2] = ((unsigned long) data & 0x0000ff00) >> 8;
ptr[3] = ((unsigned long) data & 0x000000ff) >> 0;
}
/*
* NAME: data->fetchb()
* DESCRIPTION: incrementally retrieve a byte of data
*/
void d_fetchb(unsigned char **ptr, char *dest)
{
*dest = d_getb(*ptr);
*ptr += 1;
}
/*
* NAME: data->fetchw()
* DESCRIPTION: incrementally retrieve a word of data
*/
void d_fetchw(unsigned char **ptr, short *dest)
{
*dest = d_getw(*ptr);
*ptr += 2;
}
/*
* NAME: data->fetchl()
* DESCRIPTION: incrementally retrieve a long word of data
*/
void d_fetchl(unsigned char **ptr, long *dest)
{
*dest = d_getl(*ptr);
*ptr += 4;
}
/*
* NAME: data->fetchs()
* DESCRIPTION: incrementally retrieve a string
*/
void d_fetchs(unsigned char **ptr, char *dest, int size)
{
int len;
char blen;
d_fetchb(ptr, &blen);
len = blen;
if (len > 0 && len < size)
memcpy(dest, *ptr, len);
else
len = 0;
dest[len] = 0;
*ptr += size - 1;
}
/*
* NAME: data->storeb()
* DESCRIPTION: incrementally store a byte of data
*/
void d_storeb(unsigned char **ptr, char data)
{
d_putb(*ptr, data);
*ptr += 1;
}
/*
* NAME: data->storew()
* DESCRIPTION: incrementally store a word of data
*/
void d_storew(unsigned char **ptr, short data)
{
d_putw(*ptr, data);
*ptr += 2;
}
/*
* NAME: data->storel()
* DESCRIPTION: incrementally store a long word of data
*/
void d_storel(unsigned char **ptr, long data)
{
d_putl(*ptr, data);
*ptr += 4;
}
/*
* NAME: data->stores()
* DESCRIPTION: incrementally store a string
*/
void d_stores(unsigned char **ptr, char *src, int size)
{
int len;
len = strlen(src);
if (len > --size)
len = 0;
d_storeb(ptr, (unsigned char) len);
memcpy(*ptr, src, len);
memset(*ptr + len, 0, size - len);
*ptr += size;
}
/*
* NAME: calctzdiff()
* DESCRIPTION: calculate the timezone difference between local time and UTC
*/
static
void calctzdiff(void)
{
time_t t;
int isdst;
struct tm tm, *tmp;
time(&t);
isdst = localtime(&t)->tm_isdst;
tmp = gmtime(&t);
if (tmp)
{
tm = *tmp;
tm.tm_isdst = isdst;
tzdiff = t - mktime(&tm);
}
else
tzdiff = 0;
}
/*
* NAME: data->tomtime()
* DESCRIPTION: convert UNIX time to Macintosh time
*/
unsigned long d_tomtime(unsigned long secs)
{
time_t utime = secs;
if (tzdiff == -1)
calctzdiff();
return utime + tzdiff + MUTDIFF;
}
/*
* NAME: data->toutime()
* DESCRIPTION: convert Macintosh time to UNIX time
*/
unsigned long d_toutime(unsigned long secs)
{
time_t utime = secs;
if (tzdiff == -1)
calctzdiff();
return utime - MUTDIFF - tzdiff;
}
/*
* NAME: data->relstring()
* DESCRIPTION: compare two strings as per MacOS for HFS
*/
int d_relstring(char *str1, char *str2)
{
int diff;
while (*str1 && *str2)
{
diff = hfs_charorder[(unsigned char) *str1] -
hfs_charorder[(unsigned char) *str2];
if (diff)
return diff;
++str1, ++str2;
}
if (! *str1 && *str2)
return -1;
else if (*str1 && ! *str2)
return 1;
return 0;
}

View File

@ -0,0 +1,41 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
char d_getb(unsigned char *);
short d_getw(unsigned char *);
long d_getl(unsigned char *);
void d_putb(unsigned char *, char);
void d_putw(unsigned char *, short);
void d_putl(unsigned char *, long);
void d_fetchb(unsigned char **, char *);
void d_fetchw(unsigned char **, short *);
void d_fetchl(unsigned char **, long *);
void d_fetchs(unsigned char **, char *, int);
void d_storeb(unsigned char **, char);
void d_storew(unsigned char **, short);
void d_storel(unsigned char **, long);
void d_stores(unsigned char **, char *, int);
unsigned long d_tomtime(unsigned long);
unsigned long d_toutime(unsigned long);
int d_relstring(char *, char *);

View File

@ -0,0 +1,456 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <string.h>
# include <errno.h>
# include "internal.h"
# include "data.h"
# include "block.h"
# include "file.h"
# include "btree.h"
# include "record.h"
# include "volume.h"
/* #include <stdio.h> */
/*
* NAME: file->selectfork()
* DESCRIPTION: choose a fork for file operations
*/
void f_selectfork(hfsfile *file, int fork)
{
if (fork == 0)
{
file->fork = fkData;
memcpy(file->ext, file->cat.u.fil.filExtRec, sizeof(ExtDataRec));
}
else
{
file->fork = fkRsrc;
memcpy(file->ext, file->cat.u.fil.filRExtRec, sizeof(ExtDataRec));
}
file->fabn = 0;
file->pos = 0;
}
/*
* NAME: file->getptrs()
* DESCRIPTION: make pointers to the current fork's lengths and extents
*/
void f_getptrs(hfsfile *file, unsigned long **lglen,
unsigned long **pylen, ExtDataRec **extrec)
{
if (file->fork == fkData)
{
if (lglen)
*lglen = &file->cat.u.fil.filLgLen;
if (pylen)
*pylen = &file->cat.u.fil.filPyLen;
if (extrec)
*extrec = &file->cat.u.fil.filExtRec;
}
else
{
if (lglen)
*lglen = &file->cat.u.fil.filRLgLen;
if (pylen)
*pylen = &file->cat.u.fil.filRPyLen;
if (extrec)
*extrec = &file->cat.u.fil.filRExtRec;
}
}
/*
* NAME: file->doblock()
* DESCRIPTION: read or write a numbered block from a file
*/
int f_doblock(hfsfile *file, unsigned long num, block *bp,
int (*func)(hfsvol *, unsigned int, unsigned int, block *))
{
unsigned int abnum;
unsigned int blnum;
unsigned int fabn;
int i;
abnum = num / file->vol->lpa;
blnum = num % file->vol->lpa;
/* locate the appropriate extent record */
fabn = file->fabn;
if (abnum < fabn)
{
ExtDataRec *extrec;
f_getptrs(file, 0, 0, &extrec);
fabn = file->fabn = 0;
memcpy(file->ext, extrec, sizeof(ExtDataRec));
}
else
abnum -= fabn;
while (1)
{
unsigned int num;
for (i = 0; i < 3; ++i)
{
num = file->ext[i].xdrNumABlks;
#ifdef APPLE_HYB
if (i > 0) {
/* SHOULD NOT HAPPEN! - all the files should not be fragmented
if this happens, then a serious problem has occured, may be
a hard linked file? */
#ifdef DEBUG
fprintf(stderr,"file: %s %d\n",file->name, i); */
#endif /* DEBUG */
ERROR(HCE_ERROR, "Possible Catalog file overflow - please report error");
return -1;
}
#endif /* APPLE_HYB */
if (abnum < num)
return func(file->vol, file->ext[i].xdrStABN + abnum, blnum, bp);
fabn += num;
abnum -= num;
}
if (v_extsearch(file, fabn, &file->ext, 0) <= 0)
return -1;
file->fabn = fabn;
}
}
/*
* NAME: file->alloc()
* DESCRIPTION: reserve disk blocks for a file
*/
int f_alloc(hfsfile *file)
{
hfsvol *vol = file->vol;
ExtDescriptor blocks;
ExtDataRec *extrec;
unsigned long *pylen, clumpsz;
unsigned int start, end;
node n;
int i;
clumpsz = file->clump;
if (clumpsz == 0)
clumpsz = vol->mdb.drClpSiz;
blocks.xdrNumABlks = clumpsz / vol->mdb.drAlBlkSiz;
if (v_allocblocks(vol, &blocks) < 0)
return -1;
/* update the file's extents */
f_getptrs(file, 0, &pylen, &extrec);
start = file->fabn;
end = *pylen / vol->mdb.drAlBlkSiz;
n.nnum = 0;
i = -1;
while (start < end)
{
for (i = 0; i < 3; ++i)
{
unsigned int num;
num = file->ext[i].xdrNumABlks;
start += num;
if (start == end)
break;
else if (start > end)
{
v_freeblocks(vol, &blocks);
ERROR(EIO, "file extents exceed file physical length");
return -1;
}
else if (num == 0)
{
v_freeblocks(vol, &blocks);
ERROR(EIO, "empty file extent");
return -1;
}
}
if (start == end)
break;
if (v_extsearch(file, start, &file->ext, &n) <= 0)
{
v_freeblocks(vol, &blocks);
return -1;
}
file->fabn = start;
}
if (i >= 0 &&
file->ext[i].xdrStABN + file->ext[i].xdrNumABlks == blocks.xdrStABN)
file->ext[i].xdrNumABlks += blocks.xdrNumABlks;
else
{
/* create a new extent descriptor */
if (++i < 3)
file->ext[i] = blocks;
else
{
ExtKeyRec key;
unsigned char record[HFS_EXTRECMAXLEN];
int reclen;
/* record is full; create a new one */
file->ext[0] = blocks;
for (i = 1; i < 3; ++i)
{
file->ext[i].xdrStABN = 0;
file->ext[i].xdrNumABlks = 0;
}
file->fabn = start;
r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, end);
r_packextkey(&key, record, &reclen);
r_packextdata(&file->ext, HFS_RECDATA(record), &reclen);
if (bt_insert(&vol->ext, record, reclen) < 0)
{
v_freeblocks(vol, &blocks);
return -1;
}
i = -1;
}
}
if (i >= 0)
{
/* store the modified extent record */
if (file->fabn)
{
if ((n.nnum == 0 &&
v_extsearch(file, file->fabn, 0, &n) <= 0) ||
v_putextrec(&file->ext, &n) < 0)
{
v_freeblocks(vol, &blocks);
return -1;
}
}
else
memcpy(extrec, file->ext, sizeof(ExtDataRec));
}
*pylen += blocks.xdrNumABlks * vol->mdb.drAlBlkSiz;
file->flags |= HFS_UPDATE_CATREC;
return blocks.xdrNumABlks;
}
/*
* NAME: file->trunc()
* DESCRIPTION: release disk blocks unneeded by a file
*/
int f_trunc(hfsfile *file)
{
ExtDataRec *extrec;
unsigned long *lglen, *pylen, alblksz, newpylen;
unsigned int dlen, start, end;
node n;
int i;
f_getptrs(file, &lglen, &pylen, &extrec);
alblksz = file->vol->mdb.drAlBlkSiz;
newpylen = (*lglen / alblksz + (*lglen % alblksz != 0)) * alblksz;
if (newpylen > *pylen)
{
ERROR(EIO, "file size exceeds physical length");
return -1;
}
else if (newpylen == *pylen)
return 0;
dlen = (*pylen - newpylen) / alblksz;
start = file->fabn;
end = newpylen / alblksz;
if (start >= end)
{
start = file->fabn = 0;
memcpy(file->ext, extrec, sizeof(ExtDataRec));
}
n.nnum = 0;
i = -1;
while (start < end)
{
for (i = 0; i < 3; ++i)
{
unsigned int num;
num = file->ext[i].xdrNumABlks;
start += num;
if (start >= end)
break;
else if (num == 0)
{
ERROR(EIO, "empty file extent");
return -1;
}
}
if (start >= end)
break;
if (v_extsearch(file, start, &file->ext, &n) <= 0)
return -1;
file->fabn = start;
}
if (start > end)
{
ExtDescriptor blocks;
file->ext[i].xdrNumABlks -= start - end;
dlen -= start - end;
blocks.xdrStABN = file->ext[i].xdrStABN + file->ext[i].xdrNumABlks;
blocks.xdrNumABlks = start - end;
v_freeblocks(file->vol, &blocks);
}
*pylen = newpylen;
file->flags |= HFS_UPDATE_CATREC;
do
{
while (dlen && ++i < 3)
{
unsigned int num;
num = file->ext[i].xdrNumABlks;
start += num;
if (num == 0)
{
ERROR(EIO, "empty file extent");
return -1;
}
else if (num > dlen)
{
ERROR(EIO, "file extents exceed physical size");
return -1;
}
dlen -= num;
v_freeblocks(file->vol, &file->ext[i]);
file->ext[i].xdrStABN = 0;
file->ext[i].xdrNumABlks = 0;
}
if (file->fabn)
{
if (n.nnum == 0 &&
v_extsearch(file, file->fabn, 0, &n) <= 0)
return -1;
if (file->ext[0].xdrNumABlks)
{
if (v_putextrec(&file->ext, &n) < 0)
return -1;
}
else
{
if (bt_delete(&file->vol->ext, HFS_NODEREC(n, n.rnum)) < 0)
return -1;
n.nnum = 0;
}
}
else
memcpy(extrec, file->ext, sizeof(ExtDataRec));
if (dlen)
{
if (v_extsearch(file, start, &file->ext, &n) <= 0)
return -1;
file->fabn = start;
i = -1;
}
}
while (dlen);
return 0;
}
/*
* NAME: file->flush()
* DESCRIPTION: flush all pending changes to an open file
*/
int f_flush(hfsfile *file)
{
hfsvol *vol = file->vol;
if (! (vol->flags & HFS_READONLY))
{
if (file->flags & HFS_UPDATE_CATREC)
{
node n;
file->cat.u.fil.filStBlk = file->cat.u.fil.filExtRec[0].xdrStABN;
file->cat.u.fil.filRStBlk = file->cat.u.fil.filRExtRec[0].xdrStABN;
file->cat.u.fil.filClpSize = file->clump;
if (v_catsearch(file->vol, file->parid, file->name, 0, 0, &n) <= 0 ||
v_putcatrec(&file->cat, &n) < 0)
return -1;
file->flags &= ~HFS_UPDATE_CATREC;
}
}
return 0;
}

View File

@ -0,0 +1,36 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
enum {
fkData = 0x00,
fkRsrc = 0xff
};
void f_selectfork(hfsfile *, int);
void f_getptrs(hfsfile *, unsigned long **, unsigned long **, ExtDataRec **);
int f_doblock(hfsfile *, unsigned long, block *,
int (*)(hfsvol *, unsigned int, unsigned int, block *));
# define f_getblock(file, num, bp) f_doblock(file, num, bp, b_readab)
# define f_putblock(file, num, bp) f_doblock(file, num, bp, b_writeab)
int f_alloc(hfsfile *);
int f_trunc(hfsfile *);
int f_flush(hfsfile *);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <time.h>
#ifdef APPLE_HYB
#include "hybrid.h"
/* don't need device locking for mkhybrid */
#ifndef NODEVLOCKS
#define NODEVLOCKS
#endif /* NODEVLOCKS */
#endif /* APPLE_HYB */
# define HFS_BLOCKSZ 512
# define HFS_MAX_FLEN 31
# define HFS_MAX_VLEN 27
typedef struct _hfsvol_ hfsvol;
typedef struct _hfsfile_ hfsfile;
typedef struct _hfsdir_ hfsdir;
typedef struct {
char name[HFS_MAX_VLEN + 1]; /* name of volume */
int flags; /* volume flags */
unsigned long totbytes; /* total bytes on volume */
unsigned long freebytes; /* free bytes on volume */
time_t crdate; /* volume creation date */
time_t mddate; /* last volume modification date */
} hfsvolent;
typedef struct {
char name[HFS_MAX_FLEN + 1]; /* catalog name */
int flags; /* bit flags */
long cnid; /* catalog node id (CNID) */
long parid; /* CNID of parent directory */
time_t crdate; /* date of creation */
time_t mddate; /* date of last modification */
unsigned long dsize; /* size of data fork */
unsigned long rsize; /* size of resource fork */
char type[5]; /* file type code (plus null) */
char creator[5]; /* file creator code (plus null) */
short fdflags; /* Macintosh Finder flags */
} hfsdirent;
# define HFS_ISDIR 0x01
# define HFS_ISLOCKED 0x02
# define HFS_CNID_ROOTPAR 1
# define HFS_CNID_ROOTDIR 2
# define HFS_CNID_EXT 3
# define HFS_CNID_CAT 4
# define HFS_CNID_BADALLOC 5
# define HFS_FNDR_ISONDESK (1 << 0)
# define HFS_FNDR_COLOR 0x0e
# define HFS_FNDR_COLORRESERVED (1 << 4)
# define HFS_FNDR_REQUIRESSWITCHLAUNCH (1 << 5)
# define HFS_FNDR_ISSHARED (1 << 6)
# define HFS_FNDR_HASNOINITS (1 << 7)
# define HFS_FNDR_HASBEENINITED (1 << 8)
# define HFS_FNDR_RESERVED (1 << 9)
# define HFS_FNDR_HASCUSTOMICON (1 << 10)
# define HFS_FNDR_ISSTATIONERY (1 << 11)
# define HFS_FNDR_NAMELOCKED (1 << 12)
# define HFS_FNDR_HASBUNDLE (1 << 13)
# define HFS_FNDR_ISINVISIBLE (1 << 14)
# define HFS_FNDR_ISALIAS (1 << 15)
extern char *hfs_error;
extern unsigned char hfs_charorder[];
#ifdef APPLE_HYB
hfsvol *hfs_mount(hce_mem *, int, int);
#else
hfsvol *hfs_mount(char *, int, int);
#endif /* APPLE_HYB */
int hfs_flush(hfsvol *);
void hfs_flushall(void);
#ifdef APPLE_HYB
int hfs_umount(hfsvol *, long);
#else
int hfs_umount(hfsvol *);
#endif /* APPLE_HYB */
void hfs_umountall(void);
hfsvol *hfs_getvol(char *);
void hfs_setvol(hfsvol *);
int hfs_vstat(hfsvol *, hfsvolent *);
#ifdef APPLE_HYB
int hfs_format(hce_mem *, int, char *);
#else
int hfs_format(char *, int, char *);
#endif /* APPLE_HYB */
int hfs_chdir(hfsvol *, char *);
long hfs_getcwd(hfsvol *);
int hfs_setcwd(hfsvol *, long);
int hfs_dirinfo(hfsvol *, long *, char *);
hfsdir *hfs_opendir(hfsvol *, char *);
int hfs_readdir(hfsdir *, hfsdirent *);
int hfs_closedir(hfsdir *);
hfsfile *hfs_open(hfsvol *, char *);
int hfs_setfork(hfsfile *, int);
int hfs_getfork(hfsfile *);
long hfs_read(hfsfile *, void *, unsigned long);
long hfs_write(hfsfile *, void *, unsigned long);
int hfs_truncate(hfsfile *, unsigned long);
long hfs_lseek(hfsfile *, long, int);
#ifdef APPLE_HYB
int hfs_close(hfsfile *, long, long);
#else
int hfs_close(hfsfile *);
#endif /* APPLE_HYB */
int hfs_stat(hfsvol *, char *, hfsdirent *);
int hfs_fstat(hfsfile *, hfsdirent *);
int hfs_setattr(hfsvol *, char *, hfsdirent *);
int hfs_fsetattr(hfsfile *, hfsdirent *);
int hfs_mkdir(hfsvol *, char *);
int hfs_rmdir(hfsvol *, char *);
int hfs_create(hfsvol *, char *, char *, char *);
int hfs_delete(hfsvol *, char *);
int hfs_rename(hfsvol *, char *, char *);
#ifdef APPLE_HYB
unsigned short hfs_get_drAllocPtr(hfsfile *);
int hfs_set_drAllocPtr(hfsfile *, unsigned short, int size);
#endif /* APPLE_HYB */

View File

@ -0,0 +1,39 @@
/*
** hybrid.h: extra info needed by libhfs and mkisofs
**
** James Pearson 15/9/97
*/
#ifndef _HYBRID_H
#define CTC 2 /* factor to increase initial Catalog file
size to prevent the file growing */
#define CTC_LOOP 4 /* number of attemps before we give up
trying to create the volume */
#define HCE_ERROR -9999 /* dummy errno value for Catalog file
size problems */
#define HFS_MAP_SIZE 16 /* size of HFS partition maps (8Kb) */
typedef struct {
int hfs_ce_size; /* extents/catalog size in HFS blks */
int hfs_hdr_size; /* vol header size in HFS blks */
int hfs_dt_size; /* Desktop file size in HFS blks */
int hfs_tot_size; /* extents/catalog/dt size in HFS blks */
int hfs_map_size; /* size of partition maps in HFS blks */
int hfs_vol_size; /* size of volume in bytes */
unsigned char *hfs_ce; /* mem copy of extents/catalog files */
unsigned char *hfs_hdr; /* mem copy of vol header */
unsigned char *hfs_alt_mdb; /* location of alternate MDB */
unsigned char *hfs_map; /* location of partiton_maps */
int Csize; /* size of allocation unit */
int XTCsize; /* default size of catalog/extents files */
int ctc_size; /* factor to increase Catalog file size */
char *error; /* HFS error message */
} hce_mem;
#define ERROR_SIZE 1024
#define _HYBRID_H
#endif /* _HYBRID_H */

View File

@ -0,0 +1,355 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <time.h>
# include "hfs.h"
# define ERROR(code, str) (hfs_error = (str), errno = (code))
# define SIZE(type, n) ((size_t) (sizeof(type) * (n)))
# define ALLOC(type, n) ((type *) malloc(SIZE(type, n)))
# define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0)
# define FREE(ptr) ((ptr) ? (void) free((void *) ptr) : (void) 0)
# define REALLOC(ptr, type, n) \
((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n))))
# define REALLOCX(ptr, type, n) \
((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0))
# define BMTST(bm, num) \
(((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07)))
# define BMSET(bm, num) \
(((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07)))
# define BMCLR(bm, num) \
(((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07)))
typedef unsigned char block[HFS_BLOCKSZ];
typedef signed char Char;
typedef unsigned char UChar;
typedef signed char SignedByte;
typedef signed short Integer;
typedef unsigned short UInteger;
typedef signed long LongInt;
typedef unsigned long ULongInt;
typedef char Str15[16];
typedef char Str31[32];
typedef long OSType;
typedef struct {
UInteger xdrStABN; /* first allocation block */
UInteger xdrNumABlks; /* number of allocation blocks */
} ExtDescriptor;
typedef ExtDescriptor ExtDataRec[3];
typedef struct {
SignedByte xkrKeyLen; /* key length */
SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */
ULongInt xkrFNum; /* file number */
UInteger xkrFABN; /* starting file allocation block */
} ExtKeyRec;
typedef struct {
SignedByte ckrKeyLen; /* key length */
SignedByte ckrResrv1; /* reserved */
ULongInt ckrParID; /* parent directory ID */
Str31 ckrCName; /* catalog node name */
} CatKeyRec;
# define HFS_MAP1SZ 256
# define HFS_MAPXSZ 492
# define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum])
# define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr))
# define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1)
# define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr))
# define HFS_CATDATALEN sizeof(CatDataRec)
# define HFS_EXTDATALEN sizeof(ExtDataRec)
# define HFS_CATKEYLEN sizeof(CatKeyRec)
# define HFS_EXTKEYLEN sizeof(ExtKeyRec)
# define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN)
# define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN)
# define HFS_MAXRECLEN HFS_CATRECMAXLEN
typedef struct {
Integer v; /* vertical coordinate */
Integer h; /* horizontal coordinate */
} Point;
typedef struct {
Integer top; /* top edge of rectangle */
Integer left; /* left edge */
Integer bottom; /* bottom edge */
Integer right; /* rightmost edge */
} Rect;
typedef struct {
Rect frRect; /* folder's rectangle */
Integer frFlags; /* flags */
Point frLocation; /* folder's location */
Integer frView; /* folder's view */
} DInfo;
typedef struct {
Point frScroll; /* scroll position */
LongInt frOpenChain; /* directory ID chain of open folders */
Integer frUnused; /* reserved */
Integer frComment; /* comment ID */
LongInt frPutAway; /* directory ID */
} DXInfo;
typedef struct {
OSType fdType; /* file type */
OSType fdCreator; /* file's creator */
Integer fdFlags; /* flags */
Point fdLocation; /* file's location */
Integer fdFldr; /* file's window */
} FInfo;
typedef struct {
Integer fdIconID; /* icon ID */
Integer fdUnused[4]; /* reserved */
Integer fdComment; /* comment ID */
LongInt fdPutAway; /* home directory ID */
} FXInfo;
typedef struct {
Integer drSigWord; /* volume signature (0x4244 for HFS) */
LongInt drCrDate; /* date and time of volume creation */
LongInt drLsMod; /* date and time of last modification */
Integer drAtrb; /* volume attributes */
UInteger drNmFls; /* number of files in root directory */
UInteger drVBMSt; /* first block of volume bit map (always 3) */
UInteger drAllocPtr; /* start of next allocation search */
UInteger drNmAlBlks; /* number of allocation blocks in volume */
ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */
ULongInt drClpSiz; /* default clump size */
UInteger drAlBlSt; /* first allocation block in volume */
LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */
UInteger drFreeBks; /* number of unused allocation blocks */
char drVN[28]; /* volume name (1-27 chars) */
LongInt drVolBkUp; /* date and time of last backup */
Integer drVSeqNum; /* volume backup sequence number */
ULongInt drWrCnt; /* volume write count */
ULongInt drXTClpSiz; /* clump size for extents overflow file */
ULongInt drCTClpSiz; /* clump size for catalog file */
UInteger drNmRtDirs; /* number of directories in root directory */
ULongInt drFilCnt; /* number of files in volume */
ULongInt drDirCnt; /* number of directories in volume */
LongInt drFndrInfo[8]; /* information used by the Finder */
UInteger drVCSize; /* size (in blocks) of volume cache */
UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */
UInteger drCtlCSize; /* size (in blocks) of common volume cache */
ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */
ExtDataRec drXTExtRec; /* first extent record for extents file */
ULongInt drCTFlSize; /* size (in bytes) of catalog file */
ExtDataRec drCTExtRec; /* first extent record for catalog file */
} MDB;
# define HFS_ATRB_BUSY (1 << 6)
# define HFS_ATRB_HLOCKED (1 << 7)
# define HFS_ATRB_UMOUNTED (1 << 8)
# define HFS_ATRB_BBSPARED (1 << 9)
# define HFS_ATRB_COPYPROT (1 << 14)
# define HFS_ATRB_SLOCKED (1 << 15)
typedef enum {
cdrDirRec = 1,
cdrFilRec = 2,
cdrThdRec = 3,
cdrFThdRec = 4
} CatDataType;
typedef struct {
SignedByte cdrType; /* record type */
SignedByte cdrResrv2; /* reserved */
union {
struct { /* cdrDirRec */
Integer dirFlags; /* directory flags */
UInteger dirVal; /* directory valence */
ULongInt dirDirID; /* directory ID */
LongInt dirCrDat; /* date and time of creation */
LongInt dirMdDat; /* date and time of last modification */
LongInt dirBkDat; /* date and time of last backup */
DInfo dirUsrInfo; /* Finder information */
DXInfo dirFndrInfo; /* additional Finder information */
LongInt dirResrv[4]; /* reserved */
} dir;
struct { /* cdrFilRec */
SignedByte
filFlags; /* file flags */
SignedByte
filTyp; /* file type */
FInfo filUsrWds; /* Finder information */
ULongInt filFlNum; /* file ID */
UInteger filStBlk; /* first alloc block of data fork */
ULongInt filLgLen; /* logical EOF of data fork */
ULongInt filPyLen; /* physical EOF of data fork */
UInteger filRStBlk; /* first alloc block of resource fork */
ULongInt filRLgLen; /* logical EOF of resource fork */
ULongInt filRPyLen; /* physical EOF of resource fork */
LongInt filCrDat; /* date and time of creation */
LongInt filMdDat; /* date and time of last modification */
LongInt filBkDat; /* date and time of last backup */
FXInfo filFndrInfo; /* additional Finder information */
UInteger filClpSize; /* file clump size */
ExtDataRec
filExtRec; /* first data fork extent record */
ExtDataRec
filRExtRec; /* first resource fork extent record */
LongInt filResrv; /* reserved */
} fil;
struct { /* cdrThdRec */
LongInt thdResrv[2]; /* reserved */
ULongInt thdParID; /* parent ID for this directory */
Str31 thdCName; /* name of this directory */
} dthd;
struct { /* cdrFThdRec */
LongInt fthdResrv[2]; /* reserved */
ULongInt fthdParID; /* parent ID for this file */
Str31 fthdCName; /* name of this file */
} fthd;
} u;
} CatDataRec;
struct _hfsfile_ {
struct _hfsvol_ *vol; /* pointer to volume descriptor */
long parid; /* parent directory ID of this file */
char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */
CatDataRec cat; /* catalog information */
ExtDataRec ext; /* current extent record */
unsigned int fabn; /* starting file allocation block number */
int fork; /* current selected fork for I/O */
unsigned long pos; /* current file seek pointer */
unsigned long clump; /* file's clump size, for allocation */
int flags; /* bit flags */
struct _hfsfile_ *prev;
struct _hfsfile_ *next;
};
# define HFS_UPDATE_CATREC 0x01
typedef struct {
ULongInt ndFLink; /* forward link */
ULongInt ndBLink; /* backward link */
SignedByte ndType; /* node type */
SignedByte ndNHeight; /* node level */
UInteger ndNRecs; /* number of records in node */
Integer ndResv2; /* reserved */
} NodeDescriptor;
# define HFS_MAXRECS 35 /* maximum based on minimum record size */
typedef struct _node_ {
struct _btree_ *bt; /* btree to which this node belongs */
unsigned long nnum; /* node index */
NodeDescriptor nd; /* node descriptor */
int rnum; /* current record index */
UInteger roff[HFS_MAXRECS + 1]; /* record offsets */
block data; /* raw contents of node */
} node;
enum {
ndIndxNode = 0x00,
ndHdrNode = 0x01,
ndMapNode = 0x02,
ndLeafNode = 0xff
};
struct _hfsdir_ {
struct _hfsvol_ *vol; /* associated volume */
long dirid; /* directory ID of interest (or 0) */
node n; /* current B*-tree node */
struct _hfsvol_ *vptr; /* current volume pointer */
struct _hfsdir_ *prev;
struct _hfsdir_ *next;
};
typedef struct {
UInteger bthDepth; /* current depth of tree */
ULongInt bthRoot; /* number of root node */
ULongInt bthNRecs; /* number of leaf records in tree */
ULongInt bthFNode; /* number of first leaf node */
ULongInt bthLNode; /* number of last leaf node */
UInteger bthNodeSize; /* size of a node */
UInteger bthKeyLen; /* maximum length of a key */
ULongInt bthNNodes; /* total number of nodes in tree */
ULongInt bthFree; /* number of free nodes */
SignedByte bthResv[76]; /* reserved */
} BTHdrRec;
typedef struct _btree_ {
hfsfile f; /* subset file information */
node hdrnd; /* header node */
BTHdrRec hdr; /* header record */
char *map; /* usage bitmap */
unsigned long mapsz; /* number of bytes in bitmap */
int flags; /* bit flags */
int (*compare)(unsigned char *, unsigned char *);
/* key comparison function */
} btree;
# define HFS_UPDATE_BTHDR 0x01
struct _hfsvol_ {
int fd; /* volume's open file descriptor */
int flags; /* bit flags */
#ifdef APPLE_HYB
hce_mem *hce; /* Extras needed by libhfs/mkisofs */
#endif /* APPLE_HYB */
int pnum; /* ordinal HFS partition number */
unsigned long vstart; /* logical block offset to start of volume */
unsigned long vlen; /* number of logical blocks in volume */
unsigned int lpa; /* number of logical blocks per allocation block */
MDB mdb; /* master directory block */
block *vbm; /* volume bit map */
btree ext; /* B*-tree control block for extents overflow file */
btree cat; /* B*-tree control block for catalog file */
long cwd; /* directory id of current working directory */
int refs; /* number of external references to this volume */
hfsfile *files; /* list of open files */
hfsdir *dirs; /* list of open directories */
struct _hfsvol_ *prev;
struct _hfsvol_ *next;
};
# define HFS_READONLY 0x01
# define HFS_UPDATE_MDB 0x10
# define HFS_UPDATE_ALTMDB 0x20
# define HFS_UPDATE_VBM 0x40
extern hfsvol *hfs_mounts;
extern hfsvol *hfs_curvol;

View File

@ -0,0 +1,515 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <string.h>
# include <stdlib.h>
# include <errno.h>
# include <unistd.h>
# include <fcntl.h>
# include "internal.h"
# include "data.h"
# include "block.h"
# include "low.h"
# include "file.h"
/*
* NAME: low->lockvol()
* DESCRIPTION: prevent destructive simultaneous access
*/
int l_lockvol(hfsvol *vol)
{
# ifndef NODEVLOCKS
struct flock lock;
lock.l_type = (vol->flags & HFS_READONLY) ? F_RDLCK : F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
if (fcntl(vol->fd, F_SETLK, &lock) < 0)
{
ERROR(errno, "unable to obtain lock for device");
return -1;
}
# endif
return 0;
}
/*
* NAME: low->readblock0()
* DESCRIPTION: read the first sector and get bearings
*/
int l_readblock0(hfsvol *vol)
{
block b;
unsigned char *ptr = b;
Block0 rec;
if (b_readlb(vol, 0, &b) < 0)
return -1;
d_fetchw(&ptr, &rec.sbSig);
d_fetchw(&ptr, &rec.sbBlkSize);
d_fetchl(&ptr, &rec.sbBlkCount);
d_fetchw(&ptr, &rec.sbDevType);
d_fetchw(&ptr, &rec.sbDevId);
d_fetchl(&ptr, &rec.sbData);
d_fetchw(&ptr, &rec.sbDrvrCount);
d_fetchl(&ptr, &rec.ddBlock);
d_fetchw(&ptr, &rec.ddSize);
d_fetchw(&ptr, &rec.ddType);
switch (rec.sbSig)
{
case 0x4552: /* block device with a partition table */
{
if (rec.sbBlkSize != HFS_BLOCKSZ)
{
ERROR(EINVAL, "unsupported block size");
return -1;
}
vol->vlen = rec.sbBlkCount;
if (l_readpm(vol) < 0)
return -1;
}
break;
case 0x4c4b: /* bootable floppy */
vol->pnum = 0;
break;
default: /* non-bootable floppy or something else */
/* some miscreant media may also be partitioned;
we attempt to read a partition map, but ignore any failure */
if (l_readpm(vol) < 0)
vol->pnum = 0;
}
return 0;
}
/*
* NAME: low->readpm()
* DESCRIPTION: read the partition map and locate an HFS volume
*/
int l_readpm(hfsvol *vol)
{
block b;
unsigned char *ptr;
Partition map;
unsigned long bnum;
int pnum;
bnum = 1;
pnum = vol->pnum;
while (1)
{
if (b_readlb(vol, bnum, &b) < 0)
return -1;
ptr = b;
d_fetchw(&ptr, &map.pmSig);
d_fetchw(&ptr, &map.pmSigPad);
d_fetchl(&ptr, &map.pmMapBlkCnt);
d_fetchl(&ptr, &map.pmPyPartStart);
d_fetchl(&ptr, &map.pmPartBlkCnt);
memcpy(map.pmPartName, ptr, 32);
map.pmPartName[32] = 0;
ptr += 32;
memcpy(map.pmParType, ptr, 32);
map.pmParType[32] = 0;
ptr += 32;
d_fetchl(&ptr, &map.pmLgDataStart);
d_fetchl(&ptr, &map.pmDataCnt);
d_fetchl(&ptr, &map.pmPartStatus);
d_fetchl(&ptr, &map.pmLgBootStart);
d_fetchl(&ptr, &map.pmBootSize);
d_fetchl(&ptr, &map.pmBootAddr);
d_fetchl(&ptr, &map.pmBootAddr2);
d_fetchl(&ptr, &map.pmBootEntry);
d_fetchl(&ptr, &map.pmBootEntry2);
d_fetchl(&ptr, &map.pmBootCksum);
memcpy(map.pmProcessor, ptr, 16);
map.pmProcessor[16] = 0;
ptr += 16;
if (map.pmSig == 0x5453)
{
/* old partition map sig */
ERROR(EINVAL, "unsupported partition map signature");
return -1;
}
if (map.pmSig != 0x504d)
{
ERROR(EINVAL, "bad partition map");
return -1;
}
if (strcmp((char *) map.pmParType, "Apple_HFS") == 0 && --pnum == 0)
{
if (map.pmLgDataStart != 0)
{
ERROR(EINVAL, "unsupported start of partition logical data");
return -1;
}
vol->vstart = map.pmPyPartStart;
vol->vlen = map.pmPartBlkCnt;
return 0;
}
if (bnum >= map.pmMapBlkCnt)
{
ERROR(EINVAL, "can't find HFS partition");
return -1;
}
++bnum;
}
}
/*
* NAME: low->readmdb()
* DESCRIPTION: read the master directory block into memory
*/
int l_readmdb(hfsvol *vol)
{
block b;
unsigned char *ptr = b;
MDB *mdb = &vol->mdb;
hfsfile *ext = &vol->ext.f;
hfsfile *cat = &vol->cat.f;
int i;
if (b_readlb(vol, 2, &b) < 0)
return -1;
d_fetchw(&ptr, &mdb->drSigWord);
d_fetchl(&ptr, &mdb->drCrDate);
d_fetchl(&ptr, &mdb->drLsMod);
d_fetchw(&ptr, &mdb->drAtrb);
d_fetchw(&ptr, (short *) &mdb->drNmFls);
d_fetchw(&ptr, (short *) &mdb->drVBMSt);
d_fetchw(&ptr, (short *) &mdb->drAllocPtr);
d_fetchw(&ptr, (short *) &mdb->drNmAlBlks);
d_fetchl(&ptr, (long *) &mdb->drAlBlkSiz);
d_fetchl(&ptr, (long *) &mdb->drClpSiz);
d_fetchw(&ptr, (short *) &mdb->drAlBlSt);
d_fetchl(&ptr, &mdb->drNxtCNID);
d_fetchw(&ptr, (short *) &mdb->drFreeBks);
d_fetchs(&ptr, mdb->drVN, sizeof(mdb->drVN));
if (ptr - b != 64)
abort();
d_fetchl(&ptr, &mdb->drVolBkUp);
d_fetchw(&ptr, &mdb->drVSeqNum);
d_fetchl(&ptr, (long *) &mdb->drWrCnt);
d_fetchl(&ptr, (long *) &mdb->drXTClpSiz);
d_fetchl(&ptr, (long *) &mdb->drCTClpSiz);
d_fetchw(&ptr, (short *) &mdb->drNmRtDirs);
d_fetchl(&ptr, (long *) &mdb->drFilCnt);
d_fetchl(&ptr, (long *) &mdb->drDirCnt);
for (i = 0; i < 8; ++i)
d_fetchl(&ptr, &mdb->drFndrInfo[i]);
if (ptr - b != 124)
abort();
d_fetchw(&ptr, (short *) &mdb->drVCSize);
d_fetchw(&ptr, (short *) &mdb->drVBMCSize);
d_fetchw(&ptr, (short *) &mdb->drCtlCSize);
d_fetchl(&ptr, (long *) &mdb->drXTFlSize);
for (i = 0; i < 3; ++i)
{
d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrStABN);
d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrNumABlks);
}
if (ptr - b != 146)
abort();
d_fetchl(&ptr, (long *) &mdb->drCTFlSize);
for (i = 0; i < 3; ++i)
{
d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrStABN);
d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrNumABlks);
}
if (ptr - b != 162)
abort();
vol->lpa = mdb->drAlBlkSiz / HFS_BLOCKSZ;
/* extents pseudo-file structs */
ext->vol = vol;
ext->parid = 0;
strcpy(ext->name, "extents overflow");
ext->cat.cdrType = cdrFilRec;
/* ext->cat.cdrResrv2 */
ext->cat.u.fil.filFlags = 0;
ext->cat.u.fil.filTyp = 0;
/* ext->cat.u.fil.filUsrWds */
ext->cat.u.fil.filFlNum = HFS_CNID_EXT;
ext->cat.u.fil.filStBlk = mdb->drXTExtRec[0].xdrStABN;
ext->cat.u.fil.filLgLen = mdb->drXTFlSize;
ext->cat.u.fil.filPyLen = mdb->drXTFlSize;
ext->cat.u.fil.filRStBlk = 0;
ext->cat.u.fil.filRLgLen = 0;
ext->cat.u.fil.filRPyLen = 0;
ext->cat.u.fil.filCrDat = mdb->drCrDate;
ext->cat.u.fil.filMdDat = mdb->drLsMod;
ext->cat.u.fil.filBkDat = 0;
/* ext->cat.u.fil.filFndrInfo */
ext->cat.u.fil.filClpSize = 0;
memcpy(ext->cat.u.fil.filExtRec, mdb->drXTExtRec, sizeof(ExtDataRec));
for (i = 0; i < 3; ++i)
{
ext->cat.u.fil.filRExtRec[i].xdrStABN = 0;
ext->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
}
f_selectfork(ext, 0);
ext->clump = mdb->drXTClpSiz;
ext->flags = 0;
ext->prev = ext->next = 0;
/* catalog pseudo-file structs */
cat->vol = vol;
cat->parid = 0;
strcpy(cat->name, "catalog");
cat->cat.cdrType = cdrFilRec;
/* cat->cat.cdrResrv2 */
cat->cat.u.fil.filFlags = 0;
cat->cat.u.fil.filTyp = 0;
/* cat->cat.u.fil.filUsrWds */
cat->cat.u.fil.filFlNum = HFS_CNID_CAT;
cat->cat.u.fil.filStBlk = mdb->drCTExtRec[0].xdrStABN;
cat->cat.u.fil.filLgLen = mdb->drCTFlSize;
cat->cat.u.fil.filPyLen = mdb->drCTFlSize;
cat->cat.u.fil.filRStBlk = 0;
cat->cat.u.fil.filRLgLen = 0;
cat->cat.u.fil.filRPyLen = 0;
cat->cat.u.fil.filCrDat = mdb->drCrDate;
cat->cat.u.fil.filMdDat = mdb->drLsMod;
cat->cat.u.fil.filBkDat = 0;
/* cat->cat.u.fil.filFndrInfo */
cat->cat.u.fil.filClpSize = 0;
memcpy(cat->cat.u.fil.filExtRec, mdb->drCTExtRec, sizeof(ExtDataRec));
for (i = 0; i < 3; ++i)
{
cat->cat.u.fil.filRExtRec[i].xdrStABN = 0;
cat->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;
}
f_selectfork(cat, 0);
cat->clump = mdb->drCTClpSiz;
cat->flags = 0;
cat->prev = cat->next = 0;
return 0;
}
/*
* NAME: low->writemdb()
* DESCRIPTION: write the master directory block to disk
*/
int l_writemdb(hfsvol *vol)
{
block b;
unsigned char *ptr = b;
MDB *mdb = &vol->mdb;
hfsfile *ext = &vol->ext.f;
hfsfile *cat = &vol->cat.f;
int i;
memset(&b, 0, sizeof(b));
mdb->drXTFlSize = ext->cat.u.fil.filPyLen;
mdb->drXTClpSiz = ext->clump;
memcpy(mdb->drXTExtRec, ext->cat.u.fil.filExtRec, sizeof(ExtDataRec));
mdb->drCTFlSize = cat->cat.u.fil.filPyLen;
mdb->drCTClpSiz = cat->clump;
memcpy(mdb->drCTExtRec, cat->cat.u.fil.filExtRec, sizeof(ExtDataRec));
d_storew(&ptr, mdb->drSigWord);
d_storel(&ptr, mdb->drCrDate);
d_storel(&ptr, mdb->drLsMod);
d_storew(&ptr, mdb->drAtrb);
d_storew(&ptr, mdb->drNmFls);
d_storew(&ptr, mdb->drVBMSt);
d_storew(&ptr, mdb->drAllocPtr);
d_storew(&ptr, mdb->drNmAlBlks);
d_storel(&ptr, mdb->drAlBlkSiz);
d_storel(&ptr, mdb->drClpSiz);
d_storew(&ptr, mdb->drAlBlSt);
d_storel(&ptr, mdb->drNxtCNID);
d_storew(&ptr, mdb->drFreeBks);
d_stores(&ptr, mdb->drVN, sizeof(mdb->drVN));
if (ptr - b != 64)
abort();
d_storel(&ptr, mdb->drVolBkUp);
d_storew(&ptr, mdb->drVSeqNum);
d_storel(&ptr, mdb->drWrCnt);
d_storel(&ptr, mdb->drXTClpSiz);
d_storel(&ptr, mdb->drCTClpSiz);
d_storew(&ptr, mdb->drNmRtDirs);
d_storel(&ptr, mdb->drFilCnt);
d_storel(&ptr, mdb->drDirCnt);
for (i = 0; i < 8; ++i)
d_storel(&ptr, mdb->drFndrInfo[i]);
if (ptr - b != 124)
abort();
d_storew(&ptr, mdb->drVCSize);
d_storew(&ptr, mdb->drVBMCSize);
d_storew(&ptr, mdb->drCtlCSize);
d_storel(&ptr, mdb->drXTFlSize);
for (i = 0; i < 3; ++i)
{
d_storew(&ptr, mdb->drXTExtRec[i].xdrStABN);
d_storew(&ptr, mdb->drXTExtRec[i].xdrNumABlks);
}
if (ptr - b != 146)
abort();
d_storel(&ptr, mdb->drCTFlSize);
for (i = 0; i < 3; ++i)
{
d_storew(&ptr, mdb->drCTExtRec[i].xdrStABN);
d_storew(&ptr, mdb->drCTExtRec[i].xdrNumABlks);
}
if (ptr - b != 162)
abort();
if (b_writelb(vol, 2, &b) < 0)
return -1;
if (vol->flags & HFS_UPDATE_ALTMDB)
{
#ifdef APPLE_HYB
/* "write" alternative MDB to memory copy */
memcpy(vol->hce->hfs_alt_mdb, &b, sizeof(b));
#else
if (b_writelb(vol, vol->vlen - 2, &b) < 0)
return -1;
#endif /* APPLE_HYB */
}
vol->flags &= ~(HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB);
return 0;
}
/*
* NAME: low->readvbm()
* DESCRIPTION: read the volume bit map into memory
*/
int l_readvbm(hfsvol *vol)
{
int vbmst = vol->mdb.drVBMSt;
int vbmsz = (vol->mdb.drNmAlBlks + 4095) / 4096;
block *bp;
if (vol->mdb.drAlBlSt - vbmst < vbmsz)
{
ERROR(EIO, "volume bitmap collides with volume data");
return -1;
}
bp = ALLOC(block, vbmsz);
if (bp == 0)
{
ERROR(ENOMEM, 0);
return -1;
}
vol->vbm = bp;
while (vbmsz--)
{
if (b_readlb(vol, vbmst++, bp++) < 0)
{
FREE(vol->vbm);
vol->vbm = 0;
return -1;
}
}
return 0;
}
/*
* NAME: low->writevbm()
* DESCRIPTION: write the volume bit map to disk
*/
int l_writevbm(hfsvol *vol)
{
int vbmst = vol->mdb.drVBMSt;
int vbmsz = (vol->mdb.drNmAlBlks + 4095) / 4096;
block *bp = vol->vbm;
while (vbmsz--)
{
if (b_writelb(vol, vbmst++, bp++) < 0)
return -1;
}
vol->flags &= ~HFS_UPDATE_VBM;
return 0;
}

View File

@ -0,0 +1,98 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
typedef struct {
Integer sbSig; /* device signature (should be 0x4552) */
Integer sbBlkSize; /* block size of the device (in bytes) */
LongInt sbBlkCount; /* number of blocks on the device */
Integer sbDevType; /* reserved */
Integer sbDevId; /* reserved */
LongInt sbData; /* reserved */
Integer sbDrvrCount; /* number of driver descriptor entries */
LongInt ddBlock; /* first driver's starting block */
Integer ddSize; /* size of the driver, in 512-byte blocks */
Integer ddType; /* driver operating system type (MacOS = 1) */
Integer ddPad[243]; /* additional drivers, if any */
} Block0;
typedef struct {
Integer bbID; /* boot blocks signature */
LongInt bbEntry; /* entry point to boot code */
Integer bbVersion; /* boot blocks version number */
Integer bbPageFlags; /* used internally */
Str15 bbSysName; /* System filename */
Str15 bbShellName; /* Finder filename */
Str15 bbDbg1Name; /* debugger filename */
Str15 bbDbg2Name; /* debugger filename */
Str15 bbScreenName; /* name of startup screen */
Str15 bbHelloName; /* name of startup program */
Str15 bbScrapName; /* name of system scrap file */
Integer bbCntFCBs; /* number of FCBs to allocate */
Integer bbCntEvts; /* number of event queue elements */
LongInt bb128KSHeap; /* system heap size on 128K Mac */
LongInt bb256KSHeap; /* used internally */
LongInt bbSysHeapSize; /* system heap size on all machines */
Integer filler; /* reserved */
LongInt bbSysHeapExtra; /* additional system heap space */
LongInt bbSysHeapFract; /* fraction of RAM for system heap */
} BootBlkHdr;
typedef struct {
Integer pmSig; /* partition signature (0x504d or 0x5453) */
Integer pmSigPad; /* reserved */
LongInt pmMapBlkCnt; /* number of blocks in partition map */
LongInt pmPyPartStart; /* first physical block of partition */
LongInt pmPartBlkCnt; /* number of blocks in partition */
Char pmPartName[33]; /* partition name */
Char pmParType[33]; /* partition type */
/*
* Apple_partition_map partition map
* Apple_Driver device driver
* Apple_Driver43 SCSI Manager 4.3 device driver
* Apple_MFS Macintosh 64K ROM filesystem
* Apple_HFS Macintosh hierarchical filesystem
* Apple_Unix_SVR2 Unix filesystem
* Apple_PRODOS ProDOS filesystem
* Apple_Free unused
* Apple_Scratch empty
*/
LongInt pmLgDataStart; /* first logical block of data area */
LongInt pmDataCnt; /* number of blocks in data area */
LongInt pmPartStatus; /* partition status information */
LongInt pmLgBootStart; /* first logical block of boot code */
LongInt pmBootSize; /* size of boot code, in bytes */
LongInt pmBootAddr; /* boot code load address */
LongInt pmBootAddr2; /* reserved */
LongInt pmBootEntry; /* boot code entry point */
LongInt pmBootEntry2; /* reserved */
LongInt pmBootCksum; /* boot code checksum */
Char pmProcessor[17];/* processor type */
Integer pmPad[188]; /* reserved */
} Partition;
int l_lockvol(hfsvol *);
int l_readblock0(hfsvol *);
int l_readpm(hfsvol *);
int l_readmdb(hfsvol *);
int l_writemdb(hfsvol *);
int l_readvbm(hfsvol *);
int l_writevbm(hfsvol *);

View File

@ -0,0 +1,725 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include <time.h>
# include "internal.h"
# include "data.h"
# include "low.h"
# include "btree.h"
# include "record.h"
# include "volume.h"
/*
* NAME: vol->catsearch()
* DESCRIPTION: search catalog tree
*/
int v_catsearch(hfsvol *vol, long parid, char *name,
CatDataRec *data, char *cname, node *np)
{
CatKeyRec key;
unsigned char pkey[HFS_CATKEYLEN];
node n;
unsigned char *ptr;
int found;
if (np == 0)
np = &n;
r_makecatkey(&key, parid, name);
r_packcatkey(&key, pkey, 0);
found = bt_search(&vol->cat, pkey, np);
if (found <= 0)
return found;
ptr = HFS_NODEREC(*np, np->rnum);
if (cname)
{
r_unpackcatkey(ptr, &key);
strcpy(cname, key.ckrCName);
}
if (data)
r_unpackcatdata(HFS_RECDATA(ptr), data);
return 1;
}
/*
* NAME: vol->extsearch()
* DESCRIPTION: search extents tree
*/
int v_extsearch(hfsfile *file, unsigned int fabn, ExtDataRec *data, node *np)
{
ExtKeyRec key;
ExtDataRec extsave;
unsigned int fabnsave;
unsigned char pkey[HFS_EXTKEYLEN];
node n;
unsigned char *ptr;
int found;
if (np == 0)
np = &n;
r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, fabn);
r_packextkey(&key, pkey, 0);
/* in case bt_search() clobbers these */
memcpy(&extsave, &file->ext, sizeof(ExtDataRec));
fabnsave = file->fabn;
found = bt_search(&file->vol->ext, pkey, np);
memcpy(&file->ext, &extsave, sizeof(ExtDataRec));
file->fabn = fabnsave;
if (found <= 0)
return found;
if (data)
{
ptr = HFS_NODEREC(*np, np->rnum);
r_unpackextdata(HFS_RECDATA(ptr), data);
}
return 1;
}
/*
* NAME: vol->getthread()
* DESCRIPTION: retrieve catalog thread information for a file or directory
*/
int v_getthread(hfsvol *vol, long id, CatDataRec *thread, node *np, int type)
{
CatDataRec rec;
int found;
if (thread == 0)
thread = &rec;
found = v_catsearch(vol, id, "", thread, 0, np);
if (found <= 0)
return found;
if (thread->cdrType != type)
{
ERROR(EIO, "bad thread record");
return -1;
}
return 1;
}
/*
* NAME: vol->putcatrec()
* DESCRIPTION: store catalog information
*/
int v_putcatrec(CatDataRec *data, node *np)
{
unsigned char pdata[HFS_CATDATALEN], *ptr;
int len = 0;
r_packcatdata(data, pdata, &len);
ptr = HFS_NODEREC(*np, np->rnum);
memcpy(HFS_RECDATA(ptr), pdata, len);
return bt_putnode(np);
}
/*
* NAME: vol->putextrec()
* DESCRIPTION: store extent information
*/
int v_putextrec(ExtDataRec *data, node *np)
{
unsigned char pdata[HFS_EXTDATALEN], *ptr;
int len = 0;
r_packextdata(data, pdata, &len);
ptr = HFS_NODEREC(*np, np->rnum);
memcpy(HFS_RECDATA(ptr), pdata, len);
return bt_putnode(np);
}
/*
* NAME: vol->allocblocks()
* DESCRIPTION: allocate a contiguous range of blocks
*/
int v_allocblocks(hfsvol *vol, ExtDescriptor *blocks)
{
unsigned int request, found, foundat, start, end, pt;
block *vbm;
int wrap = 0;
if (vol->mdb.drFreeBks == 0)
{
ERROR(ENOSPC, "volume full");
return -1;
}
request = blocks->xdrNumABlks;
found = 0;
foundat = 0;
start = vol->mdb.drAllocPtr;
end = vol->mdb.drNmAlBlks;
pt = start;
vbm = vol->vbm;
if (request == 0)
abort();
while (1)
{
unsigned int mark;
/* skip blocks in use */
while (pt < end && BMTST(vbm, pt))
++pt;
if (wrap && pt >= start)
break;
/* count blocks not in use */
mark = pt;
while (pt < end && pt - mark < request && ! BMTST(vbm, pt))
++pt;
if (pt - mark > found)
{
found = pt - mark;
foundat = mark;
}
if (pt == end)
pt = 0, wrap = 1;
if (found == request)
break;
}
if (found == 0 || found > vol->mdb.drFreeBks)
{
ERROR(EIO, "bad volume bitmap or free block count");
return -1;
}
blocks->xdrStABN = foundat;
blocks->xdrNumABlks = found;
vol->mdb.drAllocPtr = pt;
vol->mdb.drFreeBks -= found;
for (pt = foundat; pt < foundat + found; ++pt)
BMSET(vbm, pt);
vol->flags |= HFS_UPDATE_MDB | HFS_UPDATE_VBM;
return 0;
}
/*
* NAME: vol->freeblocks()
* DESCRIPTION: deallocate a contiguous range of blocks
*/
void v_freeblocks(hfsvol *vol, ExtDescriptor *blocks)
{
unsigned int start, len, pt;
block *vbm;
start = blocks->xdrStABN;
len = blocks->xdrNumABlks;
vbm = vol->vbm;
vol->mdb.drFreeBks += len;
for (pt = start; pt < start + len; ++pt)
BMCLR(vbm, pt);
vol->flags |= HFS_UPDATE_MDB | HFS_UPDATE_VBM;
}
/*
* NAME: vol->resolve()
* DESCRIPTION: translate a pathname; return catalog information
*/
int v_resolve(hfsvol **vol, char *path, CatDataRec *data,
long *parid, char *fname, node *np)
{
long dirid;
char name[HFS_MAX_FLEN + 1], *nptr;
int found;
if (*path == 0)
{
ERROR(ENOENT, "empty path");
return -1;
}
if (parid)
*parid = 0;
nptr = strchr(path, ':');
if (*path == ':' || nptr == 0)
{
dirid = (*vol)->cwd; /* relative path */
if (*path == ':')
++path;
if (*path == 0)
{
found = v_getdthread(*vol, dirid, data, 0);
if (found <= 0)
return found;
if (parid)
*parid = data->u.dthd.thdParID;
return v_catsearch(*vol, data->u.dthd.thdParID,
data->u.dthd.thdCName, data, fname, np);
}
}
else
{
hfsvol *check;
dirid = HFS_CNID_ROOTPAR; /* absolute path */
if (nptr - path > HFS_MAX_VLEN)
{
ERROR(ENAMETOOLONG, 0);
return -1;
}
strncpy(name, path, nptr - path);
name[nptr - path] = 0;
for (check = hfs_mounts; check; check = check->next)
{
if (d_relstring(check->mdb.drVN, name) == 0)
{
*vol = check;
break;
}
}
}
while (1)
{
while (*path == ':')
{
++path;
found = v_getdthread(*vol, dirid, data, 0);
if (found <= 0)
return found;
dirid = data->u.dthd.thdParID;
}
if (*path == 0)
{
found = v_getdthread(*vol, dirid, data, 0);
if (found <= 0)
return found;
if (parid)
*parid = data->u.dthd.thdParID;
return v_catsearch(*vol, data->u.dthd.thdParID,
data->u.dthd.thdCName, data, fname, np);
}
nptr = name;
while (nptr < name + sizeof(name) - 1 && *path && *path != ':')
*nptr++ = *path++;
if (*path && *path != ':')
{
ERROR(ENAMETOOLONG, 0);
return -1;
}
*nptr = 0;
if (*path == ':')
++path;
if (parid)
*parid = dirid;
found = v_catsearch(*vol, dirid, name, data, fname, np);
if (found < 0)
return -1;
if (found == 0)
{
if (*path && parid)
*parid = 0;
if (*path == 0 && fname)
strcpy(fname, name);
return 0;
}
switch (data->cdrType)
{
case cdrDirRec:
if (*path == 0)
return 1;
dirid = data->u.dir.dirDirID;
break;
case cdrFilRec:
if (*path == 0)
return 1;
ERROR(ENOTDIR, "invalid pathname");
return -1;
default:
ERROR(EIO, "unexpected catalog record");
return -1;
}
}
}
/*
* NAME: vol->destruct()
* DESCRIPTION: free memory consumed by a volume descriptor
*/
void v_destruct(hfsvol *vol)
{
FREE(vol->vbm);
FREE(vol->ext.map);
FREE(vol->cat.map);
FREE(vol);
}
/*
* NAME: vol->getvol()
* DESCRIPTION: validate a volume reference
*/
int v_getvol(hfsvol **vol)
{
if (*vol == 0)
{
if (hfs_curvol == 0)
{
ERROR(EINVAL, "no volume is current");
return -1;
}
*vol = hfs_curvol;
}
return 0;
}
/*
* NAME: vol->flush()
* DESCRIPTION: flush all pending changes (B*-tree, MDB, VBM) to disk
*/
int v_flush(hfsvol *vol, int umounting)
{
if (! (vol->flags & HFS_READONLY))
{
if ((vol->ext.flags & HFS_UPDATE_BTHDR) &&
bt_writehdr(&vol->ext) < 0)
return -1;
if ((vol->cat.flags & HFS_UPDATE_BTHDR) &&
bt_writehdr(&vol->cat) < 0)
return -1;
if ((vol->flags & HFS_UPDATE_VBM) &&
l_writevbm(vol) < 0)
return -1;
if (umounting &&
! (vol->mdb.drAtrb & HFS_ATRB_UMOUNTED))
{
vol->mdb.drAtrb |= HFS_ATRB_UMOUNTED;
vol->flags |= HFS_UPDATE_MDB;
}
if ((vol->flags & (HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB)) &&
l_writemdb(vol) < 0)
return -1;
}
return 0;
}
/*
* NAME: vol->adjvalence()
* DESCRIPTION: update a volume's valence counts
*/
int v_adjvalence(hfsvol *vol, long parid, int isdir, int adj)
{
node n;
CatDataRec data;
if (isdir)
vol->mdb.drDirCnt += adj;
else
vol->mdb.drFilCnt += adj;
vol->flags |= HFS_UPDATE_MDB;
if (parid == HFS_CNID_ROOTDIR)
{
if (isdir)
vol->mdb.drNmRtDirs += adj;
else
vol->mdb.drNmFls += adj;
}
else if (parid == HFS_CNID_ROOTPAR)
return 0;
if (v_getdthread(vol, parid, &data, 0) <= 0 ||
v_catsearch(vol, data.u.dthd.thdParID, data.u.dthd.thdCName,
&data, 0, &n) <= 0 ||
data.cdrType != cdrDirRec)
{
ERROR(EIO, "can't find parent directory");
return -1;
}
data.u.dir.dirVal += adj;
data.u.dir.dirMdDat = d_tomtime(time(0));
return v_putcatrec(&data, &n);
}
/*
* NAME: vol->newfolder()
* DESCRIPTION: create a new HFS folder
*/
int v_newfolder(hfsvol *vol, long parid, char *name)
{
CatKeyRec key;
CatDataRec data;
long id;
unsigned char record[HFS_CATRECMAXLEN];
int i, reclen;
if (bt_space(&vol->cat, 2) < 0)
return -1;
id = vol->mdb.drNxtCNID++;
vol->flags |= HFS_UPDATE_MDB;
/* create directory record */
data.cdrType = cdrDirRec;
data.cdrResrv2 = 0;
data.u.dir.dirFlags = 0;
data.u.dir.dirVal = 0;
data.u.dir.dirDirID = id;
data.u.dir.dirCrDat = d_tomtime(time(0));
data.u.dir.dirMdDat = data.u.dir.dirCrDat;
data.u.dir.dirBkDat = 0;
memset(&data.u.dir.dirUsrInfo, 0, sizeof(data.u.dir.dirUsrInfo));
memset(&data.u.dir.dirFndrInfo, 0, sizeof(data.u.dir.dirFndrInfo));
for (i = 0; i < 4; ++i)
data.u.dir.dirResrv[i] = 0;
r_makecatkey(&key, parid, name);
r_packcatkey(&key, record, &reclen);
r_packcatdata(&data, HFS_RECDATA(record), &reclen);
if (bt_insert(&vol->cat, record, reclen) < 0)
return -1;
/* create thread record */
data.cdrType = cdrThdRec;
data.cdrResrv2 = 0;
data.u.dthd.thdResrv[0] = 0;
data.u.dthd.thdResrv[1] = 0;
data.u.dthd.thdParID = parid;
strcpy(data.u.dthd.thdCName, name);
r_makecatkey(&key, id, "");
r_packcatkey(&key, record, &reclen);
r_packcatdata(&data, HFS_RECDATA(record), &reclen);
if (bt_insert(&vol->cat, record, reclen) < 0 ||
v_adjvalence(vol, parid, 1, 1) < 0)
return -1;
return 0;
}
/*
* NAME: markexts()
* DESCRIPTION: set bits from an extent record in the volume bitmap
*/
static
void markexts(block *vbm, ExtDataRec *exts)
{
int i;
unsigned int start, len;
for (i = 0; i < 3; ++i)
{
for (start = (*exts)[i].xdrStABN,
len = (*exts)[i].xdrNumABlks; len--; ++start)
BMSET(vbm, start);
}
}
/*
* NAME: vol->scavenge()
* DESCRIPTION: safeguard blocks in the volume bitmap
*/
int v_scavenge(hfsvol *vol)
{
block *vbm = vol->vbm;
node n;
unsigned int pt, blks;
if (vbm == 0)
return 0;
markexts(vbm, &vol->mdb.drXTExtRec);
markexts(vbm, &vol->mdb.drCTExtRec);
vol->flags |= HFS_UPDATE_VBM;
/* scavenge the extents overflow file */
n.bt = &vol->ext;
n.nnum = vol->ext.hdr.bthFNode;
if (n.nnum > 0)
{
if (bt_getnode(&n) < 0)
return -1;
n.rnum = 0;
while (1)
{
ExtDataRec data;
unsigned char *ptr;
while (n.rnum >= n.nd.ndNRecs)
{
n.nnum = n.nd.ndFLink;
if (n.nnum == 0)
break;
if (bt_getnode(&n) < 0)
return -1;
n.rnum = 0;
}
if (n.nnum == 0)
break;
ptr = HFS_NODEREC(n, n.rnum);
r_unpackextdata(HFS_RECDATA(ptr), &data);
markexts(vbm, &data);
++n.rnum;
}
}
/* scavenge the catalog file */
n.bt = &vol->cat;
n.nnum = vol->cat.hdr.bthFNode;
if (n.nnum > 0)
{
if (bt_getnode(&n) < 0)
return -1;
n.rnum = 0;
while (1)
{
CatDataRec data;
unsigned char *ptr;
while (n.rnum >= n.nd.ndNRecs)
{
n.nnum = n.nd.ndFLink;
if (n.nnum == 0)
break;
if (bt_getnode(&n) < 0)
return -1;
n.rnum = 0;
}
if (n.nnum == 0)
break;
ptr = HFS_NODEREC(n, n.rnum);
r_unpackcatdata(HFS_RECDATA(ptr), &data);
if (data.cdrType == cdrFilRec)
{
markexts(vbm, &data.u.fil.filExtRec);
markexts(vbm, &data.u.fil.filRExtRec);
}
++n.rnum;
}
}
for (blks = 0, pt = vol->mdb.drNmAlBlks; pt--; )
{
if (! BMTST(vbm, pt))
++blks;
}
if (vol->mdb.drFreeBks != blks)
{
vol->mdb.drFreeBks = blks;
vol->flags |= HFS_UPDATE_MDB;
}
return 0;
}

View File

@ -0,0 +1,459 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include "internal.h"
# include "data.h"
# include "btree.h"
# include "node.h"
# define NODESPACE(n) \
(HFS_BLOCKSZ - (n).roff[(n).nd.ndNRecs] - 2 * ((n).nd.ndNRecs + 1))
/*
* NAME: node->init()
* DESCRIPTION: construct an empty node
*/
void n_init(node *np, btree *bt, int type, int height)
{
np->bt = bt;
np->nnum = -1;
np->nd.ndFLink = 0;
np->nd.ndBLink = 0;
np->nd.ndType = type;
np->nd.ndNHeight = height;
np->nd.ndNRecs = 0;
np->nd.ndResv2 = 0;
np->rnum = -1;
np->roff[0] = 0x00e;
memset(np->data, 0, sizeof(np->data));
}
/*
* NAME: node->new()
* DESCRIPTION: allocate a new b*-tree node
*/
int n_new(node *np)
{
btree *bt = np->bt;
unsigned long num;
if (bt->hdr.bthFree == 0)
{
ERROR(EIO, "b*-tree full");
return -1;
}
num = 0;
while (num < bt->hdr.bthNNodes && BMTST(bt->map, num))
++num;
if (num == bt->hdr.bthNNodes)
{
ERROR(EIO, "free b*-tree node not found");
return -1;
}
np->nnum = num;
BMSET(bt->map, num);
--bt->hdr.bthFree;
bt->flags |= HFS_UPDATE_BTHDR;
return 0;
}
/*
* NAME: node->free()
* DESCRIPTION: deallocate a b*-tree node
*/
void n_free(node *np)
{
btree *bt = np->bt;
BMCLR(bt->map, np->nnum);
++bt->hdr.bthFree;
bt->flags |= HFS_UPDATE_BTHDR;
}
/*
* NAME: node->compact()
* DESCRIPTION: clean up a node, removing deleted records
*/
void n_compact(node *np)
{
unsigned char *ptr;
int offset, nrecs, i;
offset = 0x00e;
ptr = np->data + offset;
nrecs = 0;
for (i = 0; i < np->nd.ndNRecs; ++i)
{
unsigned char *rec;
int reclen;
rec = HFS_NODEREC(*np, i);
reclen = np->roff[i + 1] - np->roff[i];
if (HFS_RECKEYLEN(rec) > 0)
{
np->roff[nrecs++] = offset;
offset += reclen;
if (ptr == rec)
ptr += reclen;
else
{
while (reclen--)
*ptr++ = *rec++;
}
}
}
np->roff[nrecs] = offset;
np->nd.ndNRecs = nrecs;
}
/*
* NAME: node->search()
* DESCRIPTION: locate a record in a node, or the record it should follow
*/
int n_search(node *np, unsigned char *key)
{
btree *bt = np->bt;
int i, comp = -1;
for (i = np->nd.ndNRecs; i--; )
{
unsigned char *rec;
rec = HFS_NODEREC(*np, i);
if (HFS_RECKEYLEN(rec) == 0)
continue; /* deleted record */
comp = bt->compare(rec, key);
if (comp <= 0)
break;
}
np->rnum = i;
return comp == 0;
}
/*
* NAME: node->index()
* DESCRIPTION: create an index record from a key and node pointer
*/
void n_index(btree *bt, unsigned char *key, unsigned long nnum,
unsigned char *record, int *reclen)
{
if (bt == &bt->f.vol->cat)
{
/* force the key length to be 0x25 */
HFS_RECKEYLEN(record) = 0x25;
memset(record + 1, 0, 0x25);
memcpy(record + 1, key + 1, HFS_RECKEYLEN(key));
}
else
memcpy(record, key, HFS_RECKEYSKIP(key));
d_putl(HFS_RECDATA(record), nnum);
if (reclen)
*reclen = HFS_RECKEYSKIP(record) + 4;
}
/*
* NAME: node->split()
* DESCRIPTION: divide a node into two and insert a record
*/
int n_split(node *left, unsigned char *record, int *reclen)
{
node right;
int nrecs, i, mid;
unsigned char *rec;
right = *left;
right.nd.ndBLink = left->nnum;
if (n_new(&right) < 0)
return -1;
left->nd.ndFLink = right.nnum;
nrecs = left->nd.ndNRecs;
/*
* Ensure node split leaves enough room for new record.
* The size calculations used are based on the NODESPACE() macro, but
* I don't know what the extra 2's and 1's are needed for.
* John Witford <jwitford@hutch.com.au>
*/
n_search(&right, record);
mid = nrecs/2;
for(;;)
{
if (right.rnum < mid)
{
if ( mid > 0
&& left->roff[mid] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1))
{
--mid;
if (mid > 0)
continue;
}
}
else
{
if ( mid < nrecs
&& right.roff[nrecs] - right.roff[mid] + left->roff[0] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1))
{
++mid;
if (mid < nrecs)
continue;
}
}
break;
}
for (i = 0; i < nrecs; ++i)
{
if (i < mid)
rec = HFS_NODEREC(right, i);
else
rec = HFS_NODEREC(*left, i);
HFS_RECKEYLEN(rec) = 0;
}
/* original code ...
for (i = 0; i < nrecs; ++i)
{
if (i < nrecs / 2)
rec = HFS_NODEREC(right, i);
else
rec = HFS_NODEREC(*left, i);
HFS_RECKEYLEN(rec) = 0;
}
*/
n_compact(left);
n_compact(&right);
n_search(&right, record);
if (right.rnum >= 0)
n_insertx(&right, record, *reclen);
else
{
n_search(left, record);
n_insertx(left, record, *reclen);
}
/* store the new/modified nodes */
if (bt_putnode(left) < 0 ||
bt_putnode(&right) < 0)
return -1;
/* create an index record for the new node in the parent */
n_index(right.bt, HFS_NODEREC(right, 0), right.nnum, record, reclen);
/* update link pointers */
if (left->bt->hdr.bthLNode == left->nnum)
{
left->bt->hdr.bthLNode = right.nnum;
left->bt->flags |= HFS_UPDATE_BTHDR;
}
if (right.nd.ndFLink)
{
node n;
n.bt = right.bt;
n.nnum = right.nd.ndFLink;
if (bt_getnode(&n) < 0)
return -1;
n.nd.ndBLink = right.nnum;
if (bt_putnode(&n) < 0)
return -1;
}
return 0;
}
/*
* NAME: node->insertx()
* DESCRIPTION: insert a record into a node (which must already have room)
*/
void n_insertx(node *np, unsigned char *record, int reclen)
{
int rnum, i;
unsigned char *ptr;
rnum = np->rnum + 1;
/* push other records down to make room */
for (ptr = HFS_NODEREC(*np, np->nd.ndNRecs) + reclen;
ptr > HFS_NODEREC(*np, rnum) + reclen; --ptr)
*(ptr - 1) = *(ptr - 1 - reclen);
++np->nd.ndNRecs;
for (i = np->nd.ndNRecs; i > rnum; --i)
np->roff[i] = np->roff[i - 1] + reclen;
/* write the new record */
memcpy(HFS_NODEREC(*np, rnum), record, reclen);
}
/*
* NAME: node->insert()
* DESCRIPTION: insert a new record into a node; return a record for parent
*/
int n_insert(node *np, unsigned char *record, int *reclen)
{
n_compact(np);
/* check for free space */
if (np->nd.ndNRecs >= HFS_MAXRECS ||
*reclen + 2 > NODESPACE(*np))
return n_split(np, record, reclen);
n_insertx(np, record, *reclen);
*reclen = 0;
return bt_putnode(np);
}
/*
* NAME: node->merge()
* DESCRIPTION: combine two nodes into a single node
*/
int n_merge(node *right, node *left, unsigned char *record, int *flag)
{
int i, offset;
/* copy records and offsets */
memcpy(HFS_NODEREC(*left, left->nd.ndNRecs), HFS_NODEREC(*right, 0),
right->roff[right->nd.ndNRecs] - right->roff[0]);
offset = left->roff[left->nd.ndNRecs] - right->roff[0];
for (i = 1; i <= right->nd.ndNRecs; ++i)
left->roff[++left->nd.ndNRecs] = offset + right->roff[i];
/* update link pointers */
left->nd.ndFLink = right->nd.ndFLink;
if (bt_putnode(left) < 0)
return -1;
if (right->bt->hdr.bthLNode == right->nnum)
{
right->bt->hdr.bthLNode = left->nnum;
right->bt->flags |= HFS_UPDATE_BTHDR;
}
if (right->nd.ndFLink)
{
node n;
n.bt = right->bt;
n.nnum = right->nd.ndFLink;
if (bt_getnode(&n) < 0)
return -1;
n.nd.ndBLink = left->nnum;
if (bt_putnode(&n) < 0)
return -1;
}
n_free(right);
HFS_RECKEYLEN(record) = 0;
*flag = 1;
return 0;
}
/*
* NAME: node->delete()
* DESCRIPTION: remove a record from a node
*/
int n_delete(node *np, unsigned char *record, int *flag)
{
node left;
unsigned char *rec;
rec = HFS_NODEREC(*np, np->rnum);
HFS_RECKEYLEN(rec) = 0;
n_compact(np);
/* see if we can merge with our left sibling */
left.bt = np->bt;
left.nnum = np->nd.ndBLink;
if (left.nnum > 0)
{
if (bt_getnode(&left) < 0)
return -1;
if (np->nd.ndNRecs + left.nd.ndNRecs <= HFS_MAXRECS &&
np->roff[np->nd.ndNRecs] - np->roff[0] +
2 * np->nd.ndNRecs <= NODESPACE(left))
return n_merge(np, &left, record, flag);
}
if (np->rnum == 0)
{
/* special case: first record changed; update parent record key */
n_index(np->bt, HFS_NODEREC(*np, 0), np->nnum, record, 0);
*flag = 1;
}
return bt_putnode(np);
}

View File

@ -0,0 +1,35 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
void n_init(node *, btree *, int, int);
int n_new(node *);
void n_free(node *);
void n_compact(node *);
int n_search(node *, unsigned char *);
void n_index(btree *, unsigned char *, unsigned long, unsigned char *, int *);
int n_split(node *, unsigned char *, int *);
void n_insertx(node *, unsigned char *, int);
int n_insert(node *, unsigned char *, int *);
int n_merge(node *, node *, unsigned char *, int *);
int n_delete(node *, unsigned char *, int *);

View File

@ -0,0 +1,492 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# include <string.h>
# include <errno.h>
# include <stdlib.h>
# include "internal.h"
# include "data.h"
# include "record.h"
/*
* NAME: record->packcatkey()
* DESCRIPTION: pack a catalog record key
*/
void r_packcatkey(CatKeyRec *key, unsigned char *pkey, int *len)
{
unsigned char *start = pkey;
d_storeb(&pkey, key->ckrKeyLen);
d_storeb(&pkey, key->ckrResrv1);
d_storel(&pkey, key->ckrParID);
d_stores(&pkey, key->ckrCName, sizeof(key->ckrCName));
if (len)
*len = HFS_RECKEYSKIP(start);
}
/*
* NAME: record->unpackcatkey()
* DESCRIPTION: unpack a catalog record key
*/
void r_unpackcatkey(unsigned char *pkey, CatKeyRec *key)
{
d_fetchb(&pkey, (char *) &key->ckrKeyLen);
d_fetchb(&pkey, (char *) &key->ckrResrv1);
d_fetchl(&pkey, (long *) &key->ckrParID);
d_fetchs(&pkey, key->ckrCName, sizeof(key->ckrCName));
}
/*
* NAME: record->packextkey()
* DESCRIPTION: pack an extents record key
*/
void r_packextkey(ExtKeyRec *key, unsigned char *pkey, int *len)
{
unsigned char *start = pkey;
d_storeb(&pkey, key->xkrKeyLen);
d_storeb(&pkey, key->xkrFkType);
d_storel(&pkey, key->xkrFNum);
d_storew(&pkey, key->xkrFABN);
if (len)
*len = HFS_RECKEYSKIP(start);
}
/*
* NAME: record->unpackextkey()
* DESCRIPTION: unpack an extents record key
*/
void r_unpackextkey(unsigned char *pkey, ExtKeyRec *key)
{
d_fetchb(&pkey, (char *) &key->xkrKeyLen);
d_fetchb(&pkey, (char *) &key->xkrFkType);
d_fetchl(&pkey, (long *) &key->xkrFNum);
d_fetchw(&pkey, (short *) &key->xkrFABN);
}
/*
* NAME: record->comparecatkeys()
* DESCRIPTION: compare two (packed) catalog record keys
*/
int r_comparecatkeys(unsigned char *pkey1, unsigned char *pkey2)
{
CatKeyRec key1;
CatKeyRec key2;
int diff;
r_unpackcatkey(pkey1, &key1);
r_unpackcatkey(pkey2, &key2);
diff = key1.ckrParID - key2.ckrParID;
if (diff)
return diff;
return d_relstring(key1.ckrCName, key2.ckrCName);
}
/*
* NAME: record->compareextkeys()
* DESCRIPTION: compare two (packed) extents record keys
*/
int r_compareextkeys(unsigned char *pkey1, unsigned char *pkey2)
{
ExtKeyRec key1;
ExtKeyRec key2;
int diff;
r_unpackextkey(pkey1, &key1);
r_unpackextkey(pkey2, &key2);
diff = key1.xkrFNum - key2.xkrFNum;
if (diff)
return diff;
diff = (unsigned char) key1.xkrFkType -
(unsigned char) key2.xkrFkType;
if (diff)
return diff;
return key1.xkrFABN - key2.xkrFABN;
}
/*
* NAME: record->packcatdata()
* DESCRIPTION: pack catalog record data
*/
void r_packcatdata(CatDataRec *data, unsigned char *pdata, int *len)
{
unsigned char *start = pdata;
int i;
d_storeb(&pdata, data->cdrType);
d_storeb(&pdata, data->cdrResrv2);
switch (data->cdrType)
{
case cdrDirRec:
d_storew(&pdata, data->u.dir.dirFlags);
d_storew(&pdata, data->u.dir.dirVal);
d_storel(&pdata, data->u.dir.dirDirID);
d_storel(&pdata, data->u.dir.dirCrDat);
d_storel(&pdata, data->u.dir.dirMdDat);
d_storel(&pdata, data->u.dir.dirBkDat);
d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.top);
d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.left);
d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.bottom);
d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.right);
d_storew(&pdata, data->u.dir.dirUsrInfo.frFlags);
d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.v);
d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.h);
d_storew(&pdata, data->u.dir.dirUsrInfo.frView);
d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.v);
d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.h);
d_storel(&pdata, data->u.dir.dirFndrInfo.frOpenChain);
d_storew(&pdata, data->u.dir.dirFndrInfo.frUnused);
d_storew(&pdata, data->u.dir.dirFndrInfo.frComment);
d_storel(&pdata, data->u.dir.dirFndrInfo.frPutAway);
for (i = 0; i < 4; ++i)
d_storel(&pdata, data->u.dir.dirResrv[i]);
break;
case cdrFilRec:
d_storeb(&pdata, data->u.fil.filFlags);
d_storeb(&pdata, data->u.fil.filTyp);
d_storel(&pdata, data->u.fil.filUsrWds.fdType);
d_storel(&pdata, data->u.fil.filUsrWds.fdCreator);
d_storew(&pdata, data->u.fil.filUsrWds.fdFlags);
d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.v);
d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.h);
d_storew(&pdata, data->u.fil.filUsrWds.fdFldr);
d_storel(&pdata, data->u.fil.filFlNum);
d_storew(&pdata, data->u.fil.filStBlk);
d_storel(&pdata, data->u.fil.filLgLen);
d_storel(&pdata, data->u.fil.filPyLen);
d_storew(&pdata, data->u.fil.filRStBlk);
d_storel(&pdata, data->u.fil.filRLgLen);
d_storel(&pdata, data->u.fil.filRPyLen);
d_storel(&pdata, data->u.fil.filCrDat);
d_storel(&pdata, data->u.fil.filMdDat);
d_storel(&pdata, data->u.fil.filBkDat);
d_storew(&pdata, data->u.fil.filFndrInfo.fdIconID);
for (i = 0; i < 4; ++i)
d_storew(&pdata, data->u.fil.filFndrInfo.fdUnused[i]);
d_storew(&pdata, data->u.fil.filFndrInfo.fdComment);
d_storel(&pdata, data->u.fil.filFndrInfo.fdPutAway);
d_storew(&pdata, data->u.fil.filClpSize);
for (i = 0; i < 3; ++i)
{
d_storew(&pdata, data->u.fil.filExtRec[i].xdrStABN);
d_storew(&pdata, data->u.fil.filExtRec[i].xdrNumABlks);
}
for (i = 0; i < 3; ++i)
{
d_storew(&pdata, data->u.fil.filRExtRec[i].xdrStABN);
d_storew(&pdata, data->u.fil.filRExtRec[i].xdrNumABlks);
}
d_storel(&pdata, data->u.fil.filResrv);
break;
case cdrThdRec:
for (i = 0; i < 2; ++i)
d_storel(&pdata, data->u.dthd.thdResrv[i]);
d_storel(&pdata, data->u.dthd.thdParID);
d_stores(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName));
break;
case cdrFThdRec:
for (i = 0; i < 2; ++i)
d_storel(&pdata, data->u.fthd.fthdResrv[i]);
d_storel(&pdata, data->u.fthd.fthdParID);
d_stores(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName));
break;
default:
abort();
}
if (len)
*len += pdata - start;
}
/*
* NAME: record->unpackcatdata()
* DESCRIPTION: unpack catalog record data
*/
void r_unpackcatdata(unsigned char *pdata, CatDataRec *data)
{
int i;
d_fetchb(&pdata, (char *) &data->cdrType);
d_fetchb(&pdata, (char *) &data->cdrResrv2);
switch (data->cdrType)
{
case cdrDirRec:
d_fetchw(&pdata, &data->u.dir.dirFlags);
d_fetchw(&pdata, (short *) &data->u.dir.dirVal);
d_fetchl(&pdata, (long *) &data->u.dir.dirDirID);
d_fetchl(&pdata, &data->u.dir.dirCrDat);
d_fetchl(&pdata, &data->u.dir.dirMdDat);
d_fetchl(&pdata, &data->u.dir.dirBkDat);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.top);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.left);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.bottom);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.right);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frFlags);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.v);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.h);
d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frView);
d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.v);
d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.h);
d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frOpenChain);
d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frUnused);
d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frComment);
d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frPutAway);
for (i = 0; i < 4; ++i)
d_fetchl(&pdata, &data->u.dir.dirResrv[i]);
break;
case cdrFilRec:
d_fetchb(&pdata, (char *) &data->u.fil.filFlags);
d_fetchb(&pdata, (char *) &data->u.fil.filTyp);
d_fetchl(&pdata, &data->u.fil.filUsrWds.fdType);
d_fetchl(&pdata, &data->u.fil.filUsrWds.fdCreator);
d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFlags);
d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.v);
d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.h);
d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFldr);
d_fetchl(&pdata, (long *) &data->u.fil.filFlNum);
d_fetchw(&pdata, (short *) &data->u.fil.filStBlk);
d_fetchl(&pdata, (long *) &data->u.fil.filLgLen);
d_fetchl(&pdata, (long *) &data->u.fil.filPyLen);
d_fetchw(&pdata, (short *) &data->u.fil.filRStBlk);
d_fetchl(&pdata, (long *) &data->u.fil.filRLgLen);
d_fetchl(&pdata, (long *) &data->u.fil.filRPyLen);
d_fetchl(&pdata, &data->u.fil.filCrDat);
d_fetchl(&pdata, &data->u.fil.filMdDat);
d_fetchl(&pdata, &data->u.fil.filBkDat);
d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdIconID);
for (i = 0; i < 4; ++i)
d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdUnused[i]);
d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdComment);
d_fetchl(&pdata, &data->u.fil.filFndrInfo.fdPutAway);
d_fetchw(&pdata, (short *) &data->u.fil.filClpSize);
for (i = 0; i < 3; ++i)
{
d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrStABN);
d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrNumABlks);
}
for (i = 0; i < 3; ++i)
{
d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrStABN);
d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrNumABlks);
}
d_fetchl(&pdata, &data->u.fil.filResrv);
break;
case cdrThdRec:
for (i = 0; i < 2; ++i)
d_fetchl(&pdata, &data->u.dthd.thdResrv[i]);
d_fetchl(&pdata, (long *) &data->u.dthd.thdParID);
d_fetchs(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName));
break;
case cdrFThdRec:
for (i = 0; i < 2; ++i)
d_fetchl(&pdata, &data->u.fthd.fthdResrv[i]);
d_fetchl(&pdata, (long *) &data->u.fthd.fthdParID);
d_fetchs(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName));
break;
default:
abort();
}
}
/*
* NAME: record->packextdata()
* DESCRIPTION: pack extent record data
*/
void r_packextdata(ExtDataRec *data, unsigned char *pdata, int *len)
{
unsigned char *start = pdata;
int i;
for (i = 0; i < 3; ++i)
{
d_storew(&pdata, (*data)[i].xdrStABN);
d_storew(&pdata, (*data)[i].xdrNumABlks);
}
if (len)
*len += pdata - start;
}
/*
* NAME: record->unpackextdata()
* DESCRIPTION: unpack extent record data
*/
void r_unpackextdata(unsigned char *pdata, ExtDataRec *data)
{
int i;
for (i = 0; i < 3; ++i)
{
d_fetchw(&pdata, (short *) &(*data)[i].xdrStABN);
d_fetchw(&pdata, (short *) &(*data)[i].xdrNumABlks);
}
}
/*
* NAME: record->makecatkey()
* DESCRIPTION: construct a catalog record key
*/
void r_makecatkey(CatKeyRec *key, long parid, char *name)
{
int len;
len = strlen(name) + 1;
key->ckrKeyLen = 0x05 + len + (len & 1);
key->ckrResrv1 = 0;
key->ckrParID = parid;
strcpy(key->ckrCName, name);
}
/*
* NAME: record->makeextkey()
* DESCRIPTION: construct an extents record key
*/
void r_makeextkey(ExtKeyRec *key, int fork, long fnum, unsigned int fabn)
{
key->xkrKeyLen = 0x07;
key->xkrFkType = fork;
key->xkrFNum = fnum;
key->xkrFABN = fabn;
}
/*
* NAME: record->unpackdirent()
* DESCRIPTION: unpack catalog information into hfsdirent structure
*/
void r_unpackdirent(long parid, char *name, CatDataRec *data, hfsdirent *ent)
{
strcpy(ent->name, name);
ent->parid = parid;
switch (data->cdrType)
{
case cdrDirRec:
ent->flags = HFS_ISDIR;
ent->cnid = data->u.dir.dirDirID;
ent->crdate = d_toutime(data->u.dir.dirCrDat);
ent->mddate = d_toutime(data->u.dir.dirMdDat);
ent->dsize = data->u.dir.dirVal;
ent->rsize = 0;
ent->type[0] = ent->creator[0] = 0;
ent->fdflags = data->u.dir.dirUsrInfo.frFlags;
break;
case cdrFilRec:
ent->flags = (data->u.fil.filFlags & (1 << 0)) ? HFS_ISLOCKED : 0;
ent->cnid = data->u.fil.filFlNum;
ent->crdate = d_toutime(data->u.fil.filCrDat);
ent->mddate = d_toutime(data->u.fil.filMdDat);
ent->dsize = data->u.fil.filLgLen;
ent->rsize = data->u.fil.filRLgLen;
d_putl((unsigned char *) ent->type, data->u.fil.filUsrWds.fdType);
d_putl((unsigned char *) ent->creator, data->u.fil.filUsrWds.fdCreator);
ent->type[4] = ent->creator[4] = 0;
ent->fdflags = data->u.fil.filUsrWds.fdFlags;
break;
}
}
/*
* NAME: record->packdirent()
* DESCRIPTION: make changes to a catalog record
*/
void r_packdirent(CatDataRec *data, hfsdirent *ent)
{
switch (data->cdrType)
{
case cdrDirRec:
data->u.dir.dirCrDat = d_tomtime(ent->crdate);
data->u.dir.dirMdDat = d_tomtime(ent->mddate);
data->u.dir.dirUsrInfo.frFlags = ent->fdflags;
break;
case cdrFilRec:
if (ent->flags & HFS_ISLOCKED)
data->u.fil.filFlags |= (1 << 0);
else
data->u.fil.filFlags &= ~(1 << 0);
data->u.fil.filCrDat = d_tomtime(ent->crdate);
data->u.fil.filMdDat = d_tomtime(ent->mddate);
data->u.fil.filUsrWds.fdType = d_getl((unsigned char *) ent->type);
data->u.fil.filUsrWds.fdCreator = d_getl((unsigned char *) ent->creator);
data->u.fil.filUsrWds.fdFlags = ent->fdflags;
break;
}
}

View File

@ -0,0 +1,39 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
void r_packcatkey(CatKeyRec *, unsigned char *, int *);
void r_unpackcatkey(unsigned char *, CatKeyRec *);
void r_packextkey(ExtKeyRec *, unsigned char *, int *);
void r_unpackextkey(unsigned char *, ExtKeyRec *);
int r_comparecatkeys(unsigned char *, unsigned char *);
int r_compareextkeys(unsigned char *, unsigned char *);
void r_packcatdata(CatDataRec *, unsigned char *, int *);
void r_unpackcatdata(unsigned char *, CatDataRec *);
void r_packextdata(ExtDataRec *, unsigned char *, int *);
void r_unpackextdata(unsigned char *, ExtDataRec *);
void r_makecatkey(CatKeyRec *, long, char *);
void r_makeextkey(ExtKeyRec *, int, long, unsigned int);
void r_unpackdirent(long, char *, CatDataRec *, hfsdirent *);
void r_packdirent(CatDataRec *, hfsdirent *);

View File

@ -0,0 +1,45 @@
/*
* hfsutils - tools for reading and writing Macintosh HFS volumes
* Copyright (C) 1996, 1997 Robert Leslie
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int v_catsearch(hfsvol *, long, char *, CatDataRec *, char *, node *);
int v_extsearch(hfsfile *, unsigned int, ExtDataRec *, node *);
int v_getthread(hfsvol *, long, CatDataRec *, node *, int);
# define v_getdthread(vol, id, thread, np) \
v_getthread(vol, id, thread, np, cdrThdRec)
# define v_getfthread(vol, id, thread, np) \
v_getthread(vol, id, thread, np, cdrFThdRec)
int v_putcatrec(CatDataRec *, node *);
int v_putextrec(ExtDataRec *, node *);
int v_allocblocks(hfsvol *, ExtDescriptor *);
void v_freeblocks(hfsvol *, ExtDescriptor *);
int v_resolve(hfsvol **, char *, CatDataRec *, long *, char *, node *);
void v_destruct(hfsvol *);
int v_getvol(hfsvol **);
int v_flush(hfsvol *, int);
int v_adjvalence(hfsvol *, long, int, int);
int v_newfolder(hfsvol *, long, char *);
int v_scavenge(hfsvol *);

262
external/gpl2/mkhybrid/dist/mac_label.c vendored Normal file
View File

@ -0,0 +1,262 @@
/*
** mac_label.c: generate Mactintosh partition maps and label
**
** Taken from "mkisofs 1.05 PLUS" by Andy Polyakov <appro@fy.chalmers.se>
** (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details)
**
** The format of the HFS driver file:
**
** HFS CD Label Block 512 bytes
** Driver Partition Map (for 2048 byte blocks) 512 bytes
** Driver Partition Map (for 512 byte blocks) 512 bytes
** Empty 512 bytes
** Driver Partition N x 2048 bytes
** HFS Partition Boot Block 1024 bytes
**
** File of the above format can be extracted from a CD using
** apple_driver.c
**
** James Pearson 16/5/98
*/
#include <config.h>
#include <mkisofs.h>
#include "mac_label_proto.h"
#include <mac_label.h>
int
gen_mac_label(defer *mac_boot)
{
FILE *fp;
MacLabel *mac_label;
MacPart *mac_part;
char *buffer = hce->hfs_map;
int block_size;
int have_hfs_boot = 0;
char tmp[SECTOR_SIZE];
struct stat stat_buf;
mac_partition_table mpm[2];
int mpc = 0;
int i;
/* If we have a boot file, then open and check it */
if (mac_boot->name) {
if (stat(mac_boot->name, &stat_buf) < 0) {
snprintf(hce->error, ERROR_SIZE,
"unable to stat HFS boot file %s", mac_boot->name);
return (-1);
}
if ((fp = fopen(mac_boot->name, "rb")) == NULL) {
snprintf(hce->error, ERROR_SIZE,
"unable to open HFS boot file %s", mac_boot->name);
return (-1);
}
if (fread(tmp, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) {
snprintf(hce->error, ERROR_SIZE,
"unable to read HFS boot file %s", mac_boot->name);
return (-1);
}
/* check we have a bootable partition */
mac_part = (MacPart*)(tmp+HFS_BLOCKSZ);
if (!(IS_MAC_PART(mac_part) && !strncmp(mac_part->pmPartType, pmPartType_2, 12))) {
snprintf(hce->error, ERROR_SIZE, "%s is not a HFS boot file",
mac_boot->name);
return (-1);
}
/* check we have a boot block as well - last 2 blocks of file */
if (fseek(fp, -2 * HFS_BLOCKSZ, 2) != 0) {
snprintf(hce->error, ERROR_SIZE,
"unable to seek HFS boot file %s", mac_boot->name);
return (-1);
}
/* overwrite (empty) boot block for our HFS volume */
if (fread(hce->hfs_hdr, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) {
snprintf(hce->error, ERROR_SIZE,
"unable to read HFS boot block %s", mac_boot->name);
return (-1);
}
fclose (fp);
/* check boot block is valid */
if (d_getw((unsigned char *)hce->hfs_hdr) != HFS_BB_SIGWORD) {
snprintf(hce->error, ERROR_SIZE,
"%s does not contain a valid boot block", mac_boot->name);
return (-1);
}
/* collect info about boot file for later user - skip over the boot
file header */
mac_boot->size = stat_buf.st_size - SECTOR_SIZE - 2*HFS_BLOCKSZ;
mac_boot->off = SECTOR_SIZE;
mac_boot->pad = 0;
/* get size in SECTOR_SIZE blocks - shouldn't need to round up */
mpm[mpc].size = ROUND_UP(mac_boot->size)/SECTOR_SIZE;
mpm[mpc].ntype = PM2;
mpm[mpc].type = mac_part->pmPartType;
mpm[mpc].start = mac_boot->extent = last_extent;
mpm[mpc].name = 0;
/* flag that we have a boot file */
have_hfs_boot++;
/* add boot file size to the total size */
last_extent += mpm[mpc].size;
hfs_extra += mpm[mpc].size;
mpc++;
}
/* set info about our hybrid volume */
mpm[mpc].ntype = PM4;
mpm[mpc].type = pmPartType_4;
mpm[mpc].start = hce->hfs_map_size / BLK_CONV;
mpm[mpc].size = last_extent - mpm[mpc].start;
mpm[mpc].name = volume_id;
mpc++;
if (verbose > 1)
fprintf(stderr, "Creating HFS Label %s %s\n", mac_boot->name ?
"with boot file" : "", mac_boot->name ? mac_boot->name : "" );
/* for a bootable CD, block size is SECTOR_SIZE */
block_size = have_hfs_boot ? SECTOR_SIZE : HFS_BLOCKSZ;
/* create the CD label */
mac_label = (MacLabel *)buffer;
mac_label->sbSig [0] = 'E';
mac_label->sbSig [1] = 'R';
set_722 (mac_label->sbBlkSize,block_size);
set_732 (mac_label->sbBlkCount,last_extent*(SECTOR_SIZE/block_size));
set_722 (mac_label->sbDevType,1);
set_722 (mac_label->sbDevId,1);
/* create the partition map entry */
mac_part = (MacPart*)(buffer+block_size);
mac_part->pmSig [0] = 'P';
mac_part->pmSig [1] = 'M';
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,1);
set_732 (mac_part->pmPartBlkCnt,mpc+1);
strncpy (mac_part->pmPartName,"Apple",sizeof(mac_part->pmPartName));
strncpy (mac_part->pmPartType,"Apple_partition_map",sizeof(mac_part->pmPartType));
set_732 (mac_part->pmLgDataStart,0);
set_732 (mac_part->pmDataCnt,mpc+1);
set_732 (mac_part->pmPartStatus,PM_STAT_DEFAULT);
/* create partition map entries for our partitions */
for (i=0;i<mpc;i++) {
mac_part = (MacPart*)(buffer + (i+2)*block_size);
if (mpm[i].ntype == PM2) {
/* get driver label and patch it */
memcpy (mac_label, tmp, HFS_BLOCKSZ);
set_732 (mac_label->sbBlkCount,last_extent*(SECTOR_SIZE/block_size));
set_732 (mac_label->ddBlock,(mpm[i].start)*(SECTOR_SIZE/block_size));
memcpy (mac_part, tmp+HFS_BLOCKSZ, HFS_BLOCKSZ);
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,(mpm[i].start)*(SECTOR_SIZE/block_size));
}
else {
mac_part->pmSig [0] = 'P';
mac_part->pmSig [1] = 'M';
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,mpm[i].start*(SECTOR_SIZE/HFS_BLOCKSZ));
set_732 (mac_part->pmPartBlkCnt,mpm[i].size*(SECTOR_SIZE/HFS_BLOCKSZ));
strncpy (mac_part->pmPartName,mpm[i].name,sizeof(mac_part->pmPartName));
strncpy (mac_part->pmPartType,mpm[i].type,sizeof(mac_part->pmPartType));
set_732 (mac_part->pmLgDataStart,0);
set_732 (mac_part->pmDataCnt,mpm[i].size*(SECTOR_SIZE/HFS_BLOCKSZ));
set_732 (mac_part->pmPartStatus,PM_STAT_DEFAULT);
}
}
if (have_hfs_boot) { /* generate 512 partition table as well */
mac_part = (MacPart*)(buffer+HFS_BLOCKSZ);
if (mpc<3) { /* don't have to interleave with 2048 table */
mac_part->pmSig [0] = 'P';
mac_part->pmSig [1] = 'M';
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,1);
set_732 (mac_part->pmPartBlkCnt,mpc+1);
strncpy (mac_part->pmPartName,"Apple",sizeof(mac_part->pmPartName));
strncpy (mac_part->pmPartType,"Apple_partition_map",sizeof(mac_part->pmPartType));
set_732 (mac_part->pmLgDataStart,0);
set_732 (mac_part->pmDataCnt,mpc+1);
set_732 (mac_part->pmPartStatus,PM_STAT_DEFAULT);
mac_part++; /* +HFS_BLOCKSZ */
}
for (i=0;i<mpc;i++,mac_part++) {
if (mac_part == (MacPart*)(buffer+SECTOR_SIZE)) mac_part++; /* jump over 2048 partition entry */
if (mpm[i].ntype == PM2) {
memcpy (mac_part, tmp+HFS_BLOCKSZ*2, HFS_BLOCKSZ);
if (!IS_MAC_PART(mac_part)) { mac_part--; continue; }
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,(mpm[i].start)*(SECTOR_SIZE/HFS_BLOCKSZ));
}
else {
mac_part->pmSig [0] = 'P';
mac_part->pmSig [1] = 'M';
set_732 (mac_part->pmMapBlkCnt,mpc+1);
set_732 (mac_part->pmPyPartStart,mpm[i].start*(SECTOR_SIZE/HFS_BLOCKSZ));
set_732 (mac_part->pmPartBlkCnt,mpm[i].size*(SECTOR_SIZE/HFS_BLOCKSZ));
strncpy (mac_part->pmPartName,mpm[i].name,sizeof(mac_part->pmPartName));
strncpy (mac_part->pmPartType,mpm[i].type,sizeof(mac_part->pmPartType));
set_732 (mac_part->pmLgDataStart,0);
set_732 (mac_part->pmDataCnt,mpm[i].size*(SECTOR_SIZE/HFS_BLOCKSZ));
set_732 (mac_part->pmPartStatus,PM_STAT_DEFAULT);
}
}
}
return (0);
}
/*
** autostart: make the HFS CD use the QuickTime 2.0 Autostart feature.
**
** based on information from Eric Eisenhart <eric@sonic.net> and
** http://developer.apple.com/qa/qtpc/qtpc12.html and
** http://developer.apple.com/dev/techsupport/develop/issue26/macqa.html
**
** The name of the AutoStart file is stored in the area allocated for
** the Clipboard name. This area begins 106 bytes into the sector of
** block 0, with the first four bytes at that offset containing the
** hex value 0x006A7068. This value indicates that an AutoStart
** filename follows. After this 4-byte tag, 12 bytes remain, starting
** at offset 110. In these 12 bytes, the name of the AutoStart file is
** stored as a Pascal string, giving you up to 11 characters to identify
** the file. The file must reside in the root directory of the HFS
** volume or partition.
*/
int
autostart()
{
int len, i;
if((len = strlen(autoname)) > 11)
return (-1);
hce->hfs_hdr[106] = 0x00;
hce->hfs_hdr[107] = 0x6A;
hce->hfs_hdr[108] = 0x70;
hce->hfs_hdr[109] = 0x68;
hce->hfs_hdr[110] = len;
for(i=0;i<len;i++)
hce->hfs_hdr[111+i] = autoname[i];
return (0);
}

113
external/gpl2/mkhybrid/dist/mac_label.h vendored Normal file
View File

@ -0,0 +1,113 @@
/*
** mac_label.h: defines Macintosh partition maps and label
**
** Taken from "mkisofs 1.05 PLUS" by Andy Polyakov <appro@fy.chalmers.se>
** (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details)
**
** Much of this is already defined in the libhfs code, but to keep
** things simple we stick with these.
*/
#ifndef __MAC_LABEL__
#define __MAC_LABEL__
#ifdef __cplusplus
extern "C" {
#endif
/* Driver Descriptor Map */
#define sbSigMagic "ER"
struct MacLabel {
unsigned char sbSig[2]; /* unique value for SCSI block 0 */
unsigned char sbBlkSize[2]; /* block size of device */
unsigned char sbBlkCount[4]; /* number of blocks on device */
unsigned char sbDevType[2]; /* device type */
unsigned char sbDevId[2]; /* device id */
unsigned char sbData[4]; /* not used */
unsigned char sbDrvrCount[2]; /* driver descriptor count */
unsigned char ddBlock[4]; /* 1st driver's starting block */
unsigned char ddSize[2]; /* size of 1st driver (512-byte blks) */
unsigned char ddType[2]; /* system type (1 for Mac+) */
unsigned char ddPad[486]; /* ARRAY[0..242] OF INTEGER; not used */
};
typedef struct MacLabel MacLabel;
#define IS_MAC_LABEL(d) (((MacLabel*)(d))->sbSig[0]=='E'&&((MacLabel*)(d))->sbSig[1]=='R')
/* Partition Map Entry */
#define pmSigMagic "PM"
#define pmPartType_1 "Apple_partition_map"
# define pmPartName_11 "Apple"
#define pmPartType_2 "Apple_Driver"
#define pmPartType_21 "Apple_Driver43"
#define pmPartType_3 "Apple_UNIX_SVR2"
# define pmPartName_31 "A/UX Root"
# define pmPartName_32 "A/UX Usr"
# define pmPartName_33 "Random A/UX fs"
# define pmPartName_34 "Swap"
#define pmPartType_4 "Apple_HFS"
# define pmPartName_41 "MacOS"
#define pmPartType_5 "Apple_Free"
# define pmPartName_51 "Extra"
#define PM2 2
#define PM4 4
struct MacPart {
unsigned char pmSig[2]; /* unique value for map entry blk */
unsigned char pmSigPad[2]; /* currently unused */
unsigned char pmMapBlkCnt[4]; /* # of blks in partition map */
unsigned char pmPyPartStart[4];/* physical start blk of partition */
unsigned char pmPartBlkCnt[4];/* # of blks in this partition */
unsigned char pmPartName[32]; /* ASCII partition name */
unsigned char pmPartType[32]; /* ASCII partition type */
unsigned char pmLgDataStart[4];/* log. # of partition's 1st data blk */
unsigned char pmDataCnt[4]; /* # of blks in partition's data area */
unsigned char pmPartStatus[4];/* bit field for partition status */
unsigned char pmLgBootStart[4];/* log. blk of partition's boot code */
unsigned char pmBootSize[4]; /* number of bytes in boot code */
unsigned char pmBootAddr[4]; /* memory load address of boot code */
unsigned char pmBootAddr2[4]; /* currently unused */
unsigned char pmBootEntry[4]; /* entry point of boot code */
unsigned char pmBootEntry2[4];/* currently unused */
unsigned char pmBootCksum[4]; /* checksum of boot code */
unsigned char pmProcessor[16];/* ASCII for the processor type */
unsigned char pmPad[376]; /* ARRAY[0..187] OF INTEGER; not used */
};
typedef struct MacPart MacPart;
#define IS_MAC_PART(d) (((MacPart*)(d))->pmSig[0]=='P'&&((MacPart*)(d))->pmSig[1]=='M')
#define PM_STAT_VALID 0x01 /* Set if a valid partition map entry */
#define PM_STAT_ALLOC 0x02 /* Set if partition is already allocated; clear if available */
#define PM_STAT_INUSE 0x04 /* Set if partition is in use; may be cleared after a system reset */
#define PM_STAT_BOOTABLE 0x08 /* Set if partition contains valid boot information */
#define PM_STAT_READABLE 0x10 /* Set if partition allows reading */
#define PM_STAT_WRITABLE 0x20 /* Set if partition allows writing */
#define PM_STAT_BOOT_PIC 0x40 /* Set if boot code is position-independent */
#define PM_STAT_UNUSED 0x80 /* Unused */
#define PM_STAT_DEFAULT PM_STAT_VALID|PM_STAT_ALLOC|PM_STAT_READABLE|PM_STAT_WRITABLE
typedef struct {
char *name; /* Partition name */
char *type; /* Partition type */
int ntype; /* Partition type (numeric) */
int start; /* start extent (SECTOR_SIZE blocks) */
int size; /* extents (SECTOR_SIZE blocks) */
} mac_partition_table;
/* from libhfs */
#define HFS_BB_SIGWORD 0x4c4b
/* borrowed from write.c - we just need parts of this */
#ifdef __cplusplus
}
#endif
#endif /* __MAC_LABEL__ */

View File

@ -0,0 +1,40 @@
/* mac_label_proto.h */
/* $OpenBSD: mac_label_proto.h,v 1.1 2008/03/08 15:36:12 espie Exp $ */
/*
* Copyright (c) 2008 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef MAC_LABEL_PROTO_H
#define MAC_LABEL_PROTO_H
struct deferred_write {
struct deferred_write * next;
char * table;
unsigned int extent;
unsigned int size;
char * name;
#ifdef APPLE_HYB
struct directory_entry *s_entry;
unsigned int pad;
unsigned int off;
#endif
};
typedef struct deferred_write defer;
extern int gen_mac_label(defer *);
extern int autostart(void);
#endif

25
external/gpl2/mkhybrid/dist/mactypes.h vendored Normal file
View File

@ -0,0 +1,25 @@
/* Various types of HFS files stored on Unix systems */
#define TYPE_NONE 0 /* Unknown file type (ordinary Unix file) */
#define TYPE_CAP 1 /* AUFS CAP */
#define TYPE_NETA 2 /* Netatalk */
#define TYPE_DBL 3 /* AppleDouble */
#define TYPE_ESH 4 /* Helios EtherShare */
#define TYPE_FEU 5 /* PC Exchange (Upper case) */
#define TYPE_FEL 6 /* PC Exchange (Lower case) */
#define TYPE_SGI 7 /* SGI */
#define TYPE_MBIN 8 /* MacBinary */
#define TYPE_SGL 9 /* AppleSingle */
/* above encoded in a bit map */
#define DO_NONE (1 << TYPE_NONE)
#define DO_CAP (1 << TYPE_CAP)
#define DO_NETA (1 << TYPE_NETA)
#define DO_DBL (1 << TYPE_DBL)
#define DO_ESH (1 << TYPE_ESH)
#define DO_FEU (1 << TYPE_FEU)
#define DO_FEL (1 << TYPE_FEL)
#define DO_SGI (1 << TYPE_SGI)
#define DO_MBIN (1 << TYPE_MBIN)
#define DO_SGL (1 << TYPE_SGL)

81
external/gpl2/mkhybrid/dist/magic vendored Normal file
View File

@ -0,0 +1,81 @@
#
# Example magic file for mkhybrid
#
# The "message" for the offset MUST be 4 characters for the CREATOR
# and 4 characters for the TYPE - white space is optional between them.
# Any other characters on this line are ignored. Continuation lines (starting
# with '>') are also ignored i.e. only the initial offset lines are used.
#
# The continuation lines are given here, but they do not need to exist.
#
# James Pearson 20/5/98
# off type test message
# GIF
0 string GIF8 8BIM GIFf
>4 string 7a \b, version 8%s,
>4 string 9a \b, version 8%s,
>6 leshort >0 %hd x
>8 leshort >0 %hd,
#>10 byte &0x80 color mapped,
#>10 byte&0x07 =0x00 2 colors
#>10 byte&0x07 =0x01 4 colors
#>10 byte&0x07 =0x02 8 colors
#>10 byte&0x07 =0x03 16 colors
#>10 byte&0x07 =0x04 32 colors
#>10 byte&0x07 =0x05 64 colors
#>10 byte&0x07 =0x06 128 colors
#>10 byte&0x07 =0x07 256 colors
# JPEG images
#
0 ubeshort 0xffd8 8BIM JPEG image data
# StuffIt
#
0 string SIT! SIT!SIT!
# standard unix compress
0 string \037\235 LZIV ZIVU
>2 byte&0x80 >0 block compressed
>2 byte&0x1f x %d bits
# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
0 string \037\213 GNUz ZIVU gzip compressed data
>2 byte <8 \b, reserved method,
>2 byte 8 \b, deflated,
>3 byte &0x01 ASCII,
>3 byte &0x02 continuation,
>3 byte &0x04 extra field,
>3 byte &0x08 original filename,
>3 byte &0x10 comment,
>3 byte &0x20 encrypted,
>4 ledate x last modified: %s,
>8 byte 2 max compression,
>8 byte 4 max speed,
>9 byte =0x00 os: MS-DOS
>9 byte =0x01 os: Amiga
>9 byte =0x02 os: VMS
>9 byte =0x03 os: Unix
>9 byte =0x05 os: Atari
>9 byte =0x06 os: OS/2
>9 byte =0x07 os: MacOS
>9 byte =0x0A os: Tops/20
>9 byte =0x0B os: Win/32
# Postscript
0 string %! ASPSTEXT
>2 string PS-Adobe- conforming
>>11 string >\0 at level %.3s
>>>15 string EPS - type %s
>>>15 string Query - type %s
>>>15 string ExitServer - type %s
# Some PCs have the annoying habit of adding a ^D as a document separator
0 string \004%! ASPS TEXT PostScript document text
>3 string PS-Adobe- conforming
>>12 string >\0 at level %.3s
>>>16 string EPS - type %s
>>>16 string Query - type %s
>>>16 string ExitServer - type %s

8
external/gpl2/mkhybrid/dist/mapping vendored Normal file
View File

@ -0,0 +1,8 @@
# Example filename mapping file
#
# EXTN XLate CREATOR TYPE Comment
.tif Raw '8BIM' 'TIFF' "Photoshop TIFF image"
.hqx Ascii 'BnHq' 'TEXT' "BinHex file"
.doc Raw 'MSWD' 'WDBN' "Word file"
.mov Raw 'TVOD' 'MooV' "QuickTime Movie"
* Ascii 'ttxt' 'TEXT' "Text file"

297
external/gpl2/mkhybrid/dist/match.c vendored Normal file
View File

@ -0,0 +1,297 @@
/*
* 27-Mar-96: Jan-Piet Mens <jpm@mens.de>
* added 'match' option (-m) to specify regular expressions NOT to be included
* in the CD image.
*/
#ifdef APPLE_HYB
/*
* Added a number of routines to create lists of files to hidden from
* the ISO9660 and/or Joliet trees. James Pearson (j.pearson@ge.ucl.ac.uk)
* January 1999 (these will probably appear in mkisofs in the future)
*/
#endif /* APPLE_HYB */
#include "config.h"
#include <prototyp.h>
#include <stdio.h>
#include <fnmatch.h>
#ifndef VMS
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#endif
#include <inttypes.h>
#include <string.h>
#include "match.h"
#define MAXMATCH 1000
static char *mat[MAXMATCH];
int add_match(fn)
char * fn;
{
register int i;
for (i=0; mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return 1;
}
mat[i] = (char *) malloc(strlen(fn)+1);
if (! mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return 1;
}
strcpy(mat[i],fn);
return 0;
}
int matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; mat[i] && i<MAXMATCH; i++) {
if (fnmatch(mat[i], fn, FNM_PATHNAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
/* ISO9660/RR hide */
static char *i_mat[MAXMATCH];
int i_add_match(fn)
char * fn;
{
register int i;
for (i=0; i_mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return 1;
}
i_mat[i] = (char *) malloc(strlen(fn)+1);
if (! i_mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return 1;
}
strcpy(i_mat[i],fn);
return 0;
}
int i_matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; i_mat[i] && i<MAXMATCH; i++) {
if (fnmatch(i_mat[i], fn, FNM_PATHNAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
intptr_t i_ishidden()
{
return((intptr_t)i_mat[0]);
}
/* Joliet hide */
static char *j_mat[MAXMATCH];
int j_add_match(fn)
char * fn;
{
register int i;
for (i=0; j_mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return 1;
}
j_mat[i] = (char *) malloc(strlen(fn)+1);
if (! j_mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return 1;
}
strcpy(j_mat[i],fn);
return 0;
}
int j_matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; j_mat[i] && i<MAXMATCH; i++) {
if (fnmatch(j_mat[i], fn, FNM_PATHNAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
intptr_t j_ishidden()
{
return((intptr_t)j_mat[0]);
}
#ifdef APPLE_HYB
/* HFS hide */
static char *hfs_mat[MAXMATCH];
int hfs_add_match(fn)
char * fn;
{
register int i;
for (i=0; hfs_mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return 1;
}
hfs_mat[i] = (char *) malloc(strlen(fn)+1);
if (! hfs_mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return 1;
}
strcpy(hfs_mat[i],fn);
return 0;
}
void hfs_add_list(file)
char *file;
{
FILE *fp;
char name[1024];
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr,"Can't open hidden file list %s\n", file);
exit (1);
}
while (fscanf(fp, "%s", name) != EOF) {
if (hfs_add_match(name)) {
fclose(fp);
return;
}
}
fclose(fp);
}
int hfs_matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; hfs_mat[i] && i<MAXMATCH; i++) {
if (fnmatch(hfs_mat[i], fn, FNM_PATHNAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
intptr_t hfs_ishidden()
{
return((intptr_t)hfs_mat[0]);
}
/* These will probably appear in mkisofs in the future */
void add_list(file)
char *file;
{
FILE *fp;
char name[1024];
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr,"Can't open exclude file list %s\n", file);
exit (1);
}
while (fscanf(fp, "%s", name) != EOF) {
if (add_match(name)) {
fclose(fp);
return;
}
}
fclose(fp);
}
void i_add_list(file)
char *file;
{
FILE *fp;
char name[1024];
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr,"Can't open hidden file list %s\n", file);
exit (1);
}
while (fscanf(fp, "%s", name) != EOF) {
if (i_add_match(name)) {
fclose(fp);
return;
}
}
fclose(fp);
}
void j_add_list(file)
char *file;
{
FILE *fp;
char name[1024];
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr,"Can't open hidden file list %s\n", file);
exit (1);
}
while (fscanf(fp, "%s", name) != EOF) {
if (j_add_match(name)) {
fclose(fp);
return;
}
}
fclose(fp);
}
#endif /* APPLE_HYB */

34
external/gpl2/mkhybrid/dist/match.h vendored Normal file
View File

@ -0,0 +1,34 @@
/*
* 27th March 1996. Added by Jan-Piet Mens for matching regular expressions
* in paths.
*
*/
/*
* Id: match.h,v 1.5 2008/04/18 20:52:34 millert Exp
*/
#include <inttypes.h>
int matches __PR((char *fn));
int i_matches __PR((char *fn));
intptr_t i_ishidden __PR((void));
int j_matches __PR((char *fn));
intptr_t j_ishidden __PR((void));
int add_match __PR((char *fn));
int i_add_match __PR((char *fn));
int j_add_match __PR((char *fn));
#ifdef APPLE_HYB
int hfs_add_match __PR((char *fn));
void hfs_add_list __PR((char *fn));
int hfs_matches __PR((char *fn));
intptr_t hfs_ishidden __PR((void));
void add_list __PR((char *fn));
void i_add_list __PR((char *fn));
void j_add_list __PR((char *fn));
#endif /* APPLE_HYB */

1635
external/gpl2/mkhybrid/dist/mkhybrid.8 vendored Normal file

File diff suppressed because it is too large Load Diff

689
external/gpl2/mkhybrid/dist/mkisofs.8 vendored Normal file
View File

@ -0,0 +1,689 @@
.\" -*- nroff -*-
.\"
.\" Id: mkisofs.8,v 1.1 2000/10/10 20:40:19 beck Exp
.\"
.TH MKISOFS 8 "17 Feb 1998" "Version 1.12b5"
.SH NAME
mkisofs \- create a iso9660 filesystem with optional Rock Ridge attributes.
.SH SYNOPSIS
.B mkisofs
[
.B \-a
]
[
.B \-abstract
.I FILE
]
[
.B \-biblio
.I FILE
]
[
.B \-b
.I boot_image
]
[
.B \-c
.I boot_catalog
]
[
.B \-copyright
.I FILE
]
[
.B \-A
.I application_id
]
[
.B \-f
]
[
.B \-d
]
[
.B \-D
]
[
.B \-hide
.I glob
]
[
.B \-hide-joliet
.I glob
]
[
.B \-J
]
[
.B \-l
]
[
.B \-L
]
[
.B \-log-file
.I log_file
]
[
.B -no-split-symlink-components
]
[
.B -no-split-symlink-fields
]
[
.B \-p
.I preparer
]
[
.B \-print-size
]
[
.B \-P
.I publisher
]
[
.B \-quiet
]
[
.B \-r
]
[
.B \-R
]
[
.B \-sysid
.I ID
]
[
.B \-T
]
[
.B \-v
]
[
.B \-V
.I volid
]
[
.B \-volset
.I ID
]
[
.B \-volset-size
.I #
]
[
.B \-volset-seqno
.I #
]
[
.B \-x
.I path
]
[
.B \-z
]
[
.B \-m
.I glob
]
.B \-o
.I filename
.I pathspec [pathspec]
.SH DESCRIPTION
.B mkisofs
is effectively a pre-mastering program to generate the iso9660 filesystem - it
takes a snapshot of a given directory tree, and generates a binary image which
will correspond to an iso9660 filesystem when written to a block device.
.PP
.B mkisofs
is also capable of generating the System Use Sharing Protocol records specified
by the Rock Ridge Interchange Protocol. This is used to further describe the
files in the iso9660 filesystem to a unix host, and provides information such
as longer filenames, uid/gid, posix permissions, and block and character
devices.
.PP
Each file written to the iso9660 filesystem must have a filename in the 8.3
format (8 characters, period, 3 characters, all upper case), even if Rock Ridge
is in use. This filename is used on systems that are not able to make use of
the Rock Ridge extensions (such as MS-DOS), and each filename in each directory
must be different from the other filenames in the same directory.
.B mkisofs
generally tries to form correct names by forcing the unix filename to upper
case and truncating as required, but often times this yields unsatisfactory
results when there are cases where the
truncated names are not all unique.
.B mkisofs
assigns weightings to each filename, and if two names that are otherwise the
same are found the name with the lower priority is renamed to have a 3 digit
number as an extension (where the number is guaranteed to be unique). An
example of this would be the files foo.bar and
foo.bar.~1~ - the file foo.bar.~1~ would be written as FOO.000;1 and the file
foo.bar would be written as FOO.BAR;1
.PP
Note that
.B mkisofs
is not designed to communicate with the writer directly. Most writers
have proprietary command sets which vary from one manufacturer to
another, and you need a specialized tool to actually burn the disk.
The
.B cdwrite
utility is one such tool that runs under Linux and performs this task.
The latest version of
.B cdwrite
is capable of communicating with the Phillips/IMS/Kodak, HP and Yamaha drives
that have been manufactured before 1997.
Most writers come with some version of DOS software that allows a direct image
copy of an iso9660 image to the writer. The current version of
.B cdwrite
is available from sunsite.unc.edu: /utils/disk-management/cdwrite-2.0.tar.gz
Note that cdwrite has not been actively maintained since 1995.
.PP
The
.B
cdrecord
utility is another utility capable of burning an actual disc. The latest version
of
.B cdrecord
is available from
ftp://ftp.fokus.gmd.de/pub/unix/cdrecord
Cdrecord is under constant development.
.PP
Also you should know that most cd writers are very particular about timing.
Once you start to burn a disc, you cannot let their buffer empty before you
are done, or you will end up with a corrupt disc. Thus it is critical
that you be able to maintain an uninterrupted data stream to the writer
for the entire time that the disc is being written.
.PP
.br
.B path
is the path of the directory tree to be copied into the iso9660 filesystem.
Multiple paths can be specified, and
.B
mkisofs
will merge the files found in all of the specified path components to form the cdrom
image.
.PP
It is possible to graft the paths at points other than the root
directory, and it is possible to graft files or directories onto the
cdrom image with names different than what they have in the source filesystem. This is
easiest to illustrate with a couple of examples. Let's start by assuming that a local
file ../old.lis exists, and you wish to include it in the cdrom image.
foo/bar/=../old.lis
will include the file old.lis in the cdrom image at /foo/bar/old.lis, while
foo/bar/xxx=../old.lis
will include the file old.lis in the cdrom image at /foo/bar/xxx. The
same sort of syntax can be used with directories as well.
.B
mkisofs will create any directories required such that the graft
points exist on the cdrom image - the directories do not need to
appear in one of the paths. Any directories that are created on the
fly like this will have permissions 0555 and appear to be owned by the
person running mkisofs. If you wish other permissions or owners of
the intermediate directories, the easiest solution is to create real
directories in the path such that mkisofs doesn't have to invent them.
.SH OPTIONS
.TP
.B \-a
Include all files on the iso9660 filesystem. Normally files that contain the
characters '~' or '#' will not be included (these are typically backup files
for editors under unix).
.TP
.BI \-abstract " FILE
Specifies the abstract file name.
This parameter can also be set in the file
.B \&.mkisofsrc
with ABST=filename.
If specified in both places, the command line version is used.
.TP
.BI \-A " application_id
Specifies a text string that will be written into the volume header.
This should describe the application that will be on the disc. There
is space on the disc for 128 characters of information. This parameter can
also be set in the file
.B \&.mkisofsrc
with APPI=id.
If specified in both places, the command line version is used.
.TP
.BI \-biblio " FILE
Specifies the bibliographic file name.
This parameter can also be set in the file
.B \&.mkisofsrc
with BIBLO=filename.
If specified in both places, the command line version is used.
.TP
.BI \-b " boot_image
Specifies the path and filename of the boot image to be used when making
an "El Torito" bootable CD. The pathname must be relative to the source
path specified to
.B mkisofs.
This option is required to make a bootable CD.
The boot image must be exactly the size of either a 1.2, 1.44, or a 2.88
meg floppy, and
.B mkisofs
will use this size when creating the output iso9660
filesystem. It is assumed that the first 512 byte sector should be read
from the boot image (it is essentially emulating a normal floppy drive).
This will work, for example, if the boot image is a LILO based boot floppy.
.TP
.BI \-C " last_sess_start,next_sess_start
This option is needed when
.B mkisofs
is used to create the image of a second session or a higher level session
for a multi session disk.
The option
.B \-C
takes a pair of two numbers separated by a comma. The first number is the
sector number of the first sector in the last session of the disk
that should be appended to.
The second number is the starting sector number of the new session.
The expected pair of numbers may be retrieved by calling
.B "cdrecord -msinfo ...
the
.B \-C
option may only be uses in conjunction with the
.B \-M
option.
.TP
.BI \-c " boot_catalog
Specifies the path and filename of the boot catalog to be used when making
an "El Torito" bootable CD. The pathname must be relative to the source
path specified to
.B mkisofs.
This option is required to make a bootable CD.
This file will be created by
.B mkisofs
in the source filesystem, so be
sure the specified filename does not conflict with an existing file, as
it will be quietly overwritten! Usually a name like "boot.catalog" is
chosen.
.TP
.BI \-copyright " FILE
Specifies the Copyright file name.
This parameter can also be set in the file
.B \&.mkisofsrc
with COPY=filename.
If specified in both places, the command line version is used.
.TP
.B \-d
Omit trailing period from files that do not have a period. This violates the
ISO9660 standard, but it happens to work on many systems. Use with caution.
.TP
.B \-D
Do not use deep directory relocation, and instead just pack them in the
way we see them. This violates the ISO9660 standard, but it works on many
systems. Use with caution.
.TP
.B \-f
Follow symbolic links when generating the filesystem. When this option is not
in use, symbolic links will be entered using Rock Ridge if enabled, otherwise
the file will be ignored.
.TP
.BI \-hide " glob
Hide
.I glob
from being seen on the ISO9660 or Rock Ridge directory.
.I glob
is a shell wild-card-style pattern that must match any part of the filename
or path.
Multiple globs may be hidden (up to 1000).
If
.I glob
matches a directory, then the contents of that directory will be hidden.
All the hidden files will still be written to the output CD image file.
Should be used with the
.B \-hide-joliet
option.
.TP
.BI \-hide-joliet " glob
Hide
.I glob
from being seen on the Joliet directory.
.I glob
is a shell wild-card-style pattern that must match any part of the filename
or path.
Multiple globs may be hidden (up to 1000).
If
.I glob
matches a directory, then the contents of that directory will be hidden.
All the hidden files will still be written to the output CD image file.
Should be used with the
.B \-hide
option.
.TP
.B \-l
Allow full 32 character filenames. Normally the ISO9660 filename will be in an
8.3 format which is compatible with MS-DOS, even though the ISO9660 standard
allows filenames of up to 32 characters. If you use this option, the disc may
be difficult to use on a MS-DOS system, but this comes in handy on some other
systems (such as the Amiga). Use with caution.
.TP
.B \-J
Generate Joliet directory records in addition to regular iso9660 file
names. This is primarily useful when the discs are to be used on Windows-NT
or Windows-95 machines. The Joliet filenames are specified in Unicode and
each path component can be up to 64 Unicode characters long.
.TP
.B \-L
Allow filenames to begin with a period. Usually, a leading dot is
replaced with an underscore in order to maintain MS-DOS compatibility.
.TP
.BI \-log-file " log_file
Redirect all error, warning and informational messages to
.I log_file
instead of the standard error.
.TP
.BI \-m " glob
Exclude
.I glob
from being written to CDROM.
.I glob
is a shell wild-card-style pattern that must match part of the filename (not
the path as with option
.BR -x ).
Technically
.I glob
is matched against the
.I d->d_name
part of the directory entry.
Multiple globs may be excluded (up to 1000).
Example:
mkisofs \-o rom \-m '*.o' \-m core \-m foobar
would exclude all files ending in ".o", called "core" or "foobar" to be
copied to CDROM. Note that if you had a directory called "foobar" it too (and
of course all its descendants) would be excluded.
.sp
NOTE: The \-m and \-x option description should both be updated, they are wrong.
Both now work identical and use filename globbing. A file is exluded if either
the last component matches or the whole path matches.
.TP
.BI \-M " path
or
.TP
.BI \-M " device
Specifies path to existing iso9660 image to be merged. The alternate form
takes a SCSI device specifier that uses the same syntax as the
.B "dev=
parameter of
.B cdrecord.
The output of
.B mkisofs
will be a new session which should get written to the end of the
image specified in -M. Typically this requires multi-session capability
for the recorder and cdrom drive that you are attempting to write this
image to.
This option may only be used in conjunction with the
.B \-C
option.
.TP
.B \-N
Omit version numbers from ISO9660 file names. This may violate the ISO9660
standard, but no one really uses the version numbers anyway. Use with caution.
.TP
.B \-no-split-symlink-components
Don't split the SL components, but begin a new Continuation Area (CE)
instead. This may waste some space, but the SunOS 4.1.4 cdrom driver
has a bug in reading split SL components (link_size = component_size
instead of link_size += component_size).
.TP
.B \-no-split-symlink-fields
Don't split the SL fields, but begin a new Continuation Area (CE)
instead. This may waste some space, but the SunOS 4.1.4 and
Solaris 2.5.1 cdrom driver have a bug in reading split SL fields
(a `/' can be dropped).
.TP
.BI \-o " filename
is the name of the file to which the iso9660 filesystem image should be
written. This can be a disk file, a tape drive, or it can correspond directly
to the device name of the optical disc writer. If not specified, stdout is
used. Note that the output can also be a block special device for a regular
disk drive, in which case the disk partition can be mounted and examined to
ensure that the premastering was done correctly.
.TP
.BI \-P " publisher_id
Specifies a text string that will be written into the volume header.
This should describe the publisher of the CDROM, usually with a
mailing address and phone number. There is space on the disc for 128
characters of information. This parameter can also be set in the file
.B \&.mkisofsrc
with PUBL=.
If specified in both places, the command line version is used.
.TP
.BI \-p " preparer_id
Specifies a text string that will be written into the volume header.
This should describe the preparer of the CDROM, usually with a mailing
address and phone number. There is space on the disc for 128
characters of information. This parameter can also be set in the file
.B \&.mkisofsrc
with PREP=.
If specified in both places, the command line version is used.
.TP
.B \-print-size
Print estimated filesystem size and exit. This option is needed for
Disk At Once mode and with some CD-R drives when piping directly into
.B cdrecord.
In this case it is needed to know the size of the filesustem before the
actual CD-creation is done.
The option \-print-size allows to get this size from a "dry-run" before
the CD is actually written.
.TP
.B \-R
Generate SUSP and RR records using the Rock Ridge protocol to further describe
the files on the iso9660 filesystem.
.TP
.B \-r
This is like the \-R option, but file ownership and modes are set to
more useful values. The uid and gid are set to zero, because they are
usually only useful on the author's system, and not useful to the
client. All the file read bits are set true, so that files and
directories are globally readable on the client. If any execute bit is
set for a file, set all of the execute bits, so that executables are
globally executable on the client. If any search bit is set for a
directory, set all of the search bits, so that directories are globally
searchable on the client. All write bits are cleared, because the
CD-Rom will be mounted read-only in any case. If any of the special
mode bits are set, clear them, because file locks are not useful on a
read-only file system, and set-id bits are not desirable for uid 0 or
gid 0.
.TP
.BI \-sysid " ID
Specifies the system ID.
This parameter can also be set in the file
.B \&.mkisofsrc
with SYSI=system_id.
If specified in both places, the command line version is used.
.TP
.B \-T
Generate a file TRANS.TBL in each directory on the CDROM, which can be used
on non-Rock Ridge capable systems to help establish the correct file names.
There is also information present in the file that indicates the major and
minor numbers for block and character devices, and each symlink has the name of
the link file given.
.TP
.BI \-V " volid
Specifies the volume ID to be written into the master block. This
parameter can also be set in the file
.B \&.mkisofsrc
with VOLI=id.
If specified in both places, the command line version is used. Note that
if you assign a volume ID, this is the name that will be used as the mount
point used by the Solaris volume management system and the name that is
assigned to the disc on a Windows or Mac platform.
.TP
.BI \-volset " ID
Specifies the volset ID.
This parameter can also be set in the file
.B \&.mkisofsrc
with VOLS=volset_id.
If specified in both places, the command line version is used.
.TP
.BI \-volset-size " #
Sets the volume set size to #.
The volume set size is the number of CD's that are in a CD set.
The
.B \-volset-size
option may be used to create CD's that are part of e.g. a Operation
System installation set of CD's.
The option
.B \-volset-size
must be specified before
.B \-volset-seqno
on each command line.
.TP
.BI \-volset-seqno " #
Sets the volume set sequence number to #.
The volume set sequence number is the index number of the current
CD in a CD set.
The option
.B \-volset-size
must be specified before
.B \-volset-seqno
on each command line.
.TP
.B \-v
Verbose execution.
.TP
.BI \-x " path
Exclude
.I path
from being written to CDROM.
.I path
must be the complete pathname that results from concatenating the pathname
given as command line argument and the path relative to this directory.
Multiple paths may be excluded (up to 1000).
Example:
mkisofs \-o cd \-x /local/dir1 \-x /local/dir2 /local
.sp
NOTE: The \-m and \-x option description should both be updated, they are wrong.
Both now work identical and use filename globbing. A file is exluded if either
the last component matches or the whole path matches.
.TP
.B \-z
Generate special SUSP records for transparently compressed files. This is
only of use and interest for hosts that support transparent decompression.
This is an experimental feature, and no hosts yet support this, but there
are ALPHA patches for Linux that can make use of this feature.
.SH CONFIGURATION
.B mkisofs
looks for the
.B \&.mkisofsrc
file,
first in the current working directory,
then in the user's home directory,
and then in the directory in which the
.B mkisofs
binary is stored. This file is assumed to contain a series of lines
of the form
.BI TAG= value,
and in this way you can specify certain options.
The case of the tag is not significant.
Some fields in the volume header
are not settable on the command line, but can be altered through this
facility.
Comments may be placed in this file,
using lines which start with a hash (#) character.
.TP
.B APPI
The application identifier
should describe the application that will be on the disc.
There is space on the disc for 128 characters of information.
May be overridden using the
.B \-A
command line option.
.TP
.B COPY
The copyright information,
often the name of a file on the disc containing the copyright notice.
There is space in the disc for 37 characters of information.
May be overridden using the
.B \-copyright
command line option.
.TP
.B ABST
The abstract information,
often the name of a file on the disc containing an abstract.
There is space in the disc for 37 characters of information.
May be overridden using the
.B \-abstract
command line option.
.TP
.B BIBL
The bibliographic information,
often the name of a file on the disc containing a bibliography.
There is space in the disc for 37 characters of information.
May be overridden using the
.B \-bilio
command line option.
.TP
.B PREP
This should describe the preparer of the CDROM,
usually with a mailing address and phone number.
There is space on the disc for 128 characters of information.
May be overridden using the
.B \-p
command line option.
.TP
.B PUBL
This should describe the publisher of the CDROM,
usually with a mailing address and phone number.
There is space on the disc for 128 characters of information.
May be overridden using the
.B \-P
command line option.
.TP
.B SYSI
The System Identifier.
There is space on the disc for 32 characters of information.
May be overridden using the
.B \-sysid
command line option.
.TP
.B VOLI
The Volume Identifier.
There is space on the disc for 32 characters of information.
May be overridden using the
.B \-V
command line option.
.TP
.B VOLS
The Volume Set Name.
There is space on the disc for 128 characters of information.
May be overridden using the
.B \-volset
command line option.
.PP
.B mkisofs
can also be configured at compile time with defaults for many of these fields.
See the file defaults.h.
.SH AUTHOR
.B mkisofs
is not based on the standard mk*fs tools for unix, because we must generate
a complete copy of an existing filesystem on a disk in the iso9660
filesystem. The name mkisofs is probably a bit of a misnomer, since it
not only creates the filesystem, but it also populates it as well.
.PP
.br
Eric Youngdale <ericy@gnu.ai.mit.edu> or <eric@andante.jic.com> wrote both the
Linux isofs9660 filesystem and the mkisofs utility, and is currently
maintaining them. The copyright for the mkisofs utility is held by
Yggdrasil Computing, Incorporated.
.SH BUGS
Any files that have hard links to files not in the tree being copied to the
iso9660 filessytem will have an incorrect file reference count.
.PP
There may be some other ones. Please, report them to the author.
.SH FUTURE IMPROVEMENTS
Some sort of gui interface.
.SH AVAILABILITY
.B mkisofs
is available for anonymous ftp from tsx-11.mit.edu in
/pub/linux/packages/mkisofs and many other mirror sites.

1709
external/gpl2/mkhybrid/dist/mkisofs.c vendored Normal file

File diff suppressed because it is too large Load Diff

532
external/gpl2/mkhybrid/dist/mkisofs.h vendored Normal file
View File

@ -0,0 +1,532 @@
/*
* Header file mkisofs.h - assorted structure definitions and typecasts.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* Id: mkisofs.h,v 1.4 2015/09/09 20:02:31 miod Exp
*/
/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 12/3/99 */
#include <stdio.h>
#include <prototyp.h>
/* This symbol is used to indicate that we do not have things like
symlinks, devices, and so forth available. Just files and dirs */
#ifdef VMS
#define NON_UNIXFS
#endif
#ifdef DJGPP
#define NON_UNIXFS
#endif
#ifdef VMS
#include <sys/dir.h>
#define dirent direct
#endif
#ifdef _WIN32
#define NON_UNIXFS
#endif /* _WIN32 */
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(HAVE_DIRENT_H)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined(HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif
# if defined(HAVE_NDIR_H)
# include <ndir.h>
# endif
#endif
#if defined(HAVE_STRING_H)
#include <string.h>
#else
#if defined(HAVE_STRINGS_H)
#include <strings.h>
#endif
#endif
#ifdef ultrix
extern char *strdup();
#endif
#ifdef __STDC__
#define DECL(NAME,ARGS) NAME ARGS
#define FDECL1(NAME,TYPE0, ARG0) \
NAME(TYPE0 ARG0)
#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \
NAME(TYPE0 ARG0, TYPE1 ARG1)
#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2)
#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3)
#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4)
#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5)
#else
#define DECL(NAME,ARGS) NAME()
#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0;
#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1;
#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2;
#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3;
#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4;
#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5;
#define const
#endif
#ifdef __SVR4
#include <stdlib.h>
#else
extern int optind;
extern char *optarg;
/* extern int getopt (int __argc, char **__argv, char *__optstring); */
#endif
#include "iso9660.h"
#include "defaults.h"
#ifdef APPLE_HYB
#include <mactypes.h>
#include <hfs.h>
struct hfs_info {
hfsdirent hfs_ent;
char *keyname;
struct hfs_info *next;
};
#endif /* APPLE_HYB */
struct directory_entry{
struct directory_entry * next;
struct directory_entry * jnext;
struct iso_directory_record isorec;
unsigned int starting_block;
unsigned int size;
unsigned short priority;
unsigned char jreclen; /* Joliet record len */
char * name;
char * table;
char * whole_name;
struct directory * filedir;
struct directory_entry * parent_rec;
unsigned int de_flags;
ino_t inode; /* Used in the hash table */
dev_t dev; /* Used in the hash table */
unsigned char * rr_attributes;
unsigned int rr_attr_size;
unsigned int total_rr_attr_size;
unsigned int got_rr_name;
#ifdef APPLE_HYB
struct directory_entry * assoc; /* entry has a resource fork */
hfsdirent *hfs_ent; /* HFS parameters */
unsigned int hfs_off; /* offset to real start of fork */
unsigned int hfs_type; /* type of HFS Unix file */
#endif /* APPLE_HYB */
};
struct file_hash{
struct file_hash * next;
ino_t inode; /* Used in the hash table */
dev_t dev; /* Used in the hash table */
unsigned int starting_block;
unsigned int size;
};
/*
* This structure is used to control the output of fragments to the cdrom
* image. Everything that will be written to the output image will eventually
* go through this structure. There are two pieces - first is the sizing where
* we establish extent numbers for everything, and the second is when we actually
* generate the contents and write it to the output image.
*
* This makes it trivial to extend mkisofs to write special things in the image.
* All you need to do is hook an additional structure in the list, and the rest
* works like magic.
*
* The three passes each do the following:
*
* The 'size' pass determines the size of each component and assigns the extent number
* for that component.
*
* The 'generate' pass will adjust the contents and pointers as required now that extent
* numbers are assigned. In some cases, the contents of the record are also generated.
*
* The 'write' pass actually writes the data to the disc.
*/
struct output_fragment
{
struct output_fragment * of_next;
#ifdef __STDC__
int (*of_size)(int);
int (*of_generate)(void);
int (*of_write)(FILE *);
#else
int (*of_size)();
int (*of_generate)();
int (*of_write)();
#endif
};
extern struct output_fragment * out_list;
extern struct output_fragment * out_tail;
extern struct output_fragment padblock_desc;
extern struct output_fragment voldesc_desc;
extern struct output_fragment joliet_desc;
extern struct output_fragment torito_desc;
extern struct output_fragment end_vol;
extern struct output_fragment pathtable_desc;
extern struct output_fragment jpathtable_desc;
extern struct output_fragment dirtree_desc;
extern struct output_fragment dirtree_clean;
extern struct output_fragment jdirtree_desc;
extern struct output_fragment extension_desc;
extern struct output_fragment files_desc;
/*
* This structure describes one complete directory. It has pointers
* to other directories in the overall tree so that it is clear where
* this directory lives in the tree, and it also must contain pointers
* to the contents of the directory. Note that subdirectories of this
* directory exist twice in this stucture. Once in the subdir chain,
* and again in the contents chain.
*/
struct directory{
struct directory * next; /* Next directory at same level as this one */
struct directory * subdir; /* First subdirectory in this directory */
struct directory * parent;
struct directory_entry * contents;
struct directory_entry * jcontents;
struct directory_entry * self;
char * whole_name; /* Entire path */
char * de_name; /* Entire path */
unsigned int ce_bytes; /* Number of bytes of CE entries reqd for this dir */
unsigned int depth;
unsigned int size;
unsigned int extent;
unsigned int jsize;
unsigned int jextent;
unsigned short path_index;
unsigned short jpath_index;
unsigned short dir_flags;
unsigned short dir_nlink;
#ifdef APPLE_HYB
hfsdirent *hfs_ent; /* HFS parameters */
struct hfs_info *hfs_info; /* list of info for all entries in dir */
#endif /* APPLE_HYB */
};
struct deferred{
struct deferred * next;
unsigned int starting_block;
char * name;
struct directory * filedir;
unsigned int flags;
};
extern int goof;
extern struct directory * root;
extern struct directory * reloc_dir;
extern unsigned int next_extent;
extern unsigned int last_extent;
extern unsigned int last_extent_written;
extern unsigned int session_start;
extern unsigned int path_table_size;
extern unsigned int path_table[4];
extern unsigned int path_blocks;
extern char * path_table_l;
extern char * path_table_m;
extern unsigned int jpath_table_size;
extern unsigned int jpath_table[4];
extern unsigned int jpath_blocks;
extern char * jpath_table_l;
extern char * jpath_table_m;
extern struct iso_directory_record root_record;
extern struct iso_directory_record jroot_record;
extern int use_eltorito;
extern int use_RockRidge;
extern int use_Joliet;
extern int rationalize;
extern int follow_links;
extern int verbose;
extern int all_files;
extern int generate_tables;
extern int print_size;
extern int split_output;
extern int omit_period;
extern int omit_version_number;
extern int transparent_compression;
extern int RR_relocation_depth;
extern int full_iso9660_filenames;
extern int split_SL_component;
extern int split_SL_field;
#ifdef APPLE_HYB
extern int apple_hyb; /* create HFS hybrid */
extern int apple_ext; /* use Apple extensions */
extern int apple_both; /* common flag (for above) */
extern int hfs_extra; /* extra ISO extents (hfs_ce_size) */
extern hce_mem *hce; /* libhfs/mkisofs extras */
extern int mac_name; /* use Mac name for ISO9660/Joliet/RR */
extern int create_dt; /* create the Desktp files */
extern char *hfs_boot_file; /* name of HFS boot file */
extern char *magic_file; /* magic file for CREATOR/TYPE matching */
extern int hfs_last; /* order in which to process map/magic files */
extern char *deftype; /* default Apple TYPE */
extern char *defcreator; /* default Apple CREATOR */
extern char *trans_tbl; /* translation table name */
extern int gen_pt; /* generate HFS partition table */
extern char *autoname; /* Autostart filename */
extern int bsize; /* Apple File Exchange block size */
extern char *hfs_volume_id; /* HFS volume ID */
#define ASSOC_FLAG 4 /* ISO flag for "associated" file */
#define MAP_LAST 1 /* process magic then map file */
#define MAG_LAST 2 /* process map then magic file */
extern char *hfs_bless; /* name of folder to 'bless' (System Folder) */
#endif /* APPLE_HYB */
/* tree.c */
extern int DECL(stat_filter, (char *, struct stat *));
extern int DECL(lstat_filter, (char *, struct stat *));
extern int DECL(sort_tree,(struct directory *));
extern struct directory *
DECL(find_or_create_directory,(struct directory *, const char *,
struct directory_entry * self, int));
extern void DECL (finish_cl_pl_entries, (void));
extern int DECL(scan_directory_tree,(struct directory * this_dir,
char * path,
struct directory_entry * self));
#ifdef APPLE_HYB
extern int DECL(insert_file_entry,(struct directory *, char *,
char *, int));
#else
extern int DECL(insert_file_entry,(struct directory *, char *,
char *));
#endif /* APPLE_HYB */
extern void DECL(generate_iso9660_directories,(struct directory *, FILE*));
extern void DECL(dump_tree,(struct directory * node));
extern struct directory_entry * DECL(search_tree_file, (struct
directory * node,char * filename));
extern void DECL(update_nlink_field,(struct directory * node));
extern void DECL (init_fstatbuf, (void));
extern struct stat root_statbuf;
/* eltorito.c */
extern void DECL(init_boot_catalog, (const char * path ));
extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path ));
/* write.c */
extern int DECL(get_733,(char *));
extern int DECL(isonum_733,(unsigned char *));
extern void DECL(set_723,(char *, unsigned int));
extern void DECL(set_731,(char *, unsigned int));
extern void DECL(set_721,(char *, unsigned int));
extern void DECL(set_733,(char *, unsigned int));
extern int DECL(sort_directory,(struct directory_entry **));
extern void DECL(generate_one_directory,(struct directory *, FILE*));
extern void DECL(memcpy_max, (char *, char *, int));
extern int DECL(oneblock_size, (int starting_extent));
extern struct iso_primary_descriptor vol_desc;
extern void DECL(xfwrite, (void * buffer, int count, int size, FILE * file));
extern void DECL(set_732, (char * pnt, unsigned int i));
extern void DECL(set_722, (char * pnt, unsigned int i));
extern void DECL(outputlist_insert, (struct output_fragment * frag));
/* multi.c */
extern FILE * in_image;
extern struct iso_directory_record *
DECL(merge_isofs,(char * path));
extern int DECL(free_mdinfo, (struct directory_entry **, int len));
extern struct directory_entry **
DECL(read_merging_directory,(struct iso_directory_record *, int*));
extern void
DECL(merge_remaining_entries, (struct directory *,
struct directory_entry **, int));
extern int
DECL(merge_previous_session, (struct directory *,
struct iso_directory_record *));
extern int DECL(get_session_start, (int *));
/* joliet.c */
int DECL(joliet_sort_tree, (struct directory * node));
/* match.c */
extern int DECL(matches, (char *));
#ifdef APPLE_HYB
extern int DECL(add_match, (char *));
#else
extern void DECL(add_match, (char *));
#endif /* APPLE_HYB */
/* files.c */
struct dirent * DECL(readdir_add_files, (char **, char *, DIR *));
/* */
extern int DECL(iso9660_file_length,(const char* name,
struct directory_entry * sresult, int flag));
extern int DECL(iso9660_date,(char *, time_t));
extern void DECL(add_hash,(struct directory_entry *));
extern struct file_hash * DECL(find_hash,(dev_t, ino_t));
#ifdef APPLE_HYB
extern void flush_hash();
#endif /* APPLE_HYB */
extern void DECL(add_directory_hash,(dev_t, ino_t));
extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t));
extern void DECL (flush_file_hash, (void));
extern int DECL(delete_file_hash,(struct directory_entry *));
extern struct directory_entry * DECL(find_file_hash,(char *));
extern void DECL(add_file_hash,(struct directory_entry *));
extern int DECL(generate_rock_ridge_attributes,(char *, char *,
struct directory_entry *,
struct stat *, struct stat *,
int deep_flag));
extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor,
char * source, int * size));
extern int DECL(check_prev_session, (struct directory_entry **, int len,
struct directory_entry *,
struct stat *,
struct stat *,
struct directory_entry **));
#ifdef USE_SCG
/* scsi.c */
#ifdef __STDC__
extern int readsecs(int startsecno, void *buffer, int sectorcount);
extern int scsidev_open(char *path);
#else
extern int readsecs();
extern int scsidev_open();
#endif
#endif
extern char * extension_record;
extern int extension_record_extent;
extern int n_data_extents;
/* These are a few goodies that can be specified on the command line, and are
filled into the root record */
extern char * preparer;
extern char * publisher;
extern char * copyright;
extern char * biblio;
extern char * abstract;
extern char * appid;
extern char * volset_id;
extern char * system_id;
extern char * volume_id;
extern char * boot_catalog;
extern char * boot_image;
extern int volume_set_size;
extern int volume_sequence_number;
extern void * DECL(e_malloc,(size_t));
#define SECTOR_SIZE (2048)
#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
#ifdef APPLE_HYB
#define V_ROUND_UP(X,Y) (((X + (Y - 1)) / Y) * Y)
#define H_ROUND_UP(X) ROUND_UP(((X)*HFS_BLOCKSZ))
/* ISO blocks == 2048, HFS blocks == 512 */
#define BLK_CONV (SECTOR_SIZE/HFS_BLOCKSZ)
#define USE_MAC_NAME(N,E) ((N) && ((E)->hfs_ent != NULL) && (E)->hfs_type)
#endif /* APPLE_HYB */
#define NEED_RE 1
#define NEED_PL 2
#define NEED_CL 4
#define NEED_CE 8
#define NEED_SP 16
#define PREV_SESS_DEV (sizeof(dev_t) >= 4 ? 0x7ffffffd : 0x7ffd)
#define TABLE_INODE (sizeof(ino_t) >= 8 ? 0x7ffffffffffffffeLL : 0x7ffffffe)
#define UNCACHED_INODE (sizeof(ino_t) >= 8 ? 0x7fffffffffffffffLL : 0x7fffffff)
#define UNCACHED_DEVICE (sizeof(dev_t) >= 4 ? 0x7fffffff : 0x7fff)
#ifdef VMS
#define STAT_INODE(X) (X.st_ino[0])
#define PATH_SEPARATOR ']'
#define SPATH_SEPARATOR ""
#else
#define STAT_INODE(X) (X.st_ino)
#define PATH_SEPARATOR '/'
#define SPATH_SEPARATOR "/"
#endif
/*
* When using multi-session, indicates that we can reuse the
* TRANS.TBL information for this directory entry. If this flag
* is set for all entries in a directory, it means we can just
* reuse the TRANS.TBL and not generate a new one.
*/
#define SAFE_TO_REUSE_TABLE_ENTRY 0x01
#define DIR_HAS_DOT 0x02
#define DIR_HAS_DOTDOT 0x04
#define INHIBIT_JOLIET_ENTRY 0x08
#define INHIBIT_RR_ENTRY 0x10
#define RELOCATED_DIRECTORY 0x20
#define INHIBIT_ISO9660_ENTRY 0x40
/*
* Volume sequence number to use in all of the iso directory records.
*/
#define DEF_VSN 1
/*
* Make sure we have a definition for this. If not, take a very conservative
* guess. From what I can tell SunOS is the only one with this trouble.
*/
#ifndef NAME_MAX
#ifdef FILENAME_MAX
#define NAME_MAX FILENAME_MAX
#else
#define NAME_MAX 128
#endif
#endif

View File

@ -0,0 +1,44 @@
# Id: mkisofs.spec,v 1.1 2000/10/10 20:40:19 beck Exp
Summary: Creates a ISO9660 filesystem image
Name: mkisofs
Version: 1.12b5
Release: 1
Copyright: GPL
Group: Utilities/System
Source: tsx-11.mit.edu:/pub/linux/packages/mkisofs/mkisofs-1.12b5.tar.gz
%description
This is the mkisofs package. It is used to create ISO 9660
file system images for creating CD-ROMs. Now includes support
for making bootable "El Torito" CD-ROMs.
%prep
%setup
%build
./configure --prefix=/usr
make
%install
make install
strip /usr/bin/mkisofs
%changelog
* Tue Feb 25 1997 Michael Fulbright <msf@redhat.com>
Updated to 1.10b7.
* Wed Feb 12 1997 Michael Fulbright <msf@redhat.com>
Updated to 1.10b3.
* Wed Feb 12 1997 Michael Fulbright <msf@redhat.com>
Added %doc line to spec file (was missing all docs before).
%files
%doc COPYING ChangeLog README README.eltorito TODO
/usr/bin/mkisofs
/usr/man/man8/mkisofs.8

1214
external/gpl2/mkhybrid/dist/multi.c vendored Normal file

File diff suppressed because it is too large Load Diff

394
external/gpl2/mkhybrid/dist/name.c vendored Normal file
View File

@ -0,0 +1,394 @@
/*
* File name.c - map full Unix file names to unique 8.3 names that
* would be valid on DOS.
*
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "mkisofs.h"
#include <ctype.h>
extern int allow_leading_dots;
/*
* Function: iso9660_file_length
*
* Purpose: Map file name to 8.3 format, return length
* of result.
*
* Arguments: name file name we need to map.
* sresult directory entry structure to contain mapped name.
* dirflag flag indicating whether this is a directory or not.
*
* Notes: This procedure probably needs to be rationalized somehow.
* New options to affect the behavior of this function
* would also be nice to have.
*/
int FDECL3(iso9660_file_length,
const char*, name,
struct directory_entry *, sresult,
int, dirflag)
{
char * c;
int chars_after_dot = 0;
int chars_before_dot = 0;
int current_length = 0;
int extra = 0;
int ignore = 0;
char * last_dot;
const char * pnt;
int priority = 32767;
char * result;
int seen_dot = 0;
int seen_semic = 0;
int tildes = 0;
result = sresult->isorec.name;
/*
* For the '.' entry, generate the correct record, and return
* 1 for the length.
*/
if(strcmp(name,".") == 0)
{
if(result)
{
*result = 0;
}
return 1;
}
/*
* For the '..' entry, generate the correct record, and return
* 1 for the length.
*/
if(strcmp(name,"..") == 0)
{
if(result)
{
*result++ = 1;
*result++ = 0;
}
return 1;
}
/*
* Now scan the directory one character at a time, and figure out
* what to do.
*/
pnt = name;
/*
* Find the '.' that we intend to use for the extension. Usually this
* is the last dot, but if we have . followed by nothing or a ~, we
* would consider this to be unsatisfactory, and we keep searching.
*/
last_dot = strrchr (pnt,'.');
if( (last_dot != NULL)
&& ( (last_dot[1] == '~')
|| (last_dot[1] == '\0')) )
{
c = last_dot;
*c = '\0';
last_dot = strrchr (pnt,'.');
*c = '.';
}
while(*pnt)
{
#ifdef VMS
if( strcmp(pnt,".DIR;1") == 0 )
{
break;
}
#endif
/*
* This character indicates a Unix style of backup file
* generated by some editors. Lower the priority of
* the file.
*/
if(*pnt == '#')
{
priority = 1;
pnt++;
continue;
}
/*
* This character indicates a Unix style of backup file
* generated by some editors. Lower the priority of
* the file.
*/
if(*pnt == '~')
{
priority = 1;
tildes++;
pnt++;
continue;
}
/*
* This might come up if we had some joker already try and put
* iso9660 version numbers into the file names. This would be
* a silly thing to do on a Unix box, but we check for it
* anyways. If we see this, then we don't have to add our
* own version number at the end.
* UNLESS the ';' is part of the filename and no version
* number is following. [VK]
*/
if(*pnt == ';')
{
/* [VK] */
if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9'))
{
pnt++;
ignore++;
continue;
}
}
/*
* If we have a name with multiple '.' characters, we ignore everything
* after we have gotten the extension.
*/
if(ignore)
{
pnt++;
continue;
}
/*
* Spin past any iso9660 version number we might have.
*/
if(seen_semic)
{
if(*pnt >= '0' && *pnt <= '9')
{
*result++ = *pnt;
}
extra++;
pnt++;
continue;
}
/*
* If we have full names, the names we generate will not
* work on a DOS machine, since they are not guaranteed
* to be 8.3. Nonetheless, in many cases this is a useful
* option. We still only allow one '.' character in the
* name, however.
*/
if(full_iso9660_filenames)
{
/* Here we allow a more relaxed syntax. */
if(*pnt == '.')
{
if (seen_dot)
{
ignore++;
continue;
}
seen_dot++;
}
if(current_length < 30)
{
if(!isascii((unsigned char)*pnt))
{
*result++ = '_';
}
else
{
*result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt);
}
}
}
else
{
/*
* Dos style filenames. We really restrict the
* names here.
*/
/* It would be nice to have .tar.gz transform to .tgz,
* .ps.gz to .psz, ...
*/
if(*pnt == '.')
{
if (!chars_before_dot && !allow_leading_dots)
{
/* DOS can't read files with dot first */
chars_before_dot++;
if (result)
{
*result++ = '_'; /* Substitute underscore */
}
}
else if( pnt != last_dot )
{
/*
* If this isn't the dot that we use for the extension,
* then change the character into a '_' instead.
*/
if(chars_before_dot < 8)
{
chars_before_dot++;
if(result)
{
*result++ = '_';
}
}
}
else
{
if (seen_dot)
{
ignore++; continue;
}
if(result)
{
*result++ = '.';
}
seen_dot++;
}
}
else
{
if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot)
|| (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) )
{
if(result)
{
switch (*pnt)
{
default:
if(!isascii((unsigned char)*pnt))
{
*result++ = '_';
}
else
{
*result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt;
}
break;
/*
* Descriptions of DOS's 'Parse Filename'
* (function 29H) describes V1 and V2.0+
* separator and terminator characters.
* These characters in a DOS name make
* the file visible but un-manipulable
* (all useful operations error off.
*/
/* separators */
case '+':
case '=':
case '%': /* not legal DOS filename */
case ':':
case ';': /* already handled */
case '.': /* already handled */
case ',': /* already handled */
case '\t':
case ' ':
/* V1 only separators */
case '/':
case '"':
case '[':
case ']':
/* terminators */
case '>':
case '<':
case '|':
/* Hmm - what to do here? Skip?
* Win95 looks like it substitutes '_'
*/
*result++ = '_';
break;
} /* switch (*pnt) */
} /* if (result) */
} /* if (chars_{after,before}_dot) ... */
} /* else *pnt == '.' */
} /* else DOS file names */
current_length++;
pnt++;
} /* while (*pnt) */
/*
* OK, that wraps up the scan of the name. Now tidy up a few other
* things.
*/
/*
* Look for emacs style of numbered backups, like foo.c.~3~. If
* we see this, convert the version number into the priority
* number. In case of name conflicts, this is what would end
* up being used as the 'extension'.
*/
if(tildes == 2)
{
int prio1 = 0;
pnt = name;
while (*pnt && *pnt != '~')
{
pnt++;
}
if (*pnt)
{
pnt++;
}
while(*pnt && *pnt != '~')
{
prio1 = 10*prio1 + *pnt - '0';
pnt++;
}
priority = prio1;
}
/*
* If this is not a directory, force a '.' in case we haven't
* seen one, and add a version number if we haven't seen one
* of those either.
*/
if (!dirflag)
{
if (!seen_dot && !omit_period)
{
if (result) *result++ = '.';
extra++;
}
if(!omit_version_number && !seen_semic)
{
if(result)
{
*result++ = ';';
*result++ = '1';
};
extra += 2;
}
}
if(result)
{
*result++ = 0;
}
sresult->priority = priority;
return (chars_before_dot + chars_after_dot + seen_dot + extra);
}

655
external/gpl2/mkhybrid/dist/rock.c vendored Normal file
View File

@ -0,0 +1,655 @@
/*
* File rock.c - generate RRIP records for iso9660 filesystems.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdlib.h>
#include "config.h"
#ifndef VMS
#if defined(MAJOR_IN_SYSMACROS)
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#endif
#if defined(MAJOR_IN_MKDEV)
#include <sys/types.h>
#include <sys/mkdev.h>
#endif
#include "mkisofs.h"
#include "iso9660.h"
#include <string.h>
#ifdef DOESNT_WORK
#ifdef NON_UNIXFS
#define S_ISLNK(m) (0)
#else
#ifndef S_ISLNK
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#endif
#else
#include <statdefs.h>
#endif
#define SU_VERSION 1
#define SL_ROOT 8
#define SL_PARENT 4
#define SL_CURRENT 2
#define SL_CONTINUE 1
#define CE_SIZE 28
#define CL_SIZE 12
#define ER_SIZE 8
#define NM_SIZE 5
#define PL_SIZE 12
#define PN_SIZE 20
#define PX_SIZE 36
#define RE_SIZE 4
#define SL_SIZE 20
#define ZZ_SIZE 15
#ifdef APPLE_HYB
#define AA_SIZE 14 /* size of Apple extension */
#endif /* APPLE_HYB */
#ifdef __QNX__
#define TF_SIZE (5 + 4 * 7)
#else
#define TF_SIZE (5 + 3 * 7)
#endif
/* If we need to store this number of bytes, make sure we
do not box ourselves in so that we do not have room for
a CE entry for the continuation record */
#define MAYBE_ADD_CE_ENTRY(BYTES) \
(BYTES + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0)
/*
* Buffer to build RR attributes
*/
static unsigned char Rock[16384];
static unsigned char symlink_buff[256];
static int ipnt = 0;
static int recstart = 0;
static int currlen = 0;
static int mainrec = 0;
static int reclimit;
#ifdef APPLE_HYB
/* if we are using the HFS name, we don't want the '/' character */
static void
rstrncpy(char *t, char *f, int c)
{
while (c-- && *f) {
switch (*f) {
case '/':
*t = '_';
break;
default:
*t = *f;
break;
}
t++; f++;
}
}
#endif /* APPLE HYB */
static void add_CE_entry __PR((void));
static void add_CE_entry(){
if(recstart)
set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart);
Rock[ipnt++] ='C';
Rock[ipnt++] ='E';
Rock[ipnt++] = CE_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
recstart = ipnt;
currlen = 0;
if(!mainrec) mainrec = ipnt;
reclimit = SECTOR_SIZE - 8; /* Limit to one sector */
}
#ifdef __STDC__
int generate_rock_ridge_attributes (char * whole_name, char * name,
struct directory_entry * s_entry,
struct stat * statbuf,
struct stat * lstatbuf,
int deep_opt)
#else
int generate_rock_ridge_attributes (whole_name, name,
s_entry,
statbuf,
lstatbuf,
deep_opt)
char * whole_name; char * name; struct directory_entry * s_entry;
struct stat * statbuf, *lstatbuf;
int deep_opt;
#endif
{
int flagpos, flagval;
int need_ce;
statbuf = statbuf; /* this shuts up unreferenced compiler warnings */
mainrec = recstart = ipnt = 0;
reclimit = 0xf8;
/* no need to fill in the RR stuff if we won't see the file */
if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
return 0;
/* Obtain the amount of space that is currently used for the directory
record. Assume max for name, since name conflicts may cause us
to rename the file later on */
currlen = sizeof(s_entry->isorec);
#ifdef APPLE_HYB
/* if we have regular file, then add Apple extensions */
if (S_ISREG(lstatbuf->st_mode) && apple_ext && s_entry->hfs_ent) {
Rock[ipnt++] ='A'; /* AppleSignature */
Rock[ipnt++] ='A';
Rock[ipnt++] = AA_SIZE; /* includes AppleSignature bytes */
Rock[ipnt++] = 0x02; /* SystemUseID */
Rock[ipnt++] = s_entry->hfs_ent->type[0];
Rock[ipnt++] = s_entry->hfs_ent->type[1];
Rock[ipnt++] = s_entry->hfs_ent->type[2];
Rock[ipnt++] = s_entry->hfs_ent->type[3];
Rock[ipnt++] = s_entry->hfs_ent->creator[0];
Rock[ipnt++] = s_entry->hfs_ent->creator[1];
Rock[ipnt++] = s_entry->hfs_ent->creator[2];
Rock[ipnt++] = s_entry->hfs_ent->creator[3];
Rock[ipnt++] = (s_entry->hfs_ent->fdflags >> 8) & 0xff;
Rock[ipnt++] = s_entry->hfs_ent->fdflags & 0xff;
}
#endif /* APPLE_HYB */
/* Identify that we are using the SUSP protocol */
if(deep_opt & NEED_SP){
Rock[ipnt++] ='S';
Rock[ipnt++] ='P';
Rock[ipnt++] = 7;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 0xbe;
Rock[ipnt++] = 0xef;
Rock[ipnt++] = 0;
};
/* First build the posix name field */
Rock[ipnt++] ='R';
Rock[ipnt++] ='R';
Rock[ipnt++] = 5;
Rock[ipnt++] = SU_VERSION;
flagpos = ipnt;
flagval = 0;
Rock[ipnt++] = 0; /* We go back and fix this later */
if(strcmp(name,".") && strcmp(name,"..")){
char * npnt;
int remain, use;
#ifdef APPLE_HYB
/* use the HFS name if it exists */
if (USE_MAC_NAME(mac_name, s_entry)) {
remain = strlen(s_entry->hfs_ent->name);
npnt = s_entry->hfs_ent->name;
}
else {
#endif
remain = strlen(name);
npnt = name;
#ifdef APPLE_HYB
}
#endif /* APPLE_HYB */
while(remain){
use = remain;
need_ce = 0;
/* Can we fit this SUSP and a CE entry? */
if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
use = reclimit - currlen - CE_SIZE - (ipnt - recstart);
need_ce++;
}
/* Only room for 256 per SUSP field */
if(use > 0xf8) use = 0xf8;
/* First build the posix name field */
Rock[ipnt++] ='N';
Rock[ipnt++] ='M';
Rock[ipnt++] = NM_SIZE + use;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = (remain != use ? 1 : 0);
flagval |= (1<<3);
#ifdef APPLE_HYB
/* filter out any '/' character in HFS filename */
if (USE_MAC_NAME(mac_name, s_entry))
rstrncpy((char *)&Rock[ipnt], npnt, use);
else
#endif /* APPLE_HYB */
strncpy((char *)&Rock[ipnt], npnt, use);
npnt += use;
ipnt += use;
remain -= use;
if(remain && need_ce) add_CE_entry();
};
};
/*
* Add the posix modes
*/
if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='X';
Rock[ipnt++] = PX_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<0);
set_733((char*)Rock + ipnt, lstatbuf->st_mode);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_nlink);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_uid);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_gid);
ipnt += 8;
/*
* Check for special devices
*/
#ifndef NON_UNIXFS
if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) {
if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='N';
Rock[ipnt++] = PN_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<1);
#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)
set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev ));
ipnt += 8;
set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev));
ipnt += 8;
#else
/*
* If we don't have sysmacros.h, then we have to guess as to how
* best to pick apart the device number for major/minor.
* Note: this may very well be wrong for many systems, so
* it is always best to use the major/minor macros if the
* system supports it.
*/
if(sizeof(dev_t) <= 2) {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8));
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff);
ipnt += 8;
}
else if(sizeof(dev_t) <= 4) {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff);
ipnt += 8;
}
else {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
ipnt += 8;
}
#endif
};
#endif
/*
* Check for and symbolic links. VMS does not have these.
*/
if (S_ISLNK(lstatbuf->st_mode)){
int lenpos, lenval, j0, j1;
int nchar;
unsigned char * cpnt, *cpnt1;
nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff)-1);
symlink_buff[nchar < 0 ? 0 : nchar] = 0;
nchar = strlen((char *) symlink_buff);
set_733(s_entry->isorec.size, 0);
cpnt = &symlink_buff[0];
flagval |= (1<<2);
if (! split_SL_field)
{
int sl_bytes = 0;
for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++)
{
if (*cpnt1 == '/')
{
sl_bytes += 4;
}
else
{
sl_bytes += 1;
}
}
if (sl_bytes > 250)
{
/*
* the symbolic link won't fit into one SL System Use Field
* print an error message and continue with splited one
*/
fprintf(stderr,"symbolic link ``%s'' to long for one SL System Use Field, splitting", cpnt);
}
if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry();
}
while(nchar){
if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry();
Rock[ipnt++] ='S';
Rock[ipnt++] ='L';
lenpos = ipnt;
Rock[ipnt++] = SL_SIZE;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 0; /* Flags */
lenval = 5;
while(*cpnt){
cpnt1 = (unsigned char *) strchr((char *) cpnt, '/');
if(cpnt1) {
nchar--;
*cpnt1 = 0;
};
/* We treat certain components in a special way. */
if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_PARENT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
nchar -= 2;
} else if(cpnt[0] == '.' && cpnt[1] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_CURRENT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
nchar -= 1;
} else if(cpnt[0] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_ROOT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
} else {
/* If we do not have enough room for a component, start
a new continuations segment now */
if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) :
MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt)))
{
add_CE_entry();
if(cpnt1)
{
*cpnt1 = '/';
nchar++;
cpnt1 = NULL; /* A kluge so that we can restart properly */
}
break;
}
j0 = strlen((char *) cpnt);
while(j0) {
j1 = j0;
if(j1 > 0xf8) j1 = 0xf8;
need_ce = 0;
if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart);
need_ce++;
}
Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0);
Rock[ipnt++] = j1;
strncpy((char *) Rock + ipnt, (char *) cpnt, j1);
ipnt += j1;
lenval += j1 + 2;
cpnt += j1;
nchar -= j1; /* Number we processed this time */
j0 -= j1;
if(need_ce) {
add_CE_entry();
if(cpnt1) {
*cpnt1 = '/';
nchar++;
cpnt1 = NULL; /* A kluge so that we can restart properly */
}
break;
}
}
};
if(cpnt1) {
cpnt = cpnt1 + 1;
} else
break;
}
Rock[lenpos] = lenval;
if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */
} /* while nchar */
} /* Is a symbolic link */
/*
* Add in the Rock Ridge TF time field
*/
if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry();
Rock[ipnt++] ='T';
Rock[ipnt++] ='F';
Rock[ipnt++] = TF_SIZE;
Rock[ipnt++] = SU_VERSION;
#ifdef __QNX__
Rock[ipnt++] = 0x0f;
#else
Rock[ipnt++] = 0x0e;
#endif
flagval |= (1<<7);
#ifdef __QNX__
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime);
ipnt += 7;
#endif
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime);
ipnt += 7;
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime);
ipnt += 7;
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime);
ipnt += 7;
/*
* Add in the Rock Ridge RE time field
*/
if(deep_opt & NEED_RE){
if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry();
Rock[ipnt++] ='R';
Rock[ipnt++] ='E';
Rock[ipnt++] = RE_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<6);
};
/*
* Add in the Rock Ridge PL record, if required.
*/
if(deep_opt & NEED_PL){
if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='L';
Rock[ipnt++] = PL_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
flagval |= (1<<5);
};
/*
* Add in the Rock Ridge CL field, if required.
*/
if(deep_opt & NEED_CL){
if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry();
Rock[ipnt++] ='C';
Rock[ipnt++] ='L';
Rock[ipnt++] = CL_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
flagval |= (1<<4);
};
#ifndef VMS
/* If transparent compression was requested, fill in the correct
field for this file */
if(transparent_compression &&
S_ISREG(lstatbuf->st_mode) &&
strlen(name) > 3 &&
strcmp(name + strlen(name) - 3,".gZ") == 0){
FILE * zipfile;
char * checkname;
unsigned int file_size;
unsigned char header[8];
int OK_flag;
/* First open file and verify that the correct algorithm was used */
file_size = 0;
OK_flag = 1;
zipfile = fopen(whole_name, "rb");
fread(header, 1, sizeof(header), zipfile);
/* Check some magic numbers from gzip. */
if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0;
/* Make sure file was blocksized. */
if(((header[3] & 0x40) == 0)) OK_flag = 0;
/* OK, now go to the end of the file and get some more info */
if(OK_flag){
int status;
status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END);
if(status == -1) OK_flag = 0;
}
if(OK_flag){
if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header))
OK_flag = 0;
else {
int blocksize;
blocksize = (header[3] << 8) | header[2];
file_size = ((unsigned int)header[7] << 24) |
((unsigned int)header[6] << 16) |
((unsigned int)header[5] << 8) | header[4];
#if 0
fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size);
#endif
if(blocksize != SECTOR_SIZE) OK_flag = 0;
}
}
fclose(zipfile);
checkname = strdup(whole_name);
checkname[strlen(whole_name)-3] = 0;
zipfile = fopen(checkname, "rb");
if(zipfile) {
OK_flag = 0;
fprintf(stderr,"Unable to insert transparent compressed file - name conflict\n");
fclose(zipfile);
}
free(checkname);
if(OK_flag){
if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry();
Rock[ipnt++] ='Z';
Rock[ipnt++] ='Z';
Rock[ipnt++] = ZZ_SIZE;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 'g'; /* Identify compression technique used */
Rock[ipnt++] = 'z';
Rock[ipnt++] = 3;
set_733((char*)Rock + ipnt, file_size); /* Real file size */
ipnt += 8;
};
}
#endif
/*
* Add in the Rock Ridge CE field, if required. We use this for the
* extension record that is stored in the root directory.
*/
if(deep_opt & NEED_CE) add_CE_entry();
/*
* Done filling in all of the fields. Now copy it back to a buffer for the
* file in question.
*/
/* Now copy this back to the buffer for the file */
Rock[flagpos] = flagval;
/* If there was a CE, fill in the size field */
if(recstart)
set_733((char*)Rock + recstart - 8, ipnt - recstart);
s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt);
s_entry->total_rr_attr_size = ipnt;
s_entry->rr_attr_size = (mainrec ? mainrec : ipnt);
memcpy(s_entry->rr_attributes, Rock, ipnt);
return ipnt;
}
/* Guaranteed to return a single sector with the relevant info */
char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor,
char *, source, int *, size){
int lipnt = 0;
char * pnt;
int len_id, len_des, len_src;
len_id = strlen(id);
len_des = strlen(descriptor);
len_src = strlen(source);
Rock[lipnt++] ='E';
Rock[lipnt++] ='R';
Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src;
Rock[lipnt++] = 1;
Rock[lipnt++] = len_id;
Rock[lipnt++] = len_des;
Rock[lipnt++] = len_src;
Rock[lipnt++] = 1;
memcpy(Rock + lipnt, id, len_id);
lipnt += len_id;
memcpy(Rock + lipnt, descriptor, len_des);
lipnt += len_des;
memcpy(Rock + lipnt, source, len_src);
lipnt += len_src;
if(lipnt > SECTOR_SIZE) {
fprintf(stderr,"Extension record too long\n");
exit(1);
};
pnt = (char *) e_malloc(SECTOR_SIZE);
memset(pnt, 0, SECTOR_SIZE);
memcpy(pnt, Rock, lipnt);
*size = lipnt;
return pnt;
}

2163
external/gpl2/mkhybrid/dist/tree.c vendored Normal file

File diff suppressed because it is too large Load Diff

564
external/gpl2/mkhybrid/dist/volume.c vendored Normal file
View File

@ -0,0 +1,564 @@
/*
** volume.c: prepare HFS volume for mkhybrid
**
** James Pearson 17/7/97
** modified JCP 29/7/97 to improve allocation sizes to cut
** down on wasted space. Now uses the HFS "allocation" size rounded
** up to the nearest 2048 bytes. Savings can be significant with
** a large volume containing lots of smallish files.
**
** Updated for v1.12 - now uses the built in RELOCATED_DIRECTORY
** flag for finding the real directory location JCP 8/1/97
*/
#ifdef APPLE_HYB
#include "config.h"
#include "mkisofs.h"
#include "volume.h"
#include "write.h"
#include <errno.h>
static hfsvol *vol_save = 0; /* used to "destroy" an HFS volume */
int DECL(copy_to_mac_vol, (hfsvol *, struct directory *));
/*
** AlcSiz: find allocation size for given volume size
*/
int
AlcSiz(int vlen)
{
int lpa, drAlBlkSiz;
/* code extracted from hfs_format() */
lpa = 1 + vlen / 65536;
drAlBlkSiz = lpa * HFS_BLOCKSZ;
/* now set our "allocation size" to the allocation block rounded
up to the nearest SECTOR_SIZE (2048 bytes) */
drAlBlkSiz = V_ROUND_UP(drAlBlkSiz, SECTOR_SIZE);
return(drAlBlkSiz);
}
/*
** XClpSiz: find the default size of the catalog/extent file
*/
int
XClpSiz(int vlen)
{
int olpa, lpa, drNmAlBlks, drAlBlkSiz;
int vbmsz, drXTClpSiz;
/* code extracted from hfs_format() */
/* get the lpa from our calculated allocation block size */
drAlBlkSiz = AlcSiz(vlen);
lpa = drAlBlkSiz/HFS_BLOCKSZ;
vbmsz = (vlen / lpa + 4095) / 4096;
drNmAlBlks = (vlen - 5 - vbmsz) / lpa;
drXTClpSiz = drNmAlBlks / 128 * drAlBlkSiz;
/* make allowances because we have possibly rounded up the
allocation size */
/* get the "original" lpa " */
olpa = 1 + vlen / 65536;
/* adjust size upwards */
drXTClpSiz = (drXTClpSiz*lpa)/olpa;
/* round up to the nearest alloaction size */
drXTClpSiz = V_ROUND_UP(drXTClpSiz, drAlBlkSiz);
return(drXTClpSiz);
}
/*
** get_vol_size: get the size of the volume including the extent/catalog
*/
int
get_vol_size(int vblen)
{
int drXTClpSiz, drAlBlkSiz;
int new_vblen;
/* try to estimate a "volume size" based on the code
in hfs_format - we need the size of the catalog/extents
and Desktop files included in the volume, as we add this
to the end of the ISO volume */
drXTClpSiz = XClpSiz(vblen);
drAlBlkSiz = AlcSiz(vblen);
/* catalog file is set at CTC times (default twice) the extents file
size - hence the (ctc_size + 1) below. The Desktop starts of the
same size as the "clump size" == 4 x drAlBlkSiz, plus a spare
drAlBlkSiz for the alternative MDB */
new_vblen = vblen + ((hce->ctc_size + 1)*drXTClpSiz + 5*drAlBlkSiz)/HFS_BLOCKSZ;
return (new_vblen);
}
/*
** write_fork: "write" file data to the volume
**
** This is used to update the HFS file internal structures
** but no data is actually written (it's trapped deep down in
** libhfs).
*/
int
write_fork(hfsfile *hfp, long tot)
{
char blk[HFS_BLOCKSZ];
unsigned short start;
long len;
len = tot;
/* we need to know where this fork starts */
start = hfs_get_drAllocPtr(hfp);
/* loop through the data a block at a time */
while (len >= HFS_BLOCKSZ)
{
if(hfs_write(hfp, blk, HFS_BLOCKSZ) < 0)
return(-1);
len -= HFS_BLOCKSZ;
}
/* write out anything left */
if (len)
if(hfs_write(hfp, blk, len) < 0)
return(-1);
/* set the start of the allocation search to be immediately
after this fork */
hfs_set_drAllocPtr(hfp, start, tot);
return(0);
}
/*
** make_mac_volume: "create" an HFS volume using the ISO data
**
** The HFS volume structures are set up (but no data is written yet).
**
** ISO volumes have a allocation size of 2048 bytes - regardless
** of the size of the volume. HFS allocation size is depends on volume
** size, so we may have to update the ISO structures to add in any
** padding.
*/
int FDECL2(make_mac_volume, struct directory *, dpnt, int, start_extent)
{
char vol_name[HFS_MAX_VLEN+1]; /* Mac volume name */
hfsvol *vol; /* Mac volume */
int vlen, vblen; /* vol length (bytes, blocks) */
int Csize, lastCsize; /* allocation sizes */
int ret = 0; /* return value */
int loop = 1;
/* umount volume if we have had a previous attempt */
if (vol_save)
if (hfs_umount(vol_save, 0) < 0)
return (-1);
/* set the default clump size to the ISO block size */
lastCsize = SECTOR_SIZE;
if (verbose > 1)
fprintf(stderr, "Creating HFS Volume info\n");
/* name or copy ISO volume name to Mac Volume name */
strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id, HFS_MAX_VLEN);
vol_name[HFS_MAX_VLEN] = '\0';
/* get initial size of HFS volume (size of ISO volume) */
vblen = last_extent * BLK_CONV;
/* add on size of extents/catalog file, but this may mean
the allocation size will change, so loop round until the allocation
size doesn't change */
while (loop) {
hce->XTCsize = XClpSiz(vblen);
vblen = get_vol_size(vblen);
Csize = AlcSiz(vblen);
if (Csize == lastCsize) {
/* allocation size hasn't changed, so carry on */
loop = 0;
}
else {
/* allocation size has changed, so update ISO volume size */
if ((vlen = get_adj_size(Csize)) < 0) {
snprintf(hce->error, ERROR_SIZE,
"too many files for HFS volume");
return (-1);
}
vlen += V_ROUND_UP(start_extent * SECTOR_SIZE, Csize);
vblen = vlen / HFS_BLOCKSZ;
lastCsize = Csize;
}
}
/* set vlen to size in bytes */
/* vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; */
/* take off the label/map size */
vblen -= hce->hfs_map_size;
vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ;
/* set the default allocation size for libhfs */
hce->Csize = Csize;
/* format and mount the "volume" */
if (hfs_format(hce, 0, vol_name) < 0)
{
snprintf(hce->error, ERROR_SIZE, "can't HFS format %s",vol_name);
return(-1);
}
/* update the ISO structures with new start extents and any padding
required */
if (Csize != SECTOR_SIZE) {
last_extent = adj_size(Csize, start_extent, hce->hfs_hdr_size + hce->hfs_map_size);
adj_size_other(dpnt);
}
if ((vol = hfs_mount(hce, 0, 0)) == 0)
{
snprintf(hce->error, ERROR_SIZE, "can't HFS mount %s",vol_name);
return(-1);
}
/* save the volume for possible later use */
vol_save = vol;
/* Recursively "copy" the files to the volume - we need to
know the first allocation block in the volume as starting blocks
of files are relative to this.
*/
ret = copy_to_mac_vol(vol, dpnt);
if (ret < 0)
return(ret);
/* make the Desktop files - I *think* this stops the Mac
rebuilding the desktop when the CD is mounted on a Mac
These will be ignored if they already exist */
if (create_dt)
ret = make_desktop(vol, last_extent*BLK_CONV);
if (ret < 0)
return(ret);
/* close the volume */
if (hfs_flush(vol) < 0)
return(-1);
/* unmount and set the start blocks for the catalog/extents files */
if (hfs_umount(vol, last_extent*BLK_CONV) < 0)
return(-1);
return(Csize);
}
#define TEN 10 /* well, it is! */
#define LCHAR "_"
/* copy_to_mac_vol: copy all files in a directory to corresponding
** Mac folder.
**
** Files are copied recursively to corresponding folders on the Mac
** volume. The caller routine needs to do a hfs_chdir before calling this
** routine.
*/
int FDECL2(copy_to_mac_vol, hfsvol *, vol, struct directory *, node)
{
struct directory_entry * s_entry; /* ISO directory entry */
struct directory_entry * s_entry1; /* tmp ISO directory entry */
struct directory *dpnt; /* ISO directory */
hfsfile *hfp; /* HFS file */
hfsdirent *ent; /* HFS file entities */
long id; /* current HFS folder */
long dext, rext; /* real data/rsrc start blk */
int ret; /* result code */
int new_name; /* HFS file has modified name */
int tens;
int digits;
int i;
/* store the current HFS directory ID */
if ((id = hfs_getcwd(vol)) == 0)
return(-1);
if (verbose > 1)
fprintf(stderr,"HFS scanning %s\n", node->whole_name);
/* loop through the ISO directory entries and process files */
for(s_entry = node->contents; s_entry; s_entry = s_entry->next)
{
/* ignore directory and associated (rsrc) files */
if(s_entry->isorec.flags[0])
continue;
/* ignore any non-Mac type file */
if(!s_entry->hfs_ent)
continue;
#ifdef DEBUG
fprintf(stderr," Name = %s", s_entry->whole_name);
fprintf(stderr," Startb = %d\n", s_entry->starting_block);
#endif /* DEBUG */
ent = s_entry->hfs_ent;
/* create file */
i = HFS_MAX_FLEN - strlen(ent->name);
new_name = 0;
tens = TEN;
digits = 1;
while (1)
{
/* try to open file - if it exists, then append '_' to
the name and try again */
errno = 0;
if ((hfs_create(vol, ent->name, ent->type, ent->creator)) < 0)
{
if (errno != EEXIST )
{
/* not an "exist" error, or we can't append as
the filename is already HFS_MAX_FLEN chars */
snprintf(hce->error, ERROR_SIZE,
"can't HFS create file %s",
s_entry->whole_name);
return(-1);
}
else if (i == 0)
{
/* File name at max HFS length - make unique name */
if (!new_name) new_name++;
sprintf(ent->name + HFS_MAX_FLEN - digits - 1,
"%s%d", LCHAR, new_name);
new_name++;
if (new_name == tens) {
tens *= TEN;
digits++;
}
}
else
{
/* append '_' to get new name */
strcat(ent->name, LCHAR);
i--;
new_name = 1;
}
}
else
break;
}
/* warn that we have a new name */
if (new_name && verbose > 0)
{
fprintf(stderr, "Using HFS name: %s for %s\n", ent->name,
s_entry->whole_name);
}
/* open file */
if ((hfp = hfs_open(vol, ent->name)) == 0)
{
snprintf(hce->error, ERROR_SIZE, "can't HFS open %s",
s_entry->whole_name);
return(-1);
}
/* if it has a data fork, then "write" it out */
if (ent->dsize)
write_fork(hfp, ent->dsize);
/* if it has a resource fork, set the fork and "write" it out */
if (ent->rsize)
{
if ((hfs_setfork(hfp, 1)) < 0)
return(-1);
write_fork(hfp, ent->rsize);
}
/* update any HFS file attributes */
if ((hfs_fsetattr(hfp, ent)) < 0)
{
snprintf(hce->error, ERROR_SIZE, "can't HFS set attributes %s",
s_entry->whole_name);
return(-1);
}
/* get the ISO starting block of data fork (may be zero)
and convert to the equivalent HFS block */
if (ent->dsize)
dext = s_entry->starting_block * BLK_CONV;
else
dext = 0;
/* if the file has a resource fork (associated file), get it's
ISO starting block and convert as above */
if (s_entry->assoc && ent->rsize)
rext = s_entry->assoc->starting_block * BLK_CONV;
else
rext = 0;
/* close the file and update the starting blocks */
if (hfs_close(hfp, dext, rext) < 0)
{
snprintf(hce->error, ERROR_SIZE, "can't HFS close file %s",
s_entry->whole_name);
return(-1);
}
}
/* process sub-directories - have a slight problem here,
if the directory had been relocated, then we need to find
the real directory - we do this by first finding the real
directory_entry, and then finding it's directory info */
/* following code taken from joliet.c */
for(s_entry=node->contents;s_entry;s_entry=s_entry->next)
{
if((s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
{
/* if the directory has been reloacted, then search the
relocated directory for the real entry */
for(s_entry1=reloc_dir->contents;s_entry1;s_entry1=s_entry1->next)
{
if(s_entry1->parent_rec == s_entry)
break;
}
/* have a problem - can't find the real directory */
if(s_entry1 == NULL)
{
snprintf(hce->error, ERROR_SIZE,
"can't locate relocated directory %s",
s_entry->whole_name);
return(-1);
}
}
else
s_entry1 = s_entry;
/* now have the correct entry - now find the actual directory */
if ((s_entry1->isorec.flags[0] & 2) && strcmp(s_entry1->name,".") && strcmp(s_entry1->name,".."))
{
if((s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
dpnt = reloc_dir->subdir;
else
dpnt = node->subdir;
while(1)
{
if (dpnt->self == s_entry1)
break;
dpnt = dpnt->next;
if(!dpnt)
{
snprintf(hce->error, ERROR_SIZE,
"can't find directory location %s",
s_entry1->whole_name);
return (-1);
}
}
/* now have the correct directory - so do the HFS stuff */
ent = dpnt->hfs_ent;
/* if we don't have hfs entries, then this is a "deep"
directory - this will be processed later */
if (!ent)
continue;
/* make sub-folder */
i = HFS_MAX_FLEN - strlen(ent->name);
new_name = 0;
tens = TEN;
digits = 1;
while (1)
{
/* try to create new directory - if it exists, then
append '_' to the name and try again */
errno = 0;
if (hfs_mkdir(vol, ent->name) < 0)
{
if (errno != EEXIST)
{
/* not an "exist" error, or we can't append as
the filename is already HFS_MAX_FLEN chars */
snprintf(hce->error, ERROR_SIZE,
"can't HFS create folder %s",
s_entry->whole_name);
return(-1);
}
else if (i == 0)
{
/* File name at max HFS length - make unique name */
if (!new_name) new_name++;
sprintf(ent->name + HFS_MAX_FLEN - digits - 1,
"%s%d", LCHAR, new_name);
new_name++;
if (new_name == tens) {
tens *= TEN;
digits++;
}
}
else
{
/* append '_' to get new name */
strcat(ent->name, LCHAR);
i--;
new_name = 1;
}
}
else
break;
}
/* warn that we have a new name */
if (new_name && verbose > 0)
{
fprintf(stderr, "Using HFS name: %s for %s\n", ent->name,
s_entry->whole_name);
}
/* see if we need to "bless" this folder */
if (hfs_bless && strcmp(s_entry->whole_name, hfs_bless) == 0) {
hfs_stat(vol, ent->name, ent);
hfs_vsetbless(vol, ent->cnid);
if (verbose > 0) {
fprintf(stderr, "Blessing %s (%s)\n",
ent->name, s_entry->whole_name);
}
/* stop any further checks */
hfs_bless = NULL;
}
/* change to sub-folder */
if (hfs_chdir(vol, ent->name) < 0)
return(-1);
/* recursively copy files ... */
ret = copy_to_mac_vol(vol, dpnt);
if (ret < 0)
return(ret);
/* change back to this folder */
if (hfs_setcwd(vol, id) < 0)
return(-1);
}
}
return(0);
}
#endif /* APPLE_HYB */

23
external/gpl2/mkhybrid/dist/volume.h vendored Normal file
View File

@ -0,0 +1,23 @@
/* volume.h */
/* $OpenBSD: volume.h,v 1.1 2008/03/08 15:36:12 espie Exp $ */
/*
* Copyright (c) 2008 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef VOLUME_H
#define VOLUME_H
extern int make_mac_volume(struct directory *, int);
#endif

1818
external/gpl2/mkhybrid/dist/write.c vendored Normal file

File diff suppressed because it is too large Load Diff

28
external/gpl2/mkhybrid/dist/write.h vendored Normal file
View File

@ -0,0 +1,28 @@
/* write.h */
/* $OpenBSD: write.h,v 1.1 2008/03/08 15:36:12 espie Exp $ */
/*
* Copyright (c) 2008 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef WRITE_H
#define WRITE_H
struct directory;
extern int get_adj_size(int);
extern int adj_size(int, int, int);
extern void adj_size_other(struct directory *);
#endif