mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-16 07:11:05 +01:00
Import version 1.04 of mkisofs.
This is a vendor-branch import by now, the merge with our regular tree will happen later. Obtained from: Eric Youngdale of Yggdrasil Computing Inc.
This commit is contained in:
commit
3f2e9a763f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/mkisofs/; revision=11646
695
gnu/usr.bin/mkisofs/ChangeLog
Normal file
695
gnu/usr.bin/mkisofs/ChangeLog
Normal file
@ -0,0 +1,695 @@
|
||||
Sun Feb 26 01:52:06 1995 Eric Youngdale (eric@largo)
|
||||
|
||||
* Add patches from Ross Biro to allow you to merge arbitrary
|
||||
trees into the image. This is not compiled in by default but
|
||||
you need to add -DADD_FILES when compiling.
|
||||
|
||||
Fri Feb 17 02:29:03 1995 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* tree.c: Port to Solaris 2.4. Prefer <sys/mkdev.h> if
|
||||
HASMKDEV. Cast unknown integer types to unsigned long and
|
||||
print them with %lu or %lx.
|
||||
|
||||
Thu Jan 26 15:25:00 1995 H. Peter Anvin (hpa@yggdrasil.com)
|
||||
|
||||
* mkisofs.c: Substitute underscore for leading dot in non-Rock
|
||||
Ridge filenames, since MS-DOS cannot read files whose names
|
||||
begin with a period.
|
||||
|
||||
Mon Jan 16 18:31:41 1995 Eric Youngdale (eric@aib.com)
|
||||
|
||||
* rock.c (generate_rock_ridge_attributes): Only use ROOT
|
||||
record for symlinks if we are at the start of the symlink.
|
||||
Otherwise just generate an empty entry.
|
||||
|
||||
Mon Jan 16 16:19:50 1995 Eric Youngdale (eric@aib.com)
|
||||
|
||||
* diag/isodump.c: Use isonum_733 instead of trying to dereference
|
||||
pointers when trying to decode 733 numbers in the iso9660 image.
|
||||
|
||||
* diag/isovfy.c: Likewise.
|
||||
|
||||
* write.c: Always assign an extent number, even for zero length
|
||||
files. A zero length file with a NULL extent is apparently dropped
|
||||
by many readers.
|
||||
|
||||
Wed Jan 11 13:46:50 1995 Eric Youngdale (eric@aib.com)
|
||||
|
||||
* mkisofs.c: Modify extension record to conform to IEEE P1282
|
||||
specifications. This is commented out right now, but a trivial
|
||||
change to a #define enables this. I need to see the specs
|
||||
to see whether anything else changed before this becomes final.
|
||||
|
||||
* write.c (FDECL4): Fix so that we properly determine error
|
||||
conditions.
|
||||
|
||||
* mkisofs.h: Change rr_attributes to unsigned.
|
||||
|
||||
* tree.c(increment_nlink): Change pnt since rr_attributes is now
|
||||
unsigned.
|
||||
|
||||
Ultrix patches from petav@argon.e20.physik.tu-muenchen.de (Peter Averkamp)
|
||||
|
||||
* rock.c: Fix for ultrix systems, we have 64 bit device numbers.
|
||||
Type cast when generating file size. Change rr_attributes to
|
||||
unsigned.
|
||||
|
||||
* mkisofs.c: For ultrix systems, define our own function
|
||||
for strdup.
|
||||
|
||||
* mkisofs.c: Fix usage() since some compilers do not concatenate
|
||||
strings properly (i.e. ultrix).
|
||||
|
||||
Bugs found with Sentinel II:
|
||||
|
||||
* write.c: Fix a couple of memory leaks.
|
||||
|
||||
* mkisofs.c: Bugfix - always put a zero byte at end of name
|
||||
for ".." entry.
|
||||
|
||||
* tree.c: Set isorec.date from fstatbuf.st_ctime, not current_time,
|
||||
since current_time might not be set.
|
||||
|
||||
Sat Dec 3 14:55:42 1994 Eric Youngdale (eric@andante)
|
||||
|
||||
* mkisofs.c: When returning entry for ".." file, set second byte
|
||||
to 0.
|
||||
|
||||
* write.c: Free name and rr_attributes fields when writing.
|
||||
|
||||
Mon Nov 28 13:36:27 1994 Eric Youngdale (eric@andante)
|
||||
|
||||
* mkisofs.h: Change rr_attributes to unsigned.
|
||||
|
||||
* rock.c: Ditto. Work around >>32 bug in ultrix for 64 bit data types.
|
||||
|
||||
* mkisofs.c (usage): Fix for ultrix - use continuation lines
|
||||
instead of assuming that strings are catenated by the compiler.
|
||||
|
||||
Mon Jun 20 20:25:26 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to pre-1.02.
|
||||
|
||||
* mkisofs.h: Fix declaration of e_malloc to use DECL macros.
|
||||
|
||||
* tree.c: Fix bug in previous change.
|
||||
|
||||
* diag/*.c: Add appropriate copyright notices.
|
||||
|
||||
Sat Apr 9 13:30:46 1994 Eric Youngdale (ericy@cais.com)
|
||||
|
||||
* Configure: New file - shell script that determines a bunch of
|
||||
things to properly build mkisofs.
|
||||
|
||||
* Makefile.in: New file - copy of Makefile, but Configure sets a
|
||||
few things up for it.
|
||||
|
||||
* tree.c: Do not depend upon opendir to return NULL if we cannot
|
||||
open a directory - actually try and read the first entry. The
|
||||
foibles of NFS seem to require this.
|
||||
|
||||
* write.c: Fix definition of xfwrite (Use FDECL4)
|
||||
|
||||
Add some changes to allow more configurability of some of the
|
||||
volume header fields:
|
||||
|
||||
* mkisofs.8: Document new configuration options.
|
||||
|
||||
* mkisofs.c: Add variables to hold new fields. Add function to
|
||||
read .mkisofsrc files.
|
||||
|
||||
* defaults.h: Another way of configuring the same things.
|
||||
|
||||
Add some changes from Leo Weppelman leo@ahwau.ahold.nl.
|
||||
|
||||
* mkisofs.c: Allow -A to specify application ID. Fix usage(),
|
||||
getopt and add case switch.
|
||||
|
||||
* rock.c: Fix handling of device numbers (dev_t high should only
|
||||
be used when sizeof(dev_t) > 32 bits).
|
||||
|
||||
Add a bunch of changes from Manuel Bouyer.
|
||||
|
||||
* diag/Makefile: New file.
|
||||
|
||||
* diag/dump.c, diag/isodump.c: Use termios if system supports it.
|
||||
|
||||
* (throughout): Replace all occurences of "malloc" with e_malloc.
|
||||
|
||||
* mkisofs.c: For NetBSD, attempt to increase the rlimit for
|
||||
the size of the data segment to about 33 Mb.
|
||||
|
||||
* mkisofs.c (e_malloc): New function. Calls malloc, and prints
|
||||
nice error message and exits if NULL is returned.
|
||||
|
||||
Sun Jan 23 19:23:57 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.01.
|
||||
|
||||
Add a bunch of stuff so that mkisofs will work on a VMS system.
|
||||
|
||||
* (ALL): Change any direct use of the "st_ino" field from
|
||||
the statbuf to use a macro.
|
||||
|
||||
* mkisofs.h: Define appropriate macros for both VMS and unix.
|
||||
|
||||
* (ALL): Add type casts whenever we use the UNCACHED_DEV macro.
|
||||
|
||||
* rock.c: Wrap a #ifndef VMS around block and character device
|
||||
stuff.
|
||||
|
||||
* write.c: Add prototype for strdup if VMS is defined.
|
||||
|
||||
* make.com: Script for building mkisofs on a VMS system.
|
||||
|
||||
* Makefile: Include make.com in the distribution.
|
||||
|
||||
* mkisofs.c: Include <sys/type.h> on VMS systems.
|
||||
|
||||
* tree.c: Include <sys/file.h> and "vms.h" on VMS systems.
|
||||
|
||||
* mkisofs.h (PATH_SEPARATOR, SPATH_SEPARATOR): New macros
|
||||
that define the ascii character that separates the last directory
|
||||
component from the filename.
|
||||
|
||||
* tree.c, mkisofs.c: Use them.
|
||||
|
||||
* vms.c: New file. Contains version of getopt, strdup, opendir,
|
||||
readdir and closedir.
|
||||
|
||||
* vms.h: New file. Defines S_IS* macros. Define gmtime as
|
||||
localtime, since gmtime under VMS returns NULL.
|
||||
|
||||
Sat Jan 15 13:57:42 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
* mkisofs.h (transparent_compression): New prototype.
|
||||
|
||||
* mkisofs.c (transparent_compression): Declare, use
|
||||
'-z' option to turn on.
|
||||
|
||||
* tree.c: Change TRANS.TBL;1 to TRANS.TBL (version gets
|
||||
added later, if required).
|
||||
|
||||
* rock.c: If transparent compression requested, verify
|
||||
file is really suitable (check magic numbers), and extract
|
||||
correct file length to store in SUSP record.
|
||||
|
||||
Sat Jan 15 01:57:42 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
* write.c (compare_dirs): Bugfix for patch from Jan 6.
|
||||
|
||||
* mkisofs.h (struct directory_entry): Add element total_rr_attr_size.
|
||||
(struct file_hash): Add element ce_bytes.
|
||||
|
||||
* write.c (iso_write): Update last_extent_written, as required,
|
||||
and check it against last_extent as a sanity check.
|
||||
(generate_one_directory): If ce_bytes is non-zero, allocate
|
||||
a buffer and fill it with the CE records. Also, update
|
||||
the extent and offset entries in the CE SUSP field and
|
||||
output after directory is written.
|
||||
(assign_directory_addresses): Allow for CE sectors after each
|
||||
directory.
|
||||
|
||||
* tree.c (sort_n_finish): Set field ce_bytes by summing
|
||||
the sizes of all CE blocks in each files RR attributes.
|
||||
Do not count these bytes for main directory.
|
||||
|
||||
* rock.c (generate_rock_ridge_attributes): Generate
|
||||
CE entries to break up large records into manageable sizes.
|
||||
Allow long names to be split, and allow long symlinks to be split.
|
||||
Allow splitting before each SUSP field as well, to make
|
||||
sure we do not screw outselves.
|
||||
|
||||
Thu Jan 6 21:47:43 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
Bugfix.
|
||||
|
||||
* write.c (compare_dirs): Only compare directory names up to
|
||||
the ';' for the version number.
|
||||
|
||||
Add four new options: (1) Full 31 character filenames,
|
||||
(2) Omit version number, (3) Omit trailing period from filenames,
|
||||
(4) Skip deep directory relocation.
|
||||
|
||||
* iso9660.h: Allow 34 characters for filename.
|
||||
|
||||
* mkisofs.8: Update for new options.
|
||||
|
||||
* mkisofs.c: Add flag variables for new options.
|
||||
Mention new options in usage(), tell getopt about
|
||||
new options, and set appropriate flags when
|
||||
new options are specified.
|
||||
|
||||
* mkisofs.c (iso9660_file_length): Implement new options.
|
||||
|
||||
* mkisofs.h: Declare flag variables for new options.
|
||||
|
||||
* tree.c (sort_n_finish): Increase declaration of newname and
|
||||
rootname to 34 characters. If full_iso9660_filenames in effect,
|
||||
use different rules for making unique names.
|
||||
|
||||
* tree.c (scan_directory_tree): Use RR_relocation_depth instead of
|
||||
constant for threshold for starting deep directory relocation.
|
||||
|
||||
Wed Jan 5 01:32:34 1994 John Brezak (brezak@ch.hp.com)
|
||||
|
||||
* Makefile.bsd: New file. For NetBSD.
|
||||
|
||||
* rock.c, tree.c: Do not include sys/sysmacros.h for NetBSD.
|
||||
|
||||
Fri Dec 31 13:22:52 1993 Eric Youngdale (eric@esp22)
|
||||
|
||||
* mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.00.
|
||||
|
||||
* tree.c (scan_directory_tree): Handle case where we do not
|
||||
have permissions to open a directory.
|
||||
|
||||
* write.c (xfwrite): New function - wrapper for fwrite,
|
||||
except that we print message and punt if write fails.
|
||||
|
||||
* write.c: Move include of mkisofs.h and iso9660.h until after
|
||||
string.h and stdlib.h is included.
|
||||
|
||||
* write.c: Do not attempt to use strerror on sun systems.
|
||||
|
||||
Thu Dec 9 13:17:28 1993 R.-D. Marzusch (marzusch@odiehh.hanse.de)
|
||||
|
||||
* exclude.c, exclude.h: New files. Contains list of files to
|
||||
exclude from consideration.
|
||||
|
||||
* Makefile: Compile exclude.c, add dependencies to other files.
|
||||
|
||||
* mkisofs.8: Describe -x option.
|
||||
|
||||
* mkisofs.c: Include exclude.h, handle -x option.
|
||||
|
||||
|
||||
Fri Dec 10 01:07:43 1993 Peter van der Veen (peterv@qnx.com)
|
||||
|
||||
* mkisofs.c, mkisofs.h: Moved declaration of root_record.
|
||||
|
||||
* mkisofs.h: Added prototype for get_733().
|
||||
|
||||
* write.c(iso_write), tree.c, rock.c(generate_rock_ridge_attributes):
|
||||
Added defines for QNX operation system
|
||||
|
||||
* rock.c(generate_rock_ridge_attributes): symbolic links should
|
||||
not have CONTINUE component flag set unless there are multiple
|
||||
component records, and mkisofs does not generate these.
|
||||
st_ctime was stored as the creation time, changed to attribute time.
|
||||
QNX has a creation time, so that is stored as well under QNX.
|
||||
|
||||
Thu Oct 28 19:54:38 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.99.
|
||||
|
||||
* write.c(iso_write): Put hour, minute, second into date fields in
|
||||
volume descriptor.
|
||||
|
||||
* write.c (iso_write): Set file_structure_version to 1, instead of
|
||||
' ' (Seems to screw up Macs).
|
||||
|
||||
Sun Oct 17 01:13:36 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.98.
|
||||
|
||||
Increment nlink in root directory when rr_moved directory is present.
|
||||
|
||||
* tree.c (increment_nlink): New function.
|
||||
|
||||
* tree.c (finish_cl_pl_entries): Call increment_nlink for all
|
||||
references to the root directory.
|
||||
|
||||
* tree.c (root_statbuf): New variable.
|
||||
|
||||
* tree.c (scan_directory_tree): Initialize root_statbuf when we
|
||||
stat the root directory.
|
||||
|
||||
* tree.c (generate_reloc_directory): Use root_statbuf when
|
||||
generating the Rock Ridge stuff for the ".." entry in the
|
||||
reloc_dir.
|
||||
|
||||
* tree.c (scan_directory_tree): Use root_statbuf when generating
|
||||
the ".." entry in the root directory.
|
||||
|
||||
Sat Oct 16 10:28:30 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
Fix path tables so that they are sorted.
|
||||
|
||||
* tree.c (assign_directory_addresses): Move to write.c
|
||||
|
||||
* write.c (generate_path_tables): Create an array of pointers to
|
||||
the individual directories, and sort it based upon the name and
|
||||
the parent path table index. Then update all of the indexes and
|
||||
repeat the sort until the path table indexes no longer need to be
|
||||
changed, and then write the path table.
|
||||
|
||||
Fix problem where hard links were throwing off the total extent count.
|
||||
|
||||
* write.c (iso_write): Call assign_file_addresses, and then
|
||||
use last_extent to determine how big the volume is.
|
||||
|
||||
* write.c (generate_one_directory): Decrement n_data_extents
|
||||
for hard links to non-directories so that the expected number
|
||||
of extents is written correctly.
|
||||
|
||||
* write.c(assign_file_addresses): New function.
|
||||
|
||||
Fri Oct 15 22:35:43 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
The standard says we should do these things:
|
||||
|
||||
* tree.c (generate_reloc_directory): Add RR attributes to
|
||||
the rr_moved directory.
|
||||
|
||||
* mkisofs.c(main): Change ER text strings back to recommended
|
||||
values.
|
||||
|
||||
Tue Oct 12 21:07:38 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.97.
|
||||
|
||||
* tree.c (scan_directory_tree): Do not insert PL entry into
|
||||
root directory record (i.e. !parent)
|
||||
|
||||
* tree.c (finish_cl_pl_entries): Do not rely upon name
|
||||
comparison to locate parent - use d_entry->self instead,
|
||||
which is guaranteed to be correct.
|
||||
|
||||
* mkisofs.h: New variable n_data_extents.
|
||||
|
||||
* tree.c: Declare and initialize n_data_extents to 0.
|
||||
(scan_directory_tree) for non-directories, add
|
||||
ROUND_UP(statbuf.st_size) to n_data_extents.
|
||||
(sort_n_finish): Increment n_data_extents for translation tables,
|
||||
as appropriate.
|
||||
|
||||
* write.c(iso_write): Add n_data_extents to the
|
||||
volume_space_size field.
|
||||
|
||||
* hash.c(add_hash): If size != 0 and extent == 0, or
|
||||
if size == 0 and extent != 0, then complain about
|
||||
inserting this into the hash table. Kind of a sanity check.
|
||||
|
||||
Sat Oct 9 16:39:15 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.96.
|
||||
|
||||
Numerous bugfixes, thanks to a one-off disc from rab@cdrom.com.
|
||||
|
||||
* write.c(generate_one_directory): Wait until after we have
|
||||
filled in the starting_extent field to s_entry before calling
|
||||
add_hash. This fixes a problem where the hash table gets an
|
||||
extent of 0 for all regular files, and this turns up when you have
|
||||
hard links on the disc. (The hash table allows us to have each
|
||||
hard link point to the same extent on the cdrom, thereby saving
|
||||
some space).
|
||||
|
||||
* tree.c(scan_directory_tree): Set statbuf.st_dev and
|
||||
statbuf.st_ino to the UNCACHED numbers for symlinks that we
|
||||
are not following. This prevents the function find_hash from
|
||||
returning an inode that cooresponds to the file the symlink points
|
||||
to, which in turn prevents generate_one_directory from filling in
|
||||
a bogus file length (should be zero for symlinks).
|
||||
|
||||
* tree.c(scan_directory_tree): Always call lstat for the file
|
||||
so that non-RockRidge discs get correct treatment of symlinks.
|
||||
Improve error message when we ignore a symlink on a non-RR disc.
|
||||
|
||||
* write.c(generate_one_directory): Set fields for starting_extent
|
||||
and size in the "." and ".." entries before we add them to the
|
||||
file hash. Fixes problems with incorrect backlinks for second
|
||||
level directories.
|
||||
|
||||
Wed Oct 6 19:53:40 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* write.c (write_one_file): Print message and punt if we are
|
||||
unable to open the file.
|
||||
|
||||
* tree.c(scan_directory_tree): For regular files, use the access
|
||||
function to verify that the file is readable in the first place.
|
||||
If not, issue a warning and skip it. For directories, it probably
|
||||
does not matter, since we would not be able to descend into them
|
||||
in the first place.
|
||||
|
||||
Wed Sep 29 00:02:47 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.95.
|
||||
|
||||
* write.c, tree.c: Cosmetic changes to printed information.
|
||||
|
||||
* tree.c(scan_directory_tree): Set size to zero for
|
||||
special stub entries that correspond to the
|
||||
relocated directories. Hopefully last big bug.
|
||||
|
||||
* mkisofs.h: Change TABLE_INODE, UNCACHED_* macros
|
||||
to be 0x7fff... to be compatible with signed datatypes.
|
||||
|
||||
Mon Sep 27 20:14:49 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.94.
|
||||
|
||||
* write.c (write_path_tables): Actually search the
|
||||
directory for the matching entry in case we renamed
|
||||
the directory because of a name conflict.
|
||||
|
||||
* tree.c(scan_directory_tree): Take directory_entry pointer
|
||||
as second argument so that we can create a backpointer
|
||||
in the directory structure that points back to the original
|
||||
dir.
|
||||
|
||||
* mkisofs.c: Fix call to scan_directory_tree to use new calling
|
||||
sequence.
|
||||
|
||||
* write.c(generate_one_directory): Punt if the last_extent counter
|
||||
ever exceeds 700Mb/2048. Print name of responsible file,
|
||||
extent counter, and starting extent. Perhaps we can catch it in
|
||||
the act.
|
||||
|
||||
Sun Sep 26 20:58:05 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.93.
|
||||
|
||||
* tree.c(scan_directory_tree): Handle symlinks better. Either
|
||||
leave them as symlinks, or erase any trace that they were a
|
||||
symlink but do not do it 1/2 way as before. Also, watch for
|
||||
directory loops created with symlinks.
|
||||
|
||||
* mkisofs.h: Add new flag follow_links.
|
||||
|
||||
* mkisofs.c: Add command line switch "-f" to toggle follow_links.
|
||||
|
||||
* mkisofs.8: Document new switch.
|
||||
|
||||
* tree.c: Add code to handle symlinks using new flag.
|
||||
|
||||
* hash.c: Add add_directory_hash, find_directory_hash functions.
|
||||
|
||||
* mkisofs.h: Add prototypes.
|
||||
|
||||
Sat Sep 25 14:26:31 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.92.
|
||||
|
||||
* mkisofs.c: Make sure path is an actual directory before trying
|
||||
to scan it.
|
||||
|
||||
* mkisofs.h: Add DECL and FDECL? macros for sparc like systems.
|
||||
Do proper define of optind and optarg under SVr4.
|
||||
|
||||
* tree.c: Change translation table name from YMTRANS.TBL to TRANS.TBL.
|
||||
|
||||
* mkisofs.c: Neaten up message in extension record when RRIP is
|
||||
in use.
|
||||
|
||||
* Throughout - change all function declarations so that
|
||||
traditional C compilers (i.e. sparc) will work.
|
||||
|
||||
* Makefile: Change to use system default C compiler.
|
||||
|
||||
* mkisofs.c: Add some stuff so that this will compile under VMS.
|
||||
Many things missing for VMS still.
|
||||
|
||||
* iso9660.h: Do not use zero length array in struct definition.
|
||||
|
||||
* tree.c (sort_n_finish): Account for this.
|
||||
|
||||
* Change copyright notice.
|
||||
|
||||
|
||||
Wed Aug 25 08:06:51 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.91.
|
||||
|
||||
* mkisofs.h: Only include sys/dir.h for linux. Other systems
|
||||
will need other things.
|
||||
|
||||
* mkisofs.c, tree.c: Include unistd.h.
|
||||
|
||||
* Makefile: Use OBJS to define list of object files.
|
||||
|
||||
Sun Aug 22 20:55:17 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.9.
|
||||
|
||||
* write.c (iso_7*): Fix so that they work properly on Motorola
|
||||
systems.
|
||||
|
||||
Fri Aug 20 00:14:36 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.8.
|
||||
|
||||
* rock.c: Do not mask off write permissions from posix file modes.
|
||||
|
||||
Wed Aug 18 09:02:12 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.7.
|
||||
|
||||
* rock.c: Do not write NM field for . and .. (redundant and a
|
||||
waste of space).
|
||||
|
||||
* mkisofs.c: Take -P and -p options for publisher and preparer id
|
||||
fields.
|
||||
|
||||
* write.c: Store publisher and preparer id in volume
|
||||
descriptor.
|
||||
|
||||
* rock.c: Write optional SP field to identify SUSP. Write
|
||||
optional CE field to point to the extension header.
|
||||
|
||||
* tree.c: Request SP and CE fields be added to root directory.
|
||||
|
||||
* tree.c: Fix bug in name conflict resolution.
|
||||
|
||||
* write.c: Fill in date fields in the colume descriptor.
|
||||
|
||||
* write.c (write_one_file): If the file is large enough, write in
|
||||
chunks of 16 sectors to improve performance.
|
||||
|
||||
* hash.c (add_hash, find_hash, etc): Do not hash s_entry, instead
|
||||
store relevant info in hash structure (we free s_entry structs as
|
||||
we write files, and we need to have access to the hash table the
|
||||
whole way through.
|
||||
|
||||
* write.c: Add a few statistics about directory sizes, RR sizes,
|
||||
translation table sizes, etc.
|
||||
|
||||
* tree.c: Use major, not MAJOR. Same for minor. Define S_ISSOCK
|
||||
and S_ISLNK if not defined.
|
||||
|
||||
* rock.c: Define S_ISLNK if not defined.
|
||||
|
||||
* mkisofs.c: Print out max memory usage. Fix bug in call to getopt.
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.6.
|
||||
|
||||
* tree.c: Simplify the calculation of isorec.len, isorec.name_len
|
||||
and the calculation of the path table sizes by doing it all at
|
||||
one point after conflict resolution is done.
|
||||
|
||||
* tree.c: scan_directory_tree is now responsible for generating
|
||||
the line that goes into the YMTRANS.TBL file. These lines are
|
||||
collected later on into something that will be dumped to the
|
||||
file. Correctly handle all of the special file types.
|
||||
|
||||
Mon Aug 16 21:59:47 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.5.
|
||||
|
||||
* mkisofs.c: Add -a option (to force all files to be
|
||||
transferred). Remove find_file_hash stuff.
|
||||
|
||||
* write.c: Pad length even if Rock Ridge is not in use.
|
||||
|
||||
* hash.c: Rewrite hash_file_* stuff so that it can be used to
|
||||
easily detect (and look up) filenames that have been accepted
|
||||
for use in this directory. Used for name collision detection.
|
||||
|
||||
* tree.c (sort_n_finish): If two names collide, generate a unique
|
||||
one (verified with the hash routines). Change the lower priority
|
||||
name if there is a difference.
|
||||
|
||||
|
||||
|
||||
Sat Aug 14 13:18:21 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.4.
|
||||
|
||||
* tree.c (load_translation_table): New function - read
|
||||
YMTRANS.TBL. (scan_directory_tree) Call it.
|
||||
|
||||
* mkisofs.c (iso9660_file_length): Call find_file_hash to see
|
||||
if translated name is specified. If so, use it.
|
||||
|
||||
* hash.c (name_hash, add_file_hash, find_file_hash,
|
||||
flush_file_hash): New functions for hashing stuff from
|
||||
YMTRANS.TBL.
|
||||
|
||||
* mkisofs.h: Add a bunch of prototypes for the new functions.
|
||||
|
||||
* mkisofs.8: Update.
|
||||
|
||||
* mkisofs.c, Makefile (version_string): Bump to 0.3.
|
||||
|
||||
* Makefile: Add version number to tar file in dist target.
|
||||
|
||||
* mkisofs.c: Call finish_cl_pl_entries() after directories have
|
||||
been generated, and extent numbers assigned.
|
||||
|
||||
* write.c (generate_one_directory): Update s_entry->size for
|
||||
directories (as well as isorec.size).
|
||||
|
||||
* rock.c: Add code to generate CL, PL, and RE entries. The
|
||||
extent numbers for the CL and PL entries are NULL, and these
|
||||
are filled in later once we know where they actually belong.
|
||||
|
||||
* mkisofs.h: Add parent_rec to directory_entry. Used to fix CL/PL
|
||||
stuff.
|
||||
|
||||
* tree.c (scan_directory_tree): Set flag to generate CL/PL/RE
|
||||
entries as required, update sizes as well.
|
||||
|
||||
Fri Aug 13 19:49:30 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c (version_string): Bump to 0.2.
|
||||
|
||||
* hash.c: Do not use entries with inode == 0xffffffff or dev ==
|
||||
0xffff.
|
||||
|
||||
* write.c (write_path_tables): Strip leading directory specifications.
|
||||
|
||||
* mkisofs.h: Add definition for reloc_dir symbol. Add prototype
|
||||
for sort_n_finish, add third parameter to scan_directory_tree
|
||||
(for true parent, when directories are relocated).
|
||||
|
||||
* mkisofs.c (main): Modify call to scan_directory_tree. Call
|
||||
sort_n_finish for reloc_dir.
|
||||
|
||||
* tree.c (sort_n_finish): New function - moved code from
|
||||
scan_directory_tree.
|
||||
|
||||
* tree.c (generate_reloc_directory): New function. Generate
|
||||
directory to hold relocated directories.
|
||||
|
||||
* tree.c (scan_directory_tree): Strip leading directories when
|
||||
generating this_dir->name. If depth is too great, then move
|
||||
directory to reloc_dir (creating if it does not exist, and leave
|
||||
a dummy (non-directory) entry in the regular directory so that
|
||||
we can eventually add the required Rock Ridge record.
|
||||
|
||||
* tree.c (scan_directory_tree): Use s_entry instead of sort_dir,
|
||||
assign to this_dir->contents sooner.
|
||||
|
||||
Thu Aug 12 22:38:17 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs.c (usage): Fix syntax.
|
||||
|
||||
* mkisofs.c (main): Add new argument to scan_directory_tree
|
||||
|
||||
* tree.c (scan_directory_tree): If directory is at depth 8 or
|
||||
more, create rr_moved directory in main directory.
|
||||
|
||||
Mon Jul 26 19:45:47 1993 Eric Youngdale (eric@kafka)
|
||||
|
||||
* mkisofs v 0.1 released.
|
||||
|
51
gnu/usr.bin/mkisofs/Makefile.in
Normal file
51
gnu/usr.bin/mkisofs/Makefile.in
Normal file
@ -0,0 +1,51 @@
|
||||
#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 *~ #*#
|
||||
(cd diag/; make clean)
|
||||
(cd cdwrite/; make clean)
|
||||
|
||||
dist:
|
||||
tar -cvf - README Configure Makefile.in make.com TODO COPYING ChangeLog *.8 *.c *.h diag cdwrite.old cdwrite-1.5 | gzip > mkisofs-1.04.tar.gz
|
||||
|
84
gnu/usr.bin/mkisofs/README
Normal file
84
gnu/usr.bin/mkisofs/README
Normal file
@ -0,0 +1,84 @@
|
||||
Note:
|
||||
There is a feature which can be optionally compiled into
|
||||
mkisofs that allows you to merge arbitrary directory trees into the
|
||||
image you are creating. You need to compile with -DADD_FILES for my
|
||||
changes to take effect. Thanks to Ross Biro biro@yggdrasil.com.
|
||||
|
||||
This program requires a lot of virtual memory to run since it
|
||||
builds all of the directories in memory. The exact requirements
|
||||
depend upon a lot of things, but for Rock Ridge discs 12Mb would not
|
||||
be unreasonable. Without RockRidge and without the translation
|
||||
tables, the requirements would be considerably less.
|
||||
|
||||
The cdwrite utility is maintained separately from mkisofs by
|
||||
yggdrasil.com. It is enclosed here as a convenience, since the two programs
|
||||
are often useful together.
|
||||
|
||||
*****************************
|
||||
Notes for version 1.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).
|
||||
|
25
gnu/usr.bin/mkisofs/defaults.h
Normal file
25
gnu/usr.bin/mkisofs/defaults.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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"
|
||||
#endif
|
||||
|
||||
#ifdef __osf__
|
||||
#define SYSTEM_ID_DEFAULT "OSF"
|
||||
#endif
|
||||
|
||||
#ifndef SYSTEM_ID_DEFAULT
|
||||
#define SYSTEM_ID_DEFAULT "LINUX"
|
||||
#endif
|
16
gnu/usr.bin/mkisofs/diag/Makefile
Normal file
16
gnu/usr.bin/mkisofs/diag/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
#CC = gcc
|
||||
CC = cc -traditional
|
||||
|
||||
all: dump isodump isovfy
|
||||
|
||||
isoinfo:isoinfo.c
|
||||
${CC} -g -o isoinfo isoinfo.c
|
||||
dump:dump.c
|
||||
${CC} -o dump dump.c
|
||||
isodump:isodump.c
|
||||
${CC} -o isodump isodump.c
|
||||
isovfy:isovfy.c
|
||||
${CC} -o isovfy isovfy.c
|
||||
|
||||
clean:
|
||||
rm -f dump isodump isovfy isoinfo
|
436
gnu/usr.bin/mkisofs/diag/isodump.c
Normal file
436
gnu/usr.bin/mkisofs/diag/isodump.c
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
* 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 (unsigned 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 [1];
|
||||
};
|
||||
|
||||
#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;
|
||||
unsigned char * pnt;
|
||||
|
||||
len = idr->length[0] & 0xff;
|
||||
len -= sizeof(struct iso_directory_record);
|
||||
len += sizeof(idr->name);
|
||||
len -= idr->name_len[0];
|
||||
pnt = (unsigned char *) idr;
|
||||
pnt += sizeof(struct iso_directory_record);
|
||||
pnt -= sizeof(idr->name);
|
||||
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 ", isonum_733(idr->extent));
|
||||
printf("%8d ", isonum_733(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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
522
gnu/usr.bin/mkisofs/diag/isoinfo.c
Normal file
522
gnu/usr.bin/mkisofs/diag/isoinfo.c
Normal file
@ -0,0 +1,522 @@
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
/*
|
||||
* Simple program to dump contents of iso9660 image in more usable format.
|
||||
*
|
||||
* Usage:
|
||||
* To list contents of image (with or without RR):
|
||||
* isoinfo -l [-R] -i imagefile
|
||||
* To extract file from image:
|
||||
* isoinfo -i imagefile -x xtractfile > outfile
|
||||
* To generate a "find" like list of files:
|
||||
* isoinfo -f -i imagefile
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __svr4__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
/* extern int getopt (int __argc, char **__argv, char *__optstring); */
|
||||
#endif
|
||||
|
||||
FILE * infile;
|
||||
int use_rock = 0;
|
||||
int do_listing = 0;
|
||||
int do_find = 0;
|
||||
char * xtract = 0;
|
||||
|
||||
struct stat fstat_buf;
|
||||
char name_buf[256];
|
||||
char xname[256];
|
||||
unsigned char date_buf[9];
|
||||
|
||||
unsigned char buffer[2048];
|
||||
|
||||
#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 (unsigned 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 [1];
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
|
||||
symlink[0] = 0;
|
||||
|
||||
cont_extent = cont_offset = cont_size = 0;
|
||||
|
||||
ncount = 0;
|
||||
flag1 = flag2 = 0;
|
||||
while(len >= 4){
|
||||
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) {
|
||||
fstat_buf.st_mode = isonum_733(pnt+4);
|
||||
fstat_buf.st_nlink = isonum_733(pnt+12);
|
||||
fstat_buf.st_uid = isonum_733(pnt+20);
|
||||
fstat_buf.st_gid = isonum_733(pnt+28);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "NM", 2) == 0) {
|
||||
strncpy(name_buf, pnt+5, pnt[2] - 5);
|
||||
name_buf[pnt[2] - 5] = 0;
|
||||
}
|
||||
|
||||
if(strncmp(pnt, "CE", 2) == 0) {
|
||||
cont_extent = isonum_733(pnt+4);
|
||||
cont_offset = isonum_733(pnt+12);
|
||||
cont_size = isonum_733(pnt+20);
|
||||
};
|
||||
|
||||
if(strncmp(pnt, "PL", 2) == 0 || strncmp(pnt, "CL", 2) == 0) {
|
||||
extent = isonum_733(pnt+4);
|
||||
};
|
||||
|
||||
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(xname[0] == 0) strcpy(xname, "-> ");
|
||||
strcat(xname, 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);
|
||||
};
|
||||
};
|
||||
return flag2;
|
||||
}
|
||||
|
||||
int
|
||||
dump_rr(struct iso_directory_record * idr)
|
||||
{
|
||||
int len;
|
||||
unsigned char * pnt;
|
||||
|
||||
len = idr->length[0] & 0xff;
|
||||
len -= sizeof(struct iso_directory_record);
|
||||
len += sizeof(idr->name);
|
||||
len -= idr->name_len[0];
|
||||
pnt = (unsigned char *) idr;
|
||||
pnt += sizeof(struct iso_directory_record);
|
||||
pnt -= sizeof(idr->name);
|
||||
pnt += idr->name_len[0];
|
||||
if((idr->name_len[0] & 1) == 0){
|
||||
pnt++;
|
||||
len--;
|
||||
};
|
||||
parse_rr(pnt, len, 0);
|
||||
}
|
||||
|
||||
struct todo
|
||||
{
|
||||
struct todo * next;
|
||||
char * name;
|
||||
int extent;
|
||||
int length;
|
||||
};
|
||||
|
||||
struct todo * todo_idr = NULL;
|
||||
|
||||
char * months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
|
||||
"Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
dump_stat()
|
||||
{
|
||||
int i;
|
||||
char outline[80];
|
||||
|
||||
memset(outline, ' ', sizeof(outline));
|
||||
|
||||
if(S_ISREG(fstat_buf.st_mode))
|
||||
outline[0] = '-';
|
||||
else if(S_ISDIR(fstat_buf.st_mode))
|
||||
outline[0] = 'd';
|
||||
else if(S_ISLNK(fstat_buf.st_mode))
|
||||
outline[0] = 'l';
|
||||
else if(S_ISCHR(fstat_buf.st_mode))
|
||||
outline[0] = 'c';
|
||||
else if(S_ISBLK(fstat_buf.st_mode))
|
||||
outline[0] = 'b';
|
||||
else if(S_ISFIFO(fstat_buf.st_mode))
|
||||
outline[0] = 'f';
|
||||
else if(S_ISSOCK(fstat_buf.st_mode))
|
||||
outline[0] = 's';
|
||||
else
|
||||
outline[0] = '?';
|
||||
|
||||
memset(outline+1, '-', 9);
|
||||
if( fstat_buf.st_mode & S_IRUSR )
|
||||
outline[1] = 'r';
|
||||
if( fstat_buf.st_mode & S_IWUSR )
|
||||
outline[2] = 'w';
|
||||
if( fstat_buf.st_mode & S_IXUSR )
|
||||
outline[3] = 'x';
|
||||
|
||||
if( fstat_buf.st_mode & S_IRGRP )
|
||||
outline[4] = 'r';
|
||||
if( fstat_buf.st_mode & S_IWGRP )
|
||||
outline[5] = 'w';
|
||||
if( fstat_buf.st_mode & S_IXGRP )
|
||||
outline[6] = 'x';
|
||||
|
||||
if( fstat_buf.st_mode & S_IROTH )
|
||||
outline[7] = 'r';
|
||||
if( fstat_buf.st_mode & S_IWOTH )
|
||||
outline[8] = 'w';
|
||||
if( fstat_buf.st_mode & S_IXOTH )
|
||||
outline[9] = 'x';
|
||||
|
||||
sprintf(outline+11, "%3d", fstat_buf.st_nlink);
|
||||
sprintf(outline+15, "%4o", fstat_buf.st_uid);
|
||||
sprintf(outline+20, "%4o", fstat_buf.st_gid);
|
||||
sprintf(outline+33, "%8d", fstat_buf.st_size);
|
||||
|
||||
memcpy(outline+42, months[date_buf[1]-1], 3);
|
||||
sprintf(outline+46, "%2d", date_buf[2]);
|
||||
sprintf(outline+49, "%4d", date_buf[0]+1900);
|
||||
|
||||
for(i=0; i<54; i++)
|
||||
if(outline[i] == 0) outline[i] = ' ';
|
||||
outline[54] = 0;
|
||||
|
||||
printf("%s %s %s\n", outline, name_buf, xname);
|
||||
}
|
||||
|
||||
extract_file(struct iso_directory_record * idr)
|
||||
{
|
||||
int extent, len, tlen;
|
||||
unsigned char buff[2048];
|
||||
|
||||
extent = isonum_733(idr->extent);
|
||||
len = isonum_733(idr->size);
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
lseek(fileno(infile), extent << 11, 0);
|
||||
tlen = (len > sizeof(buff) ? sizeof(buff) : len);
|
||||
read(fileno(infile), buff, tlen);
|
||||
len -= tlen;
|
||||
extent++;
|
||||
write(1, buff, tlen);
|
||||
}
|
||||
}
|
||||
|
||||
parse_dir(char * rootname, int extent, int len){
|
||||
unsigned int k;
|
||||
char testname[256];
|
||||
struct todo * td;
|
||||
int i, j;
|
||||
struct iso_directory_record * idr;
|
||||
|
||||
|
||||
if( do_listing)
|
||||
printf("\nDirectory listing of %s\n", rootname);
|
||||
|
||||
while(len > 0 )
|
||||
{
|
||||
lseek(fileno(infile), extent << 11, 0);
|
||||
read(fileno(infile), buffer, sizeof(buffer));
|
||||
len -= sizeof(buffer);
|
||||
extent++;
|
||||
i = 0;
|
||||
while(1==1){
|
||||
idr = (struct iso_directory_record *) &buffer[i];
|
||||
if(idr->length[0] == 0) break;
|
||||
memset(&fstat_buf, 0, sizeof(fstat_buf));
|
||||
name_buf[0] = xname[0] = 0;
|
||||
fstat_buf.st_size = isonum_733(idr->size);
|
||||
if( idr->flags[0] & 2)
|
||||
fstat_buf.st_mode |= S_IFDIR;
|
||||
else
|
||||
fstat_buf.st_mode |= S_IFREG;
|
||||
if(idr->name_len[0] == 1 && idr->name[0] == 0)
|
||||
strcpy(name_buf, ".");
|
||||
else if(idr->name_len[0] == 1 && idr->name[0] == 1)
|
||||
strcpy(name_buf, "..");
|
||||
else {
|
||||
strncpy(name_buf, idr->name, idr->name_len[0]);
|
||||
name_buf[idr->name_len[0]] = 0;
|
||||
};
|
||||
memcpy(date_buf, idr->date, 9);
|
||||
if(use_rock) dump_rr(idr);
|
||||
if( (idr->flags[0] & 2) != 0
|
||||
&& (idr->name_len[0] != 1
|
||||
|| (idr->name[0] != 0 && idr->name[0] != 1)))
|
||||
{
|
||||
/*
|
||||
* Add this directory to the todo list.
|
||||
*/
|
||||
td = todo_idr;
|
||||
if( td != NULL )
|
||||
{
|
||||
while(td->next != NULL) td = td->next;
|
||||
td->next = (struct todo *) malloc(sizeof(*td));
|
||||
td = td->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
todo_idr = td = (struct todo *) malloc(sizeof(*td));
|
||||
}
|
||||
td->next = NULL;
|
||||
td->extent = isonum_733(idr->extent);
|
||||
td->length = isonum_733(idr->size);
|
||||
td->name = (char *) malloc(strlen(rootname)
|
||||
+ strlen(name_buf) + 2);
|
||||
strcpy(td->name, rootname);
|
||||
strcat(td->name, name_buf);
|
||||
strcat(td->name, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(testname, rootname);
|
||||
strcat(testname, name_buf);
|
||||
if(xtract && strcmp(xtract, testname) == 0)
|
||||
{
|
||||
extract_file(idr);
|
||||
}
|
||||
}
|
||||
if( do_find
|
||||
&& (idr->name_len[0] != 1
|
||||
|| (idr->name[0] != 0 && idr->name[0] != 1)))
|
||||
{
|
||||
strcpy(testname, rootname);
|
||||
strcat(testname, name_buf);
|
||||
printf("%s\n", testname);
|
||||
}
|
||||
if(do_listing)
|
||||
dump_stat();
|
||||
i += buffer[i];
|
||||
if (i > 2048 - sizeof(struct iso_directory_record)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "isoinfo -i filename [-l] [-R] [-x filename] [-f]\n");
|
||||
}
|
||||
|
||||
main(int argc, char * argv[]){
|
||||
char c;
|
||||
char buffer[2048];
|
||||
int nbyte;
|
||||
char * filename = NULL;
|
||||
int i,j;
|
||||
struct todo * td;
|
||||
struct iso_primary_descriptor ipd;
|
||||
struct iso_directory_record * idr;
|
||||
|
||||
if(argc < 2) return 0;
|
||||
while ((c = getopt(argc, argv, "i:Rlx:f")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
do_find++;
|
||||
break;
|
||||
case 'R':
|
||||
use_rock++;
|
||||
break;
|
||||
case 'l':
|
||||
do_listing++;
|
||||
break;
|
||||
case 'i':
|
||||
filename = optarg;
|
||||
break;
|
||||
case 'x':
|
||||
xtract = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( filename == NULL )
|
||||
{
|
||||
fprintf(stderr, "Error - file not specified\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
infile = fopen(filename,"rb");
|
||||
|
||||
if( infile == NULL )
|
||||
{
|
||||
fprintf(stderr,"Unable to open file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lseek(fileno(infile), 16<<11, 0);
|
||||
read(fileno(infile), &ipd, sizeof(ipd));
|
||||
|
||||
idr = (struct iso_directory_record *) &ipd.root_directory_record;
|
||||
|
||||
parse_dir("/", isonum_733(idr->extent), isonum_733(idr->size));
|
||||
td = todo_idr;
|
||||
while(td)
|
||||
{
|
||||
parse_dir(td->name, td->extent, td->length);
|
||||
td = td->next;
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
490
gnu/usr.bin/mkisofs/diag/isovfy.c
Normal file
490
gnu/usr.bin/mkisofs/diag/isovfy.c
Normal file
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* 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 (unsigned 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 !=isonum_733(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 !=isonum_733(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 0
|
||||
/* This is apparently legal. */
|
||||
if(size == 0 && extent) iline += sprintf(&lbuffer[iline],"****Extent!=0, size == 0", goof++);
|
||||
#endif
|
||||
|
||||
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((isonum_733(idr->extent)) << 11,
|
||||
isonum_733(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] = (char *) 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 */
|
||||
}
|
274
gnu/usr.bin/mkisofs/mkisofs.8
Normal file
274
gnu/usr.bin/mkisofs/mkisofs.8
Normal file
@ -0,0 +1,274 @@
|
||||
.\" -*- nroff -*-
|
||||
.TH MKISOFS 8 "January 1995" "Version 1.04"
|
||||
.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 \-L
|
||||
]
|
||||
[
|
||||
.B \-L
|
||||
]
|
||||
[
|
||||
.B \-V
|
||||
]
|
||||
[
|
||||
.B \-V
|
||||
.I volid
|
||||
]
|
||||
[
|
||||
.B \-i
|
||||
.I include-list
|
||||
]
|
||||
[
|
||||
.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
|
||||
Note that
|
||||
.B mkisofs
|
||||
is not designed to communicate with the writer directly. Most writers
|
||||
have proprietary command sets which vary from one manufacturer to
|
||||
another, and you need a specialized tool to actually burn the disk.
|
||||
The cdwrite utility that comes with mkisofs is capable of communicating
|
||||
with Phillips drives (newer versions of cdwrite should be available from
|
||||
Yggdrasil). Most writers come with some version of DOS software
|
||||
that allows a direct image copy of an iso9660 image to the writer.
|
||||
.PP
|
||||
Also you should know that most cd writers are very particular about timing.
|
||||
Once you start to burn a disc, you cannot let their buffer empty before you
|
||||
are done, or you will end up with a corrupt disc. Thus it is critical
|
||||
that you be able to maintain an uninterupted data stream to the writer
|
||||
for the entire time that the disc is being written.
|
||||
.PP
|
||||
.br
|
||||
.B path
|
||||
is the path of the directory tree to be copied into the iso9660 filesystem.
|
||||
.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 \-i include-list
|
||||
Use the specified file as a list of files to add to the directory tree.
|
||||
This is useful for quickly repacking a CD while adding files to it.
|
||||
The format of this file is path1/file=path2 where path1 is the directory
|
||||
in the ISO9660 file system where file should appear and path2 is the
|
||||
where to find the file.
|
||||
.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 \-L
|
||||
Allow filenames to begin with a period. Ususally, a leading dot is
|
||||
replaced with an underscore in order to maintain MS-DOS compatibility.
|
||||
.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 <eric@aib.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.
|
721
gnu/usr.bin/mkisofs/mkisofs.c
Normal file
721
gnu/usr.bin/mkisofs/mkisofs.c
Normal file
@ -0,0 +1,721 @@
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
|
||||
|
||||
#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.04";
|
||||
|
||||
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 */
|
||||
int allow_leading_dots = 0; /* DOS cannot read names with leading dots */
|
||||
|
||||
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] [-L] [-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 (!chars_before_dot && !allow_leading_dots) {
|
||||
/* DOS can't read files with dot first */
|
||||
chars_before_dot++;
|
||||
if (result) *result++ = '_'; /* Substitute underscore */
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef ADD_FILES
|
||||
|
||||
struct file_adds *root_file_adds = NULL;
|
||||
|
||||
void
|
||||
FDECL2(add_one_file, char *, addpath, char *, path )
|
||||
{
|
||||
char *cp;
|
||||
char *name;
|
||||
struct file_adds *f;
|
||||
struct file_adds *tmp;
|
||||
|
||||
f = root_file_adds;
|
||||
tmp = NULL;
|
||||
|
||||
name = rindex (addpath, PATH_SEPARATOR);
|
||||
if (name == NULL) {
|
||||
name = addpath;
|
||||
} else {
|
||||
name++;
|
||||
}
|
||||
|
||||
cp = strtok (addpath, SPATH_SEPARATOR);
|
||||
|
||||
while (cp != NULL && strcmp (name, cp)) {
|
||||
if (f == NULL) {
|
||||
root_file_adds = e_malloc (sizeof *root_file_adds);
|
||||
f=root_file_adds;
|
||||
f->name = NULL;
|
||||
f->child = NULL;
|
||||
f->next = NULL;
|
||||
f->add_count = 0;
|
||||
f->adds = NULL;
|
||||
f->used = 0;
|
||||
}
|
||||
if (f->child) {
|
||||
for (tmp = f->child; tmp->next != NULL; tmp =tmp->next) {
|
||||
if (strcmp (tmp->name, cp) == 0) {
|
||||
f = tmp;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
if (strcmp (tmp->name, cp) == 0) {
|
||||
f=tmp;
|
||||
goto next;
|
||||
}
|
||||
/* add a new node. */
|
||||
tmp->next = e_malloc (sizeof (*tmp->next));
|
||||
f=tmp->next;
|
||||
f->name = strdup (cp);
|
||||
f->child = NULL;
|
||||
f->next = NULL;
|
||||
f->add_count = 0;
|
||||
f->adds = NULL;
|
||||
f->used = 0;
|
||||
} else {
|
||||
/* no children. */
|
||||
f->child = e_malloc (sizeof (*f->child));
|
||||
f = f->child;
|
||||
f->name = strdup (cp);
|
||||
f->child = NULL;
|
||||
f->next = NULL;
|
||||
f->add_count = 0;
|
||||
f->adds = NULL;
|
||||
f->used = 0;
|
||||
|
||||
}
|
||||
next:
|
||||
cp = strtok (NULL, SPATH_SEPARATOR);
|
||||
}
|
||||
/* Now f if non-null points to where we should add things */
|
||||
if (f == NULL) {
|
||||
root_file_adds = e_malloc (sizeof *root_file_adds);
|
||||
f=root_file_adds;
|
||||
f->name = NULL;
|
||||
f->child = NULL;
|
||||
f->next = NULL;
|
||||
f->add_count = 0;
|
||||
f->adds = NULL;
|
||||
}
|
||||
|
||||
/* Now f really points to where we should add this name. */
|
||||
f->add_count++;
|
||||
f->adds = realloc (f->adds, sizeof (*f->adds)*f->add_count);
|
||||
f->adds[f->add_count-1].path = strdup (path);
|
||||
f->adds[f->add_count-1].name = strdup (name);
|
||||
}
|
||||
|
||||
void
|
||||
FDECL3(add_file_list, int, argc, char **,argv, int, ind)
|
||||
{
|
||||
char *ptr;
|
||||
char *dup_arg;
|
||||
|
||||
while (ind < argc) {
|
||||
dup_arg = strdup (argv[ind]);
|
||||
ptr = index (dup_arg,'=');
|
||||
if (ptr == NULL) {
|
||||
free (dup_arg);
|
||||
return;
|
||||
}
|
||||
*ptr = 0;
|
||||
ptr++;
|
||||
add_one_file (dup_arg, ptr);
|
||||
free (dup_arg);
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
void
|
||||
FDECL1(add_file, char *, filename)
|
||||
{
|
||||
char buff[1024];
|
||||
FILE *f;
|
||||
char *ptr;
|
||||
char *p2;
|
||||
int count=0;
|
||||
|
||||
if (strcmp (filename, "-") == 0) {
|
||||
f = stdin;
|
||||
} else {
|
||||
f = fopen (filename, "r");
|
||||
if (f == NULL) {
|
||||
perror ("fopen");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
while (fgets (buff, 1024, f)) {
|
||||
count++;
|
||||
ptr = buff;
|
||||
while (isspace (*ptr)) ptr++;
|
||||
if (*ptr==0) continue;
|
||||
if (*ptr=='#') continue;
|
||||
|
||||
if (ptr[strlen(ptr)-1]== '\n') ptr[strlen(ptr)-1]=0;
|
||||
p2 = index (ptr, '=');
|
||||
if (p2 == NULL) {
|
||||
fprintf (stderr, "Error in line %d: %s\n", count, buff);
|
||||
exit (1);
|
||||
}
|
||||
*p2 = 0;
|
||||
p2++;
|
||||
add_one_file (ptr, p2);
|
||||
}
|
||||
if (f != stdin) fclose (f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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;
|
||||
#ifdef ADD_FILES
|
||||
char *add_file_file = NULL;
|
||||
#endif
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Get the defaults from the .mkisofsrc file */
|
||||
read_rcfile(argv[0]);
|
||||
|
||||
outfile = NULL;
|
||||
while ((c = getopt(argc, argv, "i:o:V:RfvaTp:P:x:dDlLNzA:")) != 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 'L':
|
||||
allow_leading_dots++;
|
||||
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;
|
||||
case 'i':
|
||||
#ifdef ADD_FILES
|
||||
add_file_file = optarg;
|
||||
break;
|
||||
#endif
|
||||
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];
|
||||
|
||||
#ifdef ADD_FILES
|
||||
if (add_file_file) {
|
||||
add_file(add_file_file);
|
||||
}
|
||||
add_file_list (argc, argv, optind+1);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
263
gnu/usr.bin/mkisofs/mkisofs.h
Normal file
263
gnu/usr.bin/mkisofs/mkisofs.h
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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. */
|
||||
|
||||
/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
|
||||
|
||||
#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;
|
||||
char * whole_name;
|
||||
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;
|
||||
};
|
||||
|
||||
#ifdef ADD_FILES
|
||||
struct file_adds {
|
||||
char *name;
|
||||
struct file_adds *child;
|
||||
struct file_adds *next;
|
||||
int add_count;
|
||||
int used;
|
||||
struct dirent de;
|
||||
struct {
|
||||
char *path;
|
||||
char *name;
|
||||
} *adds;
|
||||
};
|
||||
extern struct file_adds *root_file_adds;
|
||||
|
||||
#endif
|
||||
|
||||
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++] = (cpnt == &symlink_buff[0] ? SL_ROOT : 0);
|
||||
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;
|
||||
}
|
1012
gnu/usr.bin/mkisofs/tree.c
Normal file
1012
gnu/usr.bin/mkisofs/tree.c
Normal file
File diff suppressed because it is too large
Load Diff
784
gnu/usr.bin/mkisofs/write.c
Normal file
784
gnu/usr.bin/mkisofs/write.c
Normal file
@ -0,0 +1,784 @@
|
||||
/*
|
||||
* 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->whole_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 {
|
||||
/*
|
||||
* This is for zero-length files. If we leave the extent 0,
|
||||
* then we get screwed, because many readers simply drop files
|
||||
* that have an extent of zero. Thus we leave the size 0,
|
||||
* and just assign the extent number.
|
||||
*/
|
||||
set_733(s_entry->isorec.extent, last_extent);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
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