This commit was generated by cvs2svn to compensate for changes in r6318,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
0afaa64088
345
gnu/usr.bin/mkisofs/COPYING
Normal file
345
gnu/usr.bin/mkisofs/COPYING
Normal file
@ -0,0 +1,345 @@
|
||||
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).
|
||||
|
||||
----------------------------------------
|
||||
|
||||
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.
|
660
gnu/usr.bin/mkisofs/ChangeLog
Normal file
660
gnu/usr.bin/mkisofs/ChangeLog
Normal file
@ -0,0 +1,660 @@
|
||||
Wed Jan 11 13:46:50 1995 Eric Youngdale (eric@localhost)
|
||||
|
||||
* 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.
|
||||
|
43
gnu/usr.bin/mkisofs/Configure
Executable file
43
gnu/usr.bin/mkisofs/Configure
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This script attempts to automatically configure for the host system.
|
||||
#
|
||||
MKDEV=
|
||||
MACROS=
|
||||
MALLOC=
|
||||
|
||||
if [ -f /usr/include/sys/mkdev.h ]
|
||||
then
|
||||
MKDEV=-DHASMKDEV
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/sys/sysmacros.h ]
|
||||
then
|
||||
MACROS=-DHASSYSMACROS
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/malloc.h ]
|
||||
then
|
||||
MALLOC=-DHASMALLOC_H
|
||||
fi
|
||||
|
||||
#
|
||||
# OK, we have all of the configuration stuff done. Now generate the Makefile.
|
||||
#
|
||||
|
||||
echo XCFLAGS=${MKDEV} ${MACROS} ${MALLOC} > Makefrag
|
||||
|
||||
sed -e "/XCFLAGS=/ r Makefrag" Makefile.in > Makefile
|
||||
rm -f Makefrag
|
||||
|
||||
#
|
||||
# Now generate config.h
|
||||
#
|
||||
rm -rf config.h
|
||||
touch config.h
|
||||
if [ -f /usr/include/termios.h ]
|
||||
then
|
||||
echo "#define USE_TERMIOS" >> config.h
|
||||
fi
|
||||
|
||||
echo "The Makefile is now properly configured for your system."
|
50
gnu/usr.bin/mkisofs/Makefile
Normal file
50
gnu/usr.bin/mkisofs/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
CFLAGS=-g -Wall -c
|
||||
CC=gcc
|
||||
|
||||
#
|
||||
# XCFLAGS is automatically set by Configure.
|
||||
#
|
||||
XCFLAGS=
|
||||
XCFLAGS= -DHASSYSMACROS -DHASMALLOC_H
|
||||
CFLAGS=-g -c $(XCFLAGS)
|
||||
LDFLAGS=
|
||||
OBJS=mkisofs.o tree.o write.o hash.o rock.o exclude.o
|
||||
|
||||
World: mkisofs
|
||||
|
||||
Makefile: Makefile.in Configure
|
||||
./Configure
|
||||
echo "Type make again to build mkisofs."
|
||||
|
||||
mkisofs: Makefile $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o mkisofs $(OBJS)
|
||||
|
||||
install: mkisofs mkisofs.8
|
||||
strip mkisofs
|
||||
cp mkisofs /usr/bin/
|
||||
if [ -d /usr/man/man8 ]; then cp mkisofs.8 /usr/man/man8/; fi
|
||||
|
||||
tree.o: tree.c mkisofs.h iso9660.h exclude.h
|
||||
$(CC) $(CFLAGS) tree.c
|
||||
|
||||
write.o: write.c mkisofs.h iso9660.h
|
||||
$(CC) $(CFLAGS) write.c
|
||||
|
||||
hash.o: hash.c mkisofs.h
|
||||
$(CC) $(CFLAGS) hash.c
|
||||
|
||||
rock.o: rock.c mkisofs.h iso9660.h
|
||||
$(CC) $(CFLAGS) rock.c
|
||||
|
||||
exclude.o: exclude.c exclude.h
|
||||
$(CC) $(CFLAGS) exclude.c
|
||||
|
||||
mkisofs.o: mkisofs.c iso9660.h mkisofs.h exclude.h
|
||||
$(CC) $(CFLAGS) mkisofs.c
|
||||
|
||||
clean:
|
||||
/bin/rm -f *.o core mkisofs *~ #*#
|
||||
|
||||
dist:
|
||||
tar -cvf - README Configure Makefile.in make.com TODO COPYING ChangeLog *.8 *.c *.h diag | gzip > mkisofs-1.02.tar.gz
|
||||
|
49
gnu/usr.bin/mkisofs/Makefile.in
Normal file
49
gnu/usr.bin/mkisofs/Makefile.in
Normal file
@ -0,0 +1,49 @@
|
||||
#CFLAGS=-g -Wall -c
|
||||
#CC=gcc
|
||||
|
||||
#
|
||||
# XCFLAGS is automatically set by Configure.
|
||||
#
|
||||
XCFLAGS=
|
||||
CFLAGS=-g -c $(XCFLAGS)
|
||||
LDFLAGS=
|
||||
OBJS=mkisofs.o tree.o write.o hash.o rock.o exclude.o
|
||||
|
||||
World: mkisofs
|
||||
|
||||
Makefile: Makefile.in Configure
|
||||
./Configure
|
||||
echo "Type make again to build mkisofs."
|
||||
|
||||
mkisofs: Makefile $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o mkisofs $(OBJS)
|
||||
|
||||
install: mkisofs mkisofs.8
|
||||
strip mkisofs
|
||||
cp mkisofs /usr/bin/
|
||||
if [ -d /usr/man/man8 ]; then cp mkisofs.8 /usr/man/man8/; fi
|
||||
|
||||
tree.o: tree.c mkisofs.h iso9660.h exclude.h
|
||||
$(CC) $(CFLAGS) tree.c
|
||||
|
||||
write.o: write.c mkisofs.h iso9660.h
|
||||
$(CC) $(CFLAGS) write.c
|
||||
|
||||
hash.o: hash.c mkisofs.h
|
||||
$(CC) $(CFLAGS) hash.c
|
||||
|
||||
rock.o: rock.c mkisofs.h iso9660.h
|
||||
$(CC) $(CFLAGS) rock.c
|
||||
|
||||
exclude.o: exclude.c exclude.h
|
||||
$(CC) $(CFLAGS) exclude.c
|
||||
|
||||
mkisofs.o: mkisofs.c iso9660.h mkisofs.h exclude.h
|
||||
$(CC) $(CFLAGS) mkisofs.c
|
||||
|
||||
clean:
|
||||
/bin/rm -f *.o core mkisofs *~ #*#
|
||||
|
||||
dist:
|
||||
tar -cvf - README Configure Makefile.in make.com TODO COPYING ChangeLog *.8 *.c *.h diag | gzip > mkisofs-1.02.tar.gz
|
||||
|
76
gnu/usr.bin/mkisofs/README
Normal file
76
gnu/usr.bin/mkisofs/README
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*****************************
|
||||
Notes for version 1.2.
|
||||
|
||||
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).
|
||||
|
15
gnu/usr.bin/mkisofs/TODO
Normal file
15
gnu/usr.bin/mkisofs/TODO
Normal file
@ -0,0 +1,15 @@
|
||||
1) Allow multiple input paths to be concatenated together.
|
||||
This is a little tricky, because the directory entries need to be
|
||||
correctly sorted as per iso9660 specifications. It would be better to
|
||||
force the user to add hard links or copies of the files rather than do
|
||||
the wrong thing. Leave alone for the time being, I am not sure that
|
||||
this feature is really needed.
|
||||
|
||||
2) For symlinks, we may need to strip out the leading path
|
||||
information if the link is to an absolute file, and the absolute
|
||||
address is in the space that we are dumping to the CDROM. Who the
|
||||
hell knows what we should really do with this, actually. Leave it
|
||||
for now and see if anyone squalks.
|
||||
|
||||
3) Find out if output needs to be written at a particular
|
||||
blocksize or not.
|
1
gnu/usr.bin/mkisofs/config.h
Normal file
1
gnu/usr.bin/mkisofs/config.h
Normal file
@ -0,0 +1 @@
|
||||
#define USE_TERMIOS
|
18
gnu/usr.bin/mkisofs/defaults.h
Normal file
18
gnu/usr.bin/mkisofs/defaults.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Header file defaults.h - assorted default values for character strings in
|
||||
* the volume descriptor.
|
||||
*/
|
||||
|
||||
#define PREPARER_DEFAULT NULL
|
||||
#define PUBLISHER_DEFAULT NULL
|
||||
#define APPID_DEFAULT NULL
|
||||
#define COPYRIGHT_DEFAULT NULL
|
||||
#define BIBLIO_DEFAULT NULL
|
||||
#define ABSTRACT_DEFAULT NULL
|
||||
#define VOLSET_ID_DEFAULT NULL
|
||||
#define VOLUME_ID_DEFAULT "CDROM"
|
||||
#ifdef __QNX__
|
||||
#define SYSTEM_ID_DEFAULT "QNX"
|
||||
#else
|
||||
#define SYSTEM_ID_DEFAULT "LINUX"
|
||||
#endif
|
10
gnu/usr.bin/mkisofs/diag/Makefile
Normal file
10
gnu/usr.bin/mkisofs/diag/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
all: dump isodump isovfy
|
||||
dump:dump.c
|
||||
gcc -o dump dump.c
|
||||
isodump:isodump.c
|
||||
gcc -o isodump isodump.c
|
||||
isovfy:isovfy.c
|
||||
gcc -o isovfy isovfy.c
|
||||
|
||||
clean:
|
||||
rm dump isodump isovfy
|
74
gnu/usr.bin/mkisofs/diag/README
Normal file
74
gnu/usr.bin/mkisofs/diag/README
Normal file
@ -0,0 +1,74 @@
|
||||
I am enclosing 3 test programs that I use to verify the
|
||||
integrity of an iso9660 disc. The first one (isodump) is pretty
|
||||
simple - it dumps to the screen the contents of the various
|
||||
directories. The second one (isovfy) goes through and looks for
|
||||
problems of one kind or another.
|
||||
|
||||
To use, type something like "./isodump /dev/ramdisk" or
|
||||
"./isodump /dev/scd0", depending upon where the iso9660 disc is. It
|
||||
starts by displaying the files in the first sector of the root
|
||||
directory. It has some pretty simple one letter commands that you
|
||||
can use to traverse the directory tree.
|
||||
|
||||
a - move back one sector.
|
||||
b - move forward one sector.
|
||||
g - go to new logical sector.
|
||||
q - quit
|
||||
|
||||
The a and b commands do not try and stop you from going past the
|
||||
beginning or end of a sector, and the g command does not have any way
|
||||
of knowing whether the sector you request is actually a directory or
|
||||
not.
|
||||
|
||||
The output is displayed in several columns. The first column
|
||||
is the total length of the directory record for the file. The second
|
||||
column (in [] brackets) is the volume number. Next comes the starting
|
||||
extent number (in hex), and then comes the file size in bytes. Then
|
||||
cones the filename (not the Rock Ridge version), and this is preceeded
|
||||
by an "*" if the file is a directory. After this is a summary of the
|
||||
Rock Ridge fields present along with a display of the translation of
|
||||
the symbolic link name if the SL Rock Ridge record is present.
|
||||
|
||||
I tailored this program for debugging some of the problems
|
||||
that I was having earlier. The idea is that you can tailor it
|
||||
to test for problems that you might be having, so it is not intended
|
||||
as a be-all and end-all dump program.
|
||||
|
||||
If you move to a sector that does not contain directory
|
||||
information, the results are unpredictable.
|
||||
|
||||
The second program, isovfy, is run in the same way as isodump,
|
||||
except that you do not have to do much except let it run. I have it
|
||||
written to verify all kinds of different things, and as people find
|
||||
other sorts of problems other tests could be added.
|
||||
|
||||
The third program, dump.c, basically does a hexdump of the cd.
|
||||
This is screen oriented, and there are some simple commands:
|
||||
|
||||
a - move back one sector.
|
||||
b - move forward one sector.
|
||||
f - enter new search string.
|
||||
+ - search forward for search string.
|
||||
g - go to new logical sector.
|
||||
q - quit
|
||||
|
||||
|
||||
Note that with the 'g' command, sectors are always given in
|
||||
hex, and represent 2048 byte sectors (as on the cdrom). If you know
|
||||
how to decode a raw iso9660 directory, you can pick out the starting
|
||||
extent number from the hexdump and know where to go from there. The
|
||||
starting extent appears something like 30 bytes prior to the start of
|
||||
the iso9660 (not Rock Ridge) filename, and it appears in a 7.3.3
|
||||
format (meaning that it occupies 8 bytes, 4 in little endian format,
|
||||
and 4 in big endian format). Thus you should see a mirror image of
|
||||
the bytes when looking at the extent number.
|
||||
|
||||
The isovfy program can also dump the contents of the path
|
||||
tables, but this capability is commented out right now. Feel free
|
||||
to enable this to see what is in the tables. Ultimately I may fix
|
||||
it so that this checks the integrity of the tables as well.
|
||||
|
||||
The isovfy program gives warnings about things like files that
|
||||
have a size of 0 but have an extent number assigned. The mkisofs program
|
||||
should never do this, but the YM software does leave these around.
|
||||
I think it is probably harmless in the YM case.~
|
201
gnu/usr.bin/mkisofs/diag/dump.c
Normal file
201
gnu/usr.bin/mkisofs/diag/dump.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* File dump.c - dump a file/device both in hex and in ASCII.
|
||||
|
||||
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 <stdio.h>
|
||||
#ifdef USE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#else
|
||||
#include <termio.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
FILE * infile;
|
||||
int file_addr;
|
||||
unsigned char buffer[256];
|
||||
unsigned char search[64];
|
||||
|
||||
#define PAGE 256
|
||||
|
||||
#ifdef USE_TERMIOS
|
||||
struct termios savetty;
|
||||
struct termios newtty;
|
||||
#else
|
||||
struct termio savetty;
|
||||
struct termio newtty;
|
||||
#endif
|
||||
|
||||
reset_tty(){
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcsetattr(0, TCSANOW, &savetty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCSETAF, &savetty)==-1)
|
||||
#endif
|
||||
{
|
||||
printf("cannot put tty into normal mode\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
set_tty(){
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcsetattr(0, TCSANOW, &newtty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCSETAF, &newtty)==-1)
|
||||
#endif
|
||||
{
|
||||
printf("cannot put tty into raw mode\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Come here when we get a suspend signal from the terminal */
|
||||
|
||||
onsusp ()
|
||||
{
|
||||
/* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
reset_tty ();
|
||||
fflush (stdout);
|
||||
signal(SIGTTOU, SIG_DFL);
|
||||
/* Send the TSTP signal to suspend our process group */
|
||||
signal(SIGTSTP, SIG_DFL);
|
||||
/* sigsetmask(0);*/
|
||||
kill (0, SIGTSTP);
|
||||
/* Pause for station break */
|
||||
|
||||
/* We're back */
|
||||
signal (SIGTSTP, onsusp);
|
||||
set_tty ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
crsr2(int row, int col){
|
||||
printf("\033[%d;%dH",row,col);
|
||||
}
|
||||
|
||||
showblock(int flag){
|
||||
unsigned int k;
|
||||
int i, j;
|
||||
lseek(fileno(infile), file_addr, 0);
|
||||
read(fileno(infile), buffer, sizeof(buffer));
|
||||
if(flag) {
|
||||
for(i=0;i<16;i++){
|
||||
crsr2(i+3,1);
|
||||
printf("%8.8x ",file_addr+(i<<4));
|
||||
for(j=15;j>=0;j--){
|
||||
printf("%2.2x",buffer[(i<<4)+j]);
|
||||
if(!(j & 0x3)) printf(" ");
|
||||
};
|
||||
for(j=0;j< 16;j++){
|
||||
k = buffer[(i << 4) + j];
|
||||
if(k >= ' ' && k < 0x80) printf("%c",k);
|
||||
else printf(".");
|
||||
};
|
||||
}
|
||||
};
|
||||
crsr2(20,1);
|
||||
printf(" Zone, zone offset: %6x %4.4x ",file_addr>>11, file_addr & 0x7ff);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
getbyte()
|
||||
{
|
||||
char c1;
|
||||
c1 = buffer[file_addr & (PAGE-1)];
|
||||
file_addr++;
|
||||
if ((file_addr & (PAGE-1)) == 0) showblock(0);
|
||||
return c1;
|
||||
}
|
||||
|
||||
main(int argc, char * argv[]){
|
||||
char c;
|
||||
int nbyte;
|
||||
int i,j;
|
||||
if(argc < 2) return 0;
|
||||
infile = fopen(argv[1],"rb");
|
||||
for(i=0;i<30;i++) printf("\n");
|
||||
file_addr = 0;
|
||||
/* Now setup the keyboard for single character input. */
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcgetattr(0, &savetty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCGETA, &savetty) == -1)
|
||||
#endif
|
||||
{
|
||||
printf("stdin must be a tty\n");
|
||||
exit(1);
|
||||
}
|
||||
newtty=savetty;
|
||||
newtty.c_lflag&=~ICANON;
|
||||
newtty.c_lflag&=~ECHO;
|
||||
newtty.c_cc[VMIN]=1;
|
||||
set_tty();
|
||||
signal(SIGTSTP, onsusp);
|
||||
|
||||
do{
|
||||
if(file_addr < 0) file_addr = 0;
|
||||
showblock(1);
|
||||
read (0, &c, 1);
|
||||
if (c == 'a') file_addr -= PAGE;
|
||||
if (c == 'b') file_addr += PAGE;
|
||||
if (c == 'g') {
|
||||
crsr2(20,1);
|
||||
printf("Enter new starting block (in hex):");
|
||||
scanf("%x",&file_addr);
|
||||
file_addr = file_addr << 11;
|
||||
crsr2(20,1);
|
||||
printf(" ");
|
||||
};
|
||||
if (c == 'f') {
|
||||
crsr2(20,1);
|
||||
printf("Enter new search string:");
|
||||
fgets(search,sizeof(search),stdin);
|
||||
while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
|
||||
crsr2(20,1);
|
||||
printf(" ");
|
||||
};
|
||||
if (c == '+') {
|
||||
while(1==1){
|
||||
while(1==1){
|
||||
c = getbyte(&file_addr);
|
||||
if (c == search[0]) break;
|
||||
};
|
||||
for (j=1;j<strlen(search);j++)
|
||||
if(search[j] != getbyte()) break;
|
||||
if(j==strlen(search)) break;
|
||||
};
|
||||
file_addr &= ~(PAGE-1);
|
||||
showblock(1);
|
||||
};
|
||||
if (c == 'q') break;
|
||||
} while(1==1);
|
||||
reset_tty();
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
434
gnu/usr.bin/mkisofs/diag/isodump.c
Normal file
434
gnu/usr.bin/mkisofs/diag/isodump.c
Normal file
@ -0,0 +1,434 @@
|
||||
/*
|
||||
* File isodump.c - dump iso9660 directory information.
|
||||
*
|
||||
|
||||
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 <stdio.h>
|
||||
#ifdef USE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#else
|
||||
#include <termio.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
FILE * infile;
|
||||
int file_addr;
|
||||
unsigned char buffer[2048];
|
||||
unsigned char search[64];
|
||||
|
||||
#define PAGE sizeof(buffer)
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
|
||||
int
|
||||
isonum_731 (char * p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8)
|
||||
| ((p[2] & 0xff) << 16)
|
||||
| ((p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isonum_733 (char * p)
|
||||
{
|
||||
return (isonum_731 (p));
|
||||
}
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
unsigned char id [ISODCL ( 2, 6)];
|
||||
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
unsigned char unused1 [ISODCL ( 8, 8)];
|
||||
unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
|
||||
unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
|
||||
unsigned char unused2 [ISODCL ( 73, 80)];
|
||||
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
unsigned char unused3 [ISODCL ( 89, 120)];
|
||||
unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
|
||||
unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
unsigned char application_id [ISODCL (575, 702)]; /* achars */
|
||||
unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
unsigned char unused4 [ISODCL (883, 883)];
|
||||
unsigned char application_data [ISODCL (884, 1395)];
|
||||
unsigned char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
struct iso_directory_record {
|
||||
unsigned char length [ISODCL (1, 1)]; /* 711 */
|
||||
unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
unsigned char extent [ISODCL (3, 10)]; /* 733 */
|
||||
unsigned char size [ISODCL (11, 18)]; /* 733 */
|
||||
unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
|
||||
unsigned char flags [ISODCL (26, 26)];
|
||||
unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
|
||||
unsigned char interleave [ISODCL (28, 28)]; /* 711 */
|
||||
unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
|
||||
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
|
||||
unsigned char name [0];
|
||||
};
|
||||
|
||||
#ifdef USE_TERMIOS
|
||||
struct termios savetty;
|
||||
struct termios newtty;
|
||||
#else
|
||||
struct termio savetty;
|
||||
struct termio newtty;
|
||||
#endif
|
||||
|
||||
reset_tty(){
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcsetattr(0, TCSANOW, &savetty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCSETAF, &savetty)==-1)
|
||||
#endif
|
||||
{
|
||||
printf("cannot put tty into normal mode\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
set_tty(){
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcsetattr(0, TCSANOW, &newtty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCSETAF, &newtty)==-1)
|
||||
#endif
|
||||
{
|
||||
printf("cannot put tty into raw mode\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Come here when we get a suspend signal from the terminal */
|
||||
|
||||
onsusp ()
|
||||
{
|
||||
/* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
reset_tty ();
|
||||
fflush (stdout);
|
||||
signal(SIGTTOU, SIG_DFL);
|
||||
/* Send the TSTP signal to suspend our process group */
|
||||
signal(SIGTSTP, SIG_DFL);
|
||||
/* sigsetmask(0);*/
|
||||
kill (0, SIGTSTP);
|
||||
/* Pause for station break */
|
||||
|
||||
/* We're back */
|
||||
signal (SIGTSTP, onsusp);
|
||||
set_tty ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
crsr2(int row, int col){
|
||||
printf("\033[%d;%dH",row,col);
|
||||
}
|
||||
|
||||
int parse_rr(unsigned char * pnt, int len, int cont_flag)
|
||||
{
|
||||
int slen;
|
||||
int ncount;
|
||||
int extent;
|
||||
int cont_extent, cont_offset, cont_size;
|
||||
int flag1, flag2;
|
||||
unsigned char *pnts;
|
||||
char symlink[1024];
|
||||
int goof;
|
||||
/* printf(" RRlen=%d ", len); */
|
||||
|
||||
symlink[0] = 0;
|
||||
|
||||
cont_extent = cont_offset = cont_size = 0;
|
||||
|
||||
ncount = 0;
|
||||
flag1 = flag2 = 0;
|
||||
while(len >= 4){
|
||||
if(ncount) printf(",");
|
||||
else printf("[");
|
||||
printf("%c%c", pnt[0], pnt[1]);
|
||||
if(pnt[3] != 1) {
|
||||
printf("**BAD RRVERSION");
|
||||
return;
|
||||
};
|
||||
ncount++;
|
||||
if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
|
||||
if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
|
||||
if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
|
||||
if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
|
||||
if(strncmp(pnt, "NM", 2) == 0) flag2 |= 8;
|
||||
if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
|
||||
if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
|
||||
if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
|
||||
if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
|
||||
|
||||
if(strncmp(pnt, "PX", 2) == 0) {
|
||||
extent = isonum_733(pnt+12);
|
||||
printf("=%x", extent);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "CE", 2) == 0) {
|
||||
cont_extent = isonum_733(pnt+4);
|
||||
cont_offset = isonum_733(pnt+12);
|
||||
cont_size = isonum_733(pnt+20);
|
||||
printf("=[%x,%x,%d]", cont_extent, cont_offset,
|
||||
cont_size);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
|
||||
extent = isonum_733(pnt+4);
|
||||
printf("=%x", extent);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "SL", 2) == 0) {
|
||||
int cflag;
|
||||
|
||||
cflag = pnt[4];
|
||||
pnts = pnt+5;
|
||||
slen = pnt[2] - 5;
|
||||
while(slen >= 1){
|
||||
switch(pnts[0] & 0xfe){
|
||||
case 0:
|
||||
strncat(symlink, pnts+2, pnts[1]);
|
||||
break;
|
||||
case 2:
|
||||
strcat (symlink, ".");
|
||||
break;
|
||||
case 4:
|
||||
strcat (symlink, "..");
|
||||
break;
|
||||
case 8:
|
||||
if((pnts[0] & 1) == 0)strcat (symlink, "/");
|
||||
break;
|
||||
case 16:
|
||||
strcat(symlink,"/mnt");
|
||||
printf("Warning - mount point requested");
|
||||
break;
|
||||
case 32:
|
||||
strcat(symlink,"kafka");
|
||||
printf("Warning - host_name requested");
|
||||
break;
|
||||
default:
|
||||
printf("Reserved bit setting in symlink", goof++);
|
||||
break;
|
||||
};
|
||||
if((pnts[0] & 0xfe) && pnts[1] != 0) {
|
||||
printf("Incorrect length in symlink component");
|
||||
};
|
||||
if((pnts[0] & 1) == 0) strcat(symlink,"/");
|
||||
|
||||
slen -= (pnts[1] + 2);
|
||||
pnts += (pnts[1] + 2);
|
||||
|
||||
};
|
||||
if(cflag) printf("+");
|
||||
printf("=%s", symlink);
|
||||
symlink[0] = 0;
|
||||
};
|
||||
|
||||
len -= pnt[2];
|
||||
pnt += pnt[2];
|
||||
if(len <= 3 && cont_extent) {
|
||||
unsigned char sector[2048];
|
||||
lseek(fileno(infile), cont_extent << 11, 0);
|
||||
read(fileno(infile), sector, sizeof(sector));
|
||||
flag2 |= parse_rr(§or[cont_offset], cont_size, 1);
|
||||
};
|
||||
};
|
||||
if(ncount) printf("]");
|
||||
if (!cont_flag && flag1 != flag2)
|
||||
printf("Flag %x != %x", flag1, flag2, goof++);
|
||||
return flag2;
|
||||
}
|
||||
|
||||
int
|
||||
dump_rr(struct iso_directory_record * idr)
|
||||
{
|
||||
int len;
|
||||
char * pnt;
|
||||
|
||||
len = idr->length[0] & 0xff;
|
||||
len -= sizeof(struct iso_directory_record);
|
||||
len -= idr->name_len[0];
|
||||
pnt = (char *) idr;
|
||||
pnt += sizeof(struct iso_directory_record);
|
||||
pnt += idr->name_len[0];
|
||||
if((idr->name_len[0] & 1) == 0){
|
||||
pnt++;
|
||||
len--;
|
||||
};
|
||||
parse_rr(pnt, len, 0);
|
||||
}
|
||||
|
||||
|
||||
showblock(int flag){
|
||||
unsigned int k;
|
||||
int i, j;
|
||||
int line;
|
||||
struct iso_directory_record * idr;
|
||||
lseek(fileno(infile), file_addr, 0);
|
||||
read(fileno(infile), buffer, sizeof(buffer));
|
||||
for(i=0;i<60;i++) printf("\n");
|
||||
fflush(stdout);
|
||||
i = line = 0;
|
||||
if(flag) {
|
||||
while(1==1){
|
||||
crsr2(line+3,1);
|
||||
idr = (struct iso_directory_record *) &buffer[i];
|
||||
if(idr->length[0] == 0) break;
|
||||
printf("%3d ", idr->length[0]);
|
||||
printf("[%2d] ", idr->volume_sequence_number[0]);
|
||||
printf("%5x ", *((unsigned int *) idr->extent));
|
||||
printf("%8d ", *((unsigned int *) idr->size));
|
||||
printf ((idr->flags[0] & 2) ? "*" : " ");
|
||||
if(idr->name_len[0] == 1 && idr->name[0] == 0)
|
||||
printf(". ");
|
||||
else if(idr->name_len[0] == 1 && idr->name[0] == 1)
|
||||
printf(".. ");
|
||||
else {
|
||||
for(j=0; j<idr->name_len[0]; j++) printf("%c", idr->name[j]);
|
||||
for(j=0; j<14 -idr->name_len[0]; j++) printf(" ");
|
||||
};
|
||||
dump_rr(idr);
|
||||
printf("\n");
|
||||
i += buffer[i];
|
||||
if (i > 2048 - sizeof(struct iso_directory_record)) break;
|
||||
line++;
|
||||
};
|
||||
};
|
||||
printf("\n");
|
||||
printf(" Zone, zone offset: %6x %4.4x ",file_addr>>11, file_addr & 0x7ff);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
getbyte()
|
||||
{
|
||||
char c1;
|
||||
c1 = buffer[file_addr & (PAGE-1)];
|
||||
file_addr++;
|
||||
if ((file_addr & (PAGE-1)) == 0) showblock(0);
|
||||
return c1;
|
||||
}
|
||||
|
||||
main(int argc, char * argv[]){
|
||||
char c;
|
||||
char buffer[2048];
|
||||
int nbyte;
|
||||
int i,j;
|
||||
struct iso_primary_descriptor ipd;
|
||||
struct iso_directory_record * idr;
|
||||
|
||||
if(argc < 2) return 0;
|
||||
infile = fopen(argv[1],"rb");
|
||||
|
||||
file_addr = 16 << 11;
|
||||
lseek(fileno(infile), file_addr, 0);
|
||||
read(fileno(infile), &ipd, sizeof(ipd));
|
||||
|
||||
idr = (struct iso_directory_record *) &ipd.root_directory_record;
|
||||
|
||||
file_addr = isonum_733(idr->extent);
|
||||
|
||||
file_addr = file_addr << 11;
|
||||
|
||||
/* Now setup the keyboard for single character input. */
|
||||
#ifdef USE_TERMIOS
|
||||
if(tcgetattr(0, &savetty) == -1)
|
||||
#else
|
||||
if(ioctl(0, TCGETA, &savetty) == -1)
|
||||
#endif
|
||||
{
|
||||
printf("stdin must be a tty\n");
|
||||
exit(1);
|
||||
}
|
||||
newtty=savetty;
|
||||
newtty.c_lflag&=~ICANON;
|
||||
newtty.c_lflag&=~ECHO;
|
||||
newtty.c_cc[VMIN]=1;
|
||||
set_tty();
|
||||
signal(SIGTSTP, onsusp);
|
||||
|
||||
do{
|
||||
if(file_addr < 0) file_addr = 0;
|
||||
showblock(1);
|
||||
read (0, &c, 1);
|
||||
if (c == 'a') file_addr -= PAGE;
|
||||
if (c == 'b') file_addr += PAGE;
|
||||
if (c == 'g') {
|
||||
crsr2(20,1);
|
||||
printf("Enter new starting block (in hex):");
|
||||
scanf("%x",&file_addr);
|
||||
file_addr = file_addr << 11;
|
||||
crsr2(20,1);
|
||||
printf(" ");
|
||||
};
|
||||
if (c == 'f') {
|
||||
crsr2(20,1);
|
||||
printf("Enter new search string:");
|
||||
fgets(search,sizeof(search),stdin);
|
||||
while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
|
||||
crsr2(20,1);
|
||||
printf(" ");
|
||||
};
|
||||
if (c == '+') {
|
||||
while(1==1){
|
||||
while(1==1){
|
||||
c = getbyte(&file_addr);
|
||||
if (c == search[0]) break;
|
||||
};
|
||||
for (j=1;j<strlen(search);j++)
|
||||
if(search[j] != getbyte()) break;
|
||||
if(j==strlen(search)) break;
|
||||
};
|
||||
file_addr &= ~(PAGE-1);
|
||||
showblock(1);
|
||||
};
|
||||
if (c == 'q') break;
|
||||
} while(1==1);
|
||||
reset_tty();
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
487
gnu/usr.bin/mkisofs/diag/isovfy.c
Normal file
487
gnu/usr.bin/mkisofs/diag/isovfy.c
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
* File isovfy.c - verify consistency of 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 <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
FILE * infile;
|
||||
|
||||
#define PAGE sizeof(buffer)
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
unsigned char id [ISODCL ( 2, 6)];
|
||||
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
unsigned char unused1 [ISODCL ( 8, 8)];
|
||||
unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
|
||||
unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
|
||||
unsigned char unused2 [ISODCL ( 73, 80)];
|
||||
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
unsigned char unused3 [ISODCL ( 89, 120)];
|
||||
unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
|
||||
unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
unsigned char application_id [ISODCL (575, 702)]; /* achars */
|
||||
unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
unsigned char unused4 [ISODCL (883, 883)];
|
||||
unsigned char application_data [ISODCL (884, 1395)];
|
||||
unsigned char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
struct iso_directory_record {
|
||||
unsigned char length [ISODCL (1, 1)]; /* 711 */
|
||||
unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
unsigned char extent [ISODCL (3, 10)]; /* 733 */
|
||||
unsigned char size [ISODCL (11, 18)]; /* 733 */
|
||||
unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
|
||||
unsigned char flags [ISODCL (26, 26)];
|
||||
unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
|
||||
unsigned char interleave [ISODCL (28, 28)]; /* 711 */
|
||||
unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
|
||||
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
|
||||
unsigned char name [38];
|
||||
};
|
||||
|
||||
int
|
||||
isonum_721 (char * p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8));
|
||||
}
|
||||
|
||||
int
|
||||
isonum_731 (char * p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8)
|
||||
| ((p[2] & 0xff) << 16)
|
||||
| ((p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
int
|
||||
isonum_722 (char * p)
|
||||
{
|
||||
return ((p[1] & 0xff)
|
||||
| ((p[0] & 0xff) << 8));
|
||||
}
|
||||
|
||||
int
|
||||
isonum_732 (char * p)
|
||||
{
|
||||
return ((p[3] & 0xff)
|
||||
| ((p[2] & 0xff) << 8)
|
||||
| ((p[1] & 0xff) << 16)
|
||||
| ((p[0] & 0xff) << 24));
|
||||
}
|
||||
|
||||
int
|
||||
isonum_733 (char * p)
|
||||
{
|
||||
return (isonum_731 (p));
|
||||
}
|
||||
|
||||
char lbuffer[1024];
|
||||
int iline;
|
||||
int rr_goof;
|
||||
|
||||
|
||||
int
|
||||
dump_rr(struct iso_directory_record * idr){
|
||||
int len;
|
||||
char * pnt;
|
||||
|
||||
len = idr->length[0] & 0xff;
|
||||
len -= (sizeof(struct iso_directory_record) - sizeof(idr->name));
|
||||
len -= idr->name_len[0];
|
||||
pnt = (char *) idr;
|
||||
pnt += (sizeof(struct iso_directory_record) - sizeof(idr->name));
|
||||
pnt += idr->name_len[0];
|
||||
|
||||
if((idr->name_len[0] & 1) == 0){
|
||||
pnt++;
|
||||
len--;
|
||||
};
|
||||
|
||||
rr_goof = 0;
|
||||
parse_rr(pnt, len, 0);
|
||||
return rr_goof;
|
||||
}
|
||||
|
||||
int parse_rr(unsigned char * pnt, int len, int cont_flag)
|
||||
{
|
||||
int slen;
|
||||
int ncount;
|
||||
int flag1, flag2;
|
||||
int extent;
|
||||
unsigned char *pnts;
|
||||
int cont_extent, cont_offset, cont_size;
|
||||
char symlink[1024];
|
||||
iline += sprintf(lbuffer+iline," RRlen=%d ", len);
|
||||
|
||||
cont_extent = cont_offset = cont_size = 0;
|
||||
|
||||
symlink[0] = 0;
|
||||
|
||||
ncount = 0;
|
||||
flag1 = flag2 = 0;
|
||||
while(len >= 4){
|
||||
if(ncount) iline += sprintf(lbuffer+iline,",");
|
||||
else iline += sprintf(lbuffer+iline,"[");
|
||||
iline += sprintf(lbuffer+iline,"%c%c", pnt[0], pnt[1]);
|
||||
|
||||
if(pnt[0] < 'A' || pnt[0] > 'Z' || pnt[1] < 'A' ||
|
||||
pnt[1] > 'Z') {
|
||||
iline += sprintf(lbuffer+iline,"**BAD SUSP %d %d]",
|
||||
pnt[0], pnt[1], rr_goof++);
|
||||
return flag2;
|
||||
};
|
||||
|
||||
if(pnt[3] != 1) {
|
||||
iline += sprintf(lbuffer+iline,"**BAD RRVERSION", rr_goof++);
|
||||
return flag2;
|
||||
};
|
||||
ncount++;
|
||||
if(pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
|
||||
if(strncmp(pnt, "PX", 2) == 0) flag2 |= 1;
|
||||
if(strncmp(pnt, "PN", 2) == 0) flag2 |= 2;
|
||||
if(strncmp(pnt, "SL", 2) == 0) flag2 |= 4;
|
||||
if(strncmp(pnt, "NM", 2) == 0) flag2 |= 8;
|
||||
if(strncmp(pnt, "CL", 2) == 0) flag2 |= 16;
|
||||
if(strncmp(pnt, "PL", 2) == 0) flag2 |= 32;
|
||||
if(strncmp(pnt, "RE", 2) == 0) flag2 |= 64;
|
||||
if(strncmp(pnt, "TF", 2) == 0) flag2 |= 128;
|
||||
|
||||
if(strncmp(pnt, "CE", 2) == 0) {
|
||||
cont_extent = isonum_733(pnt+4);
|
||||
cont_offset = isonum_733(pnt+12);
|
||||
cont_size = isonum_733(pnt+20);
|
||||
iline += sprintf(lbuffer+iline, "=[%x,%x,%d]",
|
||||
cont_extent, cont_offset, cont_size);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
|
||||
extent = isonum_733(pnt+4);
|
||||
iline += sprintf(lbuffer+iline,"=%x", extent);
|
||||
if(extent == 0) rr_goof++;
|
||||
};
|
||||
if(strncmp(pnt, "SL", 2) == 0) {
|
||||
pnts = pnt+5;
|
||||
slen = pnt[2] - 5;
|
||||
while(slen >= 1){
|
||||
switch(pnts[0] & 0xfe){
|
||||
case 0:
|
||||
strncat(symlink, pnts+2, pnts[1]);
|
||||
break;
|
||||
case 2:
|
||||
strcat (symlink, ".");
|
||||
break;
|
||||
case 4:
|
||||
strcat (symlink, "..");
|
||||
break;
|
||||
case 8:
|
||||
strcat (symlink, "/");
|
||||
break;
|
||||
case 16:
|
||||
strcat(symlink,"/mnt");
|
||||
iline += sprintf(lbuffer+iline,"Warning - mount point requested");
|
||||
break;
|
||||
case 32:
|
||||
strcat(symlink,"kafka");
|
||||
iline += sprintf(lbuffer+iline,"Warning - host_name requested");
|
||||
break;
|
||||
default:
|
||||
iline += sprintf(lbuffer+iline,"Reserved bit setting in symlink", rr_goof++);
|
||||
break;
|
||||
};
|
||||
if((pnts[0] & 0xfe) && pnts[1] != 0) {
|
||||
iline += sprintf(lbuffer+iline,"Incorrect length in symlink component");
|
||||
};
|
||||
if((pnts[0] & 1) == 0)
|
||||
strcat(symlink,"/");
|
||||
slen -= (pnts[1] + 2);
|
||||
pnts += (pnts[1] + 2);
|
||||
|
||||
};
|
||||
if(symlink[0] != 0) {
|
||||
iline += sprintf(lbuffer+iline,"=%s", symlink);
|
||||
symlink[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
len -= pnt[2];
|
||||
pnt += pnt[2];
|
||||
if(len <= 3 && cont_extent) {
|
||||
unsigned char sector[2048];
|
||||
lseek(fileno(infile), cont_extent << 11, 0);
|
||||
read(fileno(infile), sector, sizeof(sector));
|
||||
flag2 |= parse_rr(§or[cont_offset], cont_size, 1);
|
||||
};
|
||||
};
|
||||
if(ncount) iline += sprintf(lbuffer+iline,"]");
|
||||
if (!cont_flag && flag1 && flag1 != flag2)
|
||||
iline += sprintf(lbuffer+iline,"Flag %x != %x", flag1, flag2, rr_goof++);
|
||||
return flag2;
|
||||
}
|
||||
|
||||
|
||||
int dir_count = 0;
|
||||
int dir_size_count = 0;
|
||||
int ngoof = 0;
|
||||
|
||||
|
||||
check_tree(int file_addr, int file_size, int parent_addr){
|
||||
unsigned char buffer[2048];
|
||||
unsigned int k;
|
||||
int rflag;
|
||||
int i, i1, j, goof;
|
||||
int extent, size;
|
||||
int line;
|
||||
int orig_file_addr, parent_file_addr;
|
||||
struct iso_directory_record * idr;
|
||||
|
||||
i1 = 0;
|
||||
|
||||
orig_file_addr = file_addr >> 11; /* Actual extent of this directory */
|
||||
parent_file_addr = parent_addr >> 11;
|
||||
|
||||
if((dir_count % 100) == 0) printf("[%d %d]\n", dir_count, dir_size_count);
|
||||
#if 0
|
||||
printf("Starting directory %d %d %d\n", file_addr, file_size, parent_addr);
|
||||
#endif
|
||||
|
||||
dir_count++;
|
||||
dir_size_count += file_size >> 11;
|
||||
|
||||
if(file_size & 0x3ff) printf("********Directory has unusual size\n");
|
||||
|
||||
for(k=0; k < (file_size >> 11); k++){
|
||||
lseek(fileno(infile), file_addr, 0);
|
||||
read(fileno(infile), buffer, sizeof(buffer));
|
||||
i = 0;
|
||||
while(1==1){
|
||||
goof = iline=0;
|
||||
idr = (struct iso_directory_record *) &buffer[i];
|
||||
if(idr->length[0] == 0) break;
|
||||
iline += sprintf(&lbuffer[iline],"%3d ", idr->length[0]);
|
||||
extent = isonum_733(idr->extent);
|
||||
size = isonum_733(idr->size);
|
||||
iline += sprintf(&lbuffer[iline],"%5x ", extent);
|
||||
iline += sprintf(&lbuffer[iline],"%8d ", size);
|
||||
iline += sprintf (&lbuffer[iline], "%c", (idr->flags[0] & 2) ? '*' : ' ');
|
||||
|
||||
if(idr->name_len[0] > 33 || idr->name_len[0] < 0)
|
||||
iline += sprintf(&lbuffer[iline],"File name length=(%d)",
|
||||
idr->name_len[0], goof++);
|
||||
else if(idr->name_len[0] == 1 && idr->name[0] == 0) {
|
||||
iline += sprintf(&lbuffer[iline],". ");
|
||||
rflag = 0;
|
||||
if(orig_file_addr !=*((unsigned int *) idr->extent))
|
||||
iline += sprintf(&lbuffer[iline],"***** Directory has null extent.", goof++);
|
||||
if(i1)
|
||||
iline += sprintf(&lbuffer[iline],"***** . not first entry.", rr_goof++);
|
||||
} else if(idr->name_len[0] == 1 && idr->name[0] == 1) {
|
||||
iline += sprintf(&lbuffer[iline],".. ");
|
||||
rflag = 0;
|
||||
if(parent_file_addr !=*((unsigned int *) idr->extent))
|
||||
iline += sprintf(&lbuffer[iline],"***** Directory has null extent.", goof++);
|
||||
if(i1 != 1)
|
||||
iline += sprintf(&lbuffer[iline],"***** .. not second entry.", rr_goof++);
|
||||
|
||||
} else {
|
||||
if(i1 < 2) iline += sprintf(&lbuffer[iline]," Improper sorting.", rr_goof++);
|
||||
for(j=0; j<idr->name_len[0]; j++) iline += sprintf(&lbuffer[iline],"%c", idr->name[j]);
|
||||
for(j=0; j<14 -idr->name_len[0]; j++) iline += sprintf(&lbuffer[iline]," ");
|
||||
rflag = 1;
|
||||
};
|
||||
|
||||
if(size && extent == 0) iline += sprintf(&lbuffer[iline],"****Extent==0, size != 0", goof++);
|
||||
if(size == 0 && extent) iline += sprintf(&lbuffer[iline],"****Extent!=0, size == 0", goof++);
|
||||
|
||||
if(idr->flags[0] & 0xfd)
|
||||
iline += sprintf(&lbuffer[iline],"Flags=(%x) ", idr->flags[0], goof++);
|
||||
|
||||
if(idr->flags[0] & 0xfd)
|
||||
iline += sprintf(&lbuffer[iline],"Flags=(%x) ", idr->flags[0], goof++);
|
||||
|
||||
if(idr->interleave[0])
|
||||
iline += sprintf(&lbuffer[iline],"Interleave=(%d) ", idr->interleave[0], goof++);
|
||||
|
||||
if(idr->file_unit_size[0])
|
||||
iline += sprintf(&lbuffer[iline],"File unit size=(%d) ", idr->file_unit_size[0], goof++);
|
||||
|
||||
if(idr->volume_sequence_number[0] != 1)
|
||||
iline += sprintf(&lbuffer[iline],"Volume sequence number=(%d) ", idr->volume_sequence_number[0], goof++);
|
||||
|
||||
goof += dump_rr(idr);
|
||||
iline += sprintf(&lbuffer[iline],"\n");
|
||||
|
||||
|
||||
if(goof){
|
||||
ngoof++;
|
||||
lbuffer[iline++] = 0;
|
||||
printf("%x: %s", orig_file_addr, lbuffer);
|
||||
};
|
||||
|
||||
|
||||
|
||||
if(rflag && (idr->flags[0] & 2)) check_tree((*((unsigned int *) idr->extent)) << 11,
|
||||
*((unsigned int *) idr->size),
|
||||
orig_file_addr << 11);
|
||||
i += buffer[i];
|
||||
i1++;
|
||||
if (i > 2048 - sizeof(struct iso_directory_record)) break;
|
||||
};
|
||||
file_addr += sizeof(buffer);
|
||||
};
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
/* This function simply dumps the contents of the path tables. No
|
||||
consistency checking takes place, although this would proably be a good
|
||||
idea. */
|
||||
|
||||
struct path_table_info{
|
||||
char * name;
|
||||
unsigned int extent;
|
||||
unsigned short index;
|
||||
unsigned short parent;
|
||||
};
|
||||
|
||||
|
||||
check_path_tables(int typel_extent, int typem_extent, int path_table_size){
|
||||
int file_addr;
|
||||
int count;
|
||||
int j;
|
||||
char * pnt;
|
||||
char * typel, *typem;
|
||||
|
||||
/* Now read in the path tables */
|
||||
|
||||
typel = (char *) malloc(path_table_size);
|
||||
lseek(fileno(infile), typel_extent << 11, 0);
|
||||
read(fileno(infile), typel, path_table_size);
|
||||
|
||||
typem = (char *) malloc(path_table_size);
|
||||
lseek(fileno(infile), typem_extent << 11, 0);
|
||||
read(fileno(infile), typem, path_table_size);
|
||||
|
||||
j = path_table_size;
|
||||
pnt = typel;
|
||||
count = 1;
|
||||
while(j){
|
||||
int namelen, extent, index;
|
||||
char name[32];
|
||||
namelen = *pnt++; pnt++;
|
||||
extent = isonum_731(pnt); pnt += 4;
|
||||
index = isonum_721(pnt); pnt+= 2;
|
||||
j -= 8+namelen;
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
strncpy(name, pnt, namelen);
|
||||
pnt += namelen;
|
||||
if(j & 1) { j--; pnt++;};
|
||||
printf("%4.4d %4.4d %8.8x %s\n",count++, index, extent, name);
|
||||
};
|
||||
|
||||
j = path_table_size;
|
||||
pnt = typem;
|
||||
count = 1;
|
||||
while(j){
|
||||
int namelen, extent, index;
|
||||
char name[32];
|
||||
namelen = *pnt++; pnt++;
|
||||
extent = isonum_732(pnt); pnt += 4;
|
||||
index = isonum_722(pnt); pnt+= 2;
|
||||
j -= 8+namelen;
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
strncpy(name, pnt, namelen);
|
||||
pnt += namelen;
|
||||
if(j & 1) { j--; pnt++;};
|
||||
printf("%4.4d %4.4d %8.8x %s\n", count++, index, extent, name);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
main(int argc, char * argv[]){
|
||||
int file_addr, file_size;
|
||||
char c;
|
||||
int nbyte;
|
||||
struct iso_primary_descriptor ipd;
|
||||
struct iso_directory_record * idr;
|
||||
int typel_extent, typem_extent;
|
||||
int path_table_size;
|
||||
int i,j;
|
||||
if(argc < 2) return 0;
|
||||
infile = fopen(argv[1],"rb");
|
||||
|
||||
|
||||
file_addr = 16 << 11;
|
||||
lseek(fileno(infile), file_addr, 0);
|
||||
read(fileno(infile), &ipd, sizeof(ipd));
|
||||
|
||||
idr = (struct iso_directory_record *) &ipd.root_directory_record;
|
||||
|
||||
file_addr = isonum_733(idr->extent);
|
||||
file_size = isonum_733(idr->size);
|
||||
|
||||
printf("Root at extent %x, %d bytes\n", file_addr, file_size);
|
||||
file_addr = file_addr << 11;
|
||||
|
||||
check_tree(file_addr, file_size, file_addr);
|
||||
|
||||
typel_extent = isonum_731(ipd.type_l_path_table);
|
||||
typem_extent = isonum_732(ipd.type_m_path_table);
|
||||
path_table_size = isonum_733(ipd.path_table_size);
|
||||
|
||||
/* Enable this to get the dump of the path tables */
|
||||
#if 0
|
||||
check_path_tables(typel_extent, typem_extent, path_table_size);
|
||||
#endif
|
||||
|
||||
fclose(infile);
|
||||
|
||||
if(!ngoof) printf("No errors found\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
54
gnu/usr.bin/mkisofs/exclude.c
Normal file
54
gnu/usr.bin/mkisofs/exclude.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de:
|
||||
* added 'exclude' option (-x) to specify pathnames NOT to be included in
|
||||
* CD image.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#ifndef VMS
|
||||
#ifdef HASMALLOC_H
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/* this allows for 1000 entries to be excluded ... */
|
||||
#define MAXEXCL 1000
|
||||
static char * excl[MAXEXCL];
|
||||
|
||||
void exclude(fn)
|
||||
char * fn;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i=0; excl[i] && i<MAXEXCL; i++);
|
||||
if (i == MAXEXCL) {
|
||||
fprintf(stderr,"Can't exclude '%s' - too many entries in table\n",fn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
excl[i] = malloc(strlen(fn)+1);
|
||||
if (! excl[i]) {
|
||||
fprintf(stderr,"Can't allocate memory for excluded filename\n");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(excl[i],fn);
|
||||
}
|
||||
|
||||
int is_excluded(fn)
|
||||
char * fn;
|
||||
{
|
||||
/* very dumb search method ... */
|
||||
register int i;
|
||||
|
||||
for (i=0; excl[i] && i<MAXEXCL; i++) {
|
||||
if (strcmp(excl[i],fn) == 0) {
|
||||
return 1; /* found -> excluded filenmae */
|
||||
}
|
||||
}
|
||||
return 0; /* not found -> not excluded */
|
||||
}
|
8
gnu/usr.bin/mkisofs/exclude.h
Normal file
8
gnu/usr.bin/mkisofs/exclude.h
Normal file
@ -0,0 +1,8 @@
|
||||
/*
|
||||
* 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de:
|
||||
* added 'exclude' option (-x) to specify pathnames NOT to be included in
|
||||
* CD image.
|
||||
*/
|
||||
|
||||
void exclude();
|
||||
int is_excluded();
|
177
gnu/usr.bin/mkisofs/hash.c
Normal file
177
gnu/usr.bin/mkisofs/hash.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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 "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) 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;
|
||||
}
|
||||
|
||||
|
||||
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,};
|
||||
|
||||
static unsigned int FDECL1(name_hash, const char *, name){
|
||||
unsigned int hash = 0;
|
||||
const char * p;
|
||||
|
||||
p = name;
|
||||
|
||||
while (*p) 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;
|
||||
|
||||
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
|
||||
if(strcmp(nh->de->isorec.name, name) == 0) 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;
|
||||
|
||||
};
|
||||
}
|
107
gnu/usr.bin/mkisofs/iso9660.h
Normal file
107
gnu/usr.bin/mkisofs/iso9660.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
#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_END 255
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char unused1 [ISODCL ( 8, 8)];
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char unused3 [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
16
gnu/usr.bin/mkisofs/make.com
Normal file
16
gnu/usr.bin/mkisofs/make.com
Normal file
@ -0,0 +1,16 @@
|
||||
$! Set the def dir to proper place for use in batch. Works for interactive too.
|
||||
$flnm = f$enviroment("PROCEDURE") ! get current procedure name
|
||||
$set default 'f$parse(flnm,,,"DEVICE")''f$parse(flnm,,,"DIRECTORY")'
|
||||
$!
|
||||
$!
|
||||
$if "''p1'".eqs."LINK" then goto link
|
||||
$gcc/debug mkisofs.c
|
||||
$gcc/debug write.c
|
||||
$gcc/debug tree.c
|
||||
$gcc/debug hash.c
|
||||
$gcc/debug rock.c
|
||||
$gcc/debug vms.c
|
||||
$gcc/debug exclude.c
|
||||
$link:
|
||||
$link mkisofs.obj+write.obj+tree.obj+hash.obj+rock.obj+vms.obj+exclude.obj+ -
|
||||
gnu_cc:[000000]gcclib/lib+sys$library:vaxcrtl/lib
|
237
gnu/usr.bin/mkisofs/mkisofs.8
Normal file
237
gnu/usr.bin/mkisofs/mkisofs.8
Normal file
@ -0,0 +1,237 @@
|
||||
.\" -*- nroff -*-
|
||||
.TH MKISOFS 8 "August 1993" "Version 1.03"
|
||||
.SH NAME
|
||||
mkisofs \- create a iso9660 filesystem with optional Rock Ridge attributes.
|
||||
.SH SYNOPSIS
|
||||
.B mkisofs
|
||||
[
|
||||
.B \-R
|
||||
]
|
||||
[
|
||||
.B \-T
|
||||
]
|
||||
[
|
||||
.B \-v
|
||||
]
|
||||
[
|
||||
.B \-z
|
||||
]
|
||||
[
|
||||
.B \-a
|
||||
]
|
||||
[
|
||||
.B \-f
|
||||
]
|
||||
[
|
||||
.B \-d
|
||||
]
|
||||
[
|
||||
.B \-D
|
||||
]
|
||||
[
|
||||
.B \-l
|
||||
]
|
||||
[
|
||||
.B \-V
|
||||
]
|
||||
[
|
||||
.B \-V
|
||||
.I volid
|
||||
]
|
||||
[
|
||||
.B \-p
|
||||
.I preparer
|
||||
]
|
||||
[
|
||||
.B \-P
|
||||
.I publisher
|
||||
]
|
||||
[
|
||||
.B \-A
|
||||
.I application_id
|
||||
]
|
||||
[
|
||||
.B \-x
|
||||
.I path
|
||||
]
|
||||
.B \-o
|
||||
.I filename
|
||||
.I path
|
||||
.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
|
||||
.br
|
||||
.B path
|
||||
is the path of the directory tree to be copied into the iso9660 filesystem.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I -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
|
||||
.I -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 .mkisofsrc with APPL=id. If specified in both
|
||||
places, the command line version is used.
|
||||
.TP
|
||||
.I -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
|
||||
.I -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
|
||||
.I -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
|
||||
.I -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
|
||||
.I -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
|
||||
.I -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
|
||||
.I -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
|
||||
.mkisofsrc with PUBL=. If specified in both places, the command line
|
||||
version is used.
|
||||
.TP
|
||||
.I -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
|
||||
.mkisofsrc with PREP=. If specified in both places, the command
|
||||
line version is used.
|
||||
.TP
|
||||
.I -R
|
||||
Generate SUSP and RR records using the Rock Ridge protocol to further describe
|
||||
the files on the iso9660 filesystem.
|
||||
.TP
|
||||
.I -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
|
||||
.I -V volid
|
||||
Specifies the volume ID to be written into the master block. This
|
||||
parameter can also be set in the file .mkisofsrc with VOLI=id. If
|
||||
specified in both places, the command line version is used.
|
||||
.TP
|
||||
.I -v
|
||||
Verbose execution.
|
||||
.TP
|
||||
.I -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
|
||||
.TP
|
||||
.I -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 a file .mkisofsrc, first in the current working directory, and if not
|
||||
found there 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 "TAG=value", and in this way you can specify certain
|
||||
options. Only the first four characters of the tag are used, and 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. These are the copyright information (COPY), the
|
||||
bibliographic information (BIBL), the abstract (ABST), the volume set
|
||||
ID (VOLS) and the system ID (SYSI).
|
||||
.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@cais.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
|
||||
Allow specfication of multiple paths on the command line to be included in
|
||||
iso9660 filesystem. Can be tricky - directory entries in the root directory
|
||||
need to be properly sorted.
|
||||
.SH AVAILABILITY
|
||||
.B mkisofs
|
||||
is available for anonymous ftp from tsx-11.mit.edu in
|
||||
/pub/linux/BETA/cdrom/mkisofs and many other mirror sites. With the 1.0
|
||||
release, it is no longer considered to be in beta testing. Most of the bugs
|
||||
that are being discovered now are very minor (and interestingly enough also
|
||||
seem to be present in the YM software). Reports indicate that people are
|
||||
gearing up for production runs using version 1.00.
|
546
gnu/usr.bin/mkisofs/mkisofs.c
Normal file
546
gnu/usr.bin/mkisofs/mkisofs.c
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Program mkisofs.c - generate iso9660 filesystem based upon directory
|
||||
* tree on hard disk.
|
||||
|
||||
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 "mkisofs.h"
|
||||
|
||||
#ifdef linux
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include "iso9660.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef VMS
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include "vms.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef VMS
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "exclude.h"
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
struct directory * root = NULL;
|
||||
|
||||
static char version_string[] = "mkisofs v1.03";
|
||||
|
||||
FILE * discimage;
|
||||
unsigned int next_extent = 0;
|
||||
unsigned int last_extent = 0;
|
||||
unsigned int path_table_size = 0;
|
||||
unsigned int path_table[4] = {0,};
|
||||
unsigned int path_blocks = 0;
|
||||
struct iso_directory_record root_record;
|
||||
static int timezone_offset;
|
||||
char * extension_record = NULL;
|
||||
int extension_record_extent = 0;
|
||||
static int extension_record_size = 0;
|
||||
|
||||
/* These variables are associated with command line options */
|
||||
int use_RockRidge = 0;
|
||||
int verbose = 0;
|
||||
int all_files = 0;
|
||||
int follow_links = 0;
|
||||
int generate_tables = 0;
|
||||
char * preparer = PREPARER_DEFAULT;
|
||||
char * publisher = PUBLISHER_DEFAULT;
|
||||
char * appid = APPID_DEFAULT;
|
||||
char * copyright = COPYRIGHT_DEFAULT;
|
||||
char * biblio = BIBLIO_DEFAULT;
|
||||
char * abstract = ABSTRACT_DEFAULT;
|
||||
char * volset_id = VOLSET_ID_DEFAULT;
|
||||
char * volume_id = VOLUME_ID_DEFAULT;
|
||||
char * system_id = SYSTEM_ID_DEFAULT;
|
||||
|
||||
int omit_period = 0; /* Violates iso9660, but these are a pain */
|
||||
int transparent_compression = 0; /* So far only works with linux */
|
||||
int omit_version_number = 0; /* May violate iso9660, but noone uses vers*/
|
||||
int RR_relocation_depth = 6; /* Violates iso9660, but most systems work */
|
||||
int full_iso9660_filenames = 0; /* Used with Amiga. Disc will not work with
|
||||
DOS */
|
||||
|
||||
struct rcopts{
|
||||
char * tag;
|
||||
char ** variable;
|
||||
};
|
||||
|
||||
struct rcopts rcopt[] = {
|
||||
{"PREP", &preparer},
|
||||
{"PUBL", &publisher},
|
||||
{"APPI", &appid},
|
||||
{"COPY", ©right},
|
||||
{"BIBL", &biblio},
|
||||
{"ABST", &abstract},
|
||||
{"VOLS", &volset_id},
|
||||
{"VOLI", &volume_id},
|
||||
{"SYSI", &system_id},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef ultrix
|
||||
char *strdup(s)
|
||||
char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;}
|
||||
#endif
|
||||
|
||||
void FDECL1(read_rcfile, char *, appname)
|
||||
{
|
||||
FILE * rcfile;
|
||||
struct rcopts * rco;
|
||||
char * pnt, *pnt1;
|
||||
char linebuffer[256];
|
||||
rcfile = fopen(".mkisofsrc","r");
|
||||
|
||||
if(!rcfile) {
|
||||
if(strlen(appname)+sizeof(".mkisofsrc") > sizeof(linebuffer)) return;
|
||||
strcpy(linebuffer, appname);
|
||||
pnt = strrchr(linebuffer,'/');
|
||||
if(!pnt) return;
|
||||
pnt++;
|
||||
strcpy(pnt, ".mkisofsrc");
|
||||
rcfile = fopen(linebuffer,"r");
|
||||
fprintf(stderr, "Using %s.\n", linebuffer);
|
||||
} else {
|
||||
fprintf(stderr, "Using ./.mkisofsrc.\n");
|
||||
}
|
||||
|
||||
if(!rcfile) return;
|
||||
|
||||
/* OK, we got it. Now read in the lines and parse them */
|
||||
while(!feof(rcfile))
|
||||
{
|
||||
fgets(linebuffer, sizeof(linebuffer), rcfile);
|
||||
pnt = linebuffer;
|
||||
while(1==1) {
|
||||
if(*pnt == ' ' || *pnt == '\t' || *pnt == '\n' || *pnt == 0) break;
|
||||
if(islower(*pnt)) *pnt = toupper(*pnt);
|
||||
pnt++;
|
||||
}
|
||||
/* OK, now find the '=' sign */
|
||||
while(*pnt && *pnt != '=' && *pnt != '#') pnt++;
|
||||
|
||||
if(*pnt == '#') continue; /* SKip comment */
|
||||
if(*pnt != '=') continue; /* Skip to next line */
|
||||
pnt++; /* Skip past '=' sign */
|
||||
|
||||
while(*pnt == ' ' || *pnt == '\t') pnt++; /* And skip past whitespace */
|
||||
|
||||
/* Now get rid of trailing newline */
|
||||
pnt1 = pnt;
|
||||
while(*pnt1) {
|
||||
if(*pnt1 == '\n') *pnt1 = 0;
|
||||
else
|
||||
pnt1++;
|
||||
};
|
||||
pnt1 = linebuffer;
|
||||
while(*pnt1 == ' ' || *pnt1 == '\t') pnt1++;
|
||||
/* OK, now figure out which option we have */
|
||||
for(rco = rcopt; rco->tag; rco++) {
|
||||
if(strncmp(rco->tag, pnt1, 4) == 0)
|
||||
{
|
||||
*rco->variable = strdup(pnt);
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
fclose(rcfile);
|
||||
}
|
||||
|
||||
char * path_table_l = NULL;
|
||||
char * path_table_m = NULL;
|
||||
int goof = 0;
|
||||
|
||||
void usage(){
|
||||
fprintf(stderr,"Usage:\n");
|
||||
fprintf(stderr,
|
||||
"mkisofs [-o outfile] [-R] [-V volid] [-v] [-a] \
|
||||
[-T]\n [-l] [-d] [-V] [-D] [-p preparer] \
|
||||
[-P publisher] [ -A app_id ] [-z] \
|
||||
[-x path -x path ...] path\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int get_iso9660_timezone_offset(){
|
||||
struct tm gm;
|
||||
struct tm * pt;
|
||||
time_t ctime;
|
||||
int local_min, gmt_min;
|
||||
|
||||
time(&ctime);
|
||||
pt = gmtime(&ctime);
|
||||
gm = *pt;
|
||||
pt = localtime(&ctime);
|
||||
|
||||
if(gm.tm_year < pt->tm_year)
|
||||
gm.tm_yday = -1;
|
||||
|
||||
if(gm.tm_year > pt->tm_year)
|
||||
pt->tm_yday = -1;
|
||||
|
||||
gmt_min = gm.tm_min + 60*(gm.tm_hour + 24*gm.tm_yday);
|
||||
local_min = pt->tm_min + 60*(pt->tm_hour + 24*pt->tm_yday);
|
||||
return (gmt_min - local_min)/15;
|
||||
}
|
||||
|
||||
|
||||
/* Fill in date in the iso9660 format */
|
||||
int FDECL2(iso9660_date,char *, result, time_t, ctime){
|
||||
struct tm *local;
|
||||
local = localtime(&ctime);
|
||||
result[0] = local->tm_year;
|
||||
result[1] = local->tm_mon + 1;
|
||||
result[2] = local->tm_mday;
|
||||
result[3] = local->tm_hour;
|
||||
result[4] = local->tm_min;
|
||||
result[5] = local->tm_sec;
|
||||
result[6] = timezone_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FDECL3(iso9660_file_length,const char*, name, struct directory_entry *, sresult,
|
||||
int, dirflag){
|
||||
int seen_dot = 0;
|
||||
int seen_semic = 0;
|
||||
char * result;
|
||||
int priority = 32767;
|
||||
int tildes = 0;
|
||||
int ignore = 0;
|
||||
int extra = 0;
|
||||
int current_length = 0;
|
||||
int chars_after_dot = 0;
|
||||
int chars_before_dot = 0;
|
||||
const char * pnt;
|
||||
result = sresult->isorec.name;
|
||||
|
||||
if(strcmp(name,".") == 0){
|
||||
if(result) *result = 0;
|
||||
return 1;
|
||||
};
|
||||
|
||||
if(strcmp(name,"..") == 0){
|
||||
if(result) {
|
||||
*result++ = 1;
|
||||
*result++ = 0;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
pnt = name;
|
||||
while(*pnt){
|
||||
#ifdef VMS
|
||||
if(strcmp(pnt,".DIR;1") == 0) break;
|
||||
#endif
|
||||
if(*pnt == '#') {priority = 1; pnt++; continue; };
|
||||
if(*pnt == '~') {priority = 1; tildes++; pnt++; continue;};
|
||||
if(*pnt == ';') {seen_semic = 1; *result++ = *pnt++; continue; };
|
||||
if(ignore) {pnt++; continue;};
|
||||
if(seen_semic){
|
||||
if(*pnt >= '0' && *pnt <= '9') *result++ = *pnt;
|
||||
extra++;
|
||||
pnt++;
|
||||
continue;
|
||||
};
|
||||
if(full_iso9660_filenames) {
|
||||
/* Here we allow a more relaxed syntax. */
|
||||
if(*pnt == '.') {
|
||||
if (seen_dot) {ignore++; continue;}
|
||||
seen_dot++;
|
||||
}
|
||||
if(current_length < 30) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
|
||||
} else { /* Dos style filenames */
|
||||
if(*pnt == '.') {
|
||||
if (seen_dot) {ignore++; continue;}
|
||||
if(result) *result++ = '.';
|
||||
seen_dot++;
|
||||
} else if (seen_dot) {
|
||||
if(chars_after_dot < 3) {
|
||||
chars_after_dot++;
|
||||
if(result) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
|
||||
}
|
||||
} else {
|
||||
if(chars_before_dot < 8) {
|
||||
chars_before_dot++;
|
||||
if(result) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
|
||||
};
|
||||
};
|
||||
};
|
||||
current_length++;
|
||||
pnt++;
|
||||
};
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
|
||||
int FDECL2(main, int, argc, char **, argv){
|
||||
char * outfile;
|
||||
struct directory_entry de;
|
||||
unsigned int mem_start;
|
||||
struct stat statbuf;
|
||||
char * scan_tree;
|
||||
int c;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Get the defaults from the .mkisofsrc file */
|
||||
read_rcfile(argv[0]);
|
||||
|
||||
outfile = NULL;
|
||||
while ((c = getopt(argc, argv, "o:V:RfvaTp:P:x:dDlNzA:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'p':
|
||||
preparer = optarg;
|
||||
if(strlen(preparer) > 128) {
|
||||
fprintf(stderr,"Preparer string too long\n");
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'P':
|
||||
publisher = optarg;
|
||||
if(strlen(publisher) > 128) {
|
||||
fprintf(stderr,"Publisher string too long\n");
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'A':
|
||||
appid = optarg;
|
||||
if(strlen(appid) > 128) {
|
||||
fprintf(stderr,"Application-id string too long\n");
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'd':
|
||||
omit_period++;
|
||||
break;
|
||||
case 'D':
|
||||
RR_relocation_depth = 32767;
|
||||
break;
|
||||
case 'l':
|
||||
full_iso9660_filenames++;
|
||||
break;
|
||||
case 'N':
|
||||
omit_version_number++;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
follow_links++;
|
||||
break;
|
||||
case 'R':
|
||||
use_RockRidge++;
|
||||
break;
|
||||
case 'V':
|
||||
volume_id = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'a':
|
||||
all_files++;
|
||||
break;
|
||||
case 'T':
|
||||
generate_tables++;
|
||||
break;
|
||||
case 'z':
|
||||
#ifdef VMS
|
||||
fprintf(stderr,"Transparent compression not supported with VMS\n");
|
||||
exit(1);
|
||||
#else
|
||||
transparent_compression++;
|
||||
#endif
|
||||
break;
|
||||
case 'x':
|
||||
exclude(optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
#ifdef __NetBSD__
|
||||
{
|
||||
int resource;
|
||||
struct rlimit rlp;
|
||||
if (getrlimit(RLIMIT_DATA,&rlp) == -1)
|
||||
perror("Warning: getrlimit");
|
||||
else {
|
||||
rlp.rlim_cur=33554432;
|
||||
if (setrlimit(RLIMIT_DATA,&rlp) == -1)
|
||||
perror("Warning: setrlimit");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mem_start = (unsigned int) sbrk(0);
|
||||
|
||||
if(verbose) fprintf(stderr,"%s\n", version_string);
|
||||
/* Now find the timezone offset */
|
||||
|
||||
timezone_offset = get_iso9660_timezone_offset();
|
||||
|
||||
/* The first step is to scan the directory tree, and take some notes */
|
||||
|
||||
scan_tree = argv[optind];
|
||||
|
||||
if(!scan_tree){
|
||||
usage();
|
||||
exit(1);
|
||||
};
|
||||
|
||||
#ifndef VMS
|
||||
if(scan_tree[strlen(scan_tree)-1] != '/') {
|
||||
scan_tree = (char *) e_malloc(strlen(argv[optind])+2);
|
||||
strcpy(scan_tree, argv[optind]);
|
||||
strcat(scan_tree, "/");
|
||||
};
|
||||
#endif
|
||||
|
||||
if(use_RockRidge){
|
||||
#if 1
|
||||
extension_record = generate_rr_extension_record("RRIP_1991A",
|
||||
"THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
|
||||
"PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size);
|
||||
#else
|
||||
extension_record = generate_rr_extension_record("IEEE_P1282",
|
||||
"THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
|
||||
"PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT,PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size);
|
||||
#endif
|
||||
};
|
||||
|
||||
stat(argv[optind], &statbuf);
|
||||
add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
|
||||
|
||||
de.filedir = root; /* We need this to bootstrap */
|
||||
scan_directory_tree(argv[optind], &de);
|
||||
root->self = root->contents; /* Fix this up so that the path tables get done right */
|
||||
|
||||
if(reloc_dir) sort_n_finish(reloc_dir);
|
||||
|
||||
if (goof) exit(1);
|
||||
|
||||
if (outfile){
|
||||
discimage = fopen(outfile, "w");
|
||||
if (!discimage){
|
||||
fprintf(stderr,"Unable to open disc image file\n");
|
||||
exit(1);
|
||||
|
||||
};
|
||||
} else
|
||||
discimage = stdout;
|
||||
|
||||
/* Now assign addresses on the disc for the path table. */
|
||||
|
||||
path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11;
|
||||
if (path_blocks & 1) path_blocks++;
|
||||
path_table[0] = 0x14;
|
||||
path_table[1] = path_table[0] + path_blocks;
|
||||
path_table[2] = path_table[1] + path_blocks;
|
||||
path_table[3] = path_table[2] + path_blocks;
|
||||
|
||||
last_extent = path_table[3] + path_blocks; /* The next free block */
|
||||
|
||||
/* The next step is to go through the directory tree and assign extent
|
||||
numbers for all of the directories */
|
||||
|
||||
assign_directory_addresses(root);
|
||||
|
||||
if(extension_record) {
|
||||
struct directory_entry * s_entry;
|
||||
extension_record_extent = last_extent++;
|
||||
s_entry = root->contents;
|
||||
set_733(s_entry->rr_attributes + s_entry->rr_attr_size - 24,
|
||||
extension_record_extent);
|
||||
set_733(s_entry->rr_attributes + s_entry->rr_attr_size - 8,
|
||||
extension_record_size);
|
||||
};
|
||||
|
||||
if (use_RockRidge && reloc_dir)
|
||||
finish_cl_pl_entries();
|
||||
|
||||
/* Now we generate the path tables that are used by DOS to improve directory
|
||||
access times. */
|
||||
generate_path_tables();
|
||||
|
||||
/* Generate root record for volume descriptor. */
|
||||
generate_root_record();
|
||||
|
||||
dump_tree(root);
|
||||
|
||||
iso_write(discimage);
|
||||
|
||||
fprintf(stderr,"Max brk space used %x\n",
|
||||
((unsigned int)sbrk(0)) - mem_start);
|
||||
fprintf(stderr,"%d extents written (%d Mb)\n", last_extent, last_extent >> 9);
|
||||
#ifdef VMS
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *e_malloc(size_t size)
|
||||
{
|
||||
void* pt;
|
||||
if((pt=malloc(size))==NULL) {
|
||||
printf("Not enougth memory\n");
|
||||
exit (1);
|
||||
}
|
||||
return pt;
|
||||
}
|
243
gnu/usr.bin/mkisofs/mkisofs.h
Normal file
243
gnu/usr.bin/mkisofs/mkisofs.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
#include <stdio.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
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef linux
|
||||
#include <sys/dir.h>
|
||||
#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"
|
||||
|
||||
struct directory_entry{
|
||||
struct directory_entry * next;
|
||||
struct iso_directory_record isorec;
|
||||
unsigned int starting_block;
|
||||
unsigned int size;
|
||||
unsigned int priority;
|
||||
char * name;
|
||||
char * table;
|
||||
struct directory * filedir;
|
||||
struct directory_entry * parent_rec;
|
||||
unsigned int 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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 * 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 short path_index;
|
||||
};
|
||||
|
||||
struct deferred{
|
||||
struct deferred * next;
|
||||
unsigned int starting_block;
|
||||
char * name;
|
||||
struct directory * filedir;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
extern void DECL(sort_n_finish,(struct directory *));
|
||||
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 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 struct iso_directory_record root_record;
|
||||
|
||||
extern int use_RockRidge;
|
||||
extern int follow_links;
|
||||
extern int verbose;
|
||||
extern int all_files;
|
||||
extern int generate_tables;
|
||||
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 DECL(scan_directory_tree,(char * path, struct directory_entry * self));
|
||||
extern void DECL(dump_tree,(struct directory * node));
|
||||
extern void DECL(assign_directory_addresses,(struct directory * root));
|
||||
|
||||
extern int DECL(iso9660_file_length,(const char* name,
|
||||
struct directory_entry * sresult, int flag));
|
||||
extern int DECL(iso_write,(FILE * outfile));
|
||||
extern void generate_path_tables();
|
||||
extern void DECL(generate_iso9660_directories,(struct directory *, FILE*));
|
||||
extern void DECL(generate_one_directory,(struct directory *, FILE*));
|
||||
extern void generate_root_record();
|
||||
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));
|
||||
extern void DECL(add_directory_hash,(dev_t, ino_t));
|
||||
extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t));
|
||||
extern void flush_file_hash();
|
||||
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 void finish_cl_pl_entries();
|
||||
extern int DECL(get_733,(char *));
|
||||
|
||||
extern void DECL(set_723,(char *, unsigned int));
|
||||
extern void DECL(set_733,(char *, unsigned int));
|
||||
extern void DECL(sort_directory,(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 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 void * DECL(e_malloc,(size_t));
|
||||
|
||||
|
||||
#define SECTOR_SIZE (2048)
|
||||
#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
|
||||
|
||||
#define NEED_RE 1
|
||||
#define NEED_PL 2
|
||||
#define NEED_CL 4
|
||||
#define NEED_CE 8
|
||||
#define NEED_SP 16
|
||||
|
||||
#define TABLE_INODE (sizeof(ino_t) >= 4 ? 0x7ffffffe : 0x7ffe)
|
||||
#define UNCACHED_INODE (sizeof(ino_t) >= 4 ? 0x7fffffff : 0x7fff)
|
||||
#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
|
||||
|
530
gnu/usr.bin/mkisofs/rock.c
Normal file
530
gnu/usr.bin/mkisofs/rock.c
Normal file
@ -0,0 +1,530 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#ifndef VMS
|
||||
#if defined(HASSYSMACROS) && !defined(HASMKDEV)
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HASMKDEV
|
||||
#include <sys/types.h>
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
|
||||
#include "mkisofs.h"
|
||||
#include "iso9660.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NON_UNIXFS
|
||||
#define S_ISLNK(m) (0)
|
||||
#else
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#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 __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;
|
||||
|
||||
static 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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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;
|
||||
|
||||
remain = strlen(name);
|
||||
npnt = name;
|
||||
|
||||
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);
|
||||
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(sizeof(dev_t) <= 4) {
|
||||
set_733((char*)Rock + ipnt, 0);
|
||||
ipnt += 8;
|
||||
set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
|
||||
ipnt += 8;
|
||||
}
|
||||
else {
|
||||
#ifdef ultrix
|
||||
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16);
|
||||
#else
|
||||
set_733((char*)Rock + ipnt, lstatbuf->st_rdev >> 32);
|
||||
#endif
|
||||
ipnt += 8;
|
||||
set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
|
||||
ipnt += 8;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Check for and symbolic links. VMS does not have these.
|
||||
*/
|
||||
if (S_ISLNK(lstatbuf->st_mode)){
|
||||
int lenpos, lenval, j0, j1;
|
||||
int cflag, nchar;
|
||||
unsigned char * cpnt, *cpnt1;
|
||||
nchar = readlink(whole_name, symlink_buff, sizeof(symlink_buff));
|
||||
symlink_buff[nchar] = 0;
|
||||
set_733(s_entry->isorec.size, 0);
|
||||
cpnt = &symlink_buff[0];
|
||||
flagval |= (1<<2);
|
||||
|
||||
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(MAYBE_ADD_CE_ENTRY(6)) {
|
||||
add_CE_entry();
|
||||
if(cpnt1){
|
||||
*cpnt1 = '/';
|
||||
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 = '/';
|
||||
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, "r");
|
||||
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, "r");
|
||||
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 ipnt = 0;
|
||||
char * pnt;
|
||||
int len_id, len_des, len_src;
|
||||
|
||||
len_id = strlen(id);
|
||||
len_des = strlen(descriptor);
|
||||
len_src = strlen(source);
|
||||
Rock[ipnt++] ='E';
|
||||
Rock[ipnt++] ='R';
|
||||
Rock[ipnt++] = ER_SIZE + len_id + len_des + len_src;
|
||||
Rock[ipnt++] = 1;
|
||||
Rock[ipnt++] = len_id;
|
||||
Rock[ipnt++] = len_des;
|
||||
Rock[ipnt++] = len_src;
|
||||
Rock[ipnt++] = 1;
|
||||
|
||||
memcpy(Rock + ipnt, id, len_id);
|
||||
ipnt += len_id;
|
||||
|
||||
memcpy(Rock + ipnt, descriptor, len_des);
|
||||
ipnt += len_des;
|
||||
|
||||
memcpy(Rock + ipnt, source, len_src);
|
||||
ipnt += len_src;
|
||||
|
||||
if(ipnt > 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, ipnt);
|
||||
*size = ipnt;
|
||||
return pnt;
|
||||
}
|
889
gnu/usr.bin/mkisofs/tree.c
Normal file
889
gnu/usr.bin/mkisofs/tree.c
Normal file
@ -0,0 +1,889 @@
|
||||
/*
|
||||
* File tree.c - scan directory tree and build memory structures 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 <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef VMS
|
||||
#include <unistd.h>
|
||||
#ifdef HASSYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#include <vms/fabdef.h>
|
||||
#include "vms.h"
|
||||
extern char * strdup(const char *);
|
||||
#endif
|
||||
|
||||
#include "mkisofs.h"
|
||||
#include "iso9660.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "exclude.h"
|
||||
|
||||
#ifdef NON_UNIXFS
|
||||
#define S_ISLNK(m) (0)
|
||||
#define S_ISSOCK(m) (0)
|
||||
#define S_ISFIFO(m) (0)
|
||||
#else
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#ifndef S_ISSOCK
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __svr4__
|
||||
extern char * strdup(const char *);
|
||||
#endif
|
||||
|
||||
static unsigned char symlink_buff[256];
|
||||
|
||||
extern int verbose;
|
||||
|
||||
struct stat fstatbuf = {0,}; /* We use this for the artificial entries we create */
|
||||
|
||||
struct stat root_statbuf = {0, }; /* Stat buffer for root directory */
|
||||
|
||||
struct directory * reloc_dir = NULL;
|
||||
|
||||
|
||||
void FDECL1(sort_n_finish, struct directory *, this_dir)
|
||||
{
|
||||
struct directory_entry *s_entry, *s_entry1;
|
||||
time_t current_time;
|
||||
struct directory_entry * table;
|
||||
int count;
|
||||
int new_reclen;
|
||||
char * c;
|
||||
int tablesize = 0;
|
||||
char newname[34], rootname[34];
|
||||
|
||||
/* Here we can take the opportunity to toss duplicate entries from the
|
||||
directory. */
|
||||
|
||||
table = NULL;
|
||||
|
||||
if(fstatbuf.st_ctime == 0){
|
||||
time (¤t_time);
|
||||
fstatbuf.st_uid = 0;
|
||||
fstatbuf.st_gid = 0;
|
||||
fstatbuf.st_ctime = current_time;
|
||||
fstatbuf.st_mtime = current_time;
|
||||
fstatbuf.st_atime = current_time;
|
||||
};
|
||||
|
||||
flush_file_hash();
|
||||
s_entry = this_dir->contents;
|
||||
while(s_entry){
|
||||
|
||||
/* First assume no conflict, and handle this case */
|
||||
|
||||
if(!(s_entry1 = find_file_hash(s_entry->isorec.name))){
|
||||
add_file_hash(s_entry);
|
||||
s_entry = s_entry->next;
|
||||
continue;
|
||||
};
|
||||
|
||||
if(s_entry1 == s_entry){
|
||||
fprintf(stderr,"Fatal goof\n");
|
||||
exit(1);
|
||||
};
|
||||
/* OK, handle the conflicts. Try substitute names until we come
|
||||
up with a winner */
|
||||
strcpy(rootname, s_entry->isorec.name);
|
||||
if(full_iso9660_filenames) {
|
||||
if(strlen(rootname) > 27) rootname[27] = 0;
|
||||
}
|
||||
c = strchr(rootname, '.');
|
||||
if (c) *c = 0;
|
||||
count = 0;
|
||||
while(count < 1000){
|
||||
sprintf(newname,"%s.%3.3d%s", rootname, count,
|
||||
(s_entry->isorec.flags[0] == 2 ||
|
||||
omit_version_number ? "" : ";1"));
|
||||
|
||||
#ifdef VMS
|
||||
/* Sigh. VAXCRTL seems to be broken here */
|
||||
{ int ijk = 0;
|
||||
while(newname[ijk]) {
|
||||
if(newname[ijk] == ' ') newname[ijk] = '0';
|
||||
ijk++;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!find_file_hash(newname)) break;
|
||||
count++;
|
||||
};
|
||||
if(count >= 1000){
|
||||
fprintf(stderr,"Unable to generate unique name for file %s\n", s_entry->name);
|
||||
exit(1);
|
||||
};
|
||||
|
||||
/* OK, now we have a good replacement name. Now decide which one
|
||||
of these two beasts should get the name changed */
|
||||
|
||||
if(s_entry->priority < s_entry1->priority) {
|
||||
fprintf(stderr,"Using %s for %s%s%s (%s)\n", newname, this_dir->whole_name, SPATH_SEPARATOR, s_entry->name, s_entry1->name);
|
||||
s_entry->isorec.name_len[0] = strlen(newname);
|
||||
new_reclen = sizeof(struct iso_directory_record) -
|
||||
sizeof(s_entry->isorec.name) +
|
||||
strlen(newname);
|
||||
if(use_RockRidge) {
|
||||
if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
|
||||
new_reclen += s_entry->rr_attr_size;
|
||||
};
|
||||
if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
|
||||
s_entry->isorec.length[0] = new_reclen;
|
||||
strcpy(s_entry->isorec.name, newname);
|
||||
} else {
|
||||
delete_file_hash(s_entry1);
|
||||
fprintf(stderr,"Using %s for %s%s%s (%s)\n", newname, this_dir->whole_name, SPATH_SEPARATOR, s_entry1->name, s_entry->name);
|
||||
s_entry1->isorec.name_len[0] = strlen(newname);
|
||||
new_reclen = sizeof(struct iso_directory_record) -
|
||||
sizeof(s_entry1->isorec.name) +
|
||||
strlen(newname);
|
||||
if(use_RockRidge) {
|
||||
if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
|
||||
new_reclen += s_entry1->rr_attr_size;
|
||||
};
|
||||
if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
|
||||
s_entry1->isorec.length[0] = new_reclen;
|
||||
strcpy(s_entry1->isorec.name, newname);
|
||||
add_file_hash(s_entry1);
|
||||
};
|
||||
add_file_hash(s_entry);
|
||||
s_entry = s_entry->next;
|
||||
};
|
||||
|
||||
if(generate_tables && !find_file_hash("TRANS.TBL") && (reloc_dir != this_dir)){
|
||||
/* First we need to figure out how big this table is */
|
||||
for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
|
||||
if(strcmp(s_entry->name, ".") == 0 ||
|
||||
strcmp(s_entry->name, "..") == 0) continue;
|
||||
if(s_entry->table) tablesize += 35 + strlen(s_entry->table);
|
||||
};
|
||||
table = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
memset(table, 0, sizeof(struct directory_entry));
|
||||
table->table = NULL;
|
||||
table->next = this_dir->contents;
|
||||
this_dir->contents = table;
|
||||
|
||||
table->filedir = root;
|
||||
table->isorec.flags[0] = 0;
|
||||
table->priority = 32768;
|
||||
iso9660_date(table->isorec.date, fstatbuf.st_ctime);
|
||||
table->inode = TABLE_INODE;
|
||||
table->dev = (dev_t) UNCACHED_DEVICE;
|
||||
set_723(table->isorec.volume_sequence_number, 1);
|
||||
set_733(table->isorec.size, tablesize);
|
||||
table->size = tablesize;
|
||||
table->filedir = this_dir;
|
||||
table->name = strdup("<translation table>");
|
||||
table->table = (char *) e_malloc(ROUND_UP(tablesize));
|
||||
memset(table->table, 0, ROUND_UP(tablesize));
|
||||
iso9660_file_length ("TRANS.TBL", table, 1);
|
||||
|
||||
if(use_RockRidge){
|
||||
fstatbuf.st_mode = 0444 | S_IFREG;
|
||||
fstatbuf.st_nlink = 1;
|
||||
generate_rock_ridge_attributes("",
|
||||
"TRANS.TBL", table,
|
||||
&fstatbuf, &fstatbuf, 0);
|
||||
};
|
||||
};
|
||||
|
||||
for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
|
||||
new_reclen = strlen(s_entry->isorec.name);
|
||||
|
||||
if(s_entry->isorec.flags[0] == 2){
|
||||
if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) {
|
||||
path_table_size += new_reclen + sizeof(struct iso_path_table) - 1;
|
||||
if (new_reclen & 1) path_table_size++;
|
||||
} else {
|
||||
new_reclen = 1;
|
||||
if (this_dir == root && strlen(s_entry->name) == 1)
|
||||
path_table_size += sizeof(struct iso_path_table);
|
||||
}
|
||||
};
|
||||
if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */
|
||||
s_entry->isorec.name_len[0] = new_reclen;
|
||||
|
||||
new_reclen +=
|
||||
sizeof(struct iso_directory_record) -
|
||||
sizeof(s_entry->isorec.name);
|
||||
|
||||
if (new_reclen & 1)
|
||||
new_reclen++;
|
||||
if(use_RockRidge){
|
||||
new_reclen += s_entry->rr_attr_size;
|
||||
|
||||
if (new_reclen & 1)
|
||||
new_reclen++;
|
||||
};
|
||||
if(new_reclen > 0xff) {
|
||||
fprintf(stderr,"Fatal error - RR overflow for file %s\n",
|
||||
s_entry->name);
|
||||
exit(1);
|
||||
};
|
||||
s_entry->isorec.length[0] = new_reclen;
|
||||
};
|
||||
|
||||
sort_directory(&this_dir->contents);
|
||||
|
||||
if(table){
|
||||
char buffer[1024];
|
||||
count = 0;
|
||||
for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
|
||||
if(s_entry == table) continue;
|
||||
if(!s_entry->table) continue;
|
||||
if(strcmp(s_entry->name, ".") == 0 ||
|
||||
strcmp(s_entry->name, "..") == 0) continue;
|
||||
|
||||
sprintf(buffer,"%c %-34s%s",s_entry->table[0],
|
||||
s_entry->isorec.name, s_entry->table+1);
|
||||
memcpy(table->table + count, buffer, strlen(buffer));
|
||||
count += strlen(buffer);
|
||||
free(s_entry->table);
|
||||
s_entry->table = NULL;
|
||||
};
|
||||
if(count != tablesize) {
|
||||
fprintf(stderr,"Translation table size mismatch %d %d\n",
|
||||
count, tablesize);
|
||||
exit(1);
|
||||
};
|
||||
};
|
||||
|
||||
/* Now go through the directory and figure out how large this one will be.
|
||||
Do not split a directory entry across a sector boundary */
|
||||
|
||||
s_entry = this_dir->contents;
|
||||
this_dir->ce_bytes = 0;
|
||||
while(s_entry){
|
||||
new_reclen = s_entry->isorec.length[0];
|
||||
if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE)
|
||||
this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) &
|
||||
~(SECTOR_SIZE - 1);
|
||||
this_dir->size += new_reclen;
|
||||
|
||||
/* See if continuation entries were used on disc */
|
||||
if(use_RockRidge &&
|
||||
s_entry->rr_attr_size != s_entry->total_rr_attr_size) {
|
||||
unsigned char * pnt;
|
||||
int len;
|
||||
int nbytes;
|
||||
|
||||
pnt = s_entry->rr_attributes;
|
||||
len = s_entry->total_rr_attr_size;
|
||||
|
||||
/* We make sure that each continuation entry record is not
|
||||
split across sectors, but each file could in theory have more
|
||||
than one CE, so we scan through and figure out what we need. */
|
||||
|
||||
while(len > 3){
|
||||
if(pnt[0] == 'C' && pnt[1] == 'E') {
|
||||
nbytes = get_733(pnt+20);
|
||||
|
||||
if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >=
|
||||
SECTOR_SIZE) this_dir->ce_bytes =
|
||||
ROUND_UP(this_dir->ce_bytes);
|
||||
/* Now store the block in the ce buffer */
|
||||
this_dir->ce_bytes += nbytes;
|
||||
if(this_dir->ce_bytes & 1) this_dir->ce_bytes++;
|
||||
};
|
||||
len -= pnt[2];
|
||||
pnt += pnt[2];
|
||||
}
|
||||
}
|
||||
s_entry = s_entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_reloc_directory()
|
||||
{
|
||||
int new_reclen;
|
||||
time_t current_time;
|
||||
struct directory_entry *s_entry;
|
||||
|
||||
/* Create an entry for our internal tree */
|
||||
time (¤t_time);
|
||||
reloc_dir = (struct directory *)
|
||||
e_malloc(sizeof(struct directory));
|
||||
memset(reloc_dir, 0, sizeof(struct directory));
|
||||
reloc_dir->parent = root;
|
||||
reloc_dir->next = root->subdir;
|
||||
root->subdir = reloc_dir;
|
||||
reloc_dir->depth = 1;
|
||||
reloc_dir->whole_name = strdup("./rr_moved");
|
||||
reloc_dir->de_name = strdup("rr_moved");
|
||||
reloc_dir->extent = 0;
|
||||
|
||||
new_reclen = strlen(reloc_dir->de_name);
|
||||
|
||||
/* Now create an actual directory entry */
|
||||
s_entry = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
memset(s_entry, 0, sizeof(struct directory_entry));
|
||||
s_entry->next = root->contents;
|
||||
reloc_dir->self = s_entry;
|
||||
|
||||
root->contents = s_entry;
|
||||
root->contents->name = strdup(reloc_dir->de_name);
|
||||
root->contents->filedir = root;
|
||||
root->contents->isorec.flags[0] = 2;
|
||||
root->contents->priority = 32768;
|
||||
iso9660_date(root->contents->isorec.date, current_time);
|
||||
root->contents->inode = UNCACHED_INODE;
|
||||
root->contents->dev = (dev_t) UNCACHED_DEVICE;
|
||||
set_723(root->contents->isorec.volume_sequence_number, 1);
|
||||
iso9660_file_length (reloc_dir->de_name, root->contents, 1);
|
||||
|
||||
if(use_RockRidge){
|
||||
fstatbuf.st_mode = 0555 | S_IFDIR;
|
||||
fstatbuf.st_nlink = 2;
|
||||
generate_rock_ridge_attributes("",
|
||||
"rr_moved", s_entry,
|
||||
&fstatbuf, &fstatbuf, 0);
|
||||
};
|
||||
|
||||
/* Now create the . and .. entries in rr_moved */
|
||||
/* Now create an actual directory entry */
|
||||
s_entry = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
memcpy(s_entry, root->contents,
|
||||
sizeof(struct directory_entry));
|
||||
s_entry->name = strdup(".");
|
||||
iso9660_file_length (".", s_entry, 1);
|
||||
|
||||
s_entry->filedir = reloc_dir;
|
||||
reloc_dir->contents = s_entry;
|
||||
|
||||
if(use_RockRidge){
|
||||
fstatbuf.st_mode = 0555 | S_IFDIR;
|
||||
fstatbuf.st_nlink = 2;
|
||||
generate_rock_ridge_attributes("",
|
||||
".", s_entry,
|
||||
&fstatbuf, &fstatbuf, 0);
|
||||
};
|
||||
|
||||
s_entry = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
memcpy(s_entry, root->contents,
|
||||
sizeof(struct directory_entry));
|
||||
s_entry->name = strdup("..");
|
||||
iso9660_file_length ("..", s_entry, 1);
|
||||
s_entry->filedir = root;
|
||||
reloc_dir->contents->next = s_entry;
|
||||
reloc_dir->contents->next->next = NULL;
|
||||
if(use_RockRidge){
|
||||
fstatbuf.st_mode = 0555 | S_IFDIR;
|
||||
fstatbuf.st_nlink = 2;
|
||||
generate_rock_ridge_attributes("",
|
||||
"..", s_entry,
|
||||
&root_statbuf, &root_statbuf, 0);
|
||||
};
|
||||
}
|
||||
|
||||
static void FDECL1(increment_nlink, struct directory_entry *, s_entry){
|
||||
unsigned char * pnt;
|
||||
int len, nlink;
|
||||
|
||||
pnt = s_entry->rr_attributes;
|
||||
len = s_entry->total_rr_attr_size;
|
||||
while(len){
|
||||
if(pnt[0] == 'P' && pnt[1] == 'X') {
|
||||
nlink = get_733(pnt+12);
|
||||
set_733(pnt+12, nlink+1);
|
||||
break;
|
||||
};
|
||||
len -= pnt[2];
|
||||
pnt += pnt[2];
|
||||
};
|
||||
}
|
||||
|
||||
void finish_cl_pl_entries(){
|
||||
struct directory_entry *s_entry, *s_entry1;
|
||||
struct directory * d_entry;
|
||||
|
||||
s_entry = reloc_dir->contents;
|
||||
s_entry = s_entry->next->next; /* Skip past . and .. */
|
||||
for(; s_entry; s_entry = s_entry->next){
|
||||
d_entry = reloc_dir->subdir;
|
||||
while(d_entry){
|
||||
if(d_entry->self == s_entry) break;
|
||||
d_entry = d_entry->next;
|
||||
};
|
||||
if(!d_entry){
|
||||
fprintf(stderr,"Unable to locate directory parent\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
/* First fix the PL pointer in the directory in the rr_reloc dir */
|
||||
s_entry1 = d_entry->contents->next;
|
||||
set_733(s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8,
|
||||
s_entry->filedir->extent);
|
||||
|
||||
/* Now fix the CL pointer */
|
||||
s_entry1 = s_entry->parent_rec;
|
||||
|
||||
set_733(s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8,
|
||||
d_entry->extent);
|
||||
|
||||
s_entry->filedir = reloc_dir; /* Now we can fix this */
|
||||
}
|
||||
/* Next we need to modify the NLINK terms in the assorted root directory records
|
||||
to account for the presence of the RR_MOVED directory */
|
||||
|
||||
increment_nlink(root->self);
|
||||
increment_nlink(root->self->next);
|
||||
d_entry = root->subdir;
|
||||
while(d_entry){
|
||||
increment_nlink(d_entry->contents->next);
|
||||
d_entry = d_entry->next;
|
||||
};
|
||||
}
|
||||
/*
|
||||
* This function scans the directory tree, looking for files, and it makes
|
||||
* note of everything that is found. We also begin to construct the ISO9660
|
||||
* directory entries, so that we can determine how large each directory is.
|
||||
*/
|
||||
|
||||
int
|
||||
FDECL2(scan_directory_tree,char *, path, struct directory_entry *, de){
|
||||
DIR * current_dir;
|
||||
char whole_path[1024];
|
||||
struct dirent * d_entry;
|
||||
struct directory_entry *s_entry, *s_entry1;
|
||||
struct directory * this_dir, *next_brother, *parent;
|
||||
struct stat statbuf, lstatbuf;
|
||||
int status, dflag;
|
||||
char * cpnt;
|
||||
int new_reclen;
|
||||
int deep_flag;
|
||||
|
||||
current_dir = opendir(path);
|
||||
d_entry = NULL;
|
||||
|
||||
/* Apparently NFS sometimes allows you to open the directory, but
|
||||
then refuses to allow you to read the contents. Allow for this */
|
||||
|
||||
if(current_dir) d_entry = readdir(current_dir);
|
||||
|
||||
if(!current_dir || !d_entry) {
|
||||
fprintf(stderr,"Unable to open directory %s\n", path);
|
||||
de->isorec.flags[0] &= ~2; /* Mark as not a directory */
|
||||
if(current_dir) closedir(current_dir);
|
||||
return 0;
|
||||
};
|
||||
|
||||
parent = de->filedir;
|
||||
/* Set up the struct for the current directory, and insert it into the
|
||||
tree */
|
||||
|
||||
#ifdef VMS
|
||||
vms_path_fixup(path);
|
||||
#endif
|
||||
|
||||
this_dir = (struct directory *) e_malloc(sizeof(struct directory));
|
||||
this_dir->next = NULL;
|
||||
new_reclen = 0;
|
||||
this_dir->subdir = NULL;
|
||||
this_dir->self = de;
|
||||
this_dir->contents = NULL;
|
||||
this_dir->whole_name = strdup(path);
|
||||
cpnt = strrchr(path, PATH_SEPARATOR);
|
||||
if(cpnt)
|
||||
cpnt++;
|
||||
else
|
||||
cpnt = path;
|
||||
this_dir->de_name = strdup(cpnt);
|
||||
this_dir->size = 0;
|
||||
this_dir->extent = 0;
|
||||
|
||||
if(!parent || parent == root){
|
||||
if (!root) {
|
||||
root = this_dir; /* First time through for root directory only */
|
||||
root->depth = 0;
|
||||
root->parent = root;
|
||||
} else {
|
||||
this_dir->depth = 1;
|
||||
if(!root->subdir)
|
||||
root->subdir = this_dir;
|
||||
else {
|
||||
next_brother = root->subdir;
|
||||
while(next_brother->next) next_brother = next_brother->next;
|
||||
next_brother->next = this_dir;
|
||||
};
|
||||
this_dir->parent = parent;
|
||||
};
|
||||
} else {
|
||||
/* Come through here for normal traversal of tree */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"%s(%d) ", path, this_dir->depth);
|
||||
#endif
|
||||
if(parent->depth > RR_relocation_depth) {
|
||||
fprintf(stderr,"Directories too deep %s\n", path);
|
||||
exit(1);
|
||||
};
|
||||
|
||||
this_dir->parent = parent;
|
||||
this_dir->depth = parent->depth + 1;
|
||||
|
||||
if(!parent->subdir)
|
||||
parent->subdir = this_dir;
|
||||
else {
|
||||
next_brother = parent->subdir;
|
||||
while(next_brother->next) next_brother = next_brother->next;
|
||||
next_brother->next = this_dir;
|
||||
};
|
||||
};
|
||||
|
||||
/* Now we scan the directory itself, and look at what is inside of it. */
|
||||
|
||||
dflag = 0;
|
||||
while(1==1){
|
||||
|
||||
/* The first time through, skip this, since we already asked for
|
||||
the first entry when we opened the directory. */
|
||||
if(dflag) d_entry = readdir(current_dir);
|
||||
dflag++;
|
||||
|
||||
if(!d_entry) break;
|
||||
|
||||
/* OK, got a valid entry */
|
||||
|
||||
/* If we do not want all files, then pitch the backups. */
|
||||
if(!all_files){
|
||||
if(strchr(d_entry->d_name,'~')) continue;
|
||||
if(strchr(d_entry->d_name,'#')) continue;
|
||||
};
|
||||
|
||||
if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)){
|
||||
fprintf(stderr, "Overflow of stat buffer\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
/* Generate the complete ASCII path for this file */
|
||||
strcpy(whole_path, path);
|
||||
#ifndef VMS
|
||||
if(whole_path[strlen(whole_path)-1] != '/')
|
||||
strcat(whole_path, "/");
|
||||
#endif
|
||||
strcat(whole_path, d_entry->d_name);
|
||||
|
||||
/* Should we exclude this file? */
|
||||
if (is_excluded(whole_path)) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Excluded: %s\n",whole_path);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
if (verbose) fprintf(stderr, "%s\n",whole_path);
|
||||
#endif
|
||||
status = stat(whole_path, &statbuf);
|
||||
|
||||
lstat(whole_path, &lstatbuf);
|
||||
|
||||
if(this_dir == root && strcmp(d_entry->d_name, ".") == 0)
|
||||
root_statbuf = statbuf; /* Save this for later on */
|
||||
|
||||
/* We do this to make sure that the root entries are consistent */
|
||||
if(this_dir == root && strcmp(d_entry->d_name, "..") == 0) {
|
||||
statbuf = root_statbuf;
|
||||
lstatbuf = root_statbuf;
|
||||
};
|
||||
|
||||
if(S_ISLNK(lstatbuf.st_mode)){
|
||||
|
||||
/* Here we decide how to handle the symbolic links. Here we
|
||||
handle the general case - if we are not following links or there is an
|
||||
error, then we must change something. If RR is in use, it is easy, we
|
||||
let RR describe the file. If not, then we punt the file. */
|
||||
|
||||
if((status || !follow_links)){
|
||||
if(use_RockRidge){
|
||||
status = 0;
|
||||
statbuf.st_size = 0;
|
||||
STAT_INODE(statbuf) = UNCACHED_INODE;
|
||||
statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
|
||||
statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
|
||||
} else {
|
||||
if(follow_links) fprintf(stderr,
|
||||
"Unable to stat file %s - ignoring and continuing.\n",
|
||||
whole_path);
|
||||
else fprintf(stderr,
|
||||
"Symlink %s ignored - continuing.\n",
|
||||
whole_path);
|
||||
continue; /* Non Rock Ridge discs - ignore all symlinks */
|
||||
};
|
||||
}
|
||||
|
||||
/* Here we handle a different kind of case. Here we have a symlink,
|
||||
but we want to follow symlinks. If we run across a directory loop,
|
||||
then we need to pretend that we are not following symlinks for this file.
|
||||
If this is the first time we have seen this, then make this seem
|
||||
as if there was no symlink there in the first place */
|
||||
|
||||
else if(strcmp(d_entry->d_name, ".") &&
|
||||
strcmp(d_entry->d_name, "..")) {
|
||||
if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))){
|
||||
fprintf(stderr, "Infinite loop detected (%s)\n", whole_path);
|
||||
if(!use_RockRidge) continue;
|
||||
statbuf.st_size = 0;
|
||||
STAT_INODE(statbuf) = UNCACHED_INODE;
|
||||
statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
|
||||
statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
|
||||
} else {
|
||||
lstatbuf = statbuf;
|
||||
add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef VMS
|
||||
if(!S_ISDIR(lstatbuf.st_mode) && (statbuf.st_fab_rfm != FAB$C_FIX &&
|
||||
statbuf.st_fab_rfm != FAB$C_STMLF)) {
|
||||
fprintf(stderr,"Warning - file %s has an unsupported VMS record"
|
||||
" format (%d)\n",
|
||||
whole_path, statbuf.st_fab_rfm);
|
||||
};
|
||||
#endif
|
||||
|
||||
if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))){
|
||||
fprintf(stderr, "File %s is not readable (errno = %d) - ignoring\n",
|
||||
whole_path, errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add this so that we can detect directory loops with hard links.
|
||||
If we are set up to follow symlinks, then we skip this checking. */
|
||||
if(!follow_links && S_ISDIR(lstatbuf.st_mode) && strcmp(d_entry->d_name, ".") &&
|
||||
strcmp(d_entry->d_name, "..")) {
|
||||
if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) {
|
||||
fprintf(stderr,"Directory loop - fatal goof (%s %x %d).\n",
|
||||
whole_path, statbuf.st_dev, STAT_INODE(statbuf));
|
||||
exit(1);
|
||||
};
|
||||
add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
|
||||
};
|
||||
|
||||
if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) &&
|
||||
!S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode)
|
||||
&& !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) &&
|
||||
!S_ISDIR(lstatbuf.st_mode)) {
|
||||
fprintf(stderr,"Unknown file type %s - ignoring and continuing.\n",
|
||||
whole_path);
|
||||
continue;
|
||||
};
|
||||
|
||||
/* Who knows what trash this is - ignore and continue */
|
||||
|
||||
if(status) {
|
||||
fprintf(stderr,
|
||||
"Unable to stat file %s - ignoring and continuing.\n",
|
||||
whole_path);
|
||||
continue;
|
||||
};
|
||||
|
||||
s_entry = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
s_entry->next = this_dir->contents;
|
||||
this_dir->contents = s_entry;
|
||||
deep_flag = 0;
|
||||
s_entry->table = NULL;
|
||||
|
||||
s_entry->name = strdup(d_entry->d_name);
|
||||
|
||||
s_entry->filedir = this_dir;
|
||||
s_entry->isorec.flags[0] = 0;
|
||||
s_entry->isorec.ext_attr_length[0] = 0;
|
||||
iso9660_date(s_entry->isorec.date, statbuf.st_ctime);
|
||||
s_entry->isorec.file_unit_size[0] = 0;
|
||||
s_entry->isorec.interleave[0] = 0;
|
||||
if(parent && parent == reloc_dir && strcmp(d_entry->d_name, "..") == 0){
|
||||
s_entry->inode = UNCACHED_INODE;
|
||||
s_entry->dev = (dev_t) UNCACHED_DEVICE;
|
||||
deep_flag = NEED_PL;
|
||||
} else {
|
||||
s_entry->inode = STAT_INODE(statbuf);
|
||||
s_entry->dev = statbuf.st_dev;
|
||||
};
|
||||
set_723(s_entry->isorec.volume_sequence_number, 1);
|
||||
iso9660_file_length(d_entry->d_name, s_entry, S_ISDIR(statbuf.st_mode));
|
||||
s_entry->rr_attr_size = 0;
|
||||
s_entry->total_rr_attr_size = 0;
|
||||
s_entry->rr_attributes = NULL;
|
||||
|
||||
/* Directories are assigned sizes later on */
|
||||
if (!S_ISDIR(statbuf.st_mode)) {
|
||||
set_733(s_entry->isorec.size, statbuf.st_size);
|
||||
|
||||
if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) ||
|
||||
S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode)
|
||||
|| S_ISLNK(lstatbuf.st_mode))
|
||||
s_entry->size = 0;
|
||||
else
|
||||
s_entry->size = statbuf.st_size;
|
||||
} else
|
||||
s_entry->isorec.flags[0] = 2;
|
||||
|
||||
if (strcmp(d_entry->d_name,".") && strcmp(d_entry->d_name,"..") &&
|
||||
S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth){
|
||||
if(!reloc_dir) generate_reloc_directory();
|
||||
|
||||
s_entry1 = (struct directory_entry *)
|
||||
e_malloc(sizeof (struct directory_entry));
|
||||
memcpy(s_entry1, this_dir->contents,
|
||||
sizeof(struct directory_entry));
|
||||
s_entry1->table = NULL;
|
||||
s_entry1->name = strdup(this_dir->contents->name);
|
||||
s_entry1->next = reloc_dir->contents;
|
||||
reloc_dir->contents = s_entry1;
|
||||
s_entry1->priority = 32768;
|
||||
s_entry1->parent_rec = this_dir->contents;
|
||||
|
||||
deep_flag = NEED_RE;
|
||||
|
||||
if(use_RockRidge) {
|
||||
generate_rock_ridge_attributes(whole_path,
|
||||
d_entry->d_name, s_entry1,
|
||||
&statbuf, &lstatbuf, deep_flag);
|
||||
};
|
||||
|
||||
deep_flag = 0;
|
||||
|
||||
/* We need to set this temporarily so that the parent to this is correctly
|
||||
determined. */
|
||||
s_entry1->filedir = reloc_dir;
|
||||
scan_directory_tree(whole_path, s_entry1);
|
||||
s_entry1->filedir = this_dir;
|
||||
|
||||
statbuf.st_size = 0;
|
||||
statbuf.st_mode &= 0777;
|
||||
set_733(s_entry->isorec.size, 0);
|
||||
s_entry->size = 0;
|
||||
s_entry->isorec.flags[0] = 0;
|
||||
s_entry->inode = UNCACHED_INODE;
|
||||
deep_flag = NEED_CL;
|
||||
};
|
||||
|
||||
if(generate_tables && strcmp(s_entry->name, ".") && strcmp(s_entry->name, "..")) {
|
||||
char buffer[2048];
|
||||
switch(lstatbuf.st_mode & S_IFMT){
|
||||
case S_IFDIR:
|
||||
sprintf(buffer,"D\t%s\n",
|
||||
s_entry->name);
|
||||
break;
|
||||
#ifndef NON_UNIXFS
|
||||
case S_IFBLK:
|
||||
sprintf(buffer,"B\t%s\t%d %d\n",
|
||||
s_entry->name,
|
||||
major(statbuf.st_rdev), minor(statbuf.st_rdev));
|
||||
break;
|
||||
case S_IFIFO:
|
||||
sprintf(buffer,"P\t%s\n",
|
||||
s_entry->name);
|
||||
break;
|
||||
case S_IFCHR:
|
||||
sprintf(buffer,"C\t%s\t%d %d\n",
|
||||
s_entry->name,
|
||||
major(statbuf.st_rdev), minor(statbuf.st_rdev));
|
||||
break;
|
||||
case S_IFLNK:
|
||||
readlink(whole_path, symlink_buff, sizeof(symlink_buff));
|
||||
sprintf(buffer,"L\t%s\t%s\n",
|
||||
s_entry->name, symlink_buff);
|
||||
break;
|
||||
case S_IFSOCK:
|
||||
sprintf(buffer,"S\t%s\n",
|
||||
s_entry->name);
|
||||
break;
|
||||
#endif /* NON_UNIXFS */
|
||||
case S_IFREG:
|
||||
default:
|
||||
sprintf(buffer,"F\t%s\n",
|
||||
s_entry->name);
|
||||
break;
|
||||
};
|
||||
s_entry->table = strdup(buffer);
|
||||
};
|
||||
|
||||
if(S_ISDIR(statbuf.st_mode)){
|
||||
int dflag;
|
||||
if (strcmp(d_entry->d_name,".") && strcmp(d_entry->d_name,"..")) {
|
||||
dflag = scan_directory_tree(whole_path, s_entry);
|
||||
/* If unable to scan directory, mark this as a non-directory */
|
||||
if(!dflag)
|
||||
lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;
|
||||
}
|
||||
};
|
||||
|
||||
if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0)
|
||||
deep_flag |= NEED_CE | NEED_SP; /* For extension record */
|
||||
|
||||
/* Now figure out how much room this file will take in the directory */
|
||||
|
||||
if(use_RockRidge) {
|
||||
generate_rock_ridge_attributes(whole_path,
|
||||
d_entry->d_name, s_entry,
|
||||
&statbuf, &lstatbuf, deep_flag);
|
||||
|
||||
}
|
||||
}
|
||||
closedir(current_dir);
|
||||
sort_n_finish(this_dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){
|
||||
struct directory * dpnt;
|
||||
|
||||
dpnt = node;
|
||||
|
||||
while (dpnt){
|
||||
generate_one_directory(dpnt, outfile);
|
||||
if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile);
|
||||
dpnt = dpnt->next;
|
||||
};
|
||||
}
|
||||
|
||||
void FDECL1(dump_tree, struct directory *, node){
|
||||
struct directory * dpnt;
|
||||
|
||||
dpnt = node;
|
||||
|
||||
while (dpnt){
|
||||
fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name);
|
||||
if(dpnt->subdir) dump_tree(dpnt->subdir);
|
||||
dpnt = dpnt->next;
|
||||
};
|
||||
}
|
||||
|
269
gnu/usr.bin/mkisofs/vms.c
Normal file
269
gnu/usr.bin/mkisofs/vms.c
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* File vms.c - assorted bletcherous hacks for VMS.
|
||||
|
||||
Written by Eric Youngdale (1993).
|
||||
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#include <rms.h>
|
||||
#include <descrip.h>
|
||||
#include <ssdef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#define opendir fake_opendir
|
||||
#include "mkisofs.h"
|
||||
#undef opendir
|
||||
#include <stdio.h>
|
||||
|
||||
static struct RAB *rab; /* used for external mailfiles */
|
||||
static int rms_status;
|
||||
|
||||
static error_exit(char * text){
|
||||
fprintf(stderr,"%s\n", text);
|
||||
exit(33);
|
||||
}
|
||||
|
||||
|
||||
char * strrchr(const char *, char);
|
||||
|
||||
char * strdup(char * source){
|
||||
char * pnt;
|
||||
pnt = (char *) e_malloc(strlen(source) + 1);
|
||||
strcpy(pnt, source);
|
||||
return pnt;
|
||||
}
|
||||
|
||||
int VMS_stat(char * path, struct stat * spnt){
|
||||
char * spath;
|
||||
char sbuffer[255];
|
||||
char * pnt, *ppnt;
|
||||
char * pnt1;
|
||||
|
||||
ppnt = strrchr(path,']');
|
||||
if(ppnt) ppnt++;
|
||||
else ppnt = path;
|
||||
|
||||
spath = path;
|
||||
|
||||
if(strcmp(ppnt,".") == 0 || strcmp(ppnt,"..") == 0){
|
||||
strcpy(sbuffer, path);
|
||||
|
||||
/* Find end of actual name */
|
||||
pnt = strrchr(sbuffer,']');
|
||||
if(!pnt) return 0;
|
||||
|
||||
pnt1 = pnt;
|
||||
while(*pnt1 != '[' && *pnt1 != '.') pnt1--;
|
||||
|
||||
if(*pnt1 != '[' && strcmp(ppnt,"..") == 0) {
|
||||
pnt1--;
|
||||
while(*pnt1 != '[' && *pnt1 != '.') pnt1--;
|
||||
};
|
||||
|
||||
if(*pnt1 == '.') {
|
||||
*pnt1 = ']';
|
||||
pnt = pnt1;
|
||||
while(*pnt != '.' && *pnt != ']') pnt++;
|
||||
*pnt++ = ']';
|
||||
while(*pnt != '.' && *pnt != ']') pnt++;
|
||||
*pnt = 0;
|
||||
strcat(sbuffer,".DIR;1");
|
||||
};
|
||||
|
||||
if(*pnt1 == '[') {
|
||||
pnt1++;
|
||||
*pnt1 = 0;
|
||||
strcat(pnt1,"000000]");
|
||||
pnt1 = strrchr(path,'[') + 1;
|
||||
pnt = sbuffer + strlen(sbuffer);
|
||||
while(*pnt1 && *pnt1 != '.' && *pnt1 != ']') *pnt++ = *pnt1++;
|
||||
*pnt = 0;
|
||||
strcat(sbuffer,".DIR;1");
|
||||
};
|
||||
|
||||
spath = sbuffer;
|
||||
};
|
||||
return stat(spath, spnt);
|
||||
}
|
||||
|
||||
static int dircontext[32] = {0,};
|
||||
static char * searchpath[32];
|
||||
static struct direct d_entry[32];
|
||||
|
||||
int optind = 0;
|
||||
char * optarg;
|
||||
|
||||
int getopt(int argc, char *argv[], char * flags){
|
||||
char * pnt;
|
||||
char c;
|
||||
optind++;
|
||||
if(*argv[optind] != '-') return EOF;
|
||||
optarg = 0;
|
||||
|
||||
c = *(argv[optind]+1);
|
||||
pnt = (char *) strchr(flags, c);
|
||||
if(!pnt) return c; /* Not found */
|
||||
if(pnt[1] == ':') {
|
||||
optind++;
|
||||
optarg = argv[optind];
|
||||
};
|
||||
return c;
|
||||
}
|
||||
|
||||
void vms_path_fixup(char * name){
|
||||
char * pnt1;
|
||||
pnt1 = name + strlen(name) - 6;
|
||||
|
||||
/* First strip the .DIR;1 */
|
||||
if(strcmp(pnt1, ".DIR;1") == 0) *pnt1 = 0;
|
||||
|
||||
pnt1 = (char*) strrchr(name, ']');
|
||||
if(pnt1) {
|
||||
if(pnt1[1] == 0) return;
|
||||
*pnt1 = '.';
|
||||
strcat(name,"]");
|
||||
return;
|
||||
};
|
||||
pnt1 = (char*) strrchr(name, '>');
|
||||
if(pnt1) {
|
||||
if(pnt1[1] == 0) return;
|
||||
*pnt1 = '.';
|
||||
strcat(name,">");
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
int opendir(char * path){
|
||||
int i;
|
||||
for(i=1; i<32; i++) {
|
||||
if(dircontext[i] == 0){
|
||||
dircontext[i] = -1;
|
||||
searchpath[i] = (char *) e_malloc(strlen(path) + 6);
|
||||
strcpy(searchpath[i], path);
|
||||
vms_path_fixup(searchpath[i]);
|
||||
strcat(searchpath[i],"*.*.*");
|
||||
return i;
|
||||
};
|
||||
};
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct direct * readdir(int context){
|
||||
int i;
|
||||
char cresult[100];
|
||||
char * pnt;
|
||||
int status;
|
||||
$DESCRIPTOR(dpath,searchpath[context]);
|
||||
$DESCRIPTOR(result,cresult);
|
||||
|
||||
if(dircontext[context] == -1) {
|
||||
dircontext[context] = -2;
|
||||
strcpy(d_entry[context].d_name, ".");
|
||||
return &d_entry[context];
|
||||
};
|
||||
|
||||
if(dircontext[context] == -2) {
|
||||
dircontext[context] = -3;
|
||||
strcpy(d_entry[context].d_name, "..");
|
||||
return &d_entry[context];
|
||||
};
|
||||
|
||||
if(dircontext[context] == -3) dircontext[context] = 0;
|
||||
|
||||
dpath.dsc$w_length = strlen(searchpath[context]);
|
||||
lib$find_file(&dpath, &result, &dircontext[context],
|
||||
0, 0, &status, 0);
|
||||
|
||||
if(status == SS$_NOMOREFILES) return 0;
|
||||
|
||||
/* Now trim trailing spaces from the name */
|
||||
i = result.dsc$w_length - 1;
|
||||
while(i && cresult[i] == ' ') i--;
|
||||
cresult[i+1] = 0;
|
||||
|
||||
/* Now locate the actual portion of the file we want */
|
||||
|
||||
pnt = (char *) strrchr(cresult,']');
|
||||
if(pnt) pnt++;
|
||||
else
|
||||
pnt = cresult;
|
||||
|
||||
strcpy(d_entry[context].d_name, pnt);
|
||||
return &d_entry[context];
|
||||
}
|
||||
|
||||
void closedir(int context){
|
||||
lib$find_file_end(&dircontext[context]);
|
||||
free(searchpath[context]);
|
||||
searchpath[context] = (char *) 0;
|
||||
dircontext[context] = 0;
|
||||
}
|
||||
|
||||
static open_file(char* fn){
|
||||
/* this routine initializes a rab and fab required to get the
|
||||
correct definition of the external data file used by mail */
|
||||
struct FAB * fab;
|
||||
|
||||
rab = (struct RAB*) e_malloc(sizeof(struct RAB));
|
||||
fab = (struct FAB*) e_malloc(sizeof(struct FAB));
|
||||
|
||||
*rab = cc$rms_rab; /* initialize RAB*/
|
||||
rab->rab$l_fab = fab;
|
||||
|
||||
*fab = cc$rms_fab; /* initialize FAB*/
|
||||
fab->fab$l_fna = fn;
|
||||
fab->fab$b_fns = strlen(fn);
|
||||
fab->fab$w_mrs = 512;
|
||||
fab->fab$b_fac = FAB$M_BIO | FAB$M_GET;
|
||||
fab->fab$b_org = FAB$C_SEQ;
|
||||
fab->fab$b_rfm = FAB$C_FIX;
|
||||
fab->fab$l_xab = (char*) 0;
|
||||
|
||||
rms_status = sys$open(rab->rab$l_fab);
|
||||
if(rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED)
|
||||
error_exit("$OPEN");
|
||||
rms_status = sys$connect(rab);
|
||||
if(rms_status != RMS$_NORMAL)
|
||||
error_exit("$CONNECT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static close_file(struct RAB * prab){
|
||||
rms_status = sys$close(prab->rab$l_fab);
|
||||
free(prab->rab$l_fab);
|
||||
free(prab);
|
||||
if(rms_status != RMS$_NORMAL)
|
||||
error_exit("$CLOSE");
|
||||
}
|
||||
|
||||
#define NSECT 16
|
||||
extern unsigned int last_extent_written;
|
||||
|
||||
int vms_write_one_file(char * filename, int size, FILE * outfile){
|
||||
int status, i;
|
||||
char buffer[SECTOR_SIZE * NSECT];
|
||||
int count;
|
||||
int use;
|
||||
int remain;
|
||||
|
||||
open_file(filename);
|
||||
|
||||
remain = size;
|
||||
|
||||
while(remain > 0){
|
||||
use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain);
|
||||
use = ROUND_UP(use); /* Round up to nearest sector boundary */
|
||||
memset(buffer, 0, use);
|
||||
rab->rab$l_ubf = buffer;
|
||||
rab->rab$w_usz = sizeof(buffer);
|
||||
status = sys$read(rab);
|
||||
fwrite(buffer, 1, use, outfile);
|
||||
last_extent_written += use/SECTOR_SIZE;
|
||||
if((last_extent_written % 1000) < use/SECTOR_SIZE) fprintf(stderr,"%d..", last_extent_written);
|
||||
remain -= use;
|
||||
};
|
||||
|
||||
close_file(rab);
|
||||
}
|
||||
#endif
|
19
gnu/usr.bin/mkisofs/vms.h
Normal file
19
gnu/usr.bin/mkisofs/vms.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Header file mkisofs.h - assorted structure definitions and typecasts.
|
||||
|
||||
Written by Eric Youngdale (1993).
|
||||
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#define stat(X,Y) VMS_stat(X,Y)
|
||||
#define lstat VMS_stat
|
||||
|
||||
/* gmtime not available under VMS - make it look like we are in Greenwich */
|
||||
#define gmtime localtime
|
||||
|
||||
#define S_ISBLK(X) (0)
|
||||
#define S_ISCHR(X) (0)
|
||||
#define S_ISREG(X) (((X) & S_IFMT) == S_IFREG)
|
||||
#define S_ISDIR(X) (((X) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
781
gnu/usr.bin/mkisofs/write.c
Normal file
781
gnu/usr.bin/mkisofs/write.c
Normal file
@ -0,0 +1,781 @@
|
||||
/*
|
||||
* Program write.c - dump memory structures to file 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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "mkisofs.h"
|
||||
#include "iso9660.h"
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __svr4__
|
||||
extern char * strdup(const char *);
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
extern char * strdup(const char *);
|
||||
#endif
|
||||
|
||||
|
||||
/* Max number of sectors we will write at one time */
|
||||
#define NSECT 16
|
||||
|
||||
/* Counters for statistics */
|
||||
|
||||
static int table_size = 0;
|
||||
static int total_dir_size = 0;
|
||||
static int rockridge_size = 0;
|
||||
static struct directory ** pathlist;
|
||||
static next_path_index = 1;
|
||||
|
||||
/* Used to fill in some of the information in the volume descriptor. */
|
||||
static struct tm *local;
|
||||
|
||||
/* Routines to actually write the disc. We write sequentially so that
|
||||
we could write a tape, or write the disc directly */
|
||||
|
||||
|
||||
#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X))
|
||||
|
||||
void FDECL2(set_721, char *, pnt, unsigned int, i){
|
||||
pnt[0] = i & 0xff;
|
||||
pnt[1] = (i >> 8) & 0xff;
|
||||
}
|
||||
|
||||
void FDECL2(set_722, char *, pnt, unsigned int, i){
|
||||
pnt[0] = (i >> 8) & 0xff;
|
||||
pnt[1] = i & 0xff;
|
||||
}
|
||||
|
||||
void FDECL2(set_723, char *, pnt, unsigned int, i){
|
||||
pnt[3] = pnt[0] = i & 0xff;
|
||||
pnt[2] = pnt[1] = (i >> 8) & 0xff;
|
||||
}
|
||||
|
||||
void FDECL2(set_731, char *, pnt, unsigned int, i){
|
||||
pnt[0] = i & 0xff;
|
||||
pnt[1] = (i >> 8) & 0xff;
|
||||
pnt[2] = (i >> 16) & 0xff;
|
||||
pnt[3] = (i >> 24) & 0xff;
|
||||
}
|
||||
|
||||
void FDECL2(set_732, char *, pnt, unsigned int, i){
|
||||
pnt[3] = i & 0xff;
|
||||
pnt[2] = (i >> 8) & 0xff;
|
||||
pnt[1] = (i >> 16) & 0xff;
|
||||
pnt[0] = (i >> 24) & 0xff;
|
||||
}
|
||||
|
||||
int FDECL1(get_733, char *, p){
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8)
|
||||
| ((p[2] & 0xff) << 16)
|
||||
| ((p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
void FDECL2(set_733, char *, pnt, unsigned int, i){
|
||||
pnt[7] = pnt[0] = i & 0xff;
|
||||
pnt[6] = pnt[1] = (i >> 8) & 0xff;
|
||||
pnt[5] = pnt[2] = (i >> 16) & 0xff;
|
||||
pnt[4] = pnt[3] = (i >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static FDECL4(xfwrite, void *, buffer, int, count, int, size, FILE *, file)
|
||||
{
|
||||
while(count) {
|
||||
int got=fwrite(buffer,size,count,file);
|
||||
if(got<=0) fprintf(stderr,"cannot fwrite %d*%d\n",size,count),exit(1);
|
||||
count-=got,*(char**)&buffer+=size*got;
|
||||
}
|
||||
}
|
||||
|
||||
struct deferred_write{
|
||||
struct deferred_write * next;
|
||||
char * table;
|
||||
unsigned int extent;
|
||||
unsigned int size;
|
||||
char * name;
|
||||
};
|
||||
|
||||
static struct deferred_write * dw_head = NULL, * dw_tail = NULL;
|
||||
|
||||
static struct directory_entry * sort_dir;
|
||||
|
||||
unsigned int last_extent_written =0;
|
||||
static struct iso_primary_descriptor vol_desc;
|
||||
static path_table_index;
|
||||
|
||||
/* We recursively walk through all of the directories and assign extent
|
||||
numbers to them. We have already assigned extent numbers to everything that
|
||||
goes in front of them */
|
||||
|
||||
void FDECL1(assign_directory_addresses, struct directory *, node){
|
||||
struct directory * dpnt;
|
||||
int dir_size;
|
||||
|
||||
dpnt = node;
|
||||
|
||||
while (dpnt){
|
||||
dpnt->extent = last_extent;
|
||||
dpnt->path_index = next_path_index++;
|
||||
dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11;
|
||||
|
||||
last_extent += dir_size;
|
||||
|
||||
/* Leave room for the CE entries for this directory. Keep them
|
||||
close to the reference directory so that access will be quick. */
|
||||
if(dpnt->ce_bytes)
|
||||
last_extent += ROUND_UP(dpnt->ce_bytes) >> 11;
|
||||
|
||||
if(dpnt->subdir) assign_directory_addresses(dpnt->subdir);
|
||||
dpnt = dpnt->next;
|
||||
};
|
||||
}
|
||||
|
||||
static void FDECL3(write_one_file, char *, filename, unsigned int, size, FILE *, outfile){
|
||||
FILE * infile;
|
||||
char buffer[SECTOR_SIZE * NSECT];
|
||||
int use;
|
||||
int remain;
|
||||
if ((infile = fopen(filename, "rb")) == NULL) {
|
||||
#ifdef sun
|
||||
fprintf(stderr, "cannot open %s: (%d)\n", filename, errno);
|
||||
#else
|
||||
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
remain = size;
|
||||
|
||||
while(remain > 0){
|
||||
use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain);
|
||||
use = ROUND_UP(use); /* Round up to nearest sector boundary */
|
||||
memset(buffer, 0, use);
|
||||
if (fread(buffer, 1, use, infile) == 0) {
|
||||
fprintf(stderr,"cannot read from %s\n",filename);
|
||||
exit(1);
|
||||
}
|
||||
xfwrite(buffer, 1, use, outfile);
|
||||
last_extent_written += use/SECTOR_SIZE;
|
||||
if((last_extent_written % 1000) < use/SECTOR_SIZE) fprintf(stderr,"%d..", last_extent_written);
|
||||
remain -= use;
|
||||
};
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
static void FDECL1(write_files, FILE *, outfile){
|
||||
struct deferred_write * dwpnt, *dwnext;
|
||||
dwpnt = dw_head;
|
||||
while(dwpnt){
|
||||
if(dwpnt->table) {
|
||||
xfwrite(dwpnt->table, 1, ROUND_UP(dwpnt->size), outfile);
|
||||
last_extent_written += ROUND_UP(dwpnt->size) / SECTOR_SIZE;
|
||||
table_size += dwpnt->size;
|
||||
/* fprintf(stderr,"Size %d ", dwpnt->size); */
|
||||
free(dwpnt->table);
|
||||
} else {
|
||||
|
||||
#ifdef VMS
|
||||
vms_write_one_file(dwpnt->name, dwpnt->size, outfile);
|
||||
#else
|
||||
write_one_file(dwpnt->name, dwpnt->size, outfile);
|
||||
#endif
|
||||
free(dwpnt->name);
|
||||
};
|
||||
|
||||
dwnext = dwpnt;
|
||||
dwpnt = dwpnt->next;
|
||||
free(dwnext);
|
||||
};
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void dump_filelist(){
|
||||
struct deferred_write * dwpnt;
|
||||
dwpnt = dw_head;
|
||||
while(dwpnt){
|
||||
fprintf(stderr, "File %s\n",dwpnt->name);
|
||||
dwpnt = dwpnt->next;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
};
|
||||
#endif
|
||||
|
||||
int FDECL2(compare_dirs, const struct directory_entry **, r, const struct directory_entry **, l) {
|
||||
char * rpnt, *lpnt;
|
||||
|
||||
rpnt = (*r)->isorec.name;
|
||||
lpnt = (*l)->isorec.name;
|
||||
|
||||
while(*rpnt && *lpnt) {
|
||||
if(*rpnt == ';' && *lpnt != ';') return -1;
|
||||
if(*rpnt != ';' && *lpnt == ';') return 1;
|
||||
if(*rpnt == ';' && *lpnt == ';') return 0;
|
||||
if(*rpnt < *lpnt) return -1;
|
||||
if(*rpnt > *lpnt) return 1;
|
||||
rpnt++; lpnt++;
|
||||
}
|
||||
if(*rpnt) return 1;
|
||||
if(*lpnt) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FDECL1(sort_directory, struct directory_entry **, sort_dir){
|
||||
int dcount = 0;
|
||||
int i, len;
|
||||
struct directory_entry * s_entry;
|
||||
struct directory_entry ** sortlist;
|
||||
|
||||
s_entry = *sort_dir;
|
||||
while(s_entry){
|
||||
dcount++;
|
||||
s_entry = s_entry->next;
|
||||
};
|
||||
/* OK, now we know how many there are. Build a vector for sorting. */
|
||||
|
||||
sortlist = (struct directory_entry **)
|
||||
e_malloc(sizeof(struct directory_entry *) * dcount);
|
||||
|
||||
dcount = 0;
|
||||
s_entry = *sort_dir;
|
||||
while(s_entry){
|
||||
sortlist[dcount] = s_entry;
|
||||
len = s_entry->isorec.name_len[0];
|
||||
s_entry->isorec.name[len] = 0;
|
||||
dcount++;
|
||||
s_entry = s_entry->next;
|
||||
};
|
||||
|
||||
qsort(sortlist, dcount, sizeof(struct directory_entry *), compare_dirs);
|
||||
|
||||
/* Now reassemble the linked list in the proper sorted order */
|
||||
for(i=0; i<dcount-1; i++)
|
||||
sortlist[i]->next = sortlist[i+1];
|
||||
|
||||
sortlist[dcount-1]->next = NULL;
|
||||
*sort_dir = sortlist[0];
|
||||
|
||||
free(sortlist);
|
||||
|
||||
}
|
||||
|
||||
void generate_root_record(){
|
||||
time_t ctime;
|
||||
|
||||
time (&ctime);
|
||||
local = localtime(&ctime);
|
||||
|
||||
root_record.length[0] = 1 + sizeof(struct iso_directory_record);
|
||||
root_record.ext_attr_length[0] = 0;
|
||||
set_733(root_record.extent, root->extent);
|
||||
set_733(root_record.size, ROUND_UP(root->size));
|
||||
iso9660_date(root_record.date, ctime);
|
||||
root_record.flags[0] = 2;
|
||||
root_record.file_unit_size[0] = 0;
|
||||
root_record.interleave[0] = 0;
|
||||
set_723(root_record.volume_sequence_number, 1);
|
||||
root_record.name_len[0] = 1;
|
||||
}
|
||||
|
||||
static void FDECL1(assign_file_addresses, struct directory *, dpnt){
|
||||
struct directory * finddir;
|
||||
struct directory_entry * s_entry;
|
||||
struct file_hash *s_hash;
|
||||
struct deferred_write * dwpnt;
|
||||
char whole_path[1024];
|
||||
|
||||
while (dpnt){
|
||||
s_entry = dpnt->contents;
|
||||
for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next){
|
||||
|
||||
/* This saves some space if there are symlinks present */
|
||||
s_hash = find_hash(s_entry->dev, s_entry->inode);
|
||||
if(s_hash){
|
||||
if(verbose)
|
||||
fprintf(stderr, "Cache hit for %s%s%s\n",s_entry->filedir->de_name,
|
||||
SPATH_SEPARATOR, s_entry->name);
|
||||
set_733(s_entry->isorec.extent, s_hash->starting_block);
|
||||
set_733(s_entry->isorec.size, s_hash->size);
|
||||
continue;
|
||||
};
|
||||
if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") &&
|
||||
s_entry->isorec.flags[0] == 2){
|
||||
finddir = dpnt->subdir;
|
||||
while(1==1){
|
||||
if(finddir->self == s_entry) break;
|
||||
finddir = finddir->next;
|
||||
if(!finddir) {fprintf(stderr,"Fatal goof\n"); exit(1);};
|
||||
};
|
||||
set_733(s_entry->isorec.extent, finddir->extent);
|
||||
s_entry->starting_block = finddir->extent;
|
||||
s_entry->size = ROUND_UP(finddir->size);
|
||||
total_dir_size += s_entry->size;
|
||||
add_hash(s_entry);
|
||||
set_733(s_entry->isorec.size, ROUND_UP(finddir->size));
|
||||
} else {
|
||||
if(strcmp(s_entry->name,".") ==0 || strcmp(s_entry->name,"..") == 0) {
|
||||
if(strcmp(s_entry->name,".") == 0) {
|
||||
set_733(s_entry->isorec.extent, dpnt->extent);
|
||||
|
||||
/* Set these so that the hash table has the correct information */
|
||||
s_entry->starting_block = dpnt->extent;
|
||||
s_entry->size = ROUND_UP(dpnt->size);
|
||||
|
||||
add_hash(s_entry);
|
||||
s_entry->starting_block = dpnt->extent;
|
||||
set_733(s_entry->isorec.size, ROUND_UP(dpnt->size));
|
||||
} else {
|
||||
if(dpnt == root) total_dir_size += root->size;
|
||||
set_733(s_entry->isorec.extent, dpnt->parent->extent);
|
||||
|
||||
/* Set these so that the hash table has the correct information */
|
||||
s_entry->starting_block = dpnt->parent->extent;
|
||||
s_entry->size = ROUND_UP(dpnt->parent->size);
|
||||
|
||||
add_hash(s_entry);
|
||||
s_entry->starting_block = dpnt->parent->extent;
|
||||
set_733(s_entry->isorec.size, ROUND_UP(dpnt->parent->size));
|
||||
};
|
||||
} else {
|
||||
/* Now we schedule the file to be written. This is all quite
|
||||
straightforward, just make a list and assign extents as we go.
|
||||
Once we get through writing all of the directories, we should
|
||||
be ready write out these files */
|
||||
|
||||
if(s_entry->size) {
|
||||
dwpnt = (struct deferred_write *)
|
||||
e_malloc(sizeof(struct deferred_write));
|
||||
if(dw_tail){
|
||||
dw_tail->next = dwpnt;
|
||||
dw_tail = dwpnt;
|
||||
} else {
|
||||
dw_head = dwpnt;
|
||||
dw_tail = dwpnt;
|
||||
};
|
||||
if(s_entry->inode == TABLE_INODE) {
|
||||
dwpnt->table = s_entry->table;
|
||||
dwpnt->name = NULL;
|
||||
} else {
|
||||
dwpnt->table = NULL;
|
||||
strcpy(whole_path, s_entry->filedir->whole_name);
|
||||
#ifndef VMS
|
||||
if(strlen(whole_path)) strcat(whole_path, "/");
|
||||
#endif
|
||||
strcat(whole_path, s_entry->name);
|
||||
dwpnt->name = strdup(whole_path);
|
||||
};
|
||||
dwpnt->next = NULL;
|
||||
dwpnt->size = s_entry->size;
|
||||
dwpnt->extent = last_extent;
|
||||
set_733(s_entry->isorec.extent, last_extent);
|
||||
s_entry->starting_block = last_extent;
|
||||
add_hash(s_entry);
|
||||
last_extent += ROUND_UP(s_entry->size) >> 11;
|
||||
if(verbose)
|
||||
fprintf(stderr,"%d %d %s\n", s_entry->starting_block,
|
||||
last_extent-1, whole_path);
|
||||
#ifdef DBG_ISO
|
||||
if((ROUND_UP(s_entry->size) >> 11) > 500){
|
||||
fprintf(stderr,"Warning: large file %s\n", whole_path);
|
||||
fprintf(stderr,"Starting block is %d\n", s_entry->starting_block);
|
||||
fprintf(stderr,"Reported file size is %d extents\n", s_entry->size);
|
||||
|
||||
};
|
||||
#endif
|
||||
if(last_extent > (700000000 >> 11)) { /* More than 700Mb? Punt */
|
||||
fprintf(stderr,"Extent overflow processing file %s\n", whole_path);
|
||||
fprintf(stderr,"Starting block is %d\n", s_entry->starting_block);
|
||||
fprintf(stderr,"Reported file size is %d extents\n", s_entry->size);
|
||||
exit(1);
|
||||
};
|
||||
} else
|
||||
set_733(s_entry->isorec.extent, 0);
|
||||
};
|
||||
};
|
||||
};
|
||||
if(dpnt->subdir) assign_file_addresses(dpnt->subdir);
|
||||
dpnt = dpnt->next;
|
||||
};
|
||||
}
|
||||
|
||||
void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile){
|
||||
unsigned int total_size, ce_size;
|
||||
char * directory_buffer;
|
||||
char * ce_buffer;
|
||||
unsigned int ce_address;
|
||||
struct directory_entry * s_entry, *s_entry_d;
|
||||
int new_reclen;
|
||||
unsigned int dir_index, ce_index;
|
||||
|
||||
total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1);
|
||||
directory_buffer = (char *) e_malloc(total_size);
|
||||
memset(directory_buffer, 0, total_size);
|
||||
dir_index = 0;
|
||||
|
||||
ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1);
|
||||
ce_buffer = NULL;
|
||||
|
||||
if(ce_size) {
|
||||
ce_buffer = (char *) e_malloc(ce_size);
|
||||
memset(ce_buffer, 0, ce_size);
|
||||
|
||||
ce_index = 0;
|
||||
|
||||
/* Absolute byte address of CE entries for this directory */
|
||||
ce_address = last_extent_written + (total_size >> 11);
|
||||
ce_address = ce_address << 11;
|
||||
}
|
||||
|
||||
s_entry = dpnt->contents;
|
||||
while(s_entry) {
|
||||
|
||||
/* We do not allow directory entries to cross sector boundaries. Simply
|
||||
pad, and then start the next entry at the next sector */
|
||||
new_reclen = s_entry->isorec.length[0];
|
||||
if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE)
|
||||
dir_index = (dir_index + (SECTOR_SIZE - 1)) &
|
||||
~(SECTOR_SIZE - 1);
|
||||
|
||||
memcpy(directory_buffer + dir_index, &s_entry->isorec,
|
||||
sizeof(struct iso_directory_record) -
|
||||
sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]);
|
||||
dir_index += sizeof(struct iso_directory_record) -
|
||||
sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0];
|
||||
|
||||
/* Add the Rock Ridge attributes, if present */
|
||||
if(s_entry->rr_attr_size){
|
||||
if(dir_index & 1)
|
||||
directory_buffer[dir_index++] = 0;
|
||||
|
||||
/* If the RR attributes were too long, then write the CE records,
|
||||
as required. */
|
||||
if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) {
|
||||
unsigned char * pnt;
|
||||
int len, nbytes;
|
||||
|
||||
/* Go through the entire record and fix up the CE entries
|
||||
so that the extent and offset are correct */
|
||||
|
||||
pnt = s_entry->rr_attributes;
|
||||
len = s_entry->total_rr_attr_size;
|
||||
while(len > 3){
|
||||
if(pnt[0] == 'C' && pnt[1] == 'E') {
|
||||
nbytes = get_733(pnt+20);
|
||||
|
||||
if((ce_index & (SECTOR_SIZE - 1)) + nbytes >=
|
||||
SECTOR_SIZE) ce_index = ROUND_UP(ce_index);
|
||||
|
||||
set_733(pnt+4, (ce_address + ce_index) >> 11);
|
||||
set_733(pnt+12, (ce_address + ce_index) & (SECTOR_SIZE - 1));
|
||||
|
||||
|
||||
/* Now store the block in the ce buffer */
|
||||
memcpy(ce_buffer + ce_index,
|
||||
pnt + pnt[2], nbytes);
|
||||
ce_index += nbytes;
|
||||
if(ce_index & 1) ce_index++;
|
||||
};
|
||||
len -= pnt[2];
|
||||
pnt += pnt[2];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
rockridge_size += s_entry->total_rr_attr_size;
|
||||
memcpy(directory_buffer + dir_index, s_entry->rr_attributes,
|
||||
s_entry->rr_attr_size);
|
||||
dir_index += s_entry->rr_attr_size;
|
||||
};
|
||||
if(dir_index & 1)
|
||||
directory_buffer[dir_index++] = 0;
|
||||
|
||||
s_entry_d = s_entry;
|
||||
s_entry = s_entry->next;
|
||||
|
||||
if (s_entry_d->rr_attributes) free(s_entry_d->rr_attributes);
|
||||
free (s_entry_d->name);
|
||||
free (s_entry_d);
|
||||
};
|
||||
sort_dir = NULL;
|
||||
|
||||
if(dpnt->size != dir_index)
|
||||
fprintf(stderr,"Unexpected directory length %d %d %s\n",dpnt->size,
|
||||
dir_index, dpnt->de_name);
|
||||
xfwrite(directory_buffer, 1, total_size, outfile);
|
||||
last_extent_written += total_size >> 11;
|
||||
free(directory_buffer);
|
||||
|
||||
if(ce_size){
|
||||
if(ce_index != dpnt->ce_bytes)
|
||||
fprintf(stderr,"Continuation entry record length mismatch (%d %d).\n",
|
||||
ce_index, dpnt->ce_bytes);
|
||||
xfwrite(ce_buffer, 1, ce_size, outfile);
|
||||
last_extent_written += ce_size >> 11;
|
||||
free(ce_buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void FDECL1(build_pathlist, struct directory *, node){
|
||||
struct directory * dpnt;
|
||||
|
||||
dpnt = node;
|
||||
|
||||
while (dpnt){
|
||||
pathlist[dpnt->path_index] = dpnt;
|
||||
if(dpnt->subdir) build_pathlist(dpnt->subdir);
|
||||
dpnt = dpnt->next;
|
||||
};
|
||||
}
|
||||
|
||||
int FDECL2(compare_paths, const struct directory **, r, const struct directory **, l) {
|
||||
if((*r)->parent->path_index < (*l)->parent->path_index) return -1;
|
||||
if((*r)->parent->path_index > (*l)->parent->path_index) return 1;
|
||||
return strcmp((*r)->self->isorec.name, (*l)->self->isorec.name);
|
||||
|
||||
}
|
||||
|
||||
void generate_path_tables(){
|
||||
struct directory * dpnt;
|
||||
char * npnt, *npnt1;
|
||||
int namelen;
|
||||
struct directory_entry * de;
|
||||
int fix;
|
||||
int tablesize;
|
||||
int i,j;
|
||||
/* First allocate memory for the tables and initialize the memory */
|
||||
|
||||
tablesize = path_blocks << 11;
|
||||
path_table_m = (char *) e_malloc(tablesize);
|
||||
path_table_l = (char *) e_malloc(tablesize);
|
||||
memset(path_table_l, 0, tablesize);
|
||||
memset(path_table_m, 0, tablesize);
|
||||
|
||||
/* Now start filling in the path tables. Start with root directory */
|
||||
path_table_index = 0;
|
||||
pathlist = (struct directory **) e_malloc(sizeof(struct directory *) * next_path_index);
|
||||
memset(pathlist, 0, sizeof(struct directory *) * next_path_index);
|
||||
build_pathlist(root);
|
||||
|
||||
do{
|
||||
fix = 0;
|
||||
qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), compare_paths);
|
||||
|
||||
for(j=1; j<next_path_index; j++)
|
||||
if(pathlist[j]->path_index != j){
|
||||
pathlist[j]->path_index = j;
|
||||
fix++;
|
||||
};
|
||||
} while(fix);
|
||||
|
||||
for(j=1; j<next_path_index; j++){
|
||||
dpnt = pathlist[j];
|
||||
if(!dpnt){
|
||||
fprintf(stderr,"Entry %d not in path tables\n", j);
|
||||
exit(1);
|
||||
};
|
||||
npnt = dpnt->de_name;
|
||||
if(*npnt == 0 || dpnt == root) npnt = "."; /* So the root comes out OK */
|
||||
npnt1 = strrchr(npnt, PATH_SEPARATOR);
|
||||
if(npnt1) npnt = npnt1 + 1;
|
||||
|
||||
de = dpnt->self;
|
||||
if(!de) {fprintf(stderr,"Fatal goof\n"); exit(1);};
|
||||
|
||||
|
||||
namelen = de->isorec.name_len[0];
|
||||
|
||||
path_table_l[path_table_index] = namelen;
|
||||
path_table_m[path_table_index] = namelen;
|
||||
path_table_index += 2;
|
||||
set_731(path_table_l + path_table_index, dpnt->extent);
|
||||
set_732(path_table_m + path_table_index, dpnt->extent);
|
||||
path_table_index += 4;
|
||||
set_721(path_table_l + path_table_index, dpnt->parent->path_index);
|
||||
set_722(path_table_m + path_table_index, dpnt->parent->path_index);
|
||||
path_table_index += 2;
|
||||
for(i =0; i<namelen; i++){
|
||||
path_table_l[path_table_index] = de->isorec.name[i];
|
||||
path_table_m[path_table_index] = de->isorec.name[i];
|
||||
path_table_index++;
|
||||
};
|
||||
if(path_table_index & 1) path_table_index++; /* For odd lengths we pad */
|
||||
};
|
||||
free(pathlist);
|
||||
if(path_table_index != path_table_size)
|
||||
fprintf(stderr,"Path table lengths do not match %d %d\n",path_table_index,
|
||||
path_table_size);
|
||||
}
|
||||
|
||||
int FDECL1(iso_write, FILE *, outfile){
|
||||
char buffer[2048];
|
||||
char iso_time[17];
|
||||
int should_write;
|
||||
int i;
|
||||
|
||||
assign_file_addresses(root);
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
/* This will break in the year 2000, I supose, but there is no good way
|
||||
to get the top two digits of the year. */
|
||||
sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local->tm_year,
|
||||
local->tm_mon+1, local->tm_mday,
|
||||
local->tm_hour, local->tm_min, local->tm_sec);
|
||||
|
||||
/* First, we output 16 sectors of all zero */
|
||||
|
||||
for(i=0; i<16; i++)
|
||||
xfwrite(buffer, 1, sizeof(buffer), outfile);
|
||||
|
||||
last_extent_written += 16;
|
||||
|
||||
/* Next we write out the primary descriptor for the disc */
|
||||
memset(&vol_desc, 0, sizeof(vol_desc));
|
||||
vol_desc.type[0] = ISO_VD_PRIMARY;
|
||||
memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
|
||||
vol_desc.version[0] = 1;
|
||||
|
||||
memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id));
|
||||
memcpy(vol_desc.system_id, system_id, strlen(system_id));
|
||||
|
||||
memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id));
|
||||
memcpy(vol_desc.volume_id, volume_id, strlen(volume_id));
|
||||
|
||||
should_write = last_extent;
|
||||
set_733(vol_desc.volume_space_size, last_extent);
|
||||
set_723(vol_desc.volume_set_size, 1);
|
||||
set_723(vol_desc.volume_sequence_number, 1);
|
||||
set_723(vol_desc.logical_block_size, 2048);
|
||||
|
||||
/* The path tables are used by DOS based machines to cache directory
|
||||
locations */
|
||||
|
||||
set_733(vol_desc.path_table_size, path_table_size);
|
||||
set_731(vol_desc.type_l_path_table, path_table[0]);
|
||||
set_731(vol_desc.opt_type_l_path_table, path_table[1]);
|
||||
set_732(vol_desc.type_m_path_table, path_table[2]);
|
||||
set_732(vol_desc.opt_type_m_path_table, path_table[3]);
|
||||
|
||||
/* Now we copy the actual root directory record */
|
||||
|
||||
memcpy(vol_desc.root_directory_record, &root_record,
|
||||
sizeof(struct iso_directory_record) + 1);
|
||||
|
||||
/* The rest is just fluff. It looks nice to fill in many of these fields,
|
||||
though */
|
||||
|
||||
FILL_SPACE(volume_set_id);
|
||||
if(volset_id) memcpy(vol_desc.volume_set_id, volset_id, strlen(volset_id));
|
||||
|
||||
FILL_SPACE(publisher_id);
|
||||
if(publisher) memcpy(vol_desc.publisher_id, publisher, strlen(publisher));
|
||||
|
||||
FILL_SPACE(preparer_id);
|
||||
if(preparer) memcpy(vol_desc.preparer_id, preparer, strlen(preparer));
|
||||
|
||||
FILL_SPACE(application_id);
|
||||
if(appid) memcpy(vol_desc.application_id, appid, strlen(appid));
|
||||
|
||||
FILL_SPACE(copyright_file_id);
|
||||
if(appid) memcpy(vol_desc.copyright_file_id, appid, strlen(appid));
|
||||
|
||||
FILL_SPACE(abstract_file_id);
|
||||
if(appid) memcpy(vol_desc.abstract_file_id, appid, strlen(appid));
|
||||
|
||||
FILL_SPACE(bibliographic_file_id);
|
||||
if(appid) memcpy(vol_desc.bibliographic_file_id, appid, strlen(appid));
|
||||
|
||||
FILL_SPACE(creation_date);
|
||||
FILL_SPACE(modification_date);
|
||||
FILL_SPACE(expiration_date);
|
||||
FILL_SPACE(effective_date);
|
||||
vol_desc.file_structure_version[0] = 1;
|
||||
FILL_SPACE(application_data);
|
||||
|
||||
memcpy(vol_desc.creation_date, iso_time, 16);
|
||||
memcpy(vol_desc.modification_date, iso_time, 16);
|
||||
memcpy(vol_desc.expiration_date, "0000000000000000", 16);
|
||||
memcpy(vol_desc.effective_date, iso_time, 16);
|
||||
|
||||
/* For some reason, Young Minds writes this twice. Aw, what the heck */
|
||||
xfwrite(&vol_desc, 1, 2048, outfile);
|
||||
xfwrite(&vol_desc, 1, 2048, outfile);
|
||||
last_extent_written += 2;
|
||||
|
||||
/* Now write the end volume descriptor. Much simpler than the other one */
|
||||
memset(&vol_desc, 0, sizeof(vol_desc));
|
||||
vol_desc.type[0] = ISO_VD_END;
|
||||
memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
|
||||
vol_desc.version[0] = 1;
|
||||
xfwrite(&vol_desc, 1, 2048, outfile);
|
||||
xfwrite(&vol_desc, 1, 2048, outfile);
|
||||
last_extent_written += 2;
|
||||
|
||||
/* Next we write the path tables */
|
||||
xfwrite(path_table_l, 1, path_blocks << 11, outfile);
|
||||
xfwrite(path_table_l, 1, path_blocks << 11, outfile);
|
||||
xfwrite(path_table_m, 1, path_blocks << 11, outfile);
|
||||
xfwrite(path_table_m, 1, path_blocks << 11, outfile);
|
||||
last_extent_written += 4*path_blocks;
|
||||
free(path_table_l);
|
||||
free(path_table_m);
|
||||
path_table_l = NULL;
|
||||
path_table_m = NULL;
|
||||
|
||||
/* OK, all done with that crap. Now write out the directories.
|
||||
This is where the fur starts to fly, because we need to keep track of
|
||||
each file as we find it and keep track of where we put it. */
|
||||
|
||||
#ifdef DBG_ISO
|
||||
fprintf(stderr,"Total directory extents being written = %d\n", last_extent);
|
||||
#endif
|
||||
#if 0
|
||||
generate_one_directory(root, outfile);
|
||||
#endif
|
||||
generate_iso9660_directories(root, outfile);
|
||||
|
||||
if(extension_record) {
|
||||
xfwrite(extension_record, 1, SECTOR_SIZE, outfile);
|
||||
last_extent_written++;
|
||||
}
|
||||
|
||||
/* Now write all of the files that we need. */
|
||||
fprintf(stderr,"Total extents scheduled to be written = %d\n", last_extent);
|
||||
write_files(outfile);
|
||||
|
||||
fprintf(stderr,"Total extents actually written = %d\n", last_extent_written);
|
||||
/* Hard links throw us off here */
|
||||
if(should_write != last_extent){
|
||||
fprintf(stderr,"Number of extents written not what was predicted. Please fix.\n");
|
||||
fprintf(stderr,"Predicted = %d, written = %d\n", should_write, last_extent);
|
||||
};
|
||||
|
||||
fprintf(stderr,"Total translation table size: %d\n", table_size);
|
||||
fprintf(stderr,"Total rockridge attributes bytes: %d\n", rockridge_size);
|
||||
fprintf(stderr,"Total directory bytes: %d\n", total_dir_size);
|
||||
fprintf(stderr,"Path table size(bytes): %d\n", path_table_size);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n",
|
||||
next_extent, last_extent, last_extent_written);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user