--- /dev/null
+$Id: CHANGES,v 1.254 2004/07/07 13:34:06 stelian Exp $
+
+Changes between versions 0.4b36 and 0.4b37 (released July 7, 2004)
+==================================================================
+
+1. Added the --enable-staticz configure option which enables
+ dump and restore to be linked with static versions of
+ libz and libbz2 (and dynamic versions of all other libraries).
+ This will make Debian users happy, because libz and libbz2
+ were the only needed libraries living in /usr, all the
+ others live in /lib. In case of system emergency, it is
+ better not to have to rely on an extra filesystem.
+ Thanks to Bdale Garbee <bdale@gag.com> for the suggestion.
+
+2. Fix compilation on (at least the Linux Debian port to) AMD64.
+ (<ext2fs/ext2_types.h> defines some types (__s64 and __u64)
+ that are also defined by <linux/types.h> (<asm/types.h>) and
+ they conflict).
+
+3. Make dump's reading of the dumpdates file a bit more robust,
+ preventing dump from crashing when the dumpdates file has
+ been modified by hand.
+
+4. Fixed some offset calculations in dump code which could
+ lead to "bread lseek errors" on large filesystems. Thanks
+ to Bruce Lowekamp <lowekamp@users.sourceforge.net> for
+ reporting this bug and debugging the issue.
+
+5. Made dump use the blkid library when searching for devices
+ by label or uuid instead of dump's own routines.
+
+6. Corrected a bug in dump where a wrong LABEL=... line in
+ /etc/fstab could prevent dump from dumping unrelated
+ filesystems. Thanks to Bruce Lowekamp
+ <lowekamp@users.sourceforge.net> for reporting the bug.
+
+Changes between versions 0.4b35 and 0.4b36 (released April 21, 2004)
+====================================================================
+
+1. Fixed dump compilation with old gcc versions. Thanks to
+ Mike Castle <dalgoda@users.sourceforge.net> for the patch.
+
+2. Fixed some warnings (howmany, roundup, powerof2 redefined)
+ when compiling against a recent glibc version.
+
+3. Fixed a bug in restore preventing the read of a dump tape
+ written with Solaris 7 ufsdump. Thanks to Patrick Higgins
+ <phiggins@transzap.com> for reporting the bug and providing
+ the test case.
+
+4. Changed dump to enable the creation of volumes of different
+ sizes in a single run (make -B accept a list of values).
+ Patch contributed by Florian Zumbiehl <florz@gmx.de>.
+
+5. Use the glibc provided minor() and major() macros instead
+ of our own bitmask implementation. This should be safe for
+ when the major/minor namespace will migrate to 32 bits.
+ Thanks to Zhang Jun <zhangjun@nanjing-fnst.com> for reporting
+ the bug.
+
+6. Made explicit in the dump man page that dump will not create
+ a remote file, it will only write to an already existing one.
+
+7. Another try at making size estimates better again.
+
+8. Put back the inconditional running of the end-of-tape
+ script which was changed in 0.434 to be run only when -M
+ or multiple -f were NOT specified. Some users rely on this
+ feature even when it is combined with -M/-f.
+
+9. Fixed restore when restoring huge backups (where rstdir...
+ temporary files are over 2GB). Thanks to
+ Raphael Jaffey <rjaffey@artic.edu> for reporting this,
+ debugging the issue and making the patch.
+
+10. Made restore understand FreeBSD UFS2 tapes. Thanks to
+ David <vrtin@users.sourceforge.net> for submitting the bug
+ and providing a test case.
+
+11. Made dump work with an arbitrary integer level (no more 10
+ levels only limitation). Thanks to Matthew
+ <msvincen@midway.uchicago.edu> for the patch.
+
+Changes between versions 0.4b34 and 0.4b35 (released December 21, 2003)
+=======================================================================
+
+1. Added a note in the dump man page saying that the default
+ blocksize can be 32 if -d is used with a high density argument.
+ Thanks to Antonios Christofides <A.Christofides@itia.ntua.gr>
+ for the patch.
+
+2. Fixed configure to correctly understand CPPFLAGS, CFLAGS,
+ LDFLAGS environment variables. Thanks to Arcady Genkin
+ <antipode@users.sourceforge.net> for reporting the bug.
+
+3. Made -e/-E options of dump accept an unlimited number of inodes
+ to be excluded, rather than a hardcoded maximum. Thanks to
+ Dietrich Rothe <d-rothe@users.sourceforge.net> for the patch.
+
+4. Updated the autoconf system to 2.50. Forced the -D_BSD_SOURCE
+ and -D_USE_BSD_SIGNAL defines in configure in order to solve
+ 64bit build problems because quad_t is redifined with a
+ different signature. Thanks to Mike Harris <mharris@redhat.com>
+ for reporting this bug.
+
+5. Made restore build on Solaris, making possible to
+ restore Linux's "enhanced" tapes. Thanks to Uwe Gohlke
+ <uwe@ugsoft.de> for the patch.
+
+6. Made an extension in the dump tape format capable of saving
+ MacOSX specific inode extensions. Uwe Gohlke <uwe@ugsoft.de>
+ wrote the extension and contributed the restore code back
+ into this codebase. The same extension mechanism will be
+ used in the future to save ACLs...
+
+7. Made rmt work correctly with regard to QFA and local/remote
+ files and tapes. The remote access will however work only
+ when the dump provided rmt version is used. If you want to
+ use another rmt server, please do not use the QFA feature.
+ Thanks to Uwe Gohlke <uwe@ugsoft.de> for the patch.
+
+Changes between versions 0.4b33 and 0.4b34 (released April 18, 2003)
+====================================================================
+
+1. Fixed the INSTALL file to reflect the actual install paths.
+ Thanks to David Ronis <ronis@ronispc.chem.mcgill.ca> for
+ reporting the bug.
+
+2. Fixed the configure script to only check for headers presence
+ instead of trying to compile them. This should fix issues
+ with old build environments. Thanks to Kari Lempiainen
+ <kari@funky.pp.fi> for reporting the bug.
+
+3. Fixed restore to correctly ignore sockets when comparing
+ a dump (as socket cannot be properly restored anyway). Thanks
+ to Gunther Reiszig <gunther@mit.edu> for reporting the bug.
+
+4. Fixed restore to correctly access the archive file (-A argument)
+ even when using a remote tape. Thanks to Fabrice Bellet
+ <fabrice@bellet.info> for reporting the bug.
+
+5. Fixed (again) handling of long (largefile) seeks in rmt.
+ Thanks to Fabrice Bellet <fabrice@bellet.info> for reporting
+ the bug.
+
+6. Fixed restore corner case when dealing with large block sizes
+ dump is able to write now (-b 1024). Thanks to Fabrice Bellet
+ <fabrice@bellet.info> for reporting the bug.
+
+7. Fixed a bug preventing dump to access a filesystem having
+ a label exactly 16 bytes in length. Thanks to <minduni@ti-edu.ch>
+ for reporting the bug.
+
+8. Made dump store dump dates using explicit timezones, fixing a
+ problem with incremental dumps if the timezone is modified
+ between the dumps. Thanks to Philippe Troin <phil@fifi.org> for
+ the bug report and the patch.
+
+9. Fixed a bug encountered when dumping individual files (not full
+ filesystems or directories) and dangling symbolic links happen
+ to be in the list of files. For as far as dump is concerned,
+ dangling symbolic links are allowed, and are dumped as is.
+ Thanks to Jin-su Ahn <jsahn@ee.snu.ac.kr> for reporting the
+ bug and providing the fix.
+
+10. Fixed open and creation modes and permissions for QFA and
+ table-of-contents files in dump and restore. Thanks to
+ Philippe Troin <phil@fifi.org> for the patch.
+
+11. Fixed the archive file descriptor handling enabling it to be 0.
+ This can happen in some cases when shell redirections are used.
+ Thanks to Philippe Troin <phil@fifi.org> for the patch.
+
+12. Delayed the opening of archive file until after suid had been
+ dropped (fixing a possible security issue if dump is suid).
+ Thanks to Philippe Troin <phil@fifi.org> for the patch.
+
+13. Fixed the 'S' command handling in the rmt client part.
+ Thanks to Philippe Troin <phil@fifi.org> for the patch.
+
+14. Modified the end-of-tape script handling to print out statistics
+ (and stop the timer) before launching the eot script. Also, the eot
+ script does not get run anymore when using -M (which makes sense) or
+ when multiple tapes are listed on the command line
+ (-f tape0,tape1,tapen) (which also makes sense).
+ Thanks to Philippe Troin <phil@fifi.org> for the patch.
+
+15. Relicensed dump/restore under the 'revised' BSD license, as per
+ ftp://ftp.cs.berkeley.edu/ucb/4bsd/README.Impt.License.Change.
+
+16. Added LZO compression to dump. This new compression method has
+ the advantage of being super fast, thus not killing tape streaming
+ on slow machines. Thanks to Helmut Jarausch
+ <jarausch@igpm.rwth-aachen.de> for the patch and to
+ Markus Oberhumer <markus@oberhumer.com> for giving special permission
+ to include his miniLZO project (GPL licensed) in dump/restore.
+
+17. Some small buffer overruns fixes in rmt. Thanks to Antonomasia
+ <ant@notatla.demon.co.uk> for reporting the bugs.
+
+18. Added a special rmt version which can do encryption when writing
+ to tape. Read examples/encrypted_rmt/README for details on
+ how to enable and configure it. Thanks to Ken Lalonde
+ <ken@globalremit.com> for the patch.
+
+19. Made dump work with 2.5 kernel end of tape early warning semantics.
+ Thanks to Kai Makisara <Kai.Makisara@kolumbus.fi> for the patch.
+
+20. Fixed a bug which caused dump -w|-W not to work anymore, because
+ the fs_freq and fs_passno fields in /etc/mtab are always set
+ to 0 0. Thanks to Trent Piepho <xyzzy@speakeasy.org> for
+ reporting the bug.
+
+Changes between versions 0.4b32 and 0.4b33 (released February 10, 2003)
+=======================================================================
+
+1. Added a note in the restore man page clarifying the question
+ 'set the permissions on the current directory ?' asked by
+ restore at the end of treatment in -i and -x modes.
+
+2. Fixed the endianess issues when reading compressed tapes.
+ Thanks to Dark Force <daq4th@users.sourceforge.net> for
+ reporting this bug and providing test cases.
+
+3. Fixed the "ACL won't be dumped" warning message (which showed
+ an extra, unrelated error message). Thanks to Dragan Krnic
+ <dkrnic@lycos.com> for reporting this bug.
+
+4. Made dump look first into /etc/mtab, then into /etc/fstab
+ when searching for filesystem paths. Also fixed some problems
+ caused by binding mounts or multiple block device mounts.
+ Thanks to Matus Uhlar <uhlar@fantomas.sk>, Elliott Mitchell
+ <ehem@m5p.com>, Greg Edwards <gedwards@users.sourceforge.net>,
+ Brian Hoy <brian.hoy@opus.co.nz>. (fixes Debian bugs #147086
+ and #160305, Sourceforge bugs #618699 and #679832).
+
+5. Made dump's -I option accept the value '0' meaning all the
+ read errors will be ignored. This can be useful when running
+ dump from unattended sessions (like cron jobs). Thanks to
+ John I Wang <jiwang@users.sourceforge.net> for the suggestion.
+
+6. Fixed the output of dump to indicate 'blocks' instead of
+ 'tape blocks' in the various messages (blocks are always
+ 1 Kilobyte, tape blocks are 1 BK * '-b' argument), and
+ made it clearly print the current blocksize at the start of
+ a dump. Thanks to Michal Szymanski <msz@astrouw.edu.pl> for
+ the suggestions.
+
+7. Made rmt understand long (largefiles) seeks.
+
+8. Fixed build with very old versions of libext2fs, where
+ EXT2_FT_* constants were undefined.
+
+9. Made dump accept the dumpdates path on the command line
+ (-D file option) instead of using only the hardcoded one.
+ Thanks to Piete Brooks <pb22@users.sourceforge.net> for the
+ suggestion.
+
+10. Enabled rmt, LFS, readline, QFA options by default in
+ ./configure. Updated the configure process (new versions
+ of config.guess, config.sub etc).
+
+Changes between versions 0.4b31 and 0.4b32 (released November 15, 2002)
+=======================================================================
+
+1. Changed dump to use fcntl(F_SETLK) style locking instead
+ of flock() when locking the dumpdates file. With the old
+ locking scheme, a local user having read rights on the
+ dumpdates file could be able to do a Denial of Service attack
+ on dump. In order to lock the dumpdates file with the new
+ scheme, the user would need to have write access on the file.
+ Thanks to Richard Johnson <Richard.Johnson3@ey.com> for
+ reporting the bug (originally a bugtraq post).
+
+2. Fixed interactive 'ls' which caused spurious errors warnings
+ about 'undefined filetypes' detected. Thanks to Jorgen Ostling
+ <jorgen_ostling@users.sourceforge.net> for reporting this
+ bug.
+
+3. Fixed dump's estimate when dealing with sparse inodes.
+
+4. Modified dump to allow setting a blocksize bigger than 32kB
+ (raised the limit to 1024kB), because newer hardware needs
+ this for proper operation. Thanks to Dirk Traenapp
+ <dtraenapp@users.sourceforge.net> for reporting this.
+
+5. Fixed a bug causing Dump to stop and report an error if an
+ inode number in the exclude file was followed by some amount
+ of whitespace. Thanks to Jeffrey Sofferin
+ <sofferin@users.sourceforge.net> for reporting this bug.
+
+6. Fixed a bug which caused restore, in some particular cases,
+ to ask some 'scary' questions and leave a bunch of RSTTMP
+ directories behind when restoring incremental tapes. Thanks
+ to Philippe Troin <phil@fifi.org> for reporting this bug and
+ providing the test cases.
+
+7. Changed the wording when inodes are excluded from dump:
+ replaced 'Added inode 7 to exclude list' with
+ 'Excluding inode 7 (resize inode) from dump', as suggested
+ by Elliott Mitchell <ehem@m5p.com> in a Debian bug report.
+
+Changes between versions 0.4b30 and 0.4b31 (released July 30, 2002)
+===================================================================
+
+1. Fixed rmt open flags transmission (GNU's symbolic syntax over
+ rmt) which I broke in 0.4b29. Thanks to Eros Albertazzi
+ <eros@lamel.bo.cnr.it> for reporting the bug.
+
+Changes between versions 0.4b29 and 0.4b30 (released July 25, 2002)
+===================================================================
+
+1. Made dump print out the ext2 logical block number in case of a read
+ error, which can be given as an argument to debugfs' ncheck command,
+ in order to find out the affected inode. Added note about this
+ usage in dump's man page.
+
+2. Fixed a problem in restore when reading tapes written on big
+ endian machines with very old versions of dump. The patch was
+ contributed by George Helffrich <george@geology.bristol.ac.uk>.
+
+3. Fixed the tape length calculation when using large tapes
+ and compression. Thanks to Georg Lippold
+ <g_lippold@sourceforge.net> for reporting the bug.
+
+4. Added a new set of examples in dump_on_cd_2 directory, based
+ on dump_on_cd examples but somewhat enhanced, supporting DVD
+ media, and localized in english and german. Thanks to
+ Georg Lippold <g_lippold@sourceforge.net> for the new scripts.
+
+5. Made dump save 32 bit UID/GID. Internally, this was achieved
+ by switching from the old BSD inode format to the new BSD
+ inode format, which means that the tape format was changed.
+ However, since all restore versions out there should
+ transparently support both inode formats, the change should
+ have no side effects. Thanks to John Yu <jky@cs.bu.edu> for
+ reporting the bug.
+
+6. Fixed a lot of warnings in the code shown when compiling
+ with 'gcc -W'. Thanks to Matthias Andree
+ <matthias.andree@stud.uni-dortmund.de> for reporting this.
+
+7. Fixed a small markup bug in the dump man page. Thanks to
+ Eric S. Raymond <esr@minx.thyrsus.com> for submitting the
+ patch.
+
+8. Rewrote entirely the man pages using the tmac.an macro
+ package (Linux man page format) instead of the original BSD
+ format. They should be now cleaner and easier to modify.
+
+Changes between versions 0.4b28 and 0.4b29 (released June 8, 2002)
+==================================================================
+
+1. Fixed a problem in the rmt ioctl command, where ioctl's issued from
+ non Linux clients were misinterpreted. The description of the problem
+ (incompatible numbering in Linux mtio opcodes) is documented at
+ ftp://ftp.fokus.gmd.de/pub/unix/star/README.mtio . Thanks to
+ Jörg Schilling <schilling@fokus.gmd.de> for reporting this bug and
+ providing an excellent, cross-platform replacement for rmt in his
+ star package.
+
+2. Fixed a bug reported by Andy Mentges <amentges@jumpline.com>
+ which caused restore to fail when the inode maps were not entirely
+ contained on the first volume (when using really small volumes or
+ when dumping a huge number of inodes).
+
+3. Fixed a problem in dump, where files in subdirectories of directories
+ that have the nodump flag set (or being excluded with -e/-E) were
+ sometimes incorrectly dumped (instead of being excluded). The original
+ fix is from David C Lawrence <tale@dd.org> in the FreeBSD version
+ of dump: http://www.FreeBSD.org/cgi/query-pr.cgi?pr=32414
+ Thanks to Ted Grzesik <tedgyz@roostme.com> for reporting the bug and
+ help testing the patch.
+
+4. Added some example scripts from Gerd Bavendiek <bav@epost.de>
+ which makes one able to pipe the output of dump, by the net, to
+ a remote CD-burner server.
+
+5. Made dump use O_CREAT|O_TRUNC both locally and remotely (over rmt),
+ and use GNU's symbolic syntax over rmt instead of numerical values
+ to assure multiple platform compatibility.
+
+6. Documented the -d option in restore.
+
+7. Added a -v (verbose) mode to dump. For now it just prints the number
+ of the inode being dumped, but this could evolve in future versions
+ to include interesting debugging output.
+
+8. Added a -o flag to restore, which automatically restores the current
+ directory permissions in -i or -x mode, without asking the operator
+ whether to do so. Patch submitted by Tony Clayton <tonyc@e-smith.com>
+ and Peter Samuel <peters@e-smith.com>.
+
+Changes between versions 0.4b27 and 0.4b28 (released April 12, 2002)
+====================================================================
+
+1. Fixed a bug in the QFA feature which could have caused
+ a bad tape positionning on restore (causing extra delays in
+ restore). Credits go to Uwe Gohlke <uwe@ugsoft.de>.
+
+2. Added a small note in the dump man page specifying that
+ there should be no white space between the option letter and
+ the -j or -z parameter, thanks to Kenneth Porter <shiva@well.com>
+
+3. Made restore work with older versions of the readline library,
+ by checking in configure for several extended symbols. Restore
+ can now be compiled with a readline as old as the 2.0 release
+ (though it may be a good idea to upgrade it to a more recent
+ version...). Thanks to Andrew Donkin <ard@waikato.ac.nz> for
+ reporting the build failures.
+
+4. Fixed a performance problem with the QFA file creation in
+ dump, which made unnecessary seeks on the tape slowing down
+ the dump. Thanks to Andrew Donkin <ard@waikato.ac.nz> for
+ reporting this issue.
+
+5. Removed the inclusion of some kernel headers in the dump
+ source, which prevented the compile in some kernel/glibc
+ headers/architecture combination. Thanks to Bdale Garbee
+ <bdale@gag.com> for reporting the bug.
+
+6. Added the appropriate error message when dump fails to
+ open the output file for writing. Thanks to Amith Varghese
+ <amithv@yahoo.com> for reporting this bug.
+
+7. Made restore able to understand large Solaris ufsdump tapes
+ (containing inodes bigger than 4194304). Sun have introduced
+ an "extension" to the dump tape format when dealing with
+ those inodes, which was uncorrectly handled by Linux restore.
+ Thanks to Uwe Gohlke <uwe@ugsoft.de> for reporting the bug and
+ providing a test case.
+
+8. Added the -m parameter to dump which optimises the output for
+ inodes having been changed but not modified since the last dump
+ ('changed' and 'modified' have the meaning defined in stat(2)).
+ For those inodes, dump will save only the metadata, instead of
+ saving the entire inode contents. Inodes which are either
+ directories or have been modified since the last dump are saved
+ in a regular way. Uses of this flag must be consistent, meaning
+ that either every dump in an incremental dump set have the flag,
+ or no one has it.
+
+Changes between versions 0.4b26 and 0.4b27 (released February 15, 2002)
+=======================================================================
+
+1. Fixed behaviour of dump when exceeding resource limits
+ (SIGXFSZ treatment).
+
+2. Added the -L flag to restore to allow the user to specify a
+ maximal allowed number of miscompares when using restore
+ with the -C option to check the backup.
+
+3. Detailed the manual entry for the -N option of restore.
+
+4. Added the -a flag to restore to make able doing unattended
+ restores in -i or -x mode (automatically walks through the
+ multiple dump volumes).
+
+5. Extended the QFA mode to work with local files and/or
+ remote tapes and files. This way, restore can know in advance
+ the tape number and the offset for the inodes to extract and
+ can minimize the extraction time by seeking directly to the
+ good tape/offset.
+
+6. Added the -A <archive> option to both dump and restore,
+ which makes dump to archive a dump table-of-contents in
+ the specified file to be used by restore to determine
+ whether a file is in the dump file that is being restored.
+ (the archive file syntax is also compatible with the
+ Solaris ufsdump generated one).
+
+7. Small fix in restore making it able to read some (broken ?)
+ Solaris ufsdump tapes.
+
+8. Fixed dump to correctly recognise the root filesystem when using
+ ext2 disk labels (LABEL=/). Thanks to John Yu <jky@it.bu.edu>
+ for reporting this bug.
+
+9. Added the -P <file> option to restore to create a
+ Quick File Access file from an already made dump. Patch
+ contributed by Uwe Gohlke <uwe@ugsoft.de>.
+
+10. Made restore compile and run on Solaris, making it a
+ possible replacement for the standard ufsrestore. Port was
+ contributed by Uwe Gohlke <uwe@ugsoft.de>.
+
+Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002)
+=====================================================================
+
+1. Added a set of backup scripts from Eugenio Diaz
+ <getnito@yahoo.com> in the examples section. It features
+ automatic (cron based) full and incremental dumping of
+ several filesystems on a separate filesystem.
+
+2. Fixed a off-by-one miscalculation which disabled dumping
+ a one letter subdirectory. Thanks to Chris Siebenmann
+ <cks@utcc.utoronto.ca> for reporting the bug.
+
+3. Fixed several restore bugs occuring when trying to
+ restore some missing files on the tape. Thanks to Chris
+ Siebenmann <cks@utcc.utoronto.ca> for reporting the bug.
+
+4. Fixed --with-ldopts configure argument passing, installing from
+ a separate object directory, makefile cleanups contributed
+ by <splite@purdue.edu>.
+
+5. Fix a bug which could caused, in some conditions, the highest
+ number inode of a filesystem, to not be dumped. Many thanks
+ to Chris Siebenmann <cks@utcc.utoronto.ca> for helping me
+ chase this bug.
+
+Changes between versions 0.4b24 and 0.4b25 (released November 17, 2001)
+=======================================================================
+
+1. Added a mini howto from Patrick Walsh in the examples
+ directory.
+
+2. Minor man pages syntax corrections. Thanks to
+ Chris Danis <screechco@home.com> for reporting the bugs.
+
+3. Added a script from David B. Peterson <dave@toppledwagon.com>
+ to the examples section. It features dumping several
+ filesystems to a remote tape drive upon ssh.
+
+4. Added a patch provided by Richard Jones <rich@annexia.org>
+ which allows BRADEMAX (number of read errors tolerated by
+ dump) to be adjusted using the -I option.
+
+5. Fixed a bug which disabled doing "restore -C -f -". Thanks
+ to Clemens Stiglechner <a9401816@unet.univie.ac.at> for the
+ patch.
+
+6. Add the -l option to restore to specify if, when doing a
+ remote restore, the file used to access the backup is a
+ regular file (the defaults being a tape drive). Restore needs
+ to know this information when reading a remote compressed
+ dump. Previously, this information was autodetected, but
+ the autodetection code fails (with ioctl: Inappropriate ioctl
+ for device) when using a non Linux remote box. Thanks to
+ many users and especially to Eros Albertazzi
+ <eros@lamel.bo.cnr.it> for reporting this.
+
+7. Found a workaroung for the dump deadlock problem (3 childs
+ stuck in pause(), father in read()). The workaround seems
+ to work for me and several beta-testers. If it doesn't work
+ for you, please report back.
+
+8. Updated the RPM spec file (BuildPrereq, URL etc).
+
+Changes between versions 0.4b23 and 0.4b24 (released September 12, 2001)
+========================================================================
+
+1. Fixed the permissions of a newly created QFA file by dump.
+
+2. Cleaned up the source of dump (the external variables
+ definition was a complete mess, making possible to have
+ objects overlap).
+
+3. Fixed restore to use the full tape volume path when doing
+ a compare (since it changes the working directory to the
+ filesystem being compared in the process).
+
+4. Added the -q option to dump which makes dump abort
+ whenever it needs operator attention. It should be
+ easier to use dump in scripts with this option.
+
+5. Detect the use of incompatible options to dump and
+ refuse them (like -a and -B options together).
+
+6. Added bzip2 compression to dump/restore (use option -j level
+ to select it). Note that you will need a restore version
+ >= 0.4b24 in order to restore a bzip2 compressed dump.
+ The same warning as for the zlib compression applies:
+ the tape format of a bzip2 dump is not compatible with the
+ original BSD tape format.
+
+7. Fixed a overflow problem in dump corrupting the dump when
+ very large files were encountered. Thanks to Vladimir Nadvornik
+ for the bug report.
+
+8. Added a ioctl(BLKFLSBUF) in dump which should flush the
+ kernel buffer/page cache before starting the dump, helping
+ a bit those who use dump on mounted filesystems. Thanks to
+ John Yu <jky@it.bu.edu> and to Theodore T'so <tytso@mit.edu>
+ for this suggestion.
+
+9. Updated the RPM spec file following the RedHat changes
+ (dynamically linked binaries now in /usr/sbin etc).
+
+10. Added a patch from Helmut Jarausch <jarausch@igpm.rwth-aachen.de>
+ which enables restore to recognise multi volume compressed dumps
+ done on CD. Included his scripts for dump (which pipe the dump
+ output directly into cdrecord) and restore. There is now
+ possible to to backups to CD on the fly!
+
+Changes between versions 0.4b22 and 0.4b23 (released July 20, 2001)
+===================================================================
+
+1. Fixed a buffer overflow in restore/tape.c. Patch provided by
+ Marcus Meissner (Caldera International Security Dept.).
+
+2. Implement the Sun rmt extended protocol. Patch submitted
+ by Ian Gordon <iangordon@users.sourceforge.net>.
+
+3. Check for the e2fsprogs header <ext2fs/ext2_fs.h> instead of
+ the linux kernel header. This ensures that dump always has the
+ latest version of this file. Patch submitted by
+ Andreas Dilger <adilger@turbolinux.com>.
+
+4. Report any filesystem present in either /etc/fstab with a
+ positive passno or /etc/dumpdates in dump -w output.
+ Patch submitted by Andreas Dilger <adilger@turbolinux.com>.
+
+5. Fixed the looping problem in dump introduced in the
+ previous version.
+
+6. Changed the -B option of dump to limit the size of
+ _compressed_ output per volume if compression is on.
+ Patch contributed by Helmut Jarausch
+ <jarausch@igpm.rwth-aachen.de>. Note however that, since
+ it is impossible to predict the size of the compressed
+ data before doing the compression, the -B limit is a bit
+ conservative.
+
+7. Fixed a bug in reading the operator typed file/tape path for
+ the next volume in restore.
+
+8. Implemented a "-F script" option to restore which permits the
+ user to specify a script which will be launched at the
+ beginning of each tape, useful for automatic programming of
+ tape changers for example. See the restore man page for the
+ script parameters and return codes.
+
+9. Small fix for the QFA routines provided by Uwe Gohlke
+ <uwe@ugsoft.de>, and some recommendations for QFA uses in
+ the man pages.
+
+10. Fixed the multivolume restoring where making a mistake
+ to the 'Mount next tape' prompt caused several blocks to
+ be lost.
+
+11. Enhanced the -e option of dump to take as a parameter a
+ comma separated list of inode numbers.
+
+12. Added the -E option to dump which specify a file containing
+ inode numbers to exclude from the dump.
+
+13. Fixed the compressed multi-volume dump + restore.
+
+Changes between versions 0.4b21 and 0.4b22 (released May 12, 2001)
+==================================================================
+
+1. Made dump report the number of blocks dumped per volume.
+ Thanks to Kenneth Porter <shiva@well.com> for the suggestion.
+
+2. Fix a bug in dump where waiting too much at the 'change volumes'
+ question caused the volume to be rewritten. Thanks to
+ Graham Reed <greed@users.sourceforge.net> for reporting the
+ bug and providing a patch.
+
+3. Added a compression option to dump, contributed by Jerry
+ Peters <gapeters@worldnet.att.net>.
+
+ WARNING: the compression works only on files/pipes and
+ drives supporting variable block size.
+
+ WARNING2: tapes created using the compression feature are
+ incompatible with the standard dump tape format, and a
+ version of restore >= 0.4b22 will be needed for extraction.
+
+4. Fixed some compilation problems for glibc 2.2.2 and 64 bit
+ architectures. Thanks to Paul Slootman <paul@debian.org> for
+ the patch and to Bdale Garbee <bdale@gag.com> for forwarding
+ it upstream.
+
+5. Many cleanups (CPP defines, const char warnings, check of
+ ext2fs COMPAT flags, time_t cleanups, added libext2 version
+ in dump usage text) by Andreas Dilger <adilger@turbolinux.com>.
+
+6. Made --prefix option work in configure. All the install path
+ are now based on the configure parameters.
+
+7. Added the Quick File Access mode in dump/restore, contributed
+ by Uwe Gohlke <uwe@ugsoft.de>. In this mode, dump stores in
+ a file tape position for each inode, and this file is used by
+ restore (if called with parameter Q and the filename)
+ to directly position the tape at the file restore is currently
+ working on. This saves hours when restoring single files from
+ large backups, saves the tapes and the drive's head. Use
+ --enable-qfa option of configure to compile in the QFA support.
+
+8. Added the possibility to dump several files and directories
+ in a single invocation of dump. Thanks to Uwe Gohlke
+ <uwe@ugsoft.de> for implementing this option.
+
+9. Fixed the dumping and restoring of files with holes
+ (files ending with holes didn't get dumped or restored
+ correctly).
+
+10. Fixed a socket descriptor leak in dump, which leaved opened
+ 3 file descriptors per dump process (and there is one dump
+ process per tape).
+
+11. Fixed dump large file system support, by explicit use of
+ open64/lseek64/etc functions (explicit use needed because
+ e2fsprogs libraries don't behave well when compiled with
+ FILE_OFFSET_BITS=64).
+
+Changes between versions 0.4b20 and 0.4b21 (released January 13, 2001)
+======================================================================
+
+1. Fixed some bugs in the dump -w|-W logic introduced by
+ the previous version. Thanks to Andreas Dilger
+ <adilger@turbolinux.com> for his help on this one.
+
+2. Fixed again a compilation problem when using old e2fs
+ headers (filesystem label related). Thanks to many users
+ who reported this stupid error.
+
+3. Fixed a build problem on old lib5 based systems dealing with
+ _PATH_MNTTAB being undefined. Thanks to John Adams
+ <johna@onevista.com> for reporting the bug.
+
+4. Improved the error detection in restore when creating
+ the temporary files in TMPDIR. Now restore will corectly
+ report a 'no space left on device' error instead of
+ strange errors which could imply an archive corruption.
+ Thanks to Gabriel Somlo <somlo@cs.colostate.edu> and
+ bgjenero <bgjenero@sympatico.ca> for reporting the bug.
+
+5. Added the throughput information in dump's progression
+ messages. Thanks to Andreas Dilger <adilger@turbolinux.com>
+ for the patch.
+
+6. Use libext2fs's inode scanning routines, which are particularly
+ robust when dealing with errors (especially when having some
+ bad blocks on the filesystem). Many thanks to Colin
+ <colin@horizon.com> for reporting the bug, investigating
+ the issues, finding a workaround, writing the patch and
+ fully testing it... (of course, if this patch will break
+ anything, he is to blame for :-)).
+
+7. Made dump and restore LFS aware. Dump can dump a filesystem
+ containing large files, generate a large file on output and
+ restore can restore them. This feature is not enabled by
+ default, use --enable-largefile option of configure to enable
+ it (you need to have a LFS aware glibc though). Thanks to
+ Andrea Arcangeli <andrea@suse.de> for submitting the patch,
+ and to Theodore T'so <tytso@valinux.com> for his always
+ useful thoughts.
+
+8. Made dump ask upon a tape write error if it should rewrite
+ the current volume (assume this is a bad tape) or if it should
+ assume an end-of-tape condition (useful for tape drives which
+ behaves badly at the end of the tape). Thanks to Andreas
+ Dilger <adilger@turbolinux.com> for the suggestion.
+
+Changes between versions 0.4b19 and 0.4b20 (released November 10, 2000)
+=======================================================================
+
+1. Fixed a small compilation problem due to a change
+ in the definintion of the struct sigaction in
+ glibc 2.0 / libc5. Thanks to Gunther Schlegel
+ <schlegel@riege.de> for reporting the bug and to
+ Dave Platt <dplatt@snulbug.mtview.ca.us> for suggesting
+ a fix.
+
+2. Modified the label and uuid analysis in order to be
+ self-contained (independant of kernel/libc headers). This
+ should fix the compile with older kernel/libc headers and
+ will preserve the functionality. Thanks to Bernhard Erdmann
+ <bernhard.erdmann@gmx.de> for reporting the bug.
+
+3. The 'exclude inode' option, if applied to a directory
+ inode, excludes now correctly all the leaves of this
+ directory. Thanks to John R. Dennison
+ <gerdesas@users.sourceforge.net> for reporting the bug.
+
+4. Fixed the '-e' option to disable the possibility
+ to exclude the root inode (which causes the dumps to
+ be unreadable by restore). Prevented array overflow
+ when multiple -e options are used.
+
+5. Fixed dump to correctly interpret a filesystem argument
+ which is a mountpoint and it is not an absolute path
+ (as specified in the fstab). Thanks to Bernhard R. Erdmann
+ <be@berdmann.de> for reporting the bug.
+
+6. Made dump able to backup files larger than 2 GB. Note that
+ dump still doesn't cope with files larger than 4 GB.
+
+7. Restore the real uid and gid before invoking an external
+ RSH program (big hole when dump or restore is suid root!).
+
+8. Get the values for the default tape device and the location
+ of fstab file from the system headers. Thanks to
+ Andreas Dilger <adilger@turbolinux.com> for the patch.
+
+9. Made dump -w|-W report all recognized filesystems
+ present in either /etc/fstab or /etc/dumpdates, and present
+ the list in the same order as in fstab file. Thanks
+ to Andreas Dilger <adilger@turbolinux.com> for the patch.
+
+10. Made dump's -a (automatic end of tape detection) the
+ default. Specifying one of -B, -c, -d or -s options will
+ override the EOM detection. Thanks to Andreas Dilger
+ <adilger@turbolinux.com> for the patch.
+
+11. Save the ext2 filesystem label into the dump volume label.
+ Specifying a volume label on the command line (-L option)
+ will override this feature. Thanks to Andreas Dilger
+ <adilger@turbolinux.com> for the patch.
+
+Changes between versions 0.4b18 and 0.4b19 (released August 20, 2000)
+=====================================================================
+
+1. Fixed the signal handling in dump (which I broke in 0.4b17)
+ which was causing several strange dump failures (dump
+ hanged or segmentation faults etc).
+
+2. Specified the default blocksize in the dump man page.
+
+3. Changed two info messages of restore to be written on stdout
+ instead of stderr in order to leave stderr only for errors
+ or warnings. Thanks to Stephen Atwell
+ <satwell@urbana.css.mot.com> for the suggestion.
+
+4. Corrected an off by one calculation which prevented
+ dumping a directory having a 1 character name length.
+ Thanks to Bernhard Erdmann <bernhard.erdmann@gmx.de>
+ for reporting the bug.
+
+5. Reinforce dump in order to allow only level 0 and no
+ -u option when dumping a subdirectory, and document
+ this in the man page. Thanks to Bernhard Erdmann
+ <bernhard.erdmann@gmx.de> for reporting the bug.
+
+6. Fixed a small harmless bug in restore which caused
+ in some conditions hard links to be restored several
+ times (therefore generation some warning messages).
+ Thanks to Kenneth Porter <shiva@well.com> for
+ reporting the bug.
+
+7. Updated the RPM spec file to the latest RedHat version,
+ providing FHS packaging and other cosmetic changes.
+ You will need RPM version >= 3.0.5 in order to build the RPM.
+
+8. Updated the configure script to check for libtermcap
+ before checking for libreadline, because we need this
+ library in order to compile the readline support.
+
+9. Made dump understand the LABEL= and UUID= notation
+ both in /etc/fstab and on the command line. Note that
+ you will need the /proc filesystem in order to use
+ these notations. Thanks to Erik Troan <ewt@redhat.com>
+ for providing the patch.
+
+Changes between versions 0.4b17 and 0.4b18 (released June 30, 2000)
+===================================================================
+
+1. Fixed a potential buffer overflow in restore. Thanks
+ to Stan Bubrouski <satan@fastdial.net> for reporting
+ the bug.
+
+2. Fixed a readline-related bug which prevented
+ 'cat DUMPFILE | restore -i -f -' from working. Thanks
+ to Charles Karney <karney@users.sourceforge.net>
+ for the bug report.
+
+3. Changed a few "panic" into "exit", causing restore to
+ be more stable against some attacks (like the last one
+ reported on Bugtraq, although the last version of restore
+ was not vulnerable - just dumped core). Thanks to
+ Andreas Hasenack <andreas@conectiva.com.br> for reporting
+ the bugs to me.
+
+4. Removed the suid-root bit on dump and restore in the
+ default build (and generated RPMs). It should be safer
+ now. Users who need the suid-root capabilities in order
+ to make network backups should read first the man page
+ of dump and enable the suid bit manually.
+
+5. Added -ltermcap to the compile parameters for restore
+ when using readline support, in order to make the compile
+ process work on some systems (SuSE ?). Thanks to
+ Patrik Schindler <poc@pocnet.net> for reporting the bug.
+
+Changes between versions 0.4b16 and 0.4b17 (released June 1st, 2000)
+====================================================================
+
+1. The -F script is called now *only* at the end of a tape,
+ not at the end of the dump. Thanks to Christian Haul
+ <haul@informatik.tu-darmstadt.de> for the bug report.
+
+ Normally, the device name and the current volume number
+ are passed on the command line of the script. However,
+ if you want the old style script (with no arguments
+ passed on the command line), you can enable it in
+ configure with the --enable-oldstylefscript.
+
+2. Use posix signal handling to preserve dump functionality
+ with libc5. Thanks to Jeff Johnson <jbj@redhat.com> for
+ the patch.
+
+3. Made the exit code of restore in case of a 'C'ompare
+ command reflect the result of the compare. An exit status
+ of 0 means the dump archive is correct, 1 means tape errors,
+ 2 means that some files were modified. Thanks to Kenneth Porter
+ <shiva@well.com> for the suggestion.
+
+4. Made (finally) quotes work in interactive restore.
+
+5. Small fixes in order to allow dump to compile with a
+ really old e2fsprogs version. Thanks to Ian Zimmerman
+ <itz@speakeasy.org> for the bug report.
+
+6. Add GNU readline capabilities to interactive restore.
+ Use configure's --enable-readline flag to enable this feature.
+ Thanks to Patrik Schindler <poc@pocnet.net> for the
+ suggestion.
+
+7. Do the compare on the fly in restore 'C' mode (this will
+ allow not to exhaust the available /tmp space when
+ ccmparing large files). Thanks to Kenneth Porter
+ <shiva@well.com> for the suggestion.
+
+Changes between versions 0.4b15 and 0.4b16 (released March 11, 2000)
+====================================================================
+
+1. Fixed some several duplicate 'DUMP: DUMP:' in the
+ output of dump.
+
+2. Corrected the estimation of blocks to dump. Note that
+ this is still wrong for large directory inodes, due
+ to the size of a BSD directory entry on the tape
+ (estimation is based on the size of the ext2 directory,
+ which is smaller because it doesn't contain the null
+ character at the end).
+
+3. Made dump report the total number of MB written to
+ tape at the end of run. Thanks to W. Reilly Cooley
+ <wcooley@nakedape.cc> for the patch.
+
+4. Added the -X option to restore giving the possibility
+ to read the names of the files to be extracted/listed
+ from a text file (in addition of the command line).
+ Thanks to Dejan Muhamedagic <dejan@quant-x.com> for the
+ patch.
+
+5. Added the device name and the current volume number
+ as arguments to the end of tape script (dump -F option).
+
+6. Made the multi-volume dump work again (after having
+ broken it in 0.4b15).
+
+Changes between versions 0.4b14 and 0.4b15 (released March 2, 2000)
+===================================================================
+
+1. Added a prompt command in interactive restore mode. Thanks
+ to Andreas Dilger <adilger@home.com> for the patch.
+
+2. Fixed a buffer overflow problem in dump (caused by
+ not checking the size of the filesystem parameter).
+ Thanks to Kim Yong-jun <loveyou@hackerslab.org> for
+ reporting this on Bugtraq (and to several dump users
+ who forwarded me his mail).
+
+3. Added the '-F script' option to dump in order to
+ launch a script at the end of each tape (to be used
+ with a tape changer, or to notify the sysadmin by
+ pager etc.).
+
+4. Fixed a bug in restore compare code caused by the changes
+ I made in 0.4b14.
+
+5. Fixed the treatment of options using the old BSD syntax
+ in both dump and restore.
+
+Changes between versions 0.4b13 and 0.4b14 (released February 10, 2000)
+=======================================================================
+
+1. Fixed a bug in dump which may have caused invalid deleted
+ directories to be dumped out if they were deleted after the
+ mapping pass. This could occure on active filesystem and lead
+ to heap corruption (causing dump malfunction in many possible ways).
+ Thanks to Jan Sanislo <oystr@cs.washington.edu> for finding this
+ bug and submitting the patch.
+
+2. Fixed the handling of the filesystem parameter in dump. A
+ '/mnt/disk' parameter caused the disk contents to be dumped,
+ but a '/mnt/disk/' parameter caused the mountpoint directory
+ to be dumped (generally an empty directory).
+
+3. Improved the output of dump in order to tell which directory
+ it is currently dumping (when dumping a subtree).
+
+4. Added the '-e' exclude inode option to dump. Thanks to
+ Isaac Chuang <ike@isl.stanford.edu> for contributing with the patch.
+
+5. Added a REPORTING-BUGS file in order to provide a guide
+ on how to correctly report a bug in dump/restore.
+
+6. Fixed a restore problem when restoring a hard link to an inode
+ having the immutable or append-only attribute set. Thanks to
+ Ambrose Li <acli@mingpaoxpress.com> for submitting the patch.
+
+7. Fixed a compatibility problem between dumps made on little
+ endian machines (the format was correct) and big endian
+ machines (the format was incorrect). This fix break the
+ compatibility with the older dumps made on big endian
+ machines (sparc, m86k, ppc etc). For the first time in
+ linux dump's history (I believe), the dumps made by *BSD,
+ Linux/alpha, Linux/sparc and Linux/x86 are compatible,
+ so interchangeable. Thanks to Rob Cermak
+ <cermak@ahab.rutgers.edu> for submitting the bug and
+ helping me test the fix.
+
+8. Fixed the way dump reports the remaining percent/time, if
+ the number of blocks actually dumped exceeds the estimated
+ number of blocks. Thanks to Jean-Paul van der Jagt
+ <jeanpaul@dutepp0.et.tudelft.nl> for reporting the bug.
+
+Changes between versions 0.4b12 and 0.4b13 (released January 21, 2000)
+======================================================================
+
+1. Small Y2K fix in the man pages :). Thanks to Bernhard Sadlowski
+ <sadlowsk@Mathematik.Uni-Bielefeld.DE> for reporting the bug.
+
+2. Removed the requirement to build the RPM as root from the
+ spec file. Thanks to Christian Weisgerber
+ <naddy@mips.rhein-neckar.de> for submitting this.
+
+3. Fixed a bug in dump related to the 'filetype' feature of ext2fs,
+ causing dump to block when dumping really huge filesystems.
+ Many thanks to Patrik Schindler <poc@pocnet.net> for
+ helping me find this bug.
+
+4. Fixed the treatment for an interrupt signal when dump access
+ the remote tape through RSH. Thanks to Christian Weisgerber
+ <naddy@mips.rhein-neckar.de> for providing the patch.
+
+5. Fixed a bug which was causing dump/restore to display
+ garbage characters instead of the remote host name.
+
+Changes between versions 0.4b11 and 0.4b12 (released January 8, 2000)
+=====================================================================
+
+1. Small fix in the dump man page. Thanks to Thorsten Kukuk
+ <kukuk@suse.de> for submitting the patch.
+
+2. Fix for the exit code when using the size estimate option of
+ dump. Thanks to Matti Taskinen <mkt@rni.helsinki.fi> for
+ submitting the patch.
+
+3. Handle EINTR in atomical reads/writes in dump, which was causing
+ dump to fail on some systems. Thanks to Eric Jergensen
+ <eric@dvns.com> for reporting the bug and submitting the patch.
+
+4. Handle more than 16 characters for the device names in dumpdates.
+ (up to 255 now). Thanks to Rainer Clasen <bj@ncc.cicely.de> for
+ tracking down the problem and proposing the solution.
+
+5. Fixed a bug in dump which prevented the creation of the
+ dumpdates file when doing a 0-level dump without already
+ having a dumpdates file. Thanks to Patrik Schindler
+ <poc@pocnet.net> for reporting the bug.
+
+6. Changed the way dump 'S' flag reports the size estimate
+ from number of blocks into bytes (making it compatible
+ with the Solaris version, and simplifying things for
+ amanda users). Thanks to Jason L Tibbitts III
+ <tibbs@math.uh.edu> for reporting the bug.
+
+7. Fixed a compatibility problem in linux/alpha dump tape format.
+ Now the linux/alpha dump are (again) compatible with the
+ other dump formats. But this breaks compatibility with
+ older dumps made on alpha. Thanks to Mike Tibor
+ <tibor@lib.uaa.alaska.edu> for helping me in finding this bug.
+
+Changes between versions 0.4b10 and 0.4b11 (released December 5, 1999)
+======================================================================
+
+1. Added a '--enable-kerberos' to configure.
+
+2. Added a 'S' option to dump which determines the amount of space
+ that is needed to perform the dump without actually doing it, similar
+ to the Sun's ufsdump 'S' option. Patch contributed by Rob Cermak
+ <cermak@ahab.rutgers.edu>.
+
+3. Added a 'M' multi-volume option to dump and restore which enables
+ dumping to multiple files (useful when dumping to an ext2
+ partition to make several dump files in order to bypass the 2GB
+ file size limitation). The 'f' argument is treated as a prefix and
+ the output files will be named <prefix>001, <prefix>002 etc. With
+ the 'M' flag, restore automatically selects the right file without
+ asking to enter a new tape each time.
+
+4. Fixed a memory leak which was causing dump to grow very big
+ (270MB when dumping a 10GB filesystem...). Thanks to Jason
+ Fearon <jasonf@netrider.org.au> for reporting the bug.
+
+Changes between versions 0.4b9 and 0.4b10 (released November 21, 1999)
+======================================================================
+
+1. Make configure test if the system glob routines support
+ extended syntax (ALTDIRFUNC). If not, use the internal glob
+ routines instead of system ones. Thanks to Bernhard Sadlowski
+ <sadlowsk@Mathematik.Uni-Bielefeld.DE> for reporting the bug
+ and helping me resolve this and other minor libc5 compiling
+ glitches.
+
+2. Fix a problem when dumping a ext2fs with the 'filetype'
+ feature enabled. Thanks to Patrick J. LoPresti
+ <patl@cag.lcs.mit.edu> for reporting the bug and to
+ Theodore Y. Ts'o <tytso@mit.edu> for providing the patch.
+
+3. Made the nodump flag work on directories. A directory which
+ has the nodump flag gets never dumped, regardless of its
+ contents.
+
+4. Integrate a patch from Jeremy Fitzhardinge <jeremy@goop.org>
+ which allows dump on an active ext3 filesystem. However, this
+ is a "quick and dirty" patch which enables backup of an ext3
+ filesystem through the ext2 compatibility (by ignoring the
+ NEEDS_RECOVERY bit). The journal file is not recognized and
+ it is dumped (it should not).
+
+5. Test the superblock compatibility flags when dumping, in order
+ to be sure that we know how to deal with specific features.
+
+Changes between versions 0.4b8 and 0.4b9 (released November 5, 1999)
+====================================================================
+
+1. Use lchown instead of chown, fixing a possible security problem
+ when restoring symlinks (a malicious user could use this
+ to deliberately corrupt the ownership of important system files).
+ Thanks to Chris Siebenmann <cks@utcc.utoronto.ca> for detecting
+ this and providing the patch.
+
+Changes between versions 0.4b7 and 0.4b8 (released November 3, 1999)
+====================================================================
+
+1. Put dump sources under CVS, added Id tags in all files so
+ one can use 'ident' on binary files.
+
+2. Added the dump/restore version in the usage text so one can
+ easily verify the version he is using.
+
+3. Small patch from Nuno Oliveira <nuno@eq.uc.pt> which fixes
+ a va_start/va_end problem on linux-ppc (always call va_start
+ va_end in pairs each time we use a vararg function).
+
+4. Added again the DT_* constants because old libc does not
+ contain them :(. Thanks to Eric Maisonobe <virnet@nat.fr>
+ for submitting the bug report.
+
+5. Use ext2fs_llseek instead of llseek. With recent e2fsprogs
+ this should enable dumping big (huge) filesystems.
+
+6. Added the RSH environment variable in order to be able to
+ use a rsh replacement like ssh when doing remote backups (and
+ bypass the security limitations of rcmd). Now you can do remote
+ backups without being root (or making dump setuid root).
+
+7. Modified again the way dumpdates works. For incremental dumps,
+ we need to read dumpdates even if we are not using 'u' option.
+ Thanks to Bdale Garbee <bdale@gag.com> for his ideas on how
+ this should work.
+
+Changes between versions 0.4b6 and 0.4b7 (released October 8, 1999)
+===================================================================
+
+1. Removed the 'k' flag from the restore 'about' text if kerberos
+ was not compiled in.
+
+2. Prototyped (f)setflags from e2fsprogs and corrected the calls
+ to them (fsetflags takes a char*, setflags an open fd!).
+
+3. (f)setflags is called only if the flags aren't empty. If the
+ file is a special file, a warning is printed, because changing
+ flags implies opening the device. Normally, a special file
+ should not have any flag... (Debian bug #29775, patch provided
+ by Abhijit Dasgupta <abhijit@ans.net>).
+
+4. Made possible to dump a file system not mentioned in /etc/fstab.
+ (Debian bug #11904, patch provided by Eirik Fuller <eirik@netcom.com>).
+
+5. Changed the default behaviour to not create dumpdates
+ unless 'u' option is specified. Removed the old "debian-patch"
+ which provided the same thing. (Debian bug #38136, #33818).
+
+6. Removed all those dump*announce, since they were getting old...
+
+7. Added warning messages if dumpdates does not exist and
+ when an inferior level dump does not exist (except for a level 0
+ dump).
+
+8. Debugged the glob calls in interactive mode: restore used a
+ dirent struct which was different from the /usr/include/dirent.h
+ one (this used to work, is it a glibc2 change?), so none of the
+ compat glob (which used /usr/include/dirent.h) or the system glob
+ worked. Restore use now the system dirent (and the system
+ DT_* constants), which are compatible with BSD ones.
+
+9. Added a configure flag (--with-dumpdatespath) to specify
+ the location of dumpdates file. By default, it is
+ /etc/dumpdates.
+
+10. Added the "AUTHOR" and "AVAILABILITY" sections and
+ included the current date/version in man pages.
+
+11. Corrected the estimation of remaining time when
+ the operator doesn't change the tapes quickly enough. This
+ was an old bug, I thought I corrected it, and discovered
+ that in fact it was corrected in two different places, so
+ the results canceled each other...
+
+Changes between versions 0.4b5 and 0.4b6 (released October 1, 1999)
+===================================================================
+
+1. Integrated multiple patches from RedHat, Debian and SuSE:
+
+ - tweak dump/itime.c to not try to read dumpdates if the 'u' option
+ isn't specified.
+ - several fixes in the man pages.
+ - update the default tape device to /dev/st0.
+ - many updates for Linux Alpha (byte ordering, size_t etc).
+ - buffer overruns.
+ - use environment variable for TMPDIR (instead of /tmp).
+ - use sigjmp_buf instead of jmp_buf (RedHat bug #3260).
+ - workaround egcs bug (RedHat bugs #4281 and #2989).
+ - wire $(OPT) throughout Makefile's.
+
+2. Upgrade the dump revision to 1, making possible to dump filesystems
+ made with e2fsprogs-1.15 or newer. Nothing seems to break...
+
+3. Fix some compile warnings, prototype all functions.
+
+4. Use glibc err/glob instead of internal compatibility
+ routines (only if available).
+
+5. Fix a compile error on Linux 2.2.7 / libc5 (5.4.44) (patch provided
+ by Bernhard Sadlowski <sadlowsk@mathematik.uni-bielefeld.de>).
+
+Changes between versions 0.4b4 and 0.4b5 (released September 22, 1999)
+======================================================================
+
+1. Integrated the changes from FreeBSD-3.1-RELEASE
+ (mostly bug fixes, buffer overruns, dump has now an "automatic
+ tape length calculation" flag, dump/restore can use kerberos now
+ (this is NOT tested), use environment variables for TAPE and
+ RMT etc.).
+
+2. Integrated three RedHat patches ("glibc", "kernel" and "bread" patches)
+
+3. Corrected a bug in restore when using 'C' option with multi-volumes
+ tapes (files splited accros two tapes give "size changed" errors
+ when comparing).
+
+4. Corrected the long standing bug when dumping multiple tapes.
+ This works for me, needs further testing.
+
+Changes between versions 0.4b3 and 0.4b4 (released January 17, 1997)
+====================================================================
+
+1. Dump now runs correctly on kernels 2.1.x
+ Fix made by Gerald Peters <gapeters@worldnet.att.net>
+
+Changes between versions 0.4b2 and 0.4b3
+========================================
+
+1. Use realpath() if available
+
+2. Report statistics
+
+Changes between versions 0.4b1 and 0.4b2
+========================================
+
+1. Fixed the bug fix from Greg Lutz (I had made a mistake when integrating
+ the patch)
+
+2. Fixed restore to make it able to read FreeBSD 2.x dumps again
+
+3. Fixed configure.in to correctly handle --enable-rmt
+
+Changes between versions 0.3 and 0.4b1
+======================================
+
+1. Integrated the changes from 4.4BSD-Lite2
+
+2. Integrated the patches from Debian and Red Hat
+
+3. Portability changes: use the __u32, __u16, __s32, and __s16 types
+
+4. Changed dump to use the Ext2fs library to get block addresses. This
+ should solve the endianness problem on SparcLinux.
+
+5. Created a configure.in file (shamelessly stolen from the e2fsprogs
+ distribution's one) to use autoconf
+
+6. Fixed a few minor bugs
+
+Changes between versions 0.2e and 0.2f
+======================================
+
+1. Added the creation of named pipes (fifos) in restore.
+
+2. Added the -N flag in the restore manual page.
+
+3. Added the file kernel.patch which contains the llseek() optimization
+ patch for 1.2.x kernels.
+
+4. Fixed a bug in the restoration of symbolic links: owner and group were
+ not restored.
+
+5. Integrated some changes from FreeBSD 2.2.
+
+6. Added a call to ftruncate() after restoring each file to restore
+ correctly files ending by a hole.
+
+Changes between versions 0.2d and 0.2e
+======================================
+
+1. Fixed a bug in the "set owner/mode" process. Every file was restored
+ with owner = root (0) and group = root/wheel/whatever (0).
+
+Changes between versions 0.2c and 0.2d
+======================================
+
+1. Dump is now able to backup 2GB+ filesystems.
+
+2. Dump and restore can now be linked as static binaries.
+
+Changes between versions 0.2b and 0.2c
+======================================
+
+1. Fixed a bug when dumping ``slow'' (i.e. normal) symbolic links.
+
+Changes between versions 0.2a and 0.2b
+======================================
+
+1. Really fixed the bug that I should have corrected in 0.2a.
+
+2. Enabled optimization again.
+
+Changes between versions 0.2 and 0.2a
+=====================================
+
+1. Disabled the optimization during compilation.
+
+Changes between versions 0.1 and 0.2
+====================================
+
+1. Fixed a bug in fstab.c which caused a null pointer to be stored in
+ the fs_type field (actually, I modified the file fstab.c to make it
+ use the mntent functions).
+
+2. Dump and restore now use a 4.3 BSD compatible dump format. Backups
+ made by dump should be readable by the BSD restore and backups made
+ by the BSD dump should be readable by restore. Unfortunately, this
+ means that the dump format has changed between version 0.1 and version
+ 0.2 :-(
+
+3. Dump is now able to backup a subtree, it is no longer limited to whole
+ filesystems like the BSD version.
+
+4. Dump now uses ext2_llseek() so it is able to backup filesystems bigger
+ than 2 GB.
+
+Changes between versions 0.0 and 0.1
+====================================
+
+1. Now create links rdump and rrestore during the `make install' step.
+
+2. Linux port specific bugs added to the manual pages
+
+3. Incorrect estimation of the number of tapes blocks fixed when doing
+ incremental backups.
+
+4. Better ls-like format in restore in interactive mode.
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
--- /dev/null
+$Id: INSTALL,v 1.3 2003/02/11 08:57:41 stelian Exp $
+
+ Installation of the dump/restore port should be quite easy, since
+a configure script is now provided.
+
+ Configuration is made by running the configure script. Run
+`configure --help' to get a list of options.
+
+ After configuring the package, you can type `make' to compile the
+programs, and `make install' to install the binaries in /usr/local/sbin and
+the manual pages in `/usr/local/man/man8'.
+
+ You need to have the latest Ext2fs programs installed on your system
+since this version of dump uses the Ext2fs library written by Theodore T'so.
+The Ext2fs programs are included in all Linux distributions (e2fsprogs and
+e2fsprogs-dev[el] packages), or you can download the most up to date version
+from http://e2fsprogs.sourceforge.net.
--- /dev/null
+$Id: KNOWNBUGS,v 1.5 1999/11/21 00:17:12 tiniou Exp $
+
+Known bugs and limitations of the dump/restore port
+===================================================
+
+1. I have tried to minimize changes in the BSD source and some parts
+ may look ugly. dump/tape.c is really awfull but this is pure BSD
+ code :-) Maybe, I should replace it with a simpler and cleaner
+ version.
+
+2. Kerberos mode is _NOT_ tested.
+
+3. Some users related possible problems when dumping
+ active (mounted) filesystems. The problems are reported as
+ lseek and read error messages (with a negative count). If
+ you encounter this kind of problems, please report them
+ to the author.
--- /dev/null
+$Id: MAINTAINERS,v 1.4 2002/01/16 09:32:14 stelian Exp $
+
+The dump and restore backup suit was ported to Linux's Second
+Extended File System by Rémy Card <card@Linux.EU.Org>
+
+He was the maintainer of the initial versions of dump (up and
+including 0.4b4, released in january 1997).
+
+I decided to continue the developpement and release a new version.
+Rémy didn't respond to any mail I sent to him, so I have
+promoted myself as the new maintainer :)
+
+So, starting with 0.4b5, the new maintainer is me,
+Stelian Pop <stelian@popies.net>.
+
--- /dev/null
+VERSION= 0.4b37
+DATE= July 7, 2004
+
+AR= @AR@
+CC= @CC@
+INSTALL= @INSTALL@
+LD= @LD@
+LN_S= @LN_S@
+MV= @MV@
+RANLIB= @RANLIB@
+RM= @RM@
+
+BINOWNER= @BINOWNER@
+BINGRP= @BINGRP@
+BINMODE= @BINMODE@
+MANOWNER= @MANOWNER@
+MANGRP= @MANGRP@
+MANMODE= @MANMODE@
+
+INSTALLBIN= $(INSTALL) -o $(BINOWNER) -g $(BINGRP) -m $(BINMODE)
+INSTALLMAN= $(INSTALL) -o $(MANOWNER) -g $(MANGRP) -m $(MANMODE)
+
+prefix= @prefix@
+exec_prefix= @exec_prefix@
+SBINDIR= @sbindir@
+MANDIR= @mandir@/man8
+
+DUMPDATESPATH= @DUMPDATESPATH@
+#
+# Global include directories
+#
+GINC= -I$(top_builddir) -I$(top_srcdir)/compat/include
+# indicate where the ext2fs library can be found (this is not needed if you
+# have run `make install-libs' in the e2fsprogs source directory).
+#GINC+= -I/usr/src/e2fsprogs-0.5c/lib
+
+#
+# Global libraries
+#
+# indicate where the ext2fs library can be found (this is not needed if you
+# have run `make install-libs' in the e2fsprogs source directory).
+#GLIBDIR= -L/usr/src/e2fsprogs-0.5c/lib
+GLIBS= $(GLIBDIR) -L../compat/lib -lcompat -lext2fs -lcom_err
+
+#
+# Definitions (don't change them unless you know what you are doing)
+#
+DEFS= -DRDUMP -DRRESTORE -DLINUX_FORK_BUG -DHAVE_LZO -D_PATH_DUMPDATES=\"$(DUMPDATESPATH)\" -D_DUMP_VERSION=\"$(VERSION)\" @OPTDEFS@
+
+all::
+
+#
+# Autoconf magic
+#
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+ (cd $(top_builddir); ./config.status --recheck)
+
+$(top_builddir)/MCONFIG: $(top_srcdir)/MCONFIG.in \
+ $(top_builddir)/config.status
+ (cd $(top_builddir); ./config.status)
+
+$(top_builddir)/config.h: $(top_srcdir)/config.h.in \
+ $(top_builddir)/config.status
+ (cd $(top_builddir); ./config.status)
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/MCONFIG \
+ $(top_builddir)/config.status
+ (cd $(top_builddir); ./config.status)
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in
+ cd $(top_srcdir) && autoconf
+
+$(top_srcdir)/config.h.in: $(top_srcdir)/configure.in
+ cd $(top_srcdir) && autoheader
+
+#
+# Make depend magic
+#
+
+.depend: Makefile $(SRCS) $(top_srcdir)/depfix.sed
+ if test -n "$(SRCS)" ; then \
+ $(CC) -M $(CFLAGS) $(SRCS) | \
+ sed -f $(top_srcdir)/depfix.sed \
+ -e 's; $(srcdir)/; $$(srcdir)/;g' \
+ -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' \
+ -e 's; $(top_builddir)/; $$(top_builddir)/;g' \
+ -e 's; \./; ;g' \
+ -e '/^ *\\$$/d' > .depend; \
+ else :; fi
+
+depend:: .depend
+ if test -n "$(SRCS)" ; then \
+ sed -e '/^# +++ Dependency line eater +++/,$$d' \
+ < Makefile | cat - .depend \
+ > Makefile.new; \
+ $(MV) Makefile Makefile.old; \
+ $(MV) Makefile.new Makefile; \
+ else :; fi
--- /dev/null
+srcdir= @srcdir@
+top_srcdir= @top_srcdir@
+top_builddir= .
+
+@MCONFIG@
+
+RM= @RM@
+SUBDIRS= compat/lib compat/include common dump restore @RMTDIR@
+
+all clean install dep depend realclean distclean::
+ for i in $(SUBDIRS); do \
+ (cd $$i && $(MAKE) $@) || exit 1; \
+ done
+
+distclean::
+ $(RM) -f config.status config.log config.cache
+ $(RM) -f MCONFIG Makefile config.h
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+$Id: README,v 1.3 1999/10/11 13:31:04 stelian Exp $
+
+ This is a test release of dump 0.4.
+
+ See the file CHANGES for a list of changes from the previous version.
+
+ See the file INSTALL for installation instructions.
+
+ If you encounter problems with the dump and restore backup suite,
+please contact the maintainers and send them a detailled bug report.
--- /dev/null
+Congratulations! You just found a bug in dump/restore and want
+to know what to do next.
+
+Here are some guidelines you will want to follow before sending me
+a mail:
+
+1. Are you sure it's a bug? If you just are not sure about how
+to use a specific feature of dump, please post your question on
+the dump-users mailing list. While you are there, try to browse the
+archives of the mailing list and see if someone asked the same question
+before.
+
+ NOTE: questions about how to use the d(ensity) (b)locksize parameters
+ enters this category!
+
+2. Always test the last version of dump/restore before submitting a
+bug report. Your problem is maybe already fixed!
+
+3. Consult the bugs using the bug system at sourceforge. Use this
+bug system if you want to report a new bug or contribute to an
+existing bug. You may want to create an account on sourceforge for that,
+so the comments will automatically be forwarded to your email address.
+
+4. If you are using the bug system and didn't create an account on
+sourceforge, put your email address into the bug report! If I am unable
+to contact you for more information, chances are that the bug will
+never be solved!
+
+5. Please provide detailed information about your system:
+ - distribution and its version (RedHat, Debian, Suse, homemade etc.)
+ - architecture (Intel, Sparc, PalmPilot etc.)
+ - dump/restore version (0.4b13, etc)
+ - e2fsprogs version (1.17, etc)
+ - libc version (libc5, glibc2.0, gilbc2.1 etc)
+ - complete output of the dump/restore command which caused
+ the failure (ok, you can delete the 'xx% done' lines)
+ - the device you dump into/restore from (tape drive, file etc).
+ - anything else you believe will help me to find the bug...
+
+6. In addition, if you want to report a bug on dump, provide also:
+ - details of your filesystem you want to dump:
+ output of the command 'tune2fs -l /dev/sda1'
+ (replace sda1 with your partition...)
+ - if your filesystem was mounted when doing the dump, try
+ to rerun the command with the filesystem unmounted. Does
+ the bug still occur?
+ - try to dump your filesystem using /dev/null as tape device.
+ This may help to know that the bug is not triggered by a
+ buggy device or tape or remote access problems.
+
+
+Ok, here are the pointers you may want to access:
+
+Dump latest release: http://sourceforge.net/project/filelist.php?group_id=1306
+Dump mailing lists: http://sourceforge.net/mail/?group_id=1306
+Dump bug system: http://sourceforge.net/bugs/?group_id=1306
+My email: stelian@popies.net
--- /dev/null
+$Id: THANKS,v 1.85 2004/07/01 09:14:48 stelian Exp $
+
+Dump and restore were written by the people of the CSRG at the University
+of California, Berkeley.
+
+They were ported to Linux by Remy Card <card@Linux.EU.Org>, by using
+the Ext2fs library, written by Theodore Ts'o <tytso@mit.edu>.
+
+Kevin Layer <layer@Franz.COM> added the comparison code in restore.
+
+Doug Paul <dbp@dragonsys.com> helped me to make dump able to backup 2GB+
+filesystems.
+
+David Frey <david@eos.lugs.ch> (the old Debian dump maintainer),
+Bdale Garbee <bdale@gag.com> (the new Debian dump maintainer) and the people
+from Red Hat Software provided lots of patches.
+
+Stelian Pop <stelian@popies.net> is now the current maintainer (since dump-0.4b5).
+
+Thanks to people who reported problems with the port, sent patches, and
+suggested various improvements.
+Here is a partial list of them (if I have forgotten someone, please complain):
+John Adams johna@onevista.com
+Jin-su Ahn jsahn@ee.snu.ac.kr
+Eros Albertazzi eros@lamel.bo.cnr.it
+Matthias Andree matthias.andree@stud.uni-dortmund.de
+Andrea Arcangeli andrea@suse.de
+Stephen Atwell satwell@urbana.css.mot.com
+Gerd Bavendiek bav@epost.de
+Fabrice Bellet fabrice@bellet.info
+Stan Bubrouski satan@fastdial.net
+Stephen Carr sgcarr@civeng.adelaide.edu.au
+Mike Castle dalgoda@users.sourceforge.net
+Rob Cermak cermak@ahab.rutgers.edu
+Antonios Christofides A.Christofides@itia.ntua.gr
+Isaac Chuang ike@isl.stanford.edu
+Rainer Clasen bj@ncc.cicely.de
+Tony Clayton tonyc@e-smith.com
+W. Reilly Cooley wcooley@nakedape.cc
+Chris Danis screechco@home.com
+Abhijit Dasgupta abhijit@ans.net
+John R. Dennison gerdesas@users.sourceforge.net
+Eugenio Diaz getnito@yahoo.com
+Andreas Dilger adilger@turbolinux.com
+Andrew Donkin ard@waikato.ac.nz
+Greg Edwards gedwards@users.sourceforge.net
+Bernhard Erdmann bernhard.erdmann@gmx.de
+Jason Fearon jasonf@netrider.org.au
+Jeremy Fitzhardinge jeremy@goop.org
+Eirik Fuller eirik@netcom.com
+Arcady Genkin antipode@users.sourceforge.net
+Uwe Gohlke uwe@ugsoft.de
+Ian Gordon iangordon@users.sourceforge.net
+Ted Grzesik tedgyz@roostme.com
+Mike Harris mharris@redhat.com
+Andreas Hasenack andreas@conectiva.com.br
+Christian Haul haul@informatik.tu-darmstadt.de
+George Helffrich george@geology.bristol.ac.uk
+Patrick Higgins phiggins@transzap.com
+Kjetil Torgrim Homme kjetilho@ifi.uio.no
+Raphael Jaffey rjaffey@artic.edu
+Jean-Paul van der Jagt jeanpaul@dutepp0.et.tudelft.nl
+Helmut Jarausch jarausch@igpm.rwth-aachen.de
+Eric Jergensen eric@dvns.com
+Jeff Johnson jbj@redhat.com
+Richard Johnson Richard.Johnson3@ey.com
+Richard Jones rich@annexia.org
+Zhang Jun zhangjun@nanjing-fnst.com
+Charles Karney karney@users.sourceforge.net
+Henry Katz hkatz@hkatz.dialup.access.net
+Dragan Krnic dkrnic@lycos.com
+Klaus Kudielka kkudielk@cacofonix.nt.tuwien.ac.at
+Thorsten Kukuk kukuk@suse.de
+Ken Lalonde ken@globalremit.com
+Florian La Roche florian@jurix.jura.uni-sb.de
+Kari Lempiainen kari@funky.pp.fi
+Ambrose Li acli@mingpaoxpress.com
+Georg Lippold g_lippold@sourceforge.net
+Patrick J. LoPresti patl@cag.lcs.mit.edu
+Bruce Lowekamp lowekamp@users.sourceforge.net
+Greg Lutz greglutz@ix.netcom.com
+Eric Maisonobe virnet@nat.fr
+Kai Makisara Kai.Makisara@kolumbus.fi
+Andy Mentges amentges@jumpline.com
+David Miller davem@caip.rutgers.edu
+Elliott Mitchell ehem@m5p.com
+David Monro davidm@cs.su.oz.au
+Dejan Muhamedagic dejan@quant-x.com
+Lukas Nellen L.Nellen@ThPhys.Uni-Heidelberg.DE
+Markus Oberhumer markus@oberhumer.com
+Nuno Oliveira nuno@eq.uc.pt
+Brent Olson night@halcyon.com
+Jorgen Ostling jorgen_ostling@users.sourceforge.net
+Jerry Peters gapeters@worldnet.att.net
+David B. Peterson dave@toppledwagon.com
+Trent Piepho xyzzy@speakeasy.org
+Dave Platt dplatt@snulbug.mtview.ca.us
+Kenneth Porter shiva@well.com
+Eric S. Raymond esr@minx.thyrsus.com
+Graham Reed greed@users.sourceforge.net
+Gunther Reiszig gunther@mit.edu
+David Ronis ronis@ronispc.chem.mcgill.ca
+Dietrich Rothe d-rothe@users.sourceforge.net
+Bernhard Sadlowski sadlowsk@Mathematik.Uni-Bielefeld.DE
+Peter Samuel peters@e-smith.com
+Jan Sanislo oystr@cs.washington.edu
+Jörg Schilling schilling@fokus.gmd.de
+Patrik Schindler poc@pocnet.net
+Gunther Schlegel schlegel@riege.de
+Chris Siebenmann cks@utcc.utoronto.ca
+Paul Slootman paul@debian.org
+Bob Snyder rsnyder@janet.advsys.com
+Jeffrey Sofferin sofferin@users.sourceforge.net
+Gabriel Somlo somlo@cs.colostate.edu
+Clemens Stiglechner a9401816@unet.univie.ac.at
+Michal Szymanski msz@astrouw.edu.pl
+Matti Taskinen mkt@rni.helsinki.fi
+Jason L Tibbitts III tibbs@math.uh.edu
+Mike Tibor tibor@lib.uaa.alaska.edu
+Dirk Traenapp dtraenapp@users.sourceforge.net
+Erik Troan ewt@redhat.com
+Philippe Troin phil@fifi.org
+Theodore Y. Ts'o tytso@valinux.com
+Stephen Tweedie sct@dcs.ed.ac.uk
+Matus Uhlar uhlar@fantomas.sk
+Amith Varghese amithv@yahoo.com
+Daniel Veillard Daniel.Veillard@imag.fr
+Jason Venner jason@idiom.com
+John I Wang jiwang@users.sourceforge.net
+Christian Weisgerber naddy@mips.rhein-neckar.de
+Kim Yong-jun loveyou@hackerslab.org
+John Yu jky@it.bu.edu
+Ian Zimmerman itz@speakeasy.org
+Florian Zumbiehl florz@gmx.de
--- /dev/null
+$Id: TODO,v 1.24 2002/01/25 14:59:53 stelian Exp $
+
+Need to verify:
+---------------
+
+1. Verify that dump works with kerberos authentification (this
+ was ported from *BSD and was not tested - in fact, this
+ wasn't even compiled in!). Need success reports for this.
+
+Urgent items (for the next stable version):
+-------------------------------------------
+
+All others:
+-----------
+
+1. More documentation? Examples, crontab?
+
+2. Explore and correct dump problems on active filesystems
+ (lseek/read negative count) (This should be OK as of 0.4b14.
+ Unfortunately, this seems to continue for a very few users).
+
+3. Reimplement the ext2 specific code in a "backend" and
+ make the dump code more generic. This would allow creation
+ of other backends for other filesystems. Implementing a
+ (v)fat backend should be quite easy, as for BSD ffs (we
+ already have the code for this). The BSD code in traverse.c
+ (all those #ifdef _BSD) should go into the ffs backend.
+
+4. Implement a DEBUG option which doesn't fork on each tape, making
+ it able to debug dump with gdb.
+
+5. Make a bootable dump tape? I don't know if it is possible...
+
+6. EA/ACL support in dump (requested by Michael Ju. Tokarev
+ <mjt@tls.msk.ru>.
+
+7. Better readline completition in restore (escape spaces etc).
--- /dev/null
+# $Id: Makefile.in,v 1.5 2003/05/08 21:11:39 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ..
+
+@MCONFIG@
+
+INC= -I$(top_srcdir)/dump
+ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @DUMPDEBUG@
+ALL_LDFLAGS= @LDFLAGS@ @LDOPTS@ @STATIC@
+SRCS= dumprmt.c
+OBJS= dumprmt.o
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: $(OBJS)
+
+install::
+
+clean::
+ $(RM) -f \#* *.s *.o *.a *~ core
+
+distclean:: clean
+ $(RM) -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: dumprmt.c,v 1.28 2003/10/26 16:05:45 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/param.h>
+#include <sys/mtio.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#ifdef __linux__
+#include <sys/types.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#include <signal.h>
+#elif defined sunos
+#include <sys/vnode.h>
+
+#include <ufs/inode.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <protocols/dumprestore.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <compaterr.h>
+#include <rmtflags.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+#ifdef __linux__
+#include <ext2fs/ext2fs.h>
+#endif
+
+#include <pathnames.h>
+#include "dump.h" /* for X_STARTUP, X_ABORT etc */
+
+#define TS_CLOSED 0
+#define TS_OPEN 1
+
+static int rmtstate = TS_CLOSED;
+static int tormtape = -1;
+static int fromrmtape = -1;
+int rshpid = -1;
+static const char *rmtpeer = 0;
+
+static int okname __P((const char *));
+static OFF_T rmtcall __P((const char *, const char *));
+static void rmtconnaborted __P((int));
+static int rmtgetb __P((void));
+static int rmtgetconn __P((void));
+static void rmtgets __P((char *, size_t));
+static OFF_T rmtreply __P((const char *));
+static int piped_child __P((const char **command));
+#ifdef KERBEROS
+int krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *));
+#endif
+
+static int errfd = -1;
+extern int dokerberos;
+extern int ntrec; /* blocking factor on tape */
+extern int abortifconnerr; /* set to 1 if this lib should exit on connection errors
+ otherwise just print a message using msg */
+#ifndef errno
+extern int errno;
+#endif
+
+int
+rmthost(const char *host)
+{
+ if (rmtpeer)
+ free((void *)rmtpeer);
+ if ((rmtpeer = strdup(host)) == NULL)
+ rmtpeer = host;
+ signal(SIGPIPE, rmtconnaborted);
+ return rmtgetconn();
+}
+
+static void
+rmtconnaborted(UNUSED(int signo))
+{
+ msg("Lost connection to remote host.\n");
+ if (errfd != -1) {
+ fd_set r;
+ struct timeval t;
+
+ FD_ZERO(&r);
+ FD_SET(errfd, &r);
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+ if (select(errfd + 1, &r, NULL, NULL, &t)) {
+ int i;
+ char buf[2048];
+
+ if ((i = read(errfd, buf, sizeof(buf) - 1)) > 0) {
+ buf[i] = '\0';
+ msg("on %s: %s%s", rmtpeer, buf,
+ buf[i - 1] == '\n' ? "" : "\n");
+ }
+ }
+ }
+ if (abortifconnerr)
+ exit(X_ABORT);
+}
+
+static int
+rmtgetconn(void)
+{
+ char *cp;
+ const char *rmt;
+ static struct servent *sp = NULL;
+ static struct passwd *pwd = NULL;
+ const char *tuser;
+ const char *rsh;
+ int size;
+ int throughput;
+ int on;
+ char *rmtpeercopy;
+
+ rsh = getenv("RSH");
+
+ if (!rsh && sp == NULL) {
+ sp = getservbyname(dokerberos ? "kshell" : "shell", "tcp");
+ if (sp == NULL) {
+ if (abortifconnerr) {
+ errx(1, "%s/tcp: unknown service", dokerberos ? "kshell" : "shell");
+ } else {
+ msg("%s/tcp: unknown service", dokerberos ? "kshell" : "shell");
+ return 0;
+ }
+ }
+ }
+ if (pwd == NULL) {
+ pwd = getpwuid(getuid());
+ if (pwd == NULL) {
+ if (abortifconnerr) {
+ errx(1, "who are you?");
+ } else {
+ msg("who are you?");
+ return 0;
+ }
+ }
+ }
+ if ((cp = strchr(rmtpeer, '@')) != NULL) {
+ tuser = rmtpeer;
+ *cp = '\0';
+ if (!okname(tuser)) {
+ if (abortifconnerr) {
+ exit(X_STARTUP);
+ } else {
+ return 0;
+ }
+ }
+ rmtpeer = ++cp;
+ } else
+ tuser = pwd->pw_name;
+ if ((rmt = getenv("RMT")) == NULL)
+ rmt = _PATH_RMT;
+ msg("");
+
+ if (rsh) {
+ const char *rshcmd[6];
+ rshcmd[0] = rsh;
+ rshcmd[1] = rmtpeer;
+ rshcmd[2] = "-l";
+ rshcmd[3] = tuser;
+ rshcmd[4] = rmt;
+ rshcmd[5] = NULL;
+
+ /* Restore the uid and gid. We really don't want
+ * to execute whatever is put into RSH variable with
+ * more priviledges than needed... */
+ setuid(getuid());
+ setgid(getgid());
+
+ if ((rshpid = piped_child(rshcmd)) < 0) {
+ msg("cannot open connection\n");
+ return 0;
+ }
+ }
+ else {
+ /* Copy rmtpeer to rmtpeercopy to ignore the
+ return value from rcmd. I cannot figure if
+ this is this a bug in rcmd or in my code... */
+ rmtpeercopy = (char *)rmtpeer;
+#ifdef KERBEROS
+ if (dokerberos)
+ tormtape = krcmd(&rmtpeercopy, sp->s_port, tuser, rmt, &errfd,
+ (char *)0);
+ else
+#endif
+ tormtape = rcmd(&rmtpeercopy, (u_short)sp->s_port, pwd->pw_name,
+ tuser, rmt, &errfd);
+ if (tormtape < 0) {
+ msg("login to %s as %s failed.\n", rmtpeer, tuser);
+ return 0;
+ }
+ size = ntrec * TP_BSIZE;
+ if (size > 60 * 1024) /* XXX */
+ size = 60 * 1024;
+ /* Leave some space for rmt request/response protocol */
+ size += 2 * 1024;
+ while (size > TP_BSIZE &&
+ setsockopt(tormtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
+ size -= TP_BSIZE;
+ (void)setsockopt(tormtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
+ throughput = IPTOS_THROUGHPUT;
+ if (setsockopt(tormtape, IPPROTO_IP, IP_TOS,
+ &throughput, sizeof(throughput)) < 0)
+ perror("IP_TOS:IPTOS_THROUGHPUT setsockopt");
+ on = 1;
+ if (setsockopt(tormtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
+ perror("TCP_NODELAY setsockopt");
+ fromrmtape = tormtape;
+ }
+ (void)fprintf(stdout, "Connection to %s established.\n", rmtpeer);
+ return 1;
+}
+
+static int
+okname(const char *cp0)
+{
+ const char *cp;
+ int c;
+
+ for (cp = cp0; *cp; cp++) {
+ c = *cp;
+ if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) {
+ warnx("invalid user name %s\n", cp0);
+ return (0);
+ }
+ }
+ return (1);
+}
+
+int
+rmtopen(const char *tape, const int mode)
+{
+ char buf[MAXPATHLEN];
+ char *rmtflags;
+
+ rmtflags = rmtflags_tochar(mode);
+ (void)snprintf(buf, sizeof (buf), "O%s\n%d %s\n",
+ tape,
+ mode & O_ACCMODE,
+ rmtflags);
+ free(rmtflags);
+ rmtstate = TS_OPEN;
+ return (rmtcall(tape, buf));
+}
+
+void
+rmtclose(void)
+{
+
+ if (rmtstate != TS_OPEN)
+ return;
+ rmtcall("close", "C\n");
+ rmtstate = TS_CLOSED;
+}
+
+int
+rmtread(char *buf, size_t count)
+{
+ char line[30];
+ int n, i;
+ ssize_t cc;
+
+ (void)snprintf(line, sizeof (line), "R%u\n", (unsigned)count);
+ n = rmtcall("read", line);
+ if (n < 0) {
+ /* rmtcall() properly sets errno for us on errors. */
+ errno = n;
+ return (-1);
+ }
+ for (i = 0; i < n; i += cc) {
+ cc = read(fromrmtape, buf+i, n - i);
+ if (cc <= 0)
+ rmtconnaborted(0);
+ }
+ return (n);
+}
+
+int
+rmtwrite(const char *buf, size_t count)
+{
+ char line[30];
+
+ (void)snprintf(line, sizeof (line), "W%ld\n", (long)count);
+ write(tormtape, line, strlen(line));
+ write(tormtape, buf, count);
+ return (rmtreply("write"));
+}
+
+OFF_T
+rmtseek(OFF_T offset, int pos)
+{
+ char line[80];
+
+ (void)snprintf(line, sizeof (line), "L%lld\n%d\n", (long long)offset, pos);
+ return (rmtcall("seek", line));
+}
+
+struct mtget mts;
+
+struct mtget *
+rmtstatus(void)
+{
+ int i;
+ char *cp;
+
+ if (rmtstate != TS_OPEN)
+ return (NULL);
+ i = rmtcall("status", "S");
+ if (i < 0) return NULL;
+ if (i != (int)sizeof(mts)) {
+ msg("mtget sizes different between host (%d) "
+ "and remote tape (%d)", sizeof(mts), i);
+ for ( /* empty */; i > 0; --i)
+ rmtgetb();
+ return NULL;
+ }
+ for (i = 0, cp = (char *)&mts; i < (int)sizeof(mts); i++)
+ *cp++ = rmtgetb();
+ return (&mts);
+}
+
+int
+rmtioctl(int cmd, int count)
+{
+ char buf[256];
+
+ if (count < 0)
+ return (-1);
+ (void)snprintf(buf, sizeof (buf), "I%d\n%d\n", cmd, count);
+ return (rmtcall("ioctl", buf));
+}
+
+static OFF_T
+rmtcall(const char *cmd, const char *buf)
+{
+
+ if (write(tormtape, buf, strlen(buf)) != (ssize_t)strlen(buf))
+ rmtconnaborted(0);
+ return (rmtreply(cmd));
+}
+
+static OFF_T
+rmtreply(const char *cmd)
+{
+ char *cp;
+ char code[30], emsg[BUFSIZ];
+
+ rmtgets(code, sizeof (code));
+ if (*code == 'E' || *code == 'F') {
+ rmtgets(emsg, sizeof (emsg));
+ msg("%s: %s", cmd, emsg);
+ errno = atoi(code + 1);
+ if (*code == 'F')
+ rmtstate = TS_CLOSED;
+ return (-1);
+ }
+ if (*code != 'A') {
+ /* Kill trailing newline */
+ cp = code + strlen(code);
+ if (cp > code && *--cp == '\n')
+ *cp = '\0';
+
+ msg("Protocol to remote tape server botched (code \"%s\").\n",
+ code);
+ rmtconnaborted(0);
+ }
+ return (OFF_T)(atoll(code + 1));
+}
+
+static int
+rmtgetb(void)
+{
+ char c;
+
+ if (read(fromrmtape, &c, 1) != 1)
+ rmtconnaborted(0);
+ return (c);
+}
+
+/* Get a line (guaranteed to have a trailing newline). */
+static void
+rmtgets(char *line, size_t len)
+{
+ char *cp = line;
+
+ while (len > 1) {
+ *cp = rmtgetb();
+ if (*cp == '\n') {
+ cp[1] = '\0';
+ return;
+ }
+ cp++;
+ len--;
+ }
+ *cp = '\0';
+ msg("Protocol to remote tape server botched.\n");
+ msg("(rmtgets got \"%s\").\n", line);
+ rmtconnaborted(0);
+}
+
+int piped_child(const char **command) {
+ int pid;
+ int to_child_pipe[2];
+ int from_child_pipe[2];
+
+ if (pipe (to_child_pipe) < 0) {
+ msg ("cannot create pipe: %s\n", strerror(errno));
+ return -1;
+ }
+ if (pipe (from_child_pipe) < 0) {
+ msg ("cannot create pipe: %s\n", strerror(errno));
+ return -1;
+ }
+ pid = fork ();
+ if (pid < 0) {
+ msg ("cannot fork: %s\n", strerror(errno));
+ return -1;
+ }
+ if (pid == 0) {
+ if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0) {
+ msg ("cannot dup2 pipe: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (close (to_child_pipe[1]) < 0) {
+ msg ("cannot close pipe: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (close (from_child_pipe[0]) < 0) {
+ msg ("cannot close pipe: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0) {
+ msg ("cannot dup2 pipe: %s\n", strerror(errno));
+ exit(1);
+ }
+ setpgid(0, getpid());
+ execvp (command[0], (char *const *) command);
+ msg("cannot exec %s: %s\n", command[0], strerror(errno));
+ exit(1);
+ }
+ if (close (to_child_pipe[0]) < 0) {
+ msg ("cannot close pipe: %s\n", strerror(errno));
+ return -1;
+ }
+ if (close (from_child_pipe[1]) < 0) {
+ msg ("cannot close pipe: %s\n", strerror(errno));
+ return -1;
+ }
+ tormtape = to_child_pipe[1];
+ fromrmtape = from_child_pipe[0];
+ return pid;
+}
--- /dev/null
+# $Id: Makefile.in,v 1.4 2003/01/24 11:01:48 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ../..
+
+@MCONFIG@
+
+all::
+
+install::
+
+clean::
+ $(RM) -f \#* *~ core
+
+distclean:: clean
+ $(RM) -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: bsdcompat.h,v 1.23 2004/07/01 09:14:48 stelian Exp $
+ */
+
+#include <config.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <ext2fs/ext2fs.h>
+
+#define __dead volatile
+#define UNUSED(x) x __attribute__ ((unused))
+
+#ifndef NBBY
+#define NBBY 8
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a < b) ? a : b)
+#endif
+
+#define WINO 1
+#define DEV_BSIZE 512
+#define DEV_BSHIFT 9
+
+#ifndef sunos
+#define MAXBSIZE EXT2_MAX_BLOCK_SIZE
+#define ROOTINO EXT2_ROOT_INO
+#else
+#define ROOTINO 2
+#endif
+#ifdef EXT2_NODUMP_FL
+#define UF_NODUMP EXT2_NODUMP_FL
+#endif
+
+#ifndef howmany
+#define howmany(x,y) (((x)+((y)-1))/(y))
+#endif
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#endif
+#ifndef powerof2
+#define powerof2(x) ((((x)-1)&(x))==0)
+#endif
+
+#define fsbtodb(sb,b) ((ext2_loff_t)(((long long)(b) * EXT2_BLOCK_SIZE((sb)->super)) / DEV_BSIZE))
+#define dbtofsb(sb,b) ((int)(((long long)(b) * DEV_BSIZE) / EXT2_BLOCK_SIZE((sb)->super)))
+
+#define sblock fs
+#define fs_fsize fragsize
+#define fs_bsize blocksize
+#define fs_size super->s_blocks_count
+
+#define IFMT S_IFMT
+#define IFLNK S_IFLNK
+#define IFREG S_IFREG
+#define IFDIR S_IFDIR
+#define IFCHR S_IFCHR
+#define IFBLK S_IFBLK
+#define IFSOCK S_IFSOCK
+#define IFIFO S_IFIFO
+
+#if 0
+typedef __s64 quad_t;
+typedef __u64 u_quad_t;
+#endif
+
+/*
+ * The BSD dump format reserves 4 bytes for a time_t, but other architectures
+ * (notably axp) have larger time_t. ctime4() is a modified ctime() which
+ * always accepts short 4-byte times.
+ */
+#define ctime4(timep) ({ time_t t = *(timep); ctime(&t); })
+
+/*
+ * This is the ext2_inode structure but the fields have been renamed
+ * to match 4.4BSD's names
+ */
+#define NDADDR 12
+#define NIADDR 3
+
+#define NINDIR(fs) EXT2_ADDR_PER_BLOCK(fs->super)
+
+#ifdef sunos
+typedef uint8_t __u8;
+typedef uint16_t __u16;
+typedef uint32_t __u32;
+typedef int8_t __s8;
+typedef int16_t __s16;
+typedef int32_t __s32;
+#ifndef u_int
+typedef unsigned int u_int;
+#endif
+#ifndef u_int16_t
+typedef unsigned short u_int16_t;
+#endif
+#ifndef u_char
+typedef unsigned char u_char;
+#endif
+typedef int64_t quad_t;
+#endif /* sunos */
+
+struct dinode {
+ __u16 di_mode;
+ __u16 di_uid;
+ __u32 di_size;
+ __u32 di_atime;
+ __u32 di_ctime;
+ __u32 di_mtime;
+ __u32 di_dtime;
+ __u16 di_gid;
+ __u16 di_nlink;
+ __u32 di_blocks;
+ __u32 di_flags;
+ __u32 di_reserved1;
+ __u32 di_db[NDADDR];
+ __u32 di_ib[NIADDR];
+ __u32 di_gen;
+ __u32 di_file_acl;
+ __u32 di_dir_acl;
+ __u32 di_faddr;
+ __u8 di_frag;
+ __u8 di_fsize;
+ __u16 di_pad1;
+ __u16 di_uidhigh;
+ __u16 di_gidhigh;
+ __u32 di_spare;
+};
+
+#define di_rdev di_db[0]
+/* #define di_ouid di_uid */
+/* #define di_ogid di_gid */
+#define di_size_high di_dir_acl
+
+/*
+ * This is the ext2_dir_entry structure but the fields have been renamed
+ * to match 4.4BSD's names
+ *
+ * This is the 4.4BSD directory entry structure
+ */
+#define DIRBLKSIZ DEV_BSIZE
+#ifndef MAXNAMLEN
+#define MAXNAMLEN 255
+#endif
+
+#ifdef sunos
+#define MAXNAMLEN 255
+#endif
+
+/*
+ * For old libc.
+ */
+#ifndef DT_UNKNOWN
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+
+#ifdef sunos
+#define DT_WHT 14
+#endif
+#endif
+
+#ifndef d_fileno
+#define d_fileno d_ino
+#endif
+
+/*
+ * The direct structure used by dump/restore.
+ */
+struct direct {
+ __u32 d_ino;
+ __u16 d_reclen;
+ __u8 d_type;
+ __u8 d_namlen;
+ char d_name[MAXNAMLEN + 1];
+};
+/*
+ * Convert between stat structure types and directory types.
+ */
+#define IFTODT(mode) (((mode) & 0170000) >> 12)
+#define DTTOIF(dirtype) ((dirtype) << 12)
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This requires the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ */
+#ifdef __linux__
+#if 0
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define DIRSIZ(oldfmt, dp) \
+ ((oldfmt) ? \
+ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \
+ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)))
+#else /* BYTE_ORDER */
+#define DIRSIZ(oldfmt, dp) \
+ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+#endif
+#else /* 0 */
+#define DIRSIZ(oldfmt,dp) EXT2_DIR_REC_LEN(((dp)->d_namlen & 0xff) + 1)
+#endif
+#else /* __linux__ */
+#define DIRSIZ(oldfmt, dp) \
+ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+#endif
+
+/*
+ * This is the old (Net/2) BSD inode structure
+ * copied from the FreeBSD 1.1.5.1 <ufs/dinode.h> include file
+ */
+#define MAXFASTLINK (((NDADDR + NIADDR) * sizeof(unsigned long)) - 1)
+
+struct old_bsd_inode {
+ __u16 di_mode;
+ __s16 di_nlink;
+ __u16 di_uid;
+ __u16 di_gid;
+#if 1
+ union {
+ u_quad_t v;
+ __u32 val[2];
+ } di_qsize;
+#else
+ u_quad_t di_size;
+#endif
+ __u32 di_atime;
+ __s32 di_atspare;
+ __u32 di_mtime;
+ __s32 di_mtspare;
+ __u32 di_ctime;
+ __s32 di_ctspare;
+#if 0
+ union {
+ struct {
+ daddr_t di_udb[NDADDR];
+ daddr_t di_uib[NIADDR];
+ } di_addr;
+ char di_usymlink[MAXFASTLINK + 1];
+ } di_un;
+#else
+ __u32 di_db[NDADDR];
+ __u32 di_ib[NIADDR];
+#endif
+ __s32 di_flags;
+ __s32 di_blocks;
+ __s32 di_gen;
+ __u32 di_spare[4];
+};
+
+struct bsdtimeval { /* XXX alpha-*-linux is deviant */
+ __u32 tv_sec;
+ __u32 tv_usec;
+};
+
+/*
+ * This is the new (4.4) BSD inode structure
+ * copied from the FreeBSD 2.0 <ufs/ufs/dinode.h> include file
+ */
+struct new_bsd_inode {
+ __u16 di_mode;
+ __s16 di_nlink;
+ union {
+ __u16 oldids[2];
+ __u32 inumber;
+ } di_u;
+ u_quad_t di_size;
+ struct bsdtimeval di_atime;
+ struct bsdtimeval di_mtime;
+ struct bsdtimeval di_ctime;
+ __u32 di_db[NDADDR];
+ __u32 di_ib[NIADDR];
+ __u32 di_flags;
+ __s32 di_blocks;
+ __s32 di_gen;
+ __u32 di_uid;
+ __u32 di_gid;
+ __s32 di_spare[2];
+};
+
+#define di_ouid di_u.oldids[0]
+#define di_ogid di_u.oldids[1]
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+ * - added Native Language Support
+ * 2000-01-20 James Antill <james@and.org>
+ * - Added error message if /proc/partitions cannot be opened
+ * 2000-05-09 Erik Troan <ewt@redhat.com>
+ * - Added cache for UUID and disk labels
+ * Wed Aug 16 2000 Erik Troan <ewt@redhat.com>
+ * - Ported to dump/restore
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: bylabel.h,v 1.6 2004/07/05 15:02:36 stelian Exp $
+ */
+
+#ifndef _BYLABEL_H_
+#define _BYLABEL_H_
+
+#include <config.h>
+
+#ifdef HAVE_BLKID
+
+#include <blkid/blkid.h>
+
+static inline const char * get_device_name(const char * item) {
+ return blkid_get_devname(NULL, item, NULL);
+}
+
+static inline const char * get_device_label(const char * spec) {
+ return blkid_get_tag_value(NULL, "LABEL", spec);
+}
+
+#else
+
+const char * get_device_name(const char * item);
+const char * get_device_label(const char * spec);
+
+#endif
+
+#endif /* !_BYLABEL_H_ */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: compaterr.h,v 1.10 2003/03/30 15:40:34 stelian Exp $
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COMPATERR_H_
+#define _COMPATERR_H_
+
+#include <config.h>
+
+#if defined(HAVE_ERR) || defined(HAVE_ERRX) || defined(HAVE_VERR) || defined(HAVE_VERRX) || defined(HAVE_VWARN) || defined(HAVE_VWARNX) || defined(HAVE_WARN) || defined(HAVE_WARNX)
+#include <err.h>
+#endif
+
+#include <sys/cdefs.h>
+
+#include <stdarg.h>
+
+#ifndef _BSD_VA_LIST_
+#define _BSD_VA_LIST_ va_list
+#endif
+
+#ifndef __dead
+#define __dead volatile
+#endif
+
+__BEGIN_DECLS
+#ifndef HAVE_ERR
+__dead void err __P((int, const char *, ...));
+#endif
+#ifndef HAVE_VERR
+__dead void verr __P((int, const char *, _BSD_VA_LIST_));
+#endif
+#ifndef HAVE_ERRX
+__dead void errx __P((int, const char *, ...));
+#endif
+#ifndef HAVE_VERRX
+__dead void verrx __P((int, const char *, _BSD_VA_LIST_));
+#endif
+#ifndef HAVE_WARN
+void warn __P((const char *, ...));
+#endif
+#ifndef HAVE_VWARN
+void vwarn __P((const char *, _BSD_VA_LIST_));
+#endif
+#ifndef HAVE_WARNX
+void warnx __P((const char *, ...));
+#endif
+#ifndef HAVE_VWARNX
+void vwarnx __P((const char *, _BSD_VA_LIST_));
+#endif
+__END_DECLS
+
+#endif /* !_COMPATERR_H_ */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: compatglob.h,v 1.9 2003/03/30 15:40:34 stelian Exp $
+ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COMPATGLOB_H_
+#define _COMPATGLOB_H_
+
+#include <config.h>
+
+#ifdef HAVE_GLOB
+#include <glob.h>
+#else
+
+#include <sys/cdefs.h>
+
+struct stat;
+typedef struct {
+ int gl_pathc; /* Count of total paths so far. */
+ int gl_matchc; /* Count of paths matching pattern. */
+ int gl_offs; /* Reserved at beginning of gl_pathv. */
+ int gl_flags; /* Copy of flags parameter to glob. */
+ char **gl_pathv; /* List of paths matching pattern. */
+ /* Copy of errfunc parameter to glob. */
+ int (*gl_errfunc) __P((const char *, int));
+
+ /*
+ * Alternate filesystem access methods for glob; replacement
+ * versions of closedir(3), readdir(3), opendir(3), stat(2)
+ * and lstat(2).
+ */
+ void (*gl_closedir) __P((void *));
+ struct dirent *(*gl_readdir) __P((void *));
+ void *(*gl_opendir) __P((const char *));
+ int (*gl_lstat) __P((const char *, struct stat *));
+ int (*gl_stat) __P((const char *, struct stat *));
+} glob_t;
+
+#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
+#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
+#define GLOB_ERR 0x0004 /* Return on error. */
+#define GLOB_MARK 0x0008 /* Append / to matching directories. */
+#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
+#define GLOB_NOSORT 0x0020 /* Don't sort. */
+
+#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
+#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
+#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
+#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
+#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
+#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
+
+#define GLOB_NOSPACE (-1) /* Malloc call failed. */
+#define GLOB_ABEND (-2) /* Unignored error. */
+
+__BEGIN_DECLS
+int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
+void globfree __P((glob_t *));
+__END_DECLS
+
+#endif /* HAVE_GLOB */
+
+#endif /* !_COMPATGLOB_H_ */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: compatlfs.h,v 1.5 2004/03/29 13:57:29 stelian Exp $
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COMPATLFS_H_
+#define _COMPATLFS_H_
+
+#include <config.h>
+
+#ifdef USE_LFS
+
+#define _LARGEFILE64_SOURCE
+#define OPEN open64
+#define LSEEK lseek64
+#define STAT stat64
+#define LSTAT lstat64
+#define FTRUNCATE ftruncate64
+#define OFF_T __off64_t
+#define MKSTEMP mkstemp64
+#define FTELL ftello64
+
+#else
+
+#define OPEN open
+#define LSEEK lseek
+#define STAT stat
+#define LSTAT lstat
+#define FTRUNCATE ftruncate
+#define OFF_T off_t
+#define MKSTEMP mkstemp
+#define FTELL ftell
+
+#endif /* USE_LFS */
+
+#endif /* !_COMPATLFS_H_ */
--- /dev/null
+/*
+ *
+ */
+
+#if defined(DUMP_MACOSX)
+
+#ifndef DARWIN_H
+#define DARWIN_H
+
+#define INFOLEN 32
+#define CORRECT 2
+
+
+#define DARWIN_RSRC_NAME "/..namedfork/rsrc"
+#define DARWIN_FINFO_NAME "/..namedfork/finfo"
+/*
+ * some structs from the HFS+ info for OS X
+ * - including the header file causes messy clashes
+ */
+
+struct FndrFileInfo {
+ u_int32_t fdType; /* file type */
+ u_int32_t fdCreator; /* file creator */
+ u_int16_t fdFlags; /* Finder flags */
+ struct {
+ int16_t v; /* file's location */
+ int16_t h;
+ } fdLocation;
+ int16_t opaque;
+};
+typedef struct FndrFileInfo FndrFileInfo;
+
+struct FndrDirInfo {
+ struct { /* folder's window rectangle */
+ int16_t top;
+ int16_t left;
+ int16_t bottom;
+ int16_t right;
+ } frRect;
+ unsigned short frFlags; /* Finder flags */
+ struct {
+ u_int16_t v; /* folder's location */
+ u_int16_t h;
+ } frLocation;
+ int16_t opaque;
+};
+typedef struct FndrDirInfo FndrDirInfo;
+
+
+struct FndrOpaqueInfo {
+ int8_t opaque[16];
+};
+typedef struct FndrOpaqueInfo FndrOpaqueInfo;
+
+struct fndrinfo_block_t {
+ FndrFileInfo finderInfo;
+ FndrOpaqueInfo extendedFinderInfo;
+};
+typedef struct fndrinfo_block_t fndrinfo_block_t;
+
+struct attrinfo_block_t {
+ unsigned long info_length;
+ u_int32_t objid_low;
+ u_int32_t objid_high;
+ struct timespec created;
+ struct timespec backup;
+ union {
+ fndrinfo_block_t finfo;
+ FndrDirInfo dinfo;
+ } o;
+ off_t rsrc_length;
+};
+typedef struct attrinfo_block_t attrinfo_block_t;
+
+
+#define ASINGLE_MAGIC 0x00051600 /* all in one file */
+#define ADOUBLE_MAGIC 0x00051607 /* resource + info, data separated */
+
+#define ASD_VERSION1 0x00010000 /* the original version */
+#define ASD_VERSION2 0x00020000 /* the second version */
+
+typedef struct ASDHeader {
+ u_long magic; /* either single or double */
+ u_long version; /* ASD_VERSION2 */
+ u_char filler[16]; /* reserved, zero */
+ u_short entries; /* the number of entries */
+ /* the entries follow */
+} ASDHeader, *ASDHeaderPtr, **ASDHeaderHandle;
+
+typedef enum {
+ EntryDataFork = 1,
+ EntryRSRCFork,
+ EntryRealName,
+ EntryComment,
+ EntryBWIcon,
+ EntryColorIcon,
+ EntryOldFileInfo,
+ EntryFileDates,
+ EntryFinderInfo,
+ EntryMacFileInfo,
+ EntryProDOSInfo,
+ EntryMSDOSInfo,
+ EntryShortName,
+ EntryAFPFileInfo,
+ EntryDirID
+} ASDEntryType;
+
+typedef struct {
+ u_long entryID; /* the entry type (forced to long) */
+ u_long offset; /* offset in file of entry */
+ u_long len; /* length of entry */
+} ASDEntry, *ASDEntryPtr, **ASDEntryHandle;
+
+typedef struct {
+ u_long creationDate;
+ u_long modificationDate;
+ u_long backupDate;
+ u_long accessDate;
+} FileDates, *FileDatesPtr;
+
+typedef struct dumpfinderinfo {
+ FndrFileInfo fndrinfo; /* 0: size = 16 bytes, same for FndrDirInfo */
+ u_int32_t createDate; /* 16: date and time of creation */
+ u_int32_t contentModDate;/* 20: date/time of last content modification */
+ u_int32_t attributeModDate;/* 24: date/time of last attribute modification */
+ u_int32_t accessDate; /* 30: date/time of last access (MacOS X only) */
+ u_int32_t backupDate; /* 34: date/time of last backup */
+ u_int32_t textEncoding; /* 36: hint for name conversions */
+ char filler[980]; /* 40: for later expansion, 40 + 980 - 4 = TP_BSIZE - 4 */
+} DumpFinderInfo, *DumpFinderInfoPtr;
+
+#endif /* DARWIN_H */
+#endif
--- /dev/null
+/* lzoconf.h -- configuration for the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef __LZOCONF_H
+#define __LZOCONF_H
+
+#define LZO_VERSION 0x1080
+#define LZO_VERSION_STRING "1.08"
+#define LZO_VERSION_DATE "Jul 12 2002"
+
+/* internal Autoconf configuration file - only used when building LZO */
+#if defined(LZO_HAVE_CONFIG_H)
+# include <config.h>
+#endif
+#include <limits.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***********************************************************************
+// LZO requires a conforming <limits.h>
+************************************************************************/
+
+#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
+# error "invalid CHAR_BIT"
+#endif
+#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
+# error "check your compiler installation"
+#endif
+#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
+# error "your limits.h macros are broken"
+#endif
+
+/* workaround a cpp bug under hpux 10.20 */
+#define LZO_0xffffffffL 4294967295ul
+
+#if !defined(LZO_UINT32_C)
+# if (UINT_MAX < LZO_0xffffffffL)
+# define LZO_UINT32_C(c) c ## UL
+# else
+# define LZO_UINT32_C(c) c ## U
+# endif
+#endif
+
+
+/***********************************************************************
+// architecture defines
+************************************************************************/
+
+#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2)
+# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
+# define __LZO_WIN
+# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
+# define __LZO_WIN
+# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__)
+# define __LZO_WIN
+# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS)
+# define __LZO_DOS
+# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2)
+# define __LZO_OS2
+# elif defined(__palmos__)
+# define __LZO_PALMOS
+# elif defined(__TOS__) || defined(__atarist__)
+# define __LZO_TOS
+# endif
+#endif
+
+#if (UINT_MAX < LZO_0xffffffffL)
+# if defined(__LZO_WIN)
+# define __LZO_WIN16
+# elif defined(__LZO_DOS)
+# define __LZO_DOS16
+# elif defined(__LZO_PALMOS)
+# define __LZO_PALMOS16
+# elif defined(__LZO_TOS)
+# define __LZO_TOS16
+# elif defined(__C166__)
+# else
+ /* porting hint: for pure 16-bit architectures try compiling
+ * everything with -D__LZO_STRICT_16BIT */
+# error "16-bit target not supported - contact me for porting hints"
+# endif
+#endif
+
+#if !defined(__LZO_i386)
+# if defined(__LZO_DOS) || defined(__LZO_WIN16)
+# define __LZO_i386
+# elif defined(__i386__) || defined(__386__) || defined(_M_IX86)
+# define __LZO_i386
+# endif
+#endif
+
+#if defined(__LZO_STRICT_16BIT)
+# if (UINT_MAX < LZO_0xffffffffL)
+# include <lzo16bit.h>
+# endif
+#endif
+
+/* memory checkers */
+#if !defined(__LZO_CHECKER)
+# if defined(__BOUNDS_CHECKING_ON)
+# define __LZO_CHECKER
+# elif defined(__CHECKER__)
+# define __LZO_CHECKER
+# elif defined(__INSURE__)
+# define __LZO_CHECKER
+# elif defined(__PURIFY__)
+# define __LZO_CHECKER
+# endif
+#endif
+
+
+/***********************************************************************
+// integral and pointer types
+************************************************************************/
+
+/* Integral types with 32 bits or more */
+#if !defined(LZO_UINT32_MAX)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef unsigned int lzo_uint32;
+ typedef int lzo_int32;
+# define LZO_UINT32_MAX UINT_MAX
+# define LZO_INT32_MAX INT_MAX
+# define LZO_INT32_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint32;
+ typedef long lzo_int32;
+# define LZO_UINT32_MAX ULONG_MAX
+# define LZO_INT32_MAX LONG_MAX
+# define LZO_INT32_MIN LONG_MIN
+# else
+# error "lzo_uint32"
+# endif
+#endif
+
+/* lzo_uint is used like size_t */
+#if !defined(LZO_UINT_MAX)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef unsigned int lzo_uint;
+ typedef int lzo_int;
+# define LZO_UINT_MAX UINT_MAX
+# define LZO_INT_MAX INT_MAX
+# define LZO_INT_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint;
+ typedef long lzo_int;
+# define LZO_UINT_MAX ULONG_MAX
+# define LZO_INT_MAX LONG_MAX
+# define LZO_INT_MIN LONG_MIN
+# else
+# error "lzo_uint"
+# endif
+#endif
+
+typedef int lzo_bool;
+
+
+/***********************************************************************
+// memory models
+************************************************************************/
+
+/* Memory model for the public code segment. */
+#if !defined(__LZO_CMODEL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_CMODEL __far
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_CMODEL __near
+# else
+# define __LZO_CMODEL
+# endif
+#endif
+
+/* Memory model for the public data segment. */
+#if !defined(__LZO_DMODEL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_DMODEL __far
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_DMODEL __near
+# else
+# define __LZO_DMODEL
+# endif
+#endif
+
+/* Memory model that allows to access memory at offsets of lzo_uint. */
+#if !defined(__LZO_MMODEL)
+# if (LZO_UINT_MAX <= UINT_MAX)
+# define __LZO_MMODEL
+# elif defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_MMODEL __huge
+# define LZO_999_UNSUPPORTED
+# elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16)
+# define __LZO_MMODEL
+# else
+# error "__LZO_MMODEL"
+# endif
+#endif
+
+/* no typedef here because of const-pointer issues */
+#define lzo_byte unsigned char __LZO_MMODEL
+#define lzo_bytep unsigned char __LZO_MMODEL *
+#define lzo_charp char __LZO_MMODEL *
+#define lzo_voidp void __LZO_MMODEL *
+#define lzo_shortp short __LZO_MMODEL *
+#define lzo_ushortp unsigned short __LZO_MMODEL *
+#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
+#define lzo_int32p lzo_int32 __LZO_MMODEL *
+#define lzo_uintp lzo_uint __LZO_MMODEL *
+#define lzo_intp lzo_int __LZO_MMODEL *
+#define lzo_voidpp lzo_voidp __LZO_MMODEL *
+#define lzo_bytepp lzo_bytep __LZO_MMODEL *
+
+#ifndef lzo_sizeof_dict_t
+# define lzo_sizeof_dict_t sizeof(lzo_bytep)
+#endif
+
+
+/***********************************************************************
+// calling conventions and function types
+************************************************************************/
+
+/* linkage */
+#if !defined(__LZO_EXTERN_C)
+# ifdef __cplusplus
+# define __LZO_EXTERN_C extern "C"
+# else
+# define __LZO_EXTERN_C extern
+# endif
+#endif
+
+/* calling convention */
+#if !defined(__LZO_CDECL)
+# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# elif defined(__LZO_i386) && defined(_MSC_VER)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# elif defined(__LZO_i386) && defined(__WATCOMC__)
+# define __LZO_CDECL __LZO_CMODEL __cdecl
+# else
+# define __LZO_CDECL __LZO_CMODEL
+# endif
+#endif
+#if !defined(__LZO_ENTRY)
+# define __LZO_ENTRY __LZO_CDECL
+#endif
+
+/* C++ exception specification for extern "C" function types */
+#if !defined(__cplusplus)
+# undef LZO_NOTHROW
+# define LZO_NOTHROW
+#elif !defined(LZO_NOTHROW)
+# define LZO_NOTHROW
+#endif
+
+
+typedef int
+(__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_byte *dict, lzo_uint dict_len );
+
+typedef int
+(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_byte *dict, lzo_uint dict_len );
+
+
+/* assembler versions always use __cdecl */
+typedef int
+(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+
+/* a progress indicator callback function */
+typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint);
+
+
+/***********************************************************************
+// export information
+************************************************************************/
+
+/* DLL export information */
+#if !defined(__LZO_EXPORT1)
+# define __LZO_EXPORT1
+#endif
+#if !defined(__LZO_EXPORT2)
+# define __LZO_EXPORT2
+#endif
+
+/* exported calling convention for C functions */
+#if !defined(LZO_PUBLIC)
+# define LZO_PUBLIC(_rettype) \
+ __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY
+#endif
+#if !defined(LZO_EXTERN)
+# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
+#endif
+#if !defined(LZO_PRIVATE)
+# define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY
+#endif
+
+/* exported __cdecl calling convention for assembler functions */
+#if !defined(LZO_PUBLIC_CDECL)
+# define LZO_PUBLIC_CDECL(_rettype) \
+ __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
+#endif
+#if !defined(LZO_EXTERN_CDECL)
+# define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype)
+#endif
+
+/* exported global variables (LZO currently uses no static variables and
+ * is fully thread safe) */
+#if !defined(LZO_PUBLIC_VAR)
+# define LZO_PUBLIC_VAR(_type) \
+ __LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL
+#endif
+#if !defined(LZO_EXTERN_VAR)
+# define LZO_EXTERN_VAR(_type) extern LZO_PUBLIC_VAR(_type)
+#endif
+
+
+/***********************************************************************
+// error codes and prototypes
+************************************************************************/
+
+/* Error codes for the compression/decompression functions. Negative
+ * values are errors, positive values will be used for special but
+ * normal events.
+ */
+#define LZO_E_OK 0
+#define LZO_E_ERROR (-1)
+#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
+#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
+#define LZO_E_INPUT_OVERRUN (-4)
+#define LZO_E_OUTPUT_OVERRUN (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN (-6)
+#define LZO_E_EOF_NOT_FOUND (-7)
+#define LZO_E_INPUT_NOT_CONSUMED (-8)
+
+
+/* lzo_init() should be the first function you call.
+ * Check the return code !
+ *
+ * lzo_init() is a macro to allow checking that the library and the
+ * compiler's view of various types are consistent.
+ */
+#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
+ (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
+ (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
+ (int)sizeof(lzo_compress_t))
+LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int);
+
+/* version functions (useful for shared libraries) */
+LZO_EXTERN(unsigned) lzo_version(void);
+LZO_EXTERN(const char *) lzo_version_string(void);
+LZO_EXTERN(const char *) lzo_version_date(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
+
+/* string functions */
+LZO_EXTERN(int)
+lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
+
+/* checksum functions */
+LZO_EXTERN(lzo_uint32)
+lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len);
+LZO_EXTERN(lzo_uint32)
+lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len);
+
+/* misc. */
+LZO_EXTERN(lzo_bool) lzo_assert(int _expr);
+LZO_EXTERN(int) _lzo_config_check(void);
+typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
+typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
+typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
+
+/* align a char pointer on a boundary that is a multiple of `size' */
+LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
+#define LZO_PTR_ALIGN_UP(_ptr,_size) \
+ ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
+
+/* deprecated - only for backward compatibility */
+#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size)
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* already included */
+
--- /dev/null
+/* minilzo.h -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef __MINILZO_H
+#define __MINILZO_H
+
+#define MINILZO_VERSION 0x1080
+
+#ifdef __LZOCONF_H
+# error "you cannot use both LZO and miniLZO"
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "lzoconf.h"
+
+#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
+# error "version mismatch in header files"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***********************************************************************
+//
+************************************************************************/
+
+/* Memory required for the wrkmem parameter.
+ * When the required size is 0, you can also pass a NULL pointer.
+ */
+
+#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
+#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
+#define LZO1X_MEM_DECOMPRESS (0)
+
+
+/* compression */
+LZO_EXTERN(int)
+lzo1x_1_compress ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+/* decompression */
+LZO_EXTERN(int)
+lzo1x_decompress ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+/* safe decompression with overrun testing */
+LZO_EXTERN(int)
+lzo1x_decompress_safe ( const lzo_byte *src, lzo_uint src_len,
+ lzo_byte *dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* already included */
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: pathnames.h,v 1.14 2003/10/26 16:05:46 stelian Exp $
+ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <paths.h>
+
+#ifdef __linux__
+#include <sys/mtio.h> /* use the same default tape as "mt" */
+#define _PATH_DEFTAPE DEFTAPE
+#endif
+
+#ifndef _PATH_DEFTAPE
+#ifdef __linux__
+#define _PATH_DEFTAPE "/dev/st0"
+#endif
+#ifdef sunos
+#define _PATH_DEFTAPE "/dev/rmt/0"
+#endif
+#endif
+
+#define _PATH_RMT "/etc/rmt" /* path on remote host */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: dumprestore.h,v 1.22 2004/07/01 09:14:49 stelian Exp $
+ */
+
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PROTOCOLS_DUMPRESTORE_H_
+#define _PROTOCOLS_DUMPRESTORE_H_
+
+#include <config.h>
+
+/*
+ * TP_BSIZE is the size of file blocks on the dump tapes.
+ * Note that TP_BSIZE must be a multiple of DEV_BSIZE.
+ *
+ * NTREC is the number of TP_BSIZE blocks that are written
+ * in each tape record. HIGHDENSITYTREC is the number of
+ * TP_BSIZE blocks that are written in each tape record on
+ * 6250 BPI or higher density tapes.
+ *
+ * TP_NINDIR is the number of indirect pointers in a TS_INODE
+ * or TS_ADDR record. Note that it must be a power of two.
+ */
+#define TP_BSIZE 1024
+#define NTREC 10
+#define HIGHDENSITYTREC 32
+#define TP_NINDIR (TP_BSIZE/2)
+#define TP_NINOS (TP_NINDIR / sizeof (int32_t))
+#define LBLSIZE 16
+#define NAMELEN 64
+
+#define OFS_MAGIC (int)60011
+#define NFS_MAGIC (int)60012
+#define FS_UFS2_MAGIC (int)0x19540119
+#define CHECKSUM (int)84446
+
+#ifdef __linux__
+typedef u_int32_t dump_ino_t;
+#endif
+
+#ifdef sunos
+typedef unsigned int dump_ino_t;
+#endif
+
+union u_data {
+ char s_addrs[TP_NINDIR]; /* 1 => data; 0 => hole in inode */
+ int32_t s_inos[TP_NINOS]; /* table of first inode on each volume */
+} u_data;
+
+union u_spcl {
+ char dummy[TP_BSIZE];
+ struct s_spcl {
+ int32_t c_type; /* record type (see below) */
+ int32_t c_date; /* date of this dump */
+ int32_t c_ddate; /* date of previous dump */
+ int32_t c_volume; /* dump volume number */
+ u_int32_t c_tapea; /* logical block of this record */
+ dump_ino_t c_inumber; /* number of inode */
+ int32_t c_magic; /* magic number (see above) */
+ int32_t c_checksum; /* record checksum */
+#ifdef __linux__
+ struct new_bsd_inode c_dinode;
+#else
+#ifdef sunos
+ struct new_bsd_inode c_dinode;
+#else
+ struct dinode c_dinode; /* ownership and mode of inode */
+#endif
+#endif
+ int32_t c_count; /* number of valid c_addr entries */
+ union u_data c_data; /* see above */
+ char c_label[LBLSIZE]; /* dump label */
+ int32_t c_level; /* level of this dump */
+ char c_filesys[NAMELEN]; /* name of dumpped file system */
+ char c_dev[NAMELEN]; /* name of dumpped device */
+ char c_host[NAMELEN]; /* name of dumpped host */
+ int32_t c_flags; /* additional information */
+ int32_t c_firstrec; /* first record on volume */
+ int32_t c_ntrec; /* blocksize on volume */
+ int32_t c_extattributes; /* additional inode info */
+ int32_t c_spare[30]; /* reserved for future uses */
+ } s_spcl;
+} u_spcl;
+#define spcl u_spcl.s_spcl
+#define c_addr c_data.s_addrs
+#define c_inos c_data.s_inos
+
+/*
+ * special record types
+ */
+#define TS_TAPE 1 /* dump tape header */
+#define TS_INODE 2 /* beginning of file record */
+#define TS_ADDR 4 /* continuation of file record */
+#define TS_BITS 3 /* map of inodes on tape */
+#define TS_CLRI 6 /* map of inodes deleted since last dump */
+#define TS_END 5 /* end of volume marker */
+
+/*
+ * flag values
+ */
+#define DR_NEWHEADER 0x0001 /* new format tape header */
+#define DR_NEWINODEFMT 0x0002 /* new format inodes on tape */
+#define DR_COMPRESSED 0x0080 /* dump tape is compressed */
+#define DR_METAONLY 0x0100 /* only the metadata of the inode has
+ been dumped */
+#define DR_INODEINFO 0x0002 /* TS_END header contains c_inos information */
+#define DR_EXTATTRIBUTES 0x8000
+
+/*
+ * extattributes inode info
+ */
+#define EXT_REGULAR 0
+#define EXT_MACOSFNDRINFO 1
+#define EXT_MACOSRESFORK 2
+#define EXT_ACL 3
+
+
+/*
+ * compression flags for the tapebuf header.
+ */
+#define COMPRESS_ZLIB 0
+#define COMPRESS_BZLIB 1
+#define COMPRESS_LZO 2
+
+/* used for compressed dump tapes */
+struct tapebuf {
+ unsigned int compressed:1;
+ unsigned int flags:3;
+ unsigned int length:28;
+#ifdef sunos
+ char buf;
+#else
+ char buf[0]; /* the data */
+#endif
+};
+
+#endif /* !_DUMPRESTORE_H_ */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: rmtflags.h,v 1.2 2003/03/30 15:40:34 stelian Exp $
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RMTFLAGS_H_
+#define _RMTFLAGS_H_
+
+int rmtflags_toint(char *filemode);
+char *rmtflags_tochar(int filemode);
+
+#endif
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: system.h,v 1.3 2003/03/30 15:40:34 stelian Exp $
+ */
+
+#ifndef _SYSTEM_H_
+#define _SYSTEM_H_
+
+int system_command(const char *command, const char *device, int volnum);
+
+#endif
--- /dev/null
+# $Id: Makefile.in,v 1.10 2003/05/08 21:11:39 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ../..
+
+@MCONFIG@
+
+INC= -I$(top_srcdir)/compat/include
+ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS)
+SRCS= compaterr.c compatglob.c bylabel.c system.c rmtflags.c minilzo.c
+OBJS= compaterr.o compatglob.o bylabel.o system.o rmtflags.o minilzo.o
+LIB= libcompat.a
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) r $(LIB) $(OBJS)
+ $(RANLIB) $(LIB)
+
+install::
+
+clean::
+ $(RM) -f \#* *.s *.o *.a *~ core
+
+distclean:: clean
+ $(RM) -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+
+ ============================================================================
+ miniLZO -- mini subset of the LZO real-time data compression library
+ ============================================================================
+
+ Author : Markus Franz Xaver Johannes Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ Version : 1.08
+ Date : 12-Jul-2002
+
+ I've created miniLZO for projects where it is inconvenient to
+ include (or require) the full LZO source code just because you
+ want to add a little bit of data compression to your application.
+
+ miniLZO implements the LZO1X-1 compressor and both the standard and
+ safe LZO1X decompressor. Apart from fast compression it also useful
+ for situations where you want to use pre-compressed data files (which
+ must have been compressed with LZO1X-999).
+
+ miniLZO consists of one C source file and two header files:
+ minilzo.c
+ minilzo.h
+ lzoconf.h
+
+ To use miniLZO just copy these files into your source directory, add
+ minilzo.c to your Makefile and #include minilzo.h from your program.
+ Note: you also must distribute this file (`README.LZO') with your project.
+
+ minilzo.o compiles to about 6 kB (using gcc or Visual C on a i386), and
+ the sources are about 14 kB when packed with zip - so there's no more
+ excuse that your application doesn't support data compression :-)
+
+ For more information, documentation, example programs and other support
+ files (like Makefiles and build scripts) please download the full LZO
+ package from
+ http://www.oberhumer.com/opensource/lzo/
+
+ Have fun,
+ Markus
+
+
+ P.S. minilzo.c is generated automatically from the LZO sources and
+ therefore functionality is completely identical
+
+
+ Appendix A: building miniLZO
+ ----------------------------
+ miniLZO is written such a way that it should compile and run
+ out-of-the-box on most machines.
+
+ If you are running on a very unusual architecture and lzo_init() fails then
+ you should first recompile with `-DLZO_DEBUG' to see what causes the failure.
+ The most probable case is something like `sizeof(char *) != sizeof(long)'.
+ After identifying the problem you can compile by adding some defines
+ like `-DSIZEOF_CHAR_P=8' to your Makefile.
+
+ The best solution is (of course) using Autoconf - if your project uses
+ Autoconf anyway just add `-DMINILZO_HAVE_CONFIG_H' to your compiler
+ flags when compiling minilzo.c. See the LZO distribution for an example
+ how to set up configure.in.
+
+
+ Appendix B: list of public functions available in miniLZO
+ ---------------------------------------------------------
+ Library initialization
+ lzo_init()
+
+ Compression
+ lzo1x_1_compress()
+
+ Decompression
+ lzo1x_decompress()
+ lzo1x_decompress_safe()
+
+ Checksum functions
+ lzo_adler32()
+
+ Version functions
+ lzo_version()
+ lzo_version_string()
+ lzo_version_date()
+
+ Portable (but slow) string functions
+ lzo_memcmp()
+ lzo_memcpy()
+ lzo_memmove()
+ lzo_memset()
+
+
+ Appendix C: suggested macros for `configure.in' when using Autoconf
+ -------------------------------------------------------------------
+ Checks for typedefs and structures
+ AC_CHECK_TYPE(ptrdiff_t,long)
+ AC_TYPE_SIZE_T
+ AC_CHECK_SIZEOF(unsigned short)
+ AC_CHECK_SIZEOF(unsigned)
+ AC_CHECK_SIZEOF(unsigned long)
+ AC_CHECK_SIZEOF(char *)
+ AC_CHECK_SIZEOF(ptrdiff_t)
+ AC_CHECK_SIZEOF(size_t)
+
+ Checks for compiler characteristics
+ AC_C_CONST
+
+ Checks for library functions
+ AC_CHECK_FUNCS(memcmp memcpy memmove memset)
+
+
+ Appendix D: Copyright
+ ---------------------
+ LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Markus Franz Xaver Johannes Oberhumer
+
+ LZO and miniLZO are distributed under the terms of the GNU General
+ Public License (GPL). See the file COPYING.
+
+ Special licenses for commercial and other applications which
+ are not willing to accept the GNU General Public License
+ are available by contacting the author.
+
+
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.7 (GNU/Linux)
+
+iD8DBQE9LPb4TWFXqwsgQ8kRAi/wAKCZ9Iej+voGhmKATaViOPS9chxGUwCgh5Dk
+uwMS2PQ7BXHT0vf4yz+3tTc=
+=PsNp
+-----END PGP SIGNATURE-----
--- /dev/null
+The copyright notice in appendix D of the file README.LZO fully applies.
+
+Hereby I grant a special license to the "Dump/restore utilities" project
+(currently hosted at http://dump.sourceforge.net ) to integrate the
+minilzo project (currently version 1.08 hosted at
+http://www.oberhumer.com/opensource/lzo) in source form. Both files,
+README.LZO and README2.LZO, must be distributed with the source of the
+"Dump/restore utilities".
+
+Markus Oberhumer, <markus@oberhumer.com>, http://www.oberhumer.com/
--- /dev/null
+/*
+ * mount_by_label.c - aeb
+ *
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+ * - added Native Language Support
+ * 2000-01-20 James Antill <james@and.org>
+ * - Added error message if /proc/partitions cannot be opened
+ * 2000-05-09 Erik Troan <ewt@redhat.com>
+ * - Added cache for UUID and disk labels
+ * Wed Aug 16 2000 Erik Troan <ewt@redhat.com>
+ * - Ported to dump/restore
+ */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <sys/cdefs.h>
+#include "bylabel.h"
+
+#ifndef HAVE_BLKID
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define DEVLABELDIR "/dev"
+
+#define EXT2_SUPER_OFFSET 1024
+#define EXT2_SUPER_SIZE sizeof(struct ext2_super_block)
+#define EXT2_SUPER_MAGIC 0xEF53
+
+#define VOLNAMSZ 16
+
+struct ext2_super_block {
+ unsigned char s_dummy1[56];
+ unsigned char s_magic[2];
+ unsigned char s_dummy2[46];
+ unsigned char s_uuid[16];
+ unsigned char s_volume_name[VOLNAMSZ];
+};
+#define ext2magic(s) ((unsigned int) s.s_magic[0] + (((unsigned int) s.s_magic[1]) << 8))
+
+void msg __P((const char *fmt, ...));
+
+static struct uuidCache_s {
+ struct uuidCache_s *next;
+ char uuid[16];
+ char *label;
+ char *device;
+} *uuidCache = NULL;
+
+/* for now, only ext2 is supported */
+static int
+get_label_uuid(const char *device, char **label, char *uuid) {
+
+ /* start with a test for ext2, taken from mount_guess_fstype */
+ /* should merge these later */
+ int fd;
+ struct ext2_super_block e2sb;
+
+ fd = OPEN(device, O_RDONLY);
+ if (fd < 0)
+ return 1;
+
+ if (LSEEK(fd, EXT2_SUPER_OFFSET, SEEK_SET) != EXT2_SUPER_OFFSET ||
+ read(fd, (char *) &e2sb, EXT2_SUPER_SIZE) != EXT2_SUPER_SIZE ||
+ ext2magic(e2sb) != EXT2_SUPER_MAGIC) {
+ close(fd);
+ return 1;
+ }
+
+ close(fd);
+
+ /* superblock is ext2 - now what is its label? */
+ memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
+ *label = malloc(VOLNAMSZ + 1);
+ strncpy(*label, e2sb.s_volume_name, VOLNAMSZ);
+ (*label)[VOLNAMSZ] = 0;
+
+ return 0;
+}
+
+static void
+uuidcache_addentry(char *device, char *label, char *uuid) {
+ struct uuidCache_s *last;
+
+ if (!uuidCache) {
+ last = uuidCache = (struct uuidCache_s *)malloc(sizeof(*uuidCache));
+ } else {
+ for (last = uuidCache; last->next; last = last->next) ;
+ last->next = (struct uuidCache_s *)malloc(sizeof(*uuidCache));
+ last = last->next;
+ }
+ last->next = NULL;
+ last->device = device;
+ last->label = label;
+ memcpy(last->uuid, uuid, sizeof(last->uuid));
+}
+
+static void
+uuidcache_init(void) {
+ char line[100];
+ char *s;
+ int ma, mi, sz;
+ static char ptname[100];
+ FILE *procpt;
+ char uuid[16], *label;
+ char device[110];
+ int firstPass;
+ int handleOnFirst;
+
+ if (uuidCache)
+ return;
+
+ procpt = fopen(PROC_PARTITIONS, "r");
+ if (!procpt)
+ return;
+
+ for (firstPass = 1; firstPass >= 0; firstPass--) {
+ fseek(procpt, 0, SEEK_SET);
+
+ while (fgets(line, sizeof(line), procpt)) {
+ if (sscanf (line, " %d %d %d %[^\n ]",
+ &ma, &mi, &sz, ptname) != 4)
+ continue;
+
+ /* skip extended partitions (heuristic: size 1) */
+ if (sz == 1)
+ continue;
+
+ /* look only at md devices on first pass */
+ handleOnFirst = !strncmp(ptname, "md", 2);
+ if (firstPass != handleOnFirst)
+ continue;
+
+ /* skip entire disk (minor 0, 64, ... on ide;
+ 0, 16, ... on sd) */
+ /* heuristic: partition name ends in a digit */
+
+ for(s = ptname; *s; s++);
+ if (isdigit(s[-1])) {
+ /*
+ * Note: this is a heuristic only - there is no reason
+ * why these devices should live in /dev.
+ * Perhaps this directory should be specifiable by option.
+ * One might for example have /devlabel with links to /dev
+ * for the devices that may be accessed in this way.
+ * (This is useful, if the cdrom on /dev/hdc must not
+ * be accessed.)
+ */
+ sprintf(device, "%s/%s", DEVLABELDIR, ptname);
+ if (!get_label_uuid(device, &label, uuid))
+ uuidcache_addentry(strdup(device), label, uuid);
+ }
+ }
+ }
+
+ fclose(procpt);
+}
+
+#define UUID 1
+#define VOL 2
+
+static char *
+get_spec_by_x(int n, const char *t) {
+ struct uuidCache_s *uc;
+
+ uuidcache_init();
+ uc = uuidCache;
+
+ while(uc) {
+ switch (n) {
+ case UUID:
+ if (!memcmp(t, uc->uuid, sizeof(uc->uuid)))
+ return strdup(uc->device);
+ break;
+ case VOL:
+ if (!strcmp(t, uc->label))
+ return strdup(uc->device);
+ break;
+ }
+ uc = uc->next;
+ }
+ return NULL;
+}
+
+static u_char
+fromhex(char c) {
+ if (isdigit(c))
+ return (c - '0');
+ else if (islower(c))
+ return (c - 'a' + 10);
+ else
+ return (c - 'A' + 10);
+}
+
+static char *
+get_spec_by_uuid(const char *s) {
+ u_char uuid[16];
+ int i;
+
+ if (strlen(s) != 36 ||
+ s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-')
+ goto bad_uuid;
+ for (i=0; i<16; i++) {
+ if (*s == '-') s++;
+ if (!isxdigit(s[0]) || !isxdigit(s[1]))
+ goto bad_uuid;
+ uuid[i] = ((fromhex(s[0])<<4) | fromhex(s[1]));
+ s += 2;
+ }
+ return get_spec_by_x(UUID, uuid);
+
+ bad_uuid:
+ msg("mount: bad UUID\n");
+ return NULL; /* just for gcc */
+}
+
+static char *
+get_spec_by_volume_label(const char *s) {
+ return get_spec_by_x(VOL, s);
+}
+
+const char *
+get_device_name(const char * item) {
+ const char * rc;
+
+ if (!strncmp(item, "UUID=", 5)) {
+ rc = get_spec_by_uuid(item+5);
+ }
+ else
+ if (!strncmp(item, "LABEL=", 6)) {
+ rc = get_spec_by_volume_label(item+6);
+ }
+ else {
+ rc = item;
+ }
+
+ return rc;
+}
+
+const char *
+get_device_label(const char * spec) {
+ struct uuidCache_s *uc;
+
+ uuidcache_init();
+ uc = uuidCache;
+
+ while(uc) {
+ if (!strcmp(spec, uc->device))
+ return uc->label[0] == '\0' ? NULL : strdup(uc->label);
+ uc = uc->next;
+ }
+ return NULL;
+}
+
+#endif /* !HAVE_BLKID */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: compaterr.c,v 1.11 2003/10/26 16:05:46 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/types.h>
+#include <compaterr.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern char *__progname; /* Program name, from crt0. */
+
+#if !defined(HAVE_ERR) || !defined(HAVE_ERRX) || !defined(HAVE_VERR) || !defined(HAVE_VERRX) || !defined(HAVE_VWARN) || !defined(HAVE_VWARNX) || !defined(HAVE_WARN) || !defined(HAVE_WARNX)
+
+__BEGIN_DECLS
+__dead void errc __P((int, int, const char *, ...));
+__dead void verrc __P((int, int, const char *, _BSD_VA_LIST_));
+void warnc __P((int, const char *, ...));
+void vwarnc __P((int, const char *, _BSD_VA_LIST_));
+void err_set_file __P((void *));
+void err_set_exit __P((void (*)(int)));
+__END_DECLS
+
+static void (*err_exit)(int);
+
+static FILE *err_file; /* file to use for error output */
+/*
+ * This is declared to take a `void *' so that the caller is not required
+ * to include <stdio.h> first. However, it is really a `FILE *', and the
+ * manual page documents it as such.
+ */
+void
+err_set_file(void *fp)
+{
+ if (fp)
+ err_file = fp;
+ else
+ err_file = stderr;
+}
+
+void
+err_set_exit(void (*ef)(int))
+{
+ err_exit = ef;
+}
+
+__dead void
+errc(int eval, int code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrc(eval, code, fmt, ap);
+ va_end(ap);
+}
+
+__dead void
+verrc(int eval, int code, const char *fmt, va_list ap)
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, ": ");
+ }
+ fprintf(err_file, "%s\n", strerror(code));
+ if (err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+
+void
+warnc(int code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnc(code, fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarnc(int code, const char *fmt, va_list ap)
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, ": ");
+ }
+ fprintf(err_file, "%s\n", strerror(code));
+}
+#endif
+
+#ifndef HAVE_ERR
+__dead void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrc(eval, errno, fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#ifndef HAVE_VERR
+__dead void
+verr(int eval, const char *fmt, va_list ap)
+{
+ verrc(eval, errno, fmt, ap);
+}
+#endif
+
+#ifndef HAVE_ERRX
+__dead void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#ifndef HAVE_VERRX
+__dead void
+verrx(int eval, const char *fmt, va_list ap)
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, "\n");
+ if (err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+#endif
+
+#ifndef HAVE_WARN
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnc(errno, fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#ifndef HAVE_VWARN
+void
+vwarn(const char *fmt, va_list ap)
+{
+ vwarnc(errno, fmt, ap);
+}
+#endif
+
+#ifndef HAVE_WARNX
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#ifndef HAVE_VWARNX
+void
+vwarnx(const char *fmt, va_list ap)
+{
+ if (err_file == 0)
+ err_set_file((FILE *)0);
+ fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ vfprintf(err_file, fmt, ap);
+ fprintf(err_file, "\n");
+}
+#endif
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ * Escaping convention: \ inhibits any special meaning the following
+ * character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ * Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ * Same as GLOB_NOCHECK, but it will only append pattern if it did
+ * not contain any magic characters. [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ * Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ * expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ * Number of matches in the current invocation of glob.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: compatglob.c,v 1.10 2003/10/26 16:05:46 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/types.h>
+
+#ifndef HAVE_GLOB
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <compatglob.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DOLLAR '$'
+#define DOT '.'
+#define EOS '\0'
+#define LBRACKET '['
+#define NOT '!'
+#define QUESTION '?'
+#define QUOTE '\\'
+#define RANGE '-'
+#define RBRACKET ']'
+#define SEP '/'
+#define STAR '*'
+#define TILDE '~'
+#define UNDERSCORE '_'
+#define LBRACE '{'
+#define RBRACE '}'
+#define SLASH '/'
+#define COMMA ','
+
+#ifndef DEBUG
+
+#define M_QUOTE 0x8000
+#define M_PROTECT 0x4000
+#define M_MASK 0xffff
+#define M_ASCII 0x00ff
+
+typedef u_short Char;
+
+#else
+
+#define M_QUOTE 0x80
+#define M_PROTECT 0x40
+#define M_MASK 0xff
+#define M_ASCII 0x7f
+
+typedef char Char;
+
+#endif
+
+
+#define CHAR(c) ((Char)((c)&M_ASCII))
+#define META(c) ((Char)((c)|M_QUOTE))
+#define M_ALL META('*')
+#define M_END META(']')
+#define M_NOT META('!')
+#define M_ONE META('?')
+#define M_RNG META('-')
+#define M_SET META('[')
+#define ismeta(c) (((c)&M_QUOTE) != 0)
+
+
+static int compare __P((const void *, const void *));
+static void g_Ctoc __P((const Char *, char *));
+static int g_lstat __P((Char *, struct stat *, glob_t *));
+static DIR *g_opendir __P((Char *, glob_t *));
+static Char *g_strchr __P((Char *, int));
+#ifdef notdef
+static Char *g_strcat __P((Char *, const Char *));
+#endif
+static int g_stat __P((Char *, struct stat *, glob_t *));
+static int glob0 __P((const Char *, glob_t *));
+static int glob1 __P((Char *, glob_t *));
+static int glob2 __P((Char *, Char *, Char *, glob_t *));
+static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
+static int globextend __P((const Char *, glob_t *));
+static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *));
+static int globexp1 __P((const Char *, glob_t *));
+static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
+static int match __P((Char *, Char *, Char *));
+#ifdef DEBUG
+static void qprintf __P((const char *, Char *));
+#endif
+
+int
+glob(const char *pattern, int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob)
+{
+ const u_char *patnext;
+ int c;
+ Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
+
+ patnext = (u_char *) pattern;
+ if (!(flags & GLOB_APPEND)) {
+ pglob->gl_pathc = 0;
+ pglob->gl_pathv = NULL;
+ if (!(flags & GLOB_DOOFFS))
+ pglob->gl_offs = 0;
+ }
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_errfunc = errfunc;
+ pglob->gl_matchc = 0;
+
+ bufnext = patbuf;
+ bufend = bufnext + MAXPATHLEN;
+ if (flags & GLOB_QUOTE) {
+ /* Protect the quoted characters. */
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ if (c == QUOTE) {
+ if ((c = *patnext++) == EOS) {
+ c = QUOTE;
+ --patnext;
+ }
+ *bufnext++ = c | M_PROTECT;
+ }
+ else
+ *bufnext++ = c;
+ }
+ else
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ *bufnext++ = c;
+ *bufnext = EOS;
+
+ if (flags & GLOB_BRACE)
+ return globexp1(patbuf, pglob);
+ else
+ return glob0(patbuf, pglob);
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int globexp1(const Char *pattern, glob_t *pglob)
+{
+ const Char* ptr = pattern;
+ int rv;
+
+ /* Protect a single {}, for find(1), like csh */
+ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
+ return glob0(pattern, pglob);
+
+ while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
+ if (!globexp2(ptr, pattern, pglob, &rv))
+ return rv;
+
+ return glob0(pattern, pglob);
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
+{
+ int i;
+ Char *lm, *ls;
+ const Char *pe, *pm, *pl;
+ Char patbuf[MAXPATHLEN + 1];
+
+ /* copy part up to the brace */
+ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+ continue;
+ ls = lm;
+
+ /* Find the balanced brace */
+ for (i = 0, pe = ++ptr; *pe; pe++)
+ if (*pe == LBRACKET) {
+ /* Ignore everything between [] */
+ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+ continue;
+ if (*pe == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pe = pm;
+ }
+ }
+ else if (*pe == LBRACE)
+ i++;
+ else if (*pe == RBRACE) {
+ if (i == 0)
+ break;
+ i--;
+ }
+
+ /* Non matching braces; just glob the pattern */
+ if (i != 0 || *pe == EOS) {
+ *rv = glob0(patbuf, pglob);
+ return 0;
+ }
+
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+ switch (*pm) {
+ case LBRACKET:
+ /* Ignore everything between [] */
+ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+ continue;
+ if (*pm == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pm = pl;
+ }
+ break;
+
+ case LBRACE:
+ i++;
+ break;
+
+ case RBRACE:
+ if (i) {
+ i--;
+ break;
+ }
+ /* FALLTHROUGH */
+ case COMMA:
+ if (i && *pm == COMMA)
+ break;
+ else {
+ /* Append the current string */
+ for (lm = ls; (pl < pm); *lm++ = *pl++)
+ continue;
+ /*
+ * Append the rest of the pattern after the
+ * closing brace
+ */
+ for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
+ continue;
+
+ /* Expand the current pattern */
+#ifdef DEBUG
+ qprintf("globexp2:", patbuf);
+#endif
+ *rv = globexp1(patbuf, pglob);
+
+ /* move after the comma, to the next string */
+ pl = pm + 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ *rv = 0;
+ return 0;
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b, *eb;
+
+ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /*
+ * Copy up to the end of the string or /
+ */
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
+ continue;
+
+ *h = EOS;
+
+ if (((char *) patbuf)[0] == EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME first if
+ * we're not running setuid or setgid) and then trying
+ * the password file
+ */
+ if (
+#if !defined(__linux__) && !defined(sunos)
+#ifndef __NETBSD_SYSCALLS
+ issetugid() != 0 ||
+#endif
+#endif
+ (h = getenv("HOME")) == NULL) {
+ if (((h = getlogin()) != NULL &&
+ (pwd = getpwnam(h)) != NULL) ||
+ (pwd = getpwuid(getuid())) != NULL)
+ h = pwd->pw_dir;
+ else
+ return pattern;
+ }
+ }
+ else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while (b < eb && (*b++ = *p++) != EOS)
+ continue;
+ *b = EOS;
+
+ return patbuf;
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested). Returns 0
+ * if things went well, nonzero if errors occurred. It is not an error
+ * to find no matches.
+ */
+static int
+glob0(const Char *pattern, glob_t *pglob)
+{
+ const Char *qpatnext;
+ int c, err, oldpathc;
+ Char *bufnext, patbuf[MAXPATHLEN+1];
+
+ qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char),
+ pglob);
+ oldpathc = pglob->gl_pathc;
+ bufnext = patbuf;
+
+ /* We don't need to check for buffer overflow any more. */
+ while ((c = *qpatnext++) != EOS) {
+ switch (c) {
+ case LBRACKET:
+ c = *qpatnext;
+ if (c == NOT)
+ ++qpatnext;
+ if (*qpatnext == EOS ||
+ g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
+ *bufnext++ = LBRACKET;
+ if (c == NOT)
+ --qpatnext;
+ break;
+ }
+ *bufnext++ = M_SET;
+ if (c == NOT)
+ *bufnext++ = M_NOT;
+ c = *qpatnext++;
+ do {
+ *bufnext++ = CHAR(c);
+ if (*qpatnext == RANGE &&
+ (c = qpatnext[1]) != RBRACKET) {
+ *bufnext++ = M_RNG;
+ *bufnext++ = CHAR(c);
+ qpatnext += 2;
+ }
+ } while ((c = *qpatnext++) != RBRACKET);
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_END;
+ break;
+ case QUESTION:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_ONE;
+ break;
+ case STAR:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ /* collapse adjacent stars to one,
+ * to avoid exponential behavior
+ */
+ if (bufnext == patbuf || bufnext[-1] != M_ALL)
+ *bufnext++ = M_ALL;
+ break;
+ default:
+ *bufnext++ = CHAR(c);
+ break;
+ }
+ }
+ *bufnext = EOS;
+#ifdef DEBUG
+ qprintf("glob0:", patbuf);
+#endif
+
+ if ((err = glob1(patbuf, pglob)) != 0)
+ return(err);
+
+ /*
+ * If there was no match we are going to append the pattern
+ * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+ * and the pattern did not contain any magic characters
+ * GLOB_NOMAGIC is there just for compatibility with csh.
+ */
+ if (pglob->gl_pathc == oldpathc &&
+ ((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR))))
+ return(globextend(pattern, pglob));
+ else if (!(pglob->gl_flags & GLOB_NOSORT))
+ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+ pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+ return(0);
+}
+
+static int
+compare(const void *p, const void *q)
+{
+ return(strcmp(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(Char *pattern, glob_t *pglob)
+{
+ Char pathbuf[MAXPATHLEN+1];
+
+ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+ if (*pattern == EOS)
+ return(0);
+ return(glob2(pathbuf, pathbuf, pattern, pglob));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob)
+{
+ struct stat sb;
+ Char *p, *q;
+ int anymeta;
+
+ /*
+ * Loop over pattern segments until end of pattern or until
+ * segment with meta character found.
+ */
+ for (anymeta = 0;;) {
+ if (*pattern == EOS) { /* End of pattern? */
+ *pathend = EOS;
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+
+ if (((pglob->gl_flags & GLOB_MARK) &&
+ pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
+ || (S_ISLNK(sb.st_mode) &&
+ (g_stat(pathbuf, &sb, pglob) == 0) &&
+ S_ISDIR(sb.st_mode)))) {
+ *pathend++ = SEP;
+ *pathend = EOS;
+ }
+ ++pglob->gl_matchc;
+ return(globextend(pathbuf, pglob));
+ }
+
+ /* Find end of next segment, copy tentatively to pathend. */
+ q = pathend;
+ p = pattern;
+ while (*p != EOS && *p != SEP) {
+ if (ismeta(*p))
+ anymeta = 1;
+ *q++ = *p++;
+ }
+
+ if (!anymeta) { /* No expansion, do next segment. */
+ pathend = q;
+ pattern = p;
+ while (*pattern == SEP)
+ *pathend++ = *pattern++;
+ } else /* Need expansion, recurse. */
+ return(glob3(pathbuf, pathend, pattern, p, pglob));
+ }
+ /* NOTREACHED */
+}
+
+static int
+glob3(Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern, glob_t *pglob)
+{
+ struct dirent *dp;
+ DIR *dirp;
+ int err;
+ char buf[MAXPATHLEN];
+
+ /*
+ * The readdirfunc declaration can't be prototyped, because it is
+ * assigned, below, to two functions which are prototyped in glob.h
+ * and dirent.h as taking pointers to differently typed opaque
+ * structures.
+ */
+ struct dirent *(*readdirfunc)();
+
+ *pathend = EOS;
+ errno = 0;
+
+ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+ /* TODO: don't call for ENOENT or ENOTDIR? */
+ if (pglob->gl_errfunc) {
+ g_Ctoc(pathbuf, buf);
+ if (pglob->gl_errfunc(buf, errno) ||
+ pglob->gl_flags & GLOB_ERR)
+ return (GLOB_ABEND);
+ }
+ return(0);
+ }
+
+ err = 0;
+
+ /* Search directory for matching names. */
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ readdirfunc = pglob->gl_readdir;
+ else
+ readdirfunc = readdir;
+ while ((dp = (*readdirfunc)(dirp))) {
+ u_char *sc;
+ Char *dc;
+
+ /* Initial DOT must be matched literally. */
+ if (dp->d_name[0] == DOT && *pattern != DOT)
+ continue;
+ for (sc = (u_char *) dp->d_name, dc = pathend;
+ (*dc++ = *sc++) != EOS;)
+ continue;
+ if (!match(pathend, pattern, restpattern)) {
+ *pathend = EOS;
+ continue;
+ }
+ err = glob2(pathbuf, --dc, restpattern, pglob);
+ if (err)
+ break;
+ }
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ (*pglob->gl_closedir)(dirp);
+ else
+ closedir(dirp);
+ return(err);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ * gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(const Char *path, glob_t *pglob)
+{
+ char **pathv;
+ int i;
+ u_int newsize;
+ char *copy;
+ const Char *p;
+
+ newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
+ pathv = pglob->gl_pathv ?
+ realloc((char *)pglob->gl_pathv, newsize) :
+ malloc(newsize);
+ if (pathv == NULL)
+ return(GLOB_NOSPACE);
+
+ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+ /* first time around -- clear initial gl_offs items */
+ pathv += pglob->gl_offs;
+ for (i = pglob->gl_offs; --i >= 0; )
+ *--pathv = NULL;
+ }
+ pglob->gl_pathv = pathv;
+
+ for (p = path; *p++;)
+ continue;
+ if ((copy = malloc(p - path)) != NULL) {
+ g_Ctoc(path, copy);
+ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+ return(copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+/*
+ * pattern matching function for filenames. Each occurrence of the *
+ * pattern causes a recursion level.
+ */
+static int
+match(Char *name, Char *pat, Char *patend)
+{
+ int ok, negate_range;
+ Char c, k;
+
+ while (pat < patend) {
+ c = *pat++;
+ switch (c & M_MASK) {
+ case M_ALL:
+ if (pat == patend)
+ return(1);
+ do
+ if (match(name, pat, patend))
+ return(1);
+ while (*name++ != EOS);
+ return(0);
+ case M_ONE:
+ if (*name++ == EOS)
+ return(0);
+ break;
+ case M_SET:
+ ok = 0;
+ if ((k = *name++) == EOS)
+ return(0);
+ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
+ ++pat;
+ while (((c = *pat++) & M_MASK) != M_END)
+ if ((*pat & M_MASK) == M_RNG) {
+ if (c <= k && k <= pat[1])
+ ok = 1;
+ pat += 2;
+ } else if (c == k)
+ ok = 1;
+ if (ok == negate_range)
+ return(0);
+ break;
+ default:
+ if (*name++ != c)
+ return(0);
+ break;
+ }
+ }
+ return(*name == EOS);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(glob_t *pglob)
+{
+ int i;
+ char **pp;
+
+ if (pglob->gl_pathv != NULL) {
+ pp = pglob->gl_pathv + pglob->gl_offs;
+ for (i = pglob->gl_pathc; i--; ++pp)
+ if (*pp)
+ free(*pp);
+ free(pglob->gl_pathv);
+ }
+}
+
+static DIR *
+g_opendir(Char *str, glob_t *pglob)
+{
+ char buf[MAXPATHLEN];
+
+ if (!*str)
+ strcpy(buf, ".");
+ else
+ g_Ctoc(str, buf);
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_opendir)(buf));
+
+ return(opendir(buf));
+}
+
+static int
+g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[MAXPATHLEN];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_lstat)(buf, sb));
+ return(lstat(buf, sb));
+}
+
+static int
+g_stat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[MAXPATHLEN];
+
+ g_Ctoc(fn, buf);
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_stat)(buf, sb));
+ return(stat(buf, sb));
+}
+
+static Char *
+g_strchr(Char *str, int ch)
+{
+ do {
+ if (*str == ch)
+ return (str);
+ } while (*str++);
+ return (NULL);
+}
+
+#ifdef notdef
+static Char *
+g_strcat(Char *dst, const Char *src)
+{
+ Char *sdst = dst;
+
+ while (*dst++)
+ continue;
+ --dst;
+ while((*dst++ = *src++) != EOS)
+ continue;
+
+ return (sdst);
+}
+#endif
+
+static void
+g_Ctoc(const Char *str, char *buf)
+{
+ char *dc;
+
+ for (dc = buf; (*dc++ = *str++) != EOS;)
+ continue;
+}
+
+#ifdef DEBUG
+static void
+qprintf(const char *str, Char *s)
+{
+ Char *p;
+
+ (void)printf("%s:\n", str);
+ for (p = s; *p; p++)
+ (void)printf("%c", CHAR(*p));
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", *p & M_PROTECT ? '"' : ' ');
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", ismeta(*p) ? '_' : ' ');
+ (void)printf("\n");
+}
+#endif
+
+#endif /* ! HAVE_GLOB */
--- /dev/null
+/* minilzo.c -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+#define __LZO_IN_MINILZO
+#define LZO_BUILD
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "minilzo.h"
+
+#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x1080)
+# error "version mismatch in miniLZO source files"
+#endif
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# define LZO_HAVE_CONFIG_H
+#endif
+
+#if !defined(LZO_NO_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+#include <stdio.h>
+
+#ifndef __LZO_CONF_H
+#define __LZO_CONF_H
+
+#if !defined(__LZO_IN_MINILZO)
+# ifndef __LZOCONF_H
+# include <lzoconf.h>
+# endif
+#endif
+
+#if defined(__BOUNDS_CHECKING_ON)
+# include <unchecked.h>
+#else
+# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt
+# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr)
+#endif
+
+#if !defined(LZO_HAVE_CONFIG_H)
+# include <stddef.h>
+# include <string.h>
+# if !defined(NO_STDLIB_H)
+# include <stdlib.h>
+# endif
+# define HAVE_MEMCMP
+# define HAVE_MEMCPY
+# define HAVE_MEMMOVE
+# define HAVE_MEMSET
+#else
+# include <sys/types.h>
+# if defined(HAVE_STDDEF_H)
+# include <stddef.h>
+# endif
+# if defined(STDC_HEADERS)
+# include <string.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# define HAVE_MALLOC_H
+# define HAVE_HALLOC
+#endif
+
+#undef NDEBUG
+#if !defined(LZO_DEBUG)
+# define NDEBUG
+#endif
+#if defined(LZO_DEBUG) || !defined(NDEBUG)
+# if !defined(NO_STDIO_H)
+# include <stdio.h>
+# endif
+#endif
+#include <assert.h>
+
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# define LZO_COMPILE_TIME_ASSERT(expr) \
+ { typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; }
+#endif
+
+#if !defined(LZO_UNUSED)
+# if 1
+# define LZO_UNUSED(var) ((void)&var)
+# elif 0
+# define LZO_UNUSED(var) { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; }
+# else
+# define LZO_UNUSED(parm) (parm = parm)
+# endif
+#endif
+
+#if !defined(__inline__) && !defined(__GNUC__)
+# if defined(__cplusplus)
+# define __inline__ inline
+# else
+# define __inline__
+# endif
+#endif
+
+#if defined(NO_MEMCMP)
+# undef HAVE_MEMCMP
+#endif
+
+#if !defined(HAVE_MEMCMP)
+# undef memcmp
+# define memcmp lzo_memcmp
+#endif
+#if !defined(HAVE_MEMCPY)
+# undef memcpy
+# define memcpy lzo_memcpy
+#endif
+#if !defined(HAVE_MEMMOVE)
+# undef memmove
+# define memmove lzo_memmove
+#endif
+#if !defined(HAVE_MEMSET)
+# undef memset
+# define memset lzo_memset
+#endif
+
+#if 0
+# define LZO_BYTE(x) ((unsigned char) (x))
+#else
+# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff))
+#endif
+
+#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
+#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
+#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
+#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
+
+#define lzo_sizeof(type) ((lzo_uint) (sizeof(type)))
+
+#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array))))
+
+#define LZO_SIZE(bits) (1u << (bits))
+#define LZO_MASK(bits) (LZO_SIZE(bits) - 1)
+
+#define LZO_LSIZE(bits) (1ul << (bits))
+#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1)
+
+#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits))
+#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1)
+
+#define LZO_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2)))
+#define LZO_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1)))
+
+#if !defined(SIZEOF_UNSIGNED)
+# if (UINT_MAX == 0xffff)
+# define SIZEOF_UNSIGNED 2
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED 4
+# elif (UINT_MAX >= LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED 8
+# else
+# error "SIZEOF_UNSIGNED"
+# endif
+#endif
+
+#if !defined(SIZEOF_UNSIGNED_LONG)
+# if (ULONG_MAX == LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED_LONG 4
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+# define SIZEOF_UNSIGNED_LONG 8
+# else
+# error "SIZEOF_UNSIGNED_LONG"
+# endif
+#endif
+
+#if !defined(SIZEOF_SIZE_T)
+# define SIZEOF_SIZE_T SIZEOF_UNSIGNED
+#endif
+#if !defined(SIZE_T_MAX)
+# define SIZE_T_MAX LZO_UTYPE_MAX(SIZEOF_SIZE_T)
+#endif
+
+#if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL)
+# if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff)
+# define LZO_UNALIGNED_OK_2
+# endif
+# if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL)
+# define LZO_UNALIGNED_OK_4
+# endif
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4)
+# if !defined(LZO_UNALIGNED_OK)
+# define LZO_UNALIGNED_OK
+# endif
+#endif
+
+#if defined(__LZO_NO_UNALIGNED)
+# undef LZO_UNALIGNED_OK
+# undef LZO_UNALIGNED_OK_2
+# undef LZO_UNALIGNED_OK_4
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff)
+# error "LZO_UNALIGNED_OK_2 must not be defined on this system"
+#endif
+#if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
+# error "LZO_UNALIGNED_OK_4 must not be defined on this system"
+#endif
+
+#if defined(__LZO_NO_ALIGNED)
+# undef LZO_ALIGNED_OK_4
+#endif
+
+#if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
+# error "LZO_ALIGNED_OK_4 must not be defined on this system"
+#endif
+
+#define LZO_LITTLE_ENDIAN 1234
+#define LZO_BIG_ENDIAN 4321
+#define LZO_PDP_ENDIAN 3412
+
+#if !defined(LZO_BYTE_ORDER)
+# if defined(MFX_BYTE_ORDER)
+# define LZO_BYTE_ORDER MFX_BYTE_ORDER
+# elif defined(__LZO_i386)
+# define LZO_BYTE_ORDER LZO_LITTLE_ENDIAN
+# elif defined(BYTE_ORDER)
+# define LZO_BYTE_ORDER BYTE_ORDER
+# elif defined(__BYTE_ORDER)
+# define LZO_BYTE_ORDER __BYTE_ORDER
+# endif
+#endif
+
+#if defined(LZO_BYTE_ORDER)
+# if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \
+ (LZO_BYTE_ORDER != LZO_BIG_ENDIAN)
+# error "invalid LZO_BYTE_ORDER"
+# endif
+#endif
+
+#if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER)
+# error "LZO_BYTE_ORDER is not defined"
+#endif
+
+#define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY
+
+#if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER)
+# if defined(__GNUC__) && defined(__i386__)
+# if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY)
+# define LZO_OPTIMIZE_GNUC_i386
+# endif
+# endif
+#endif
+
+__LZO_EXTERN_C int __lzo_init_done;
+__LZO_EXTERN_C const lzo_byte __lzo_copyright[];
+LZO_EXTERN(const lzo_byte *) lzo_copyright(void);
+__LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256];
+
+#define _LZO_STRINGIZE(x) #x
+#define _LZO_MEXPAND(x) _LZO_STRINGIZE(x)
+
+#define _LZO_CONCAT2(a,b) a ## b
+#define _LZO_CONCAT3(a,b,c) a ## b ## c
+#define _LZO_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define _LZO_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+
+#define _LZO_ECONCAT2(a,b) _LZO_CONCAT2(a,b)
+#define _LZO_ECONCAT3(a,b,c) _LZO_CONCAT3(a,b,c)
+#define _LZO_ECONCAT4(a,b,c,d) _LZO_CONCAT4(a,b,c,d)
+#define _LZO_ECONCAT5(a,b,c,d,e) _LZO_CONCAT5(a,b,c,d,e)
+
+#if 0
+
+#define __LZO_IS_COMPRESS_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w))
+#define __LZO_QUERY_COMPRESS(i,il,o,ol,w,n,s) \
+ (*ol = (n)*(s), LZO_E_OK)
+
+#define __LZO_IS_DECOMPRESS_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w))
+#define __LZO_QUERY_DECOMPRESS(i,il,o,ol,w,n,s) \
+ (*ol = (n)*(s), LZO_E_OK)
+
+#define __LZO_IS_OPTIMIZE_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w))
+#define __LZO_QUERY_OPTIMIZE(i,il,o,ol,w,n,s) \
+ (*ol = (n)*(s), LZO_E_OK)
+
+#endif
+
+#ifndef __LZO_PTR_H
+#define __LZO_PTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+# include <dos.h>
+# if 1 && defined(__WATCOMC__)
+# include <i86.h>
+ __LZO_EXTERN_C unsigned char _HShift;
+# define __LZO_HShift _HShift
+# elif 1 && defined(_MSC_VER)
+ __LZO_EXTERN_C unsigned short __near _AHSHIFT;
+# define __LZO_HShift ((unsigned) &_AHSHIFT)
+# elif defined(__LZO_WIN16)
+# define __LZO_HShift 3
+# else
+# define __LZO_HShift 12
+# endif
+# if !defined(_FP_SEG) && defined(FP_SEG)
+# define _FP_SEG FP_SEG
+# endif
+# if !defined(_FP_OFF) && defined(FP_OFF)
+# define _FP_OFF FP_OFF
+# endif
+#endif
+
+#if !defined(lzo_ptrdiff_t)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef ptrdiff_t lzo_ptrdiff_t;
+# else
+ typedef long lzo_ptrdiff_t;
+# endif
+#endif
+
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(lzo_ptr_t)
+# define __LZO_HAVE_PTR_T
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG)
+ typedef unsigned long lzo_ptr_t;
+ typedef long lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED)
+ typedef unsigned int lzo_ptr_t;
+ typedef int lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT)
+# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT)
+ typedef unsigned short lzo_ptr_t;
+ typedef short lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+# endif
+#endif
+#if !defined(__LZO_HAVE_PTR_T)
+# if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P)
+# error "no suitable type for lzo_ptr_t"
+# else
+ typedef unsigned long lzo_ptr_t;
+ typedef long lzo_sptr_t;
+# define __LZO_HAVE_PTR_T
+# endif
+#endif
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+#define PTR(a) ((lzo_bytep) (a))
+#define PTR_ALIGNED_4(a) ((_FP_OFF(a) & 3) == 0)
+#define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0)
+#else
+#define PTR(a) ((lzo_ptr_t) (a))
+#define PTR_LINEAR(a) PTR(a)
+#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0)
+#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0)
+#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
+#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
+#endif
+
+#define PTR_LT(a,b) (PTR(a) < PTR(b))
+#define PTR_GE(a,b) (PTR(a) >= PTR(b))
+#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
+#define pd(a,b) ((lzo_uint) ((a)-(b)))
+
+LZO_EXTERN(lzo_ptr_t)
+__lzo_ptr_linear(const lzo_voidp ptr);
+
+typedef union
+{
+ char a_char;
+ unsigned char a_uchar;
+ short a_short;
+ unsigned short a_ushort;
+ int a_int;
+ unsigned int a_uint;
+ long a_long;
+ unsigned long a_ulong;
+ lzo_int a_lzo_int;
+ lzo_uint a_lzo_uint;
+ lzo_int32 a_lzo_int32;
+ lzo_uint32 a_lzo_uint32;
+ ptrdiff_t a_ptrdiff_t;
+ lzo_ptrdiff_t a_lzo_ptrdiff_t;
+ lzo_ptr_t a_lzo_ptr_t;
+ lzo_voidp a_lzo_voidp;
+ void * a_void_p;
+ lzo_bytep a_lzo_bytep;
+ lzo_bytepp a_lzo_bytepp;
+ lzo_uintp a_lzo_uintp;
+ lzo_uint * a_lzo_uint_p;
+ lzo_uint32p a_lzo_uint32p;
+ lzo_uint32 * a_lzo_uint32_p;
+ unsigned char * a_uchar_p;
+ char * a_char_p;
+}
+lzo_full_align_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#define LZO_DETERMINISTIC
+
+#define LZO_DICT_USE_PTR
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT)
+# undef LZO_DICT_USE_PTR
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define lzo_dict_t const lzo_bytep
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#else
+# define lzo_dict_t lzo_uint
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#endif
+
+#if !defined(lzo_moff_t)
+#define lzo_moff_t lzo_uint
+#endif
+
+#endif
+
+LZO_PUBLIC(lzo_ptr_t)
+__lzo_ptr_linear(const lzo_voidp ptr)
+{
+ lzo_ptr_t p;
+
+#if defined(__LZO_DOS16) || defined(__LZO_WIN16)
+ p = (((lzo_ptr_t)(_FP_SEG(ptr))) << (16 - __LZO_HShift)) + (_FP_OFF(ptr));
+#else
+ p = PTR_LINEAR(ptr);
+#endif
+
+ return p;
+}
+
+LZO_PUBLIC(unsigned)
+__lzo_align_gap(const lzo_voidp ptr, lzo_uint size)
+{
+ lzo_ptr_t p, s, n;
+
+ assert(size > 0);
+
+ p = __lzo_ptr_linear(ptr);
+ s = (lzo_ptr_t) (size - 1);
+#if 0
+ assert((size & (size - 1)) == 0);
+ n = ((p + s) & ~s) - p;
+#else
+ n = (((p + s) / size) * size) - p;
+#endif
+
+ assert((long)n >= 0);
+ assert(n <= s);
+
+ return (unsigned)n;
+}
+
+#ifndef __LZO_UTIL_H
+#define __LZO_UTIL_H
+
+#ifndef __LZO_CONF_H
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 1 && defined(HAVE_MEMCPY)
+#if !defined(__LZO_DOS16) && !defined(__LZO_WIN16)
+
+#define MEMCPY8_DS(dest,src,len) \
+ memcpy(dest,src,len); \
+ dest += len; \
+ src += len
+
+#endif
+#endif
+
+#if 0 && !defined(MEMCPY8_DS)
+
+#define MEMCPY8_DS(dest,src,len) \
+ { do { \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ len -= 8; \
+ } while (len > 0); }
+
+#endif
+
+#if !defined(MEMCPY8_DS)
+
+#define MEMCPY8_DS(dest,src,len) \
+ { register lzo_uint __l = (len) / 8; \
+ do { \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ *dest++ = *src++; \
+ } while (--__l > 0); }
+
+#endif
+
+#define MEMCPY_DS(dest,src,len) \
+ do *dest++ = *src++; \
+ while (--len > 0)
+
+#define MEMMOVE_DS(dest,src,len) \
+ do *dest++ = *src++; \
+ while (--len > 0)
+
+#if 0 && defined(LZO_OPTIMIZE_GNUC_i386)
+
+#define BZERO8_PTR(s,l,n) \
+__asm__ __volatile__( \
+ "movl %0,%%eax \n" \
+ "movl %1,%%edi \n" \
+ "movl %2,%%ecx \n" \
+ "cld \n" \
+ "rep \n" \
+ "stosl %%eax,(%%edi) \n" \
+ : \
+ :"g" (0),"g" (s),"g" (n) \
+ :"eax","edi","ecx", "memory", "cc" \
+)
+
+#elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
+
+#if 1
+#define BZERO8_PTR(s,l,n) memset((s),0,(lzo_uint)(l)*(n))
+#else
+#define BZERO8_PTR(s,l,n) memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
+#endif
+
+#else
+
+#define BZERO8_PTR(s,l,n) \
+ lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
+
+#endif
+
+#if 0
+#if defined(__GNUC__) && defined(__i386__)
+
+unsigned char lzo_rotr8(unsigned char value, int shift);
+extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift)
+{
+ unsigned char result;
+
+ __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0"
+ : "=a"(result) : "g"(value), "c"(shift));
+ return result;
+}
+
+unsigned short lzo_rotr16(unsigned short value, int shift);
+extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift)
+{
+ unsigned short result;
+
+ __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0"
+ : "=a"(result) : "g"(value), "c"(shift));
+ return result;
+}
+
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+LZO_PUBLIC(lzo_bool)
+lzo_assert(int expr)
+{
+ return (expr) ? 1 : 0;
+}
+
+/* If you use the LZO library in a product, you *must* keep this
+ * copyright string in the executable of your product.
+ */
+
+const lzo_byte __lzo_copyright[] =
+#if !defined(__LZO_IN_MINLZO)
+ LZO_VERSION_STRING;
+#else
+ "\n\n\n"
+ "LZO real-time data compression library.\n"
+ "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n"
+ "<markus.oberhumer@jk.uni-linz.ac.at>\n"
+ "http://www.oberhumer.com/opensource/lzo/\n"
+ "\n"
+ "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n"
+ "LZO build date: " __DATE__ " " __TIME__ "\n\n"
+ "LZO special compilation options:\n"
+#ifdef __cplusplus
+ " __cplusplus\n"
+#endif
+#if defined(__PIC__)
+ " __PIC__\n"
+#elif defined(__pic__)
+ " __pic__\n"
+#endif
+#if (UINT_MAX < LZO_0xffffffffL)
+ " 16BIT\n"
+#endif
+#if defined(__LZO_STRICT_16BIT)
+ " __LZO_STRICT_16BIT\n"
+#endif
+#if (UINT_MAX > LZO_0xffffffffL)
+ " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n"
+#endif
+#if (ULONG_MAX > LZO_0xffffffffL)
+ " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n"
+#endif
+#if defined(LZO_BYTE_ORDER)
+ " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n"
+#endif
+#if defined(LZO_UNALIGNED_OK_2)
+ " LZO_UNALIGNED_OK_2\n"
+#endif
+#if defined(LZO_UNALIGNED_OK_4)
+ " LZO_UNALIGNED_OK_4\n"
+#endif
+#if defined(LZO_ALIGNED_OK_4)
+ " LZO_ALIGNED_OK_4\n"
+#endif
+#if defined(LZO_DICT_USE_PTR)
+ " LZO_DICT_USE_PTR\n"
+#endif
+#if defined(__LZO_QUERY_COMPRESS)
+ " __LZO_QUERY_COMPRESS\n"
+#endif
+#if defined(__LZO_QUERY_DECOMPRESS)
+ " __LZO_QUERY_DECOMPRESS\n"
+#endif
+#if defined(__LZO_IN_MINILZO)
+ " __LZO_IN_MINILZO\n"
+#endif
+ "\n\n"
+ "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__
+#if defined(__GNUC__) && defined(__VERSION__)
+ " by gcc " __VERSION__
+#elif defined(__BORLANDC__)
+ " by Borland C " _LZO_MEXPAND(__BORLANDC__)
+#elif defined(_MSC_VER)
+ " by Microsoft C " _LZO_MEXPAND(_MSC_VER)
+#elif defined(__PUREC__)
+ " by Pure C " _LZO_MEXPAND(__PUREC__)
+#elif defined(__SC__)
+ " by Symantec C " _LZO_MEXPAND(__SC__)
+#elif defined(__TURBOC__)
+ " by Turbo C " _LZO_MEXPAND(__TURBOC__)
+#elif defined(__WATCOMC__)
+ " by Watcom C " _LZO_MEXPAND(__WATCOMC__)
+#endif
+ " $\n"
+ "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n";
+#endif
+
+LZO_PUBLIC(const lzo_byte *)
+lzo_copyright(void)
+{
+ return __lzo_copyright;
+}
+
+LZO_PUBLIC(unsigned)
+lzo_version(void)
+{
+ return LZO_VERSION;
+}
+
+LZO_PUBLIC(const char *)
+lzo_version_string(void)
+{
+ return LZO_VERSION_STRING;
+}
+
+LZO_PUBLIC(const char *)
+lzo_version_date(void)
+{
+ return LZO_VERSION_DATE;
+}
+
+LZO_PUBLIC(const lzo_charp)
+_lzo_version_string(void)
+{
+ return LZO_VERSION_STRING;
+}
+
+LZO_PUBLIC(const lzo_charp)
+_lzo_version_date(void)
+{
+ return LZO_VERSION_DATE;
+}
+
+#define LZO_BASE 65521u
+#define LZO_NMAX 5552
+
+#define LZO_DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1);
+#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2);
+#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4);
+#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
+
+LZO_PUBLIC(lzo_uint32)
+lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len)
+{
+ lzo_uint32 s1 = adler & 0xffff;
+ lzo_uint32 s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == NULL)
+ return 1;
+
+ while (len > 0)
+ {
+ k = len < LZO_NMAX ? (int) len : LZO_NMAX;
+ len -= k;
+ if (k >= 16) do
+ {
+ LZO_DO16(buf,0);
+ buf += 16;
+ k -= 16;
+ } while (k >= 16);
+ if (k != 0) do
+ {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k > 0);
+ s1 %= LZO_BASE;
+ s2 %= LZO_BASE;
+ }
+ return (s2 << 16) | s1;
+}
+
+LZO_PUBLIC(int)
+lzo_memcmp(const lzo_voidp s1, const lzo_voidp s2, lzo_uint len)
+{
+#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP)
+ return memcmp(s1,s2,len);
+#else
+ const lzo_byte *p1 = (const lzo_byte *) s1;
+ const lzo_byte *p2 = (const lzo_byte *) s2;
+ int d;
+
+ if (len > 0) do
+ {
+ d = *p1 - *p2;
+ if (d != 0)
+ return d;
+ p1++;
+ p2++;
+ }
+ while (--len > 0);
+ return 0;
+#endif
+}
+
+LZO_PUBLIC(lzo_voidp)
+lzo_memcpy(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
+{
+#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY)
+ return memcpy(dest,src,len);
+#else
+ lzo_byte *p1 = (lzo_byte *) dest;
+ const lzo_byte *p2 = (const lzo_byte *) src;
+
+ if (len <= 0 || p1 == p2)
+ return dest;
+ do
+ *p1++ = *p2++;
+ while (--len > 0);
+ return dest;
+#endif
+}
+
+LZO_PUBLIC(lzo_voidp)
+lzo_memmove(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
+{
+#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE)
+ return memmove(dest,src,len);
+#else
+ lzo_byte *p1 = (lzo_byte *) dest;
+ const lzo_byte *p2 = (const lzo_byte *) src;
+
+ if (len <= 0 || p1 == p2)
+ return dest;
+
+ if (p1 < p2)
+ {
+ do
+ *p1++ = *p2++;
+ while (--len > 0);
+ }
+ else
+ {
+ p1 += len;
+ p2 += len;
+ do
+ *--p1 = *--p2;
+ while (--len > 0);
+ }
+ return dest;
+#endif
+}
+
+LZO_PUBLIC(lzo_voidp)
+lzo_memset(lzo_voidp s, int c, lzo_uint len)
+{
+#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
+ return memset(s,c,len);
+#else
+ lzo_byte *p = (lzo_byte *) s;
+
+ if (len > 0) do
+ *p++ = LZO_BYTE(c);
+ while (--len > 0);
+ return s;
+#endif
+}
+
+#if 0
+# define IS_SIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) < 0)
+# define IS_UNSIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) > 0)
+#else
+# define IS_SIGNED(type) (((type) (-1)) < ((type) 0))
+# define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0))
+#endif
+
+#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
+
+static lzo_bool schedule_insns_bug(void);
+static lzo_bool strength_reduce_bug(int *);
+
+#if 0 || defined(LZO_DEBUG)
+#include <stdio.h>
+static lzo_bool __lzo_assert_fail(const char *s, unsigned line)
+{
+#if defined(__palmos__)
+ printf("LZO assertion failed in line %u: '%s'\n",line,s);
+#else
+ fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s);
+#endif
+ return 0;
+}
+# define __lzo_assert(x) ((x) ? 1 : __lzo_assert_fail(#x,__LINE__))
+#else
+# define __lzo_assert(x) ((x) ? 1 : 0)
+#endif
+
+#undef COMPILE_TIME_ASSERT
+#if 0
+# define COMPILE_TIME_ASSERT(expr) r &= __lzo_assert(expr)
+#else
+# define COMPILE_TIME_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr)
+#endif
+
+static lzo_bool basic_integral_check(void)
+{
+ lzo_bool r = 1;
+
+ COMPILE_TIME_ASSERT(CHAR_BIT == 8);
+ COMPILE_TIME_ASSERT(sizeof(char) == 1);
+ COMPILE_TIME_ASSERT(sizeof(short) >= 2);
+ COMPILE_TIME_ASSERT(sizeof(long) >= 4);
+ COMPILE_TIME_ASSERT(sizeof(int) >= sizeof(short));
+ COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(int));
+
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint) == sizeof(lzo_int));
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == sizeof(lzo_int32));
+
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= 4);
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= sizeof(unsigned));
+#if defined(__LZO_STRICT_16BIT)
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint) == 2);
+#else
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= 4);
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= sizeof(unsigned));
+#endif
+
+#if (USHRT_MAX == 65535u)
+ COMPILE_TIME_ASSERT(sizeof(short) == 2);
+#elif (USHRT_MAX == LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(short) == 4);
+#elif (USHRT_MAX >= LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(short) > 4);
+#endif
+#if (UINT_MAX == 65535u)
+ COMPILE_TIME_ASSERT(sizeof(int) == 2);
+#elif (UINT_MAX == LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(int) == 4);
+#elif (UINT_MAX >= LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(int) > 4);
+#endif
+#if (ULONG_MAX == 65535ul)
+ COMPILE_TIME_ASSERT(sizeof(long) == 2);
+#elif (ULONG_MAX == LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(long) == 4);
+#elif (ULONG_MAX >= LZO_0xffffffffL)
+ COMPILE_TIME_ASSERT(sizeof(long) > 4);
+#endif
+
+#if defined(SIZEOF_UNSIGNED)
+ COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED == sizeof(unsigned));
+#endif
+#if defined(SIZEOF_UNSIGNED_LONG)
+ COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long));
+#endif
+#if defined(SIZEOF_UNSIGNED_SHORT)
+ COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short));
+#endif
+#if !defined(__LZO_IN_MINILZO)
+#if defined(SIZEOF_SIZE_T)
+ COMPILE_TIME_ASSERT(SIZEOF_SIZE_T == sizeof(size_t));
+#endif
+#endif
+
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned char));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned short));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned long));
+ COMPILE_TIME_ASSERT(IS_SIGNED(short));
+ COMPILE_TIME_ASSERT(IS_SIGNED(int));
+ COMPILE_TIME_ASSERT(IS_SIGNED(long));
+
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint32));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint));
+ COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int32));
+ COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int));
+
+ COMPILE_TIME_ASSERT(INT_MAX == LZO_STYPE_MAX(sizeof(int)));
+ COMPILE_TIME_ASSERT(UINT_MAX == LZO_UTYPE_MAX(sizeof(unsigned)));
+ COMPILE_TIME_ASSERT(LONG_MAX == LZO_STYPE_MAX(sizeof(long)));
+ COMPILE_TIME_ASSERT(ULONG_MAX == LZO_UTYPE_MAX(sizeof(unsigned long)));
+ COMPILE_TIME_ASSERT(SHRT_MAX == LZO_STYPE_MAX(sizeof(short)));
+ COMPILE_TIME_ASSERT(USHRT_MAX == LZO_UTYPE_MAX(sizeof(unsigned short)));
+ COMPILE_TIME_ASSERT(LZO_UINT32_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint32)));
+ COMPILE_TIME_ASSERT(LZO_UINT_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint)));
+#if !defined(__LZO_IN_MINILZO)
+ COMPILE_TIME_ASSERT(SIZE_T_MAX == LZO_UTYPE_MAX(sizeof(size_t)));
+#endif
+
+ r &= __lzo_assert(LZO_BYTE(257) == 1);
+
+ return r;
+}
+
+static lzo_bool basic_ptr_check(void)
+{
+ lzo_bool r = 1;
+
+ COMPILE_TIME_ASSERT(sizeof(char *) >= sizeof(int));
+ COMPILE_TIME_ASSERT(sizeof(lzo_byte *) >= sizeof(char *));
+
+ COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_byte *));
+ COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_voidpp));
+ COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_bytepp));
+ COMPILE_TIME_ASSERT(sizeof(lzo_voidp) >= sizeof(lzo_uint));
+
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_voidp));
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_sptr_t));
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) >= sizeof(lzo_uint));
+
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= 4);
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(ptrdiff_t));
+
+ COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t));
+ COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(lzo_uint));
+
+#if defined(SIZEOF_CHAR_P)
+ COMPILE_TIME_ASSERT(SIZEOF_CHAR_P == sizeof(char *));
+#endif
+#if defined(SIZEOF_PTRDIFF_T)
+ COMPILE_TIME_ASSERT(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t));
+#endif
+
+ COMPILE_TIME_ASSERT(IS_SIGNED(ptrdiff_t));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(size_t));
+ COMPILE_TIME_ASSERT(IS_SIGNED(lzo_ptrdiff_t));
+ COMPILE_TIME_ASSERT(IS_SIGNED(lzo_sptr_t));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_ptr_t));
+ COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_moff_t));
+
+ return r;
+}
+
+static lzo_bool ptr_check(void)
+{
+ lzo_bool r = 1;
+ int i;
+ char _wrkmem[10 * sizeof(lzo_byte *) + sizeof(lzo_full_align_t)];
+ lzo_bytep wrkmem;
+ lzo_bytepp dict;
+ unsigned char x[4 * sizeof(lzo_full_align_t)];
+ long d;
+ lzo_full_align_t a;
+ lzo_full_align_t u;
+
+ for (i = 0; i < (int) sizeof(x); i++)
+ x[i] = LZO_BYTE(i);
+
+ wrkmem = LZO_PTR_ALIGN_UP((lzo_byte *)_wrkmem,sizeof(lzo_full_align_t));
+
+#if 0
+ dict = (lzo_bytepp) wrkmem;
+#else
+
+ u.a_lzo_bytep = wrkmem; dict = u.a_lzo_bytepp;
+#endif
+
+ d = (long) ((const lzo_bytep) dict - (const lzo_bytep) _wrkmem);
+ r &= __lzo_assert(d >= 0);
+ r &= __lzo_assert(d < (long) sizeof(lzo_full_align_t));
+
+ memset(&a,0,sizeof(a));
+ r &= __lzo_assert(a.a_lzo_voidp == NULL);
+
+ memset(&a,0xff,sizeof(a));
+ r &= __lzo_assert(a.a_ushort == USHRT_MAX);
+ r &= __lzo_assert(a.a_uint == UINT_MAX);
+ r &= __lzo_assert(a.a_ulong == ULONG_MAX);
+ r &= __lzo_assert(a.a_lzo_uint == LZO_UINT_MAX);
+ r &= __lzo_assert(a.a_lzo_uint32 == LZO_UINT32_MAX);
+
+ if (r == 1)
+ {
+ for (i = 0; i < 8; i++)
+ r &= __lzo_assert((const lzo_voidp) (&dict[i]) == (const lzo_voidp) (&wrkmem[i * sizeof(lzo_byte *)]));
+ }
+
+ memset(&a,0,sizeof(a));
+ r &= __lzo_assert(a.a_char_p == NULL);
+ r &= __lzo_assert(a.a_lzo_bytep == NULL);
+ r &= __lzo_assert(NULL == (void *)0);
+ if (r == 1)
+ {
+ for (i = 0; i < 10; i++)
+ dict[i] = wrkmem;
+ BZERO8_PTR(dict+1,sizeof(dict[0]),8);
+ r &= __lzo_assert(dict[0] == wrkmem);
+ for (i = 1; i < 9; i++)
+ r &= __lzo_assert(dict[i] == NULL);
+ r &= __lzo_assert(dict[9] == wrkmem);
+ }
+
+ if (r == 1)
+ {
+ unsigned k = 1;
+ const unsigned n = (unsigned) sizeof(lzo_uint32);
+ lzo_byte *p0;
+ lzo_byte *p1;
+
+ k += __lzo_align_gap(&x[k],n);
+ p0 = (lzo_bytep) &x[k];
+#if defined(PTR_LINEAR)
+ r &= __lzo_assert((PTR_LINEAR(p0) & (n-1)) == 0);
+#else
+ r &= __lzo_assert(n == 4);
+ r &= __lzo_assert(PTR_ALIGNED_4(p0));
+#endif
+
+ r &= __lzo_assert(k >= 1);
+ p1 = (lzo_bytep) &x[1];
+ r &= __lzo_assert(PTR_GE(p0,p1));
+
+ r &= __lzo_assert(k < 1+n);
+ p1 = (lzo_bytep) &x[1+n];
+ r &= __lzo_assert(PTR_LT(p0,p1));
+
+ if (r == 1)
+ {
+ lzo_uint32 v0, v1;
+#if 0
+ v0 = * (lzo_uint32 *) &x[k];
+ v1 = * (lzo_uint32 *) &x[k+n];
+#else
+
+ u.a_uchar_p = &x[k];
+ v0 = *u.a_lzo_uint32_p;
+ u.a_uchar_p = &x[k+n];
+ v1 = *u.a_lzo_uint32_p;
+#endif
+ r &= __lzo_assert(v0 > 0);
+ r &= __lzo_assert(v1 > 0);
+ }
+ }
+
+ return r;
+}
+
+LZO_PUBLIC(int)
+_lzo_config_check(void)
+{
+ lzo_bool r = 1;
+ int i;
+ union {
+ lzo_uint32 a;
+ unsigned short b;
+ lzo_uint32 aa[4];
+ unsigned char x[4*sizeof(lzo_full_align_t)];
+ } u;
+
+ COMPILE_TIME_ASSERT( (int) ((unsigned char) ((signed char) -1)) == 255);
+ COMPILE_TIME_ASSERT( (((unsigned char)128) << (int)(8*sizeof(int)-8)) < 0);
+
+#if 0
+ r &= __lzo_assert((const void *)&u == (const void *)&u.a);
+ r &= __lzo_assert((const void *)&u == (const void *)&u.b);
+ r &= __lzo_assert((const void *)&u == (const void *)&u.x[0]);
+ r &= __lzo_assert((const void *)&u == (const void *)&u.aa[0]);
+#endif
+
+ r &= basic_integral_check();
+ r &= basic_ptr_check();
+ if (r != 1)
+ return LZO_E_ERROR;
+
+ u.a = 0; u.b = 0;
+ for (i = 0; i < (int) sizeof(u.x); i++)
+ u.x[i] = LZO_BYTE(i);
+
+#if defined(LZO_BYTE_ORDER)
+ if (r == 1)
+ {
+# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ lzo_uint32 a = (lzo_uint32) (u.a & LZO_0xffffffffL);
+ unsigned short b = (unsigned short) (u.b & 0xffff);
+ r &= __lzo_assert(a == 0x03020100L);
+ r &= __lzo_assert(b == 0x0100);
+# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
+ lzo_uint32 a = u.a >> (8 * sizeof(u.a) - 32);
+ unsigned short b = u.b >> (8 * sizeof(u.b) - 16);
+ r &= __lzo_assert(a == 0x00010203L);
+ r &= __lzo_assert(b == 0x0001);
+# else
+# error "invalid LZO_BYTE_ORDER"
+# endif
+ }
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2)
+ COMPILE_TIME_ASSERT(sizeof(short) == 2);
+ if (r == 1)
+ {
+ unsigned short b[4];
+
+ for (i = 0; i < 4; i++)
+ b[i] = * (const unsigned short *) &u.x[i];
+
+# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ r &= __lzo_assert(b[0] == 0x0100);
+ r &= __lzo_assert(b[1] == 0x0201);
+ r &= __lzo_assert(b[2] == 0x0302);
+ r &= __lzo_assert(b[3] == 0x0403);
+# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
+ r &= __lzo_assert(b[0] == 0x0001);
+ r &= __lzo_assert(b[1] == 0x0102);
+ r &= __lzo_assert(b[2] == 0x0203);
+ r &= __lzo_assert(b[3] == 0x0304);
+# endif
+ }
+#endif
+
+#if defined(LZO_UNALIGNED_OK_4)
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4);
+ if (r == 1)
+ {
+ lzo_uint32 a[4];
+
+ for (i = 0; i < 4; i++)
+ a[i] = * (const lzo_uint32 *) &u.x[i];
+
+# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ r &= __lzo_assert(a[0] == 0x03020100L);
+ r &= __lzo_assert(a[1] == 0x04030201L);
+ r &= __lzo_assert(a[2] == 0x05040302L);
+ r &= __lzo_assert(a[3] == 0x06050403L);
+# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
+ r &= __lzo_assert(a[0] == 0x00010203L);
+ r &= __lzo_assert(a[1] == 0x01020304L);
+ r &= __lzo_assert(a[2] == 0x02030405L);
+ r &= __lzo_assert(a[3] == 0x03040506L);
+# endif
+ }
+#endif
+
+#if defined(LZO_ALIGNED_OK_4)
+ COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4);
+#endif
+
+ COMPILE_TIME_ASSERT(lzo_sizeof_dict_t == sizeof(lzo_dict_t));
+
+#if defined(__LZO_IN_MINLZO)
+ if (r == 1)
+ {
+ lzo_uint32 adler;
+ adler = lzo_adler32(0, NULL, 0);
+ adler = lzo_adler32(adler, lzo_copyright(), 200);
+ r &= __lzo_assert(adler == 0xc76f1751L);
+ }
+#endif
+
+ if (r == 1)
+ {
+ r &= __lzo_assert(!schedule_insns_bug());
+ }
+
+ if (r == 1)
+ {
+ static int x[3];
+ static unsigned xn = 3;
+ register unsigned j;
+
+ for (j = 0; j < xn; j++)
+ x[j] = (int)j - 3;
+ r &= __lzo_assert(!strength_reduce_bug(x));
+ }
+
+ if (r == 1)
+ {
+ r &= ptr_check();
+ }
+
+ return r == 1 ? LZO_E_OK : LZO_E_ERROR;
+}
+
+static lzo_bool schedule_insns_bug(void)
+{
+#if defined(__LZO_CHECKER)
+ return 0;
+#else
+ const int clone[] = {1, 2, 0};
+ const int *q;
+ q = clone;
+ return (*q) ? 0 : 1;
+#endif
+}
+
+static lzo_bool strength_reduce_bug(int *x)
+{
+ return x[0] != -3 || x[1] != -2 || x[2] != -1;
+}
+
+#undef COMPILE_TIME_ASSERT
+
+int __lzo_init_done = 0;
+
+LZO_PUBLIC(int)
+__lzo_init2(unsigned v, int s1, int s2, int s3, int s4, int s5,
+ int s6, int s7, int s8, int s9)
+{
+ int r;
+
+ __lzo_init_done = 1;
+
+ if (v == 0)
+ return LZO_E_ERROR;
+
+ r = (s1 == -1 || s1 == (int) sizeof(short)) &&
+ (s2 == -1 || s2 == (int) sizeof(int)) &&
+ (s3 == -1 || s3 == (int) sizeof(long)) &&
+ (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) &&
+ (s5 == -1 || s5 == (int) sizeof(lzo_uint)) &&
+ (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) &&
+ (s7 == -1 || s7 == (int) sizeof(char *)) &&
+ (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) &&
+ (s9 == -1 || s9 == (int) sizeof(lzo_compress_t));
+ if (!r)
+ return LZO_E_ERROR;
+
+ r = _lzo_config_check();
+ if (r != LZO_E_OK)
+ return r;
+
+ return r;
+}
+
+#if !defined(__LZO_IN_MINILZO)
+
+LZO_EXTERN(int)
+__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7);
+
+LZO_PUBLIC(int)
+__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7)
+{
+ if (v == 0 || v > 0x1010)
+ return LZO_E_ERROR;
+ return __lzo_init2(v,s1,s2,s3,s4,s5,-1,-1,s6,s7);
+}
+
+#endif
+
+#define do_compress _lzo1x_1_do_compress
+
+#define LZO_NEED_DICT_H
+#define D_BITS 14
+#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5)
+#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
+
+#ifndef __LZO_CONFIG1X_H
+#define __LZO_CONFIG1X_H
+
+#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z)
+# define LZO1X
+#endif
+
+#if !defined(__LZO_IN_MINILZO)
+#include <lzo1x.h>
+#endif
+
+#define LZO_EOF_CODE
+#undef LZO_DETERMINISTIC
+
+#define M1_MAX_OFFSET 0x0400
+#ifndef M2_MAX_OFFSET
+#define M2_MAX_OFFSET 0x0800
+#endif
+#define M3_MAX_OFFSET 0x4000
+#define M4_MAX_OFFSET 0xbfff
+
+#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
+
+#define M1_MIN_LEN 2
+#define M1_MAX_LEN 2
+#define M2_MIN_LEN 3
+#ifndef M2_MAX_LEN
+#define M2_MAX_LEN 8
+#endif
+#define M3_MIN_LEN 3
+#define M3_MAX_LEN 33
+#define M4_MIN_LEN 3
+#define M4_MAX_LEN 9
+
+#define M1_MARKER 0
+#define M2_MARKER 64
+#define M3_MARKER 32
+#define M4_MARKER 16
+
+#ifndef MIN_LOOKAHEAD
+#define MIN_LOOKAHEAD (M2_MAX_LEN + 1)
+#endif
+
+#if defined(LZO_NEED_DICT_H)
+
+#ifndef LZO_HASH
+#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B
+#endif
+#define DL_MIN_LEN M2_MIN_LEN
+
+#ifndef __LZO_DICT_H
+#define __LZO_DICT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(D_BITS) && defined(DBITS)
+# define D_BITS DBITS
+#endif
+#if !defined(D_BITS)
+# error "D_BITS is not defined"
+#endif
+#if (D_BITS < 16)
+# define D_SIZE LZO_SIZE(D_BITS)
+# define D_MASK LZO_MASK(D_BITS)
+#else
+# define D_SIZE LZO_USIZE(D_BITS)
+# define D_MASK LZO_UMASK(D_BITS)
+#endif
+#define D_HIGH ((D_MASK >> 1) + 1)
+
+#if !defined(DD_BITS)
+# define DD_BITS 0
+#endif
+#define DD_SIZE LZO_SIZE(DD_BITS)
+#define DD_MASK LZO_MASK(DD_BITS)
+
+#if !defined(DL_BITS)
+# define DL_BITS (D_BITS - DD_BITS)
+#endif
+#if (DL_BITS < 16)
+# define DL_SIZE LZO_SIZE(DL_BITS)
+# define DL_MASK LZO_MASK(DL_BITS)
+#else
+# define DL_SIZE LZO_USIZE(DL_BITS)
+# define DL_MASK LZO_UMASK(DL_BITS)
+#endif
+
+#if (D_BITS != DL_BITS + DD_BITS)
+# error "D_BITS does not match"
+#endif
+#if (D_BITS < 8 || D_BITS > 18)
+# error "invalid D_BITS"
+#endif
+#if (DL_BITS < 8 || DL_BITS > 20)
+# error "invalid DL_BITS"
+#endif
+#if (DD_BITS < 0 || DD_BITS > 6)
+# error "invalid DD_BITS"
+#endif
+
+#if !defined(DL_MIN_LEN)
+# define DL_MIN_LEN 3
+#endif
+#if !defined(DL_SHIFT)
+# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
+#endif
+
+#define LZO_HASH_GZIP 1
+#define LZO_HASH_GZIP_INCREMENTAL 2
+#define LZO_HASH_LZO_INCREMENTAL_A 3
+#define LZO_HASH_LZO_INCREMENTAL_B 4
+
+#if !defined(LZO_HASH)
+# error "choose a hashing strategy"
+#endif
+
+#if (DL_MIN_LEN == 3)
+# define _DV2_A(p,shift1,shift2) \
+ (((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
+# define _DV2_B(p,shift1,shift2) \
+ (((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
+# define _DV3_B(p,shift1,shift2,shift3) \
+ ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
+#elif (DL_MIN_LEN == 2)
+# define _DV2_A(p,shift1,shift2) \
+ (( (lzo_uint32)(p[0]) << shift1) ^ p[1])
+# define _DV2_B(p,shift1,shift2) \
+ (( (lzo_uint32)(p[1]) << shift1) ^ p[2])
+#else
+# error "invalid DL_MIN_LEN"
+#endif
+#define _DV_A(p,shift) _DV2_A(p,shift,shift)
+#define _DV_B(p,shift) _DV2_B(p,shift,shift)
+#define DA2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
+#define DS2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
+#define DX2(p,s1,s2) \
+ (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
+#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
+#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
+#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
+#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
+#define DM(v) DMS(v,0)
+
+#if (LZO_HASH == LZO_HASH_GZIP)
+# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT))
+
+#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT)
+# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2])
+# define _DINDEX(dv,p) (dv)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
+# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_B((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5)))
+# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#else
+# error "choose a hashing strategy"
+#endif
+
+#ifndef DINDEX
+#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
+#endif
+#if !defined(DINDEX1) && defined(D_INDEX1)
+#define DINDEX1 D_INDEX1
+#endif
+#if !defined(DINDEX2) && defined(D_INDEX2)
+#define DINDEX2 D_INDEX2
+#endif
+
+#if !defined(__LZO_HASH_INCREMENTAL)
+# define DVAL_FIRST(dv,p) ((void) 0)
+# define DVAL_NEXT(dv,p) ((void) 0)
+# define DVAL_LOOKAHEAD 0
+#endif
+
+#if !defined(DVAL_ASSERT)
+#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
+static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p)
+{
+ lzo_uint32 df;
+ DVAL_FIRST(df,(p));
+ assert(DINDEX(dv,p) == DINDEX(df,p));
+}
+#else
+# define DVAL_ASSERT(dv,p) ((void) 0)
+#endif
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define DENTRY(p,in) (p)
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
+#else
+# define DENTRY(p,in) ((lzo_uint) ((p)-(in)))
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex]
+#endif
+
+#if (DD_BITS == 0)
+
+# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in)
+# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in)
+# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in)
+
+#else
+
+# define UPDATE_D(dict,drun,dv,p,in) \
+ dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_I(dict,drun,index,p,in) \
+ dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_P(ptr,drun,p,in) \
+ (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
+
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ (BOUNDS_CHECKING_OFF_IN_EXPR( \
+ (PTR_LT(m_pos,in) || \
+ (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
+ m_off > max_offset) ))
+
+#else
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_off == 0 || \
+ ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ ((lzo_moff_t) ((ip)-(in)) <= m_off || \
+ ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#endif
+
+#if defined(LZO_DETERMINISTIC)
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET
+#else
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+#endif
+
+#define DO_COMPRESS lzo1x_1_compress
+
+static
+lzo_uint do_compress ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+#if 0 && defined(__GNUC__) && defined(__i386__)
+ register const lzo_byte *ip __asm__("%esi");
+#else
+ register const lzo_byte *ip;
+#endif
+ lzo_byte *op;
+ const lzo_byte * const in_end = in + in_len;
+ const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5;
+ const lzo_byte *ii;
+ lzo_dict_p const dict = (lzo_dict_p) wrkmem;
+
+ op = out;
+ ip = in;
+ ii = ip;
+
+ ip += 4;
+ for (;;)
+ {
+#if 0 && defined(__GNUC__) && defined(__i386__)
+ register const lzo_byte *m_pos __asm__("%edi");
+#else
+ register const lzo_byte *m_pos;
+#endif
+ lzo_moff_t m_off;
+ lzo_uint m_len;
+ lzo_uint dindex;
+
+ DINDEX1(dindex,ip);
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+#if 1
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ DINDEX2(dindex,ip);
+#endif
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ goto literal;
+
+try_match:
+#if 1 && defined(LZO_UNALIGNED_OK_2)
+ if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
+#else
+ if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
+#endif
+ {
+ }
+ else
+ {
+ if (m_pos[2] == ip[2])
+ {
+#if 0
+ if (m_off <= M2_MAX_OFFSET)
+ goto match;
+ if (lit <= 3)
+ goto match;
+ if (lit == 3)
+ {
+ assert(op - 2 > out); op[-2] |= LZO_BYTE(3);
+ *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
+ goto code_match;
+ }
+ if (m_pos[3] == ip[3])
+#endif
+ goto match;
+ }
+ else
+ {
+#if 0
+#if 0
+ if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
+#else
+ if (m_off <= M1_MAX_OFFSET && lit == 3)
+#endif
+ {
+ register lzo_uint t;
+
+ t = lit;
+ assert(op - 2 > out); op[-2] |= LZO_BYTE(t);
+ do *op++ = *ii++; while (--t > 0);
+ assert(ii == ip);
+ m_off -= 1;
+ *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
+ *op++ = LZO_BYTE(m_off >> 2);
+ ip += 2;
+ goto match_done;
+ }
+#endif
+ }
+ }
+
+literal:
+ UPDATE_I(dict,0,dindex,ip,in);
+ ++ip;
+ if (ip >= ip_end)
+ break;
+ continue;
+
+match:
+ UPDATE_I(dict,0,dindex,ip,in);
+ if (pd(ip,ii) > 0)
+ {
+ register lzo_uint t = pd(ip,ii);
+
+ if (t <= 3)
+ {
+ assert(op - 2 > out);
+ op[-2] |= LZO_BYTE(t);
+ }
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ register lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ assert(ii == ip);
+ ip += 3;
+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
+ m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
+#ifdef LZO1Y
+ || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
+ || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
+#endif
+ )
+ {
+ --ip;
+ m_len = ip - ii;
+ assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
+
+ if (m_off <= M2_MAX_OFFSET)
+ {
+ m_off -= 1;
+#if defined(LZO1X)
+ *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
+ *op++ = LZO_BYTE(m_off >> 3);
+#elif defined(LZO1Y)
+ *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
+ *op++ = LZO_BYTE(m_off >> 2);
+#endif
+ }
+ else if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ goto m3_m4_offset;
+ }
+ else
+#if defined(LZO1X)
+ {
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ goto m3_m4_offset;
+ }
+#elif defined(LZO1Y)
+ goto m4_match;
+#endif
+ }
+ else
+ {
+ {
+ const lzo_byte *end = in_end;
+ const lzo_byte *m = m_pos + M2_MAX_LEN + 1;
+ while (ip < end && *m == *ip)
+ m++, ip++;
+ m_len = (ip - ii);
+ }
+ assert(m_len > M2_MAX_LEN);
+
+ if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ if (m_len <= 33)
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ else
+ {
+ m_len -= 33;
+ *op++ = M3_MARKER | 0;
+ goto m3_m4_len;
+ }
+ }
+ else
+ {
+#if defined(LZO1Y)
+m4_match:
+#endif
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ if (m_len <= M4_MAX_LEN)
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ else
+ {
+ m_len -= M4_MAX_LEN;
+ *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
+m3_m4_len:
+ while (m_len > 255)
+ {
+ m_len -= 255;
+ *op++ = 0;
+ }
+ assert(m_len > 0);
+ *op++ = LZO_BYTE(m_len);
+ }
+ }
+
+m3_m4_offset:
+ *op++ = LZO_BYTE((m_off & 63) << 2);
+ *op++ = LZO_BYTE(m_off >> 6);
+ }
+
+#if 0
+match_done:
+#endif
+ ii = ip;
+ if (ip >= ip_end)
+ break;
+ }
+
+ *out_len = op - out;
+ return pd(in_end,ii);
+}
+
+LZO_PUBLIC(int)
+DO_COMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+ lzo_byte *op = out;
+ lzo_uint t;
+
+#if defined(__LZO_QUERY_COMPRESS)
+ if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
+ return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t));
+#endif
+
+ if (in_len <= M2_MAX_LEN + 5)
+ t = in_len;
+ else
+ {
+ t = do_compress(in,in_len,op,out_len,wrkmem);
+ op += *out_len;
+ }
+
+ if (t > 0)
+ {
+ const lzo_byte *ii = in + in_len - t;
+
+ if (op == out && t <= 238)
+ *op++ = LZO_BYTE(17 + t);
+ else if (t <= 3)
+ op[-2] |= LZO_BYTE(t);
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ *op++ = M4_MARKER | 1;
+ *op++ = 0;
+ *op++ = 0;
+
+ *out_len = op - out;
+ return LZO_E_OK;
+}
+
+#undef do_compress
+#undef DO_COMPRESS
+#undef LZO_HASH
+
+#undef LZO_TEST_DECOMPRESS_OVERRUN
+#undef LZO_TEST_DECOMPRESS_OVERRUN_INPUT
+#undef LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT
+#undef LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN)
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LOOKBEHIND
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
+#else
+# define TEST_LOOKBEHIND(m_pos,op) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_byte *op;
+ register const lzo_byte *ip;
+ register lzo_uint t;
+#if defined(COPY_DICT)
+ lzo_uint m_off;
+ const lzo_byte *dict_end;
+#else
+ register const lzo_byte *m_pos;
+#endif
+
+ const lzo_byte * const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_byte * const op_end = out + *out_len;
+#endif
+#if defined(LZO1Z)
+ lzo_uint last_m_off = 0;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+#if defined(__LZO_QUERY_DECOMPRESS)
+ if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
+ return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);
+#endif
+
+#if defined(COPY_DICT)
+ if (dict)
+ {
+ if (dict_len > M4_MAX_OFFSET)
+ {
+ dict += dict_len - M4_MAX_OFFSET;
+ dict_len = M4_MAX_OFFSET;
+ }
+ dict_end = dict + dict_len;
+ }
+ else
+ {
+ dict_len = 0;
+ dict_end = NULL;
+ }
+#endif
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(3);
+ t = 3; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+
+ while (TEST_IP && TEST_OP)
+ {
+match:
+ if (t >= 64)
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1X)
+ m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ m_off = t & 0x1f;
+ if (m_off >= 0x1c)
+ m_off = last_m_off;
+ else
+ {
+ m_off = 1 + (m_off << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+ }
+ t = (t >> 5) - 1;
+#endif
+#else
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 3;
+ m_pos -= *ip++ << 2;
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ {
+ lzo_uint off = t & 0x1f;
+ m_pos = op;
+ if (off >= 0x1c)
+ {
+ assert(last_m_off > 0);
+ m_pos -= last_m_off;
+ }
+ else
+ {
+ off = 1 + (off << 6) + (*ip++ >> 2);
+ m_pos -= off;
+ last_m_off = off;
+ }
+ }
+ t = (t >> 5) - 1;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+#endif
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#else
+#if defined(LZO1Z)
+ {
+ lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ m_pos = op - off;
+ last_m_off = off;
+ }
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+#if defined(COPY_DICT)
+ m_off = (t & 8) << 11;
+#else
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+#endif
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off += (ip[0] << 6) + (ip[1] >> 2);
+#else
+ m_off += (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_off == 0)
+ goto eof_found;
+ m_off += 0x4000;
+#if defined(LZO1Z)
+ last_m_off = m_off;
+#endif
+#else
+#if defined(LZO1Z)
+ m_pos -= (ip[0] << 6) + (ip[1] >> 2);
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+#if defined(LZO1Z)
+ last_m_off = op - m_pos;
+#endif
+#endif
+ }
+ else
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(2);
+ t = 2; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = 1 + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+ }
+
+#if defined(COPY_DICT)
+
+ NEED_OP(t+3-1);
+ t += 3-1; COPY_DICT(t,m_off)
+
+#else
+
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+#endif
+
+match_done:
+#if defined(LZO1Z)
+ t = ip[-1] & 3;
+#else
+ t = ip[-2] & 3;
+#endif
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ t = *ip++;
+ }
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+#define LZO_TEST_DECOMPRESS_OVERRUN
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress_safe
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN)
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LOOKBEHIND
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+# define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
+#else
+# define TEST_LOOKBEHIND(m_pos,op) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len,
+ lzo_byte *out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_byte *op;
+ register const lzo_byte *ip;
+ register lzo_uint t;
+#if defined(COPY_DICT)
+ lzo_uint m_off;
+ const lzo_byte *dict_end;
+#else
+ register const lzo_byte *m_pos;
+#endif
+
+ const lzo_byte * const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_byte * const op_end = out + *out_len;
+#endif
+#if defined(LZO1Z)
+ lzo_uint last_m_off = 0;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+#if defined(__LZO_QUERY_DECOMPRESS)
+ if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
+ return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);
+#endif
+
+#if defined(COPY_DICT)
+ if (dict)
+ {
+ if (dict_len > M4_MAX_OFFSET)
+ {
+ dict += dict_len - M4_MAX_OFFSET;
+ dict_len = M4_MAX_OFFSET;
+ }
+ dict_end = dict + dict_len;
+ }
+ else
+ {
+ dict_len = 0;
+ dict_end = NULL;
+ }
+#endif
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(3);
+ t = 3; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+
+ while (TEST_IP && TEST_OP)
+ {
+match:
+ if (t >= 64)
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1X)
+ m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ m_off = t & 0x1f;
+ if (m_off >= 0x1c)
+ m_off = last_m_off;
+ else
+ {
+ m_off = 1 + (m_off << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+ }
+ t = (t >> 5) - 1;
+#endif
+#else
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 3;
+ m_pos -= *ip++ << 2;
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ {
+ lzo_uint off = t & 0x1f;
+ m_pos = op;
+ if (off >= 0x1c)
+ {
+ assert(last_m_off > 0);
+ m_pos -= last_m_off;
+ }
+ else
+ {
+ off = 1 + (off << 6) + (*ip++ >> 2);
+ m_pos -= off;
+ last_m_off = off;
+ }
+ }
+ t = (t >> 5) - 1;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+#endif
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#else
+#if defined(LZO1Z)
+ {
+ lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ m_pos = op - off;
+ last_m_off = off;
+ }
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+#if defined(COPY_DICT)
+ m_off = (t & 8) << 11;
+#else
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+#endif
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off += (ip[0] << 6) + (ip[1] >> 2);
+#else
+ m_off += (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_off == 0)
+ goto eof_found;
+ m_off += 0x4000;
+#if defined(LZO1Z)
+ last_m_off = m_off;
+#endif
+#else
+#if defined(LZO1Z)
+ m_pos -= (ip[0] << 6) + (ip[1] >> 2);
+#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+#if defined(LZO1Z)
+ last_m_off = op - m_pos;
+#endif
+#endif
+ }
+ else
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(2);
+ t = 2; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = 1 + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+ }
+
+#if defined(COPY_DICT)
+
+ NEED_OP(t+3-1);
+ t += 3-1; COPY_DICT(t,m_off)
+
+#else
+
+ TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+#endif
+
+match_done:
+#if defined(LZO1Z)
+ t = ip[-1] & 3;
+#else
+ t = ip[-2] & 3;
+#endif
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ t = *ip++;
+ }
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+/***** End of minilzo.c *****/
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: rmtflags.c,v 1.3 2003/03/30 15:40:35 stelian Exp $";
+#endif /* not linux */
+
+/*
+ * rmt
+ */
+#include <config.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <rmtflags.h>
+
+struct openflags {
+ char *name;
+ int value;
+} openflags[] = {
+ { "O_RDONLY", O_RDONLY },
+ { "O_WRONLY", O_WRONLY },
+ { "O_RDWR", O_RDWR },
+#ifdef O_CREAT
+ { "O_CREAT", O_CREAT },
+#endif
+#ifdef O_EXCL
+ { "O_EXCL", O_EXCL },
+#endif
+#ifdef O_NOCTTY
+ { "O_NOCTTY", O_NOCTTY },
+#endif
+#ifdef O_TRUNC
+ { "O_TRUNC", O_TRUNC },
+#endif
+#ifdef O_APPEND
+ { "O_APPEND", O_APPEND },
+#endif
+#ifdef O_NONBLOCK
+ { "O_NONBLOCK", O_NONBLOCK },
+#endif
+#ifdef O_NDELAY
+ { "O_NDELAY", O_NDELAY },
+#endif
+#ifdef O_SYNC
+ { "O_SYNC", O_SYNC },
+#endif
+#ifdef O_FSYNC
+ { "O_FSYNC", O_FSYNC },
+#endif
+#ifdef O_ASYNC
+ { "O_ASYNC", O_ASYNC },
+#endif
+#ifdef O_TEXT
+ { "O_TEXT", O_TEXT },
+#endif
+#ifdef O_DSYNC
+ { "O_DSYNC", O_DSYNC },
+#endif
+#ifdef O_RSYNC
+ { "O_RSYNC", O_RSYNC },
+#endif
+#ifdef O_PRIV
+ { "O_PRIV", O_PRIV },
+#endif
+#ifdef O_LARGEFILE
+ { "O_LARGEFILE",O_LARGEFILE },
+#endif
+ { NULL, 0 }
+};
+
+/* Parts of this stolen again from Jörg Schilling's star package... */
+int
+rmtflags_toint(char *filemode)
+{
+ char *p = filemode;
+ struct openflags *op;
+ int result = 0;
+ int numresult = 0;
+ int seentext = 0;
+
+ do {
+ /* skip space */
+ while (*p != '\0' && *p == ' ')
+ p++;
+ /* get O_XXXX constant */
+ if (p[0] != 'O' || p[1] != '_') {
+ /* numeric syntax detected */
+ numresult = atoi(filemode);
+ numresult &= O_RDONLY | O_WRONLY | O_RDWR;
+ while (*p != ' ' && *p != '\0')
+ p++;
+ while (*p != '\0' && *p == ' ')
+ p++;
+ }
+
+ if (*p == '\0')
+ break;
+
+ /* translate O_XXXX constant */
+ for (op = openflags; op->name; op++) {
+ int slen = strlen(op->name);
+ if ((strncmp(op->name, p, slen) == 0) &&
+ (p[slen] == '|' || p[slen] == ' ' ||
+ p[slen] == '\0')) {
+ seentext = 1;
+ result |= op->value;
+ break;
+ }
+ }
+
+ /* goto next constant */
+ p = strchr(p, '|');
+ } while (p && *p++ == '|');
+
+ if (!seentext)
+ result = numresult;
+ return result;
+}
+
+char *
+rmtflags_tochar(int filemode)
+{
+ struct openflags *op;
+ char *result = (char *) malloc(4096); /* enough space */
+
+ switch (filemode & O_ACCMODE) {
+ case O_RDONLY:
+ strcpy(result, "O_RDONLY");
+ break;
+ case O_WRONLY:
+ strcpy(result, "O_WRONLY");
+ break;
+ case O_RDWR:
+ strcpy(result, "O_RDWR");
+ break;
+ default:
+ strcat(result, "ERROR");
+ }
+ for (op = openflags; op->name; op++) {
+ if (op->value == O_RDONLY ||
+ op->value == O_WRONLY ||
+ op->value == O_RDWR)
+ continue;
+ if (filemode & op->value) {
+ strcat(result, "|");
+ strcat(result, op->name);
+ }
+ }
+ return result;
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: system.c,v 1.4 2003/03/30 15:40:35 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "system.h"
+
+/*
+ * Executes the command in a shell.
+ * Returns -1 if an error occured, the exit status of
+ * the command on success.
+ */
+int system_command(const char *command, const char *device, int volnum) {
+ int pid, status;
+ char commandstr[4096];
+
+ pid = fork();
+ if (pid == -1) {
+ perror(" DUMP: unable to fork");
+ return -1;
+ }
+ if (pid == 0) {
+ setuid(getuid());
+ setgid(getgid());
+#if OLD_STYLE_FSCRIPT
+ snprintf(commandstr, sizeof(commandstr), "%s", command);
+#else
+ snprintf(commandstr, sizeof(commandstr), "%s %s %d", command, device, volnum);
+#endif
+ commandstr[sizeof(commandstr) - 1] = '\0';
+ execl("/bin/sh", "sh", "-c", commandstr, NULL);
+ perror("unable to execute shell");
+ exit(-1);
+ }
+ do {
+ if (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR) {
+ perror("waitpid error");
+ return -1;
+ }
+ } else {
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else
+ return -1;
+ }
+ } while(1);
+}
+
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-07-23'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# This shell variable is my proudest work .. or something. --bje
+
+set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ;
+(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old)
+ || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ;
+dummy=$tmpdir/dummy ;
+files="$dummy.c $dummy.o $dummy.rel $dummy" ;
+trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ rm -f $files ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ;
+unset files'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ eval $set_cc_for_build
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ 2-1307)
+ UNAME_MACHINE="alphaev68"
+ ;;
+ 3-1307)
+ UNAME_MACHINE="alphaev7"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy && rmdir $tmpdir
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ fi ;;
+ esac
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ # Determine whether the default compiler uses glibc.
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #if __GLIBC__ >= 2
+ LIBC=gnu
+ #else
+ LIBC=
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ rm -f $dummy.c && rmdir $tmpdir
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:3*)
+ echo i386-pc-interix3
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ rm -f $dummy.c && rmdir $tmpdir
+ test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ rm -f $dummy.c && rmdir $tmpdir
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+rm -f $dummy.c $dummy && rmdir $tmpdir
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define this if you want to include Quick File Access debugging code. */
+#undef DEBUG_QFA
+
+/* Define this if you want to include Mac OSX restore compatibility. */
+#undef DUMP_MACOSX
+
+/* Define this if you have the blkid library. */
+#undef HAVE_BLKID
+
+/* Define this if you have bzlib compression library. */
+#undef HAVE_BZLIB
+
+/* Define to 1 if you have the `err' function. */
+#undef HAVE_ERR
+
+/* Define to 1 if you have the `errx' function. */
+#undef HAVE_ERRX
+
+/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
+#undef HAVE_EXT2FS_EXT2_FS_H
+
+/* Define if we have the ext2_ino_t type (from e2fsprogs 1.20+). */
+#undef HAVE_EXT2_INO_T
+
+/* Define if we have the s_journal_inum field in struct ext2_super_block. */
+#undef HAVE_EXT2_JOURNAL_INUM
+
+/* Define if you have the glob function. */
+#undef HAVE_GLOB
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `lchown' function. */
+#undef HAVE_LCHOWN
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you want to include readline support. */
+#undef HAVE_READLINE
+
+/* Define this if your readline libs have the rl_completion_append_character
+ variable. */
+#undef HAVE_READLINE_CAC
+
+/* Define this if your readline libs have the rl_completion_matches library.
+ */
+#undef HAVE_READLINE_RLCM
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `verr' function. */
+#undef HAVE_VERR
+
+/* Define to 1 if you have the `verrx' function. */
+#undef HAVE_VERRX
+
+/* Define to 1 if you have the `vwarn' function. */
+#undef HAVE_VWARN
+
+/* Define to 1 if you have the `vwarnx' function. */
+#undef HAVE_VWARNX
+
+/* Define to 1 if you have the `warn' function. */
+#undef HAVE_WARN
+
+/* Define to 1 if you have the `warnx' function. */
+#undef HAVE_WARNX
+
+/* Define this if you have zlib compression library. */
+#undef HAVE_ZLIB
+
+/* Define this is you want old style F script (no arguments). */
+#undef OLD_STYLE_FSCRIPT
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define this if you want Large File System support. */
+#undef USE_LFS
+
+/* Define this if you want Quick File Access support. */
+#undef USE_QFA
+
+/* Define to `int64_t' if <sys/types.h> does not define. */
+#undef quad_t
+
+/* Define to `uint64_t' if <sys/types.h> does not define. */
+#undef u_quad_t
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-07-03'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c54x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* \
+ | m32r-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipstx39 | mipstx39el \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3d)
+ basic_machine=alpha-cray
+ os=-unicos
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ windows32)
+ basic_machine=i386-pc
+ os=-windows32-msvcrt
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="dump/dump.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS SET_MAKE LN_S CP MV RM AR ac_ct_AR RANLIB ac_ct_RANLIB PATCH ac_ct_PATCH CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP DUMPDEBUG RESTOREDEBUG STATIC RMTDIR ERMT CRYPTO OPTDEFS READLINE LD CCOPTS LDOPTS BINOWNER BINGRP BINMODE MANOWNER MANGRP MANMODE DUMPDATESPATH BLKID ZLIB BZLIB top_builddir LIBOBJS LTLIBOBJS'
+ac_subst_files='MCONFIG'
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-debug include debugging code (default is NO)
+ --enable-static link dump and restore statically (default is NO)
+ --enable-staticz link libz and libbz2 statically (default is NO)
+ --enable-rmt compile and install rmt (default is YES)
+ --enable-ermt compile ermt, an encrypting version of rmt (default is NO)
+ --enable-kerberos compile kerberos extensions (default is NO)
+ --enable-readline enable readline support in restore (default is YES)
+ --enable-oldstylefscript enable old style F script (no arguments) (default is NO)
+ --enable-largefile enable Large File System support (default is YES)
+ --enable-qfa enable Quick File Access support (default is YES)
+ --enable-qfadebug include Quick File Access debugging code (default is NO)
+ --enable-macosx include Mac OSX restore compatibility (default is NO)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-cc=COMPILER select compiler to use
+ --with-linker=LINKER select linker to use
+ --with-ccopts=CCOPTS select compiler command line options
+ --with-ldopts=LDOPTS select linker command line options
+ --with-binowner=USER select owner for binaries
+ --with-bingrp=GROUP select group for binaries
+ --with-binmode=MODE select mode for binaries
+ --with-manowner=USER select owner for manual pages
+ --with-mangrp=GROUP select group for manual pages
+ --with-manmode=MODE select mode for manual pages
+ --with-dumpdatespath=PATH select path for dumpdates file
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MCONFIG=./MCONFIG
+
+
+ ac_config_headers="$ac_config_headers config.h"
+
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+# Extract the first word of "cp", so it can be a program name with args.
+set dummy cp; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $CP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CP="$CP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_CP" && ac_cv_path_CP="cp"
+ ;;
+esac
+fi
+CP=$ac_cv_path_CP
+
+if test -n "$CP"; then
+ echo "$as_me:$LINENO: result: $CP" >&5
+echo "${ECHO_T}$CP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "mv", so it can be a program name with args.
+set dummy mv; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MV+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MV in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MV="$MV" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_MV" && ac_cv_path_MV="mv"
+ ;;
+esac
+fi
+MV=$ac_cv_path_MV
+
+if test -n "$MV"; then
+ echo "$as_me:$LINENO: result: $MV" >&5
+echo "${ECHO_T}$MV" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "rm", so it can be a program name with args.
+set dummy rm; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_RM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $RM in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RM="$RM" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_RM" && ac_cv_path_RM="rm"
+ ;;
+esac
+fi
+RM=$ac_cv_path_RM
+
+if test -n "$RM"; then
+ echo "$as_me:$LINENO: result: $RM" >&5
+echo "${ECHO_T}$RM" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="ar"
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ AR=$ac_ct_AR
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}patch", so it can be a program name with args.
+set dummy ${ac_tool_prefix}patch; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_PATCH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$PATCH"; then
+ ac_cv_prog_PATCH="$PATCH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PATCH="${ac_tool_prefix}patch"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+PATCH=$ac_cv_prog_PATCH
+if test -n "$PATCH"; then
+ echo "$as_me:$LINENO: result: $PATCH" >&5
+echo "${ECHO_T}$PATCH" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_PATCH"; then
+ ac_ct_PATCH=$PATCH
+ # Extract the first word of "patch", so it can be a program name with args.
+set dummy patch; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_PATCH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_PATCH"; then
+ ac_cv_prog_ac_ct_PATCH="$ac_ct_PATCH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_PATCH="patch"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_PATCH" && ac_cv_prog_ac_ct_PATCH=":"
+fi
+fi
+ac_ct_PATCH=$ac_cv_prog_ac_ct_PATCH
+if test -n "$ac_ct_PATCH"; then
+ echo "$as_me:$LINENO: result: $ac_ct_PATCH" >&5
+echo "${ECHO_T}$ac_ct_PATCH" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ PATCH=$ac_ct_PATCH
+else
+ PATCH="$ac_cv_prog_PATCH"
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in sys/types.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+CPPFLAGS="-D_BSD_SOURCE -D_USE_BSD_SIGNAL ${CPPFLAGS}"
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+ enableval="$enable_debug"
+ if test "$enableval" = "no"
+then
+ DUMPDEBUG=""
+ RESTOREDEBUG=""
+ echo "Not including debugging code"
+else
+ DUMPDEBUG="-DFDEBUG -DTDEBUG -DWRITEDEBUG -DDIRDEBUG"
+ RESTOREDEBUG="-DDIRDEBUG"
+ echo "Including debugging code"
+fi
+else
+ DUMPDEBUG=""
+RESTOREDEBUG=""
+echo "Not including debugging code by default"
+
+fi;
+
+
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ if test "$enableval" = "no"
+then
+ STATIC=""
+ echo "Linking dump and restore dynamically"
+else
+ STATIC="-static"
+ echo "Linking dump and restore statically"
+fi
+
+else
+ STATIC=""
+echo "Linking dump and restore dynamically by default"
+
+fi;
+
+
+# Check whether --enable-staticz or --disable-staticz was given.
+if test "${enable_staticz+set}" = set; then
+ enableval="$enable_staticz"
+ if test "$enableval" = "no"
+then
+ STATICZ="no"
+ echo "Linking libz and libbz2 dynamically"
+else
+ STATICZ="yes"
+ echo "Linking libz and libbz2 statically"
+fi
+
+else
+ STATICZ="no"
+echo "Linking libz and libbz2 dynamically by default"
+
+fi;
+
+# Check whether --enable-rmt or --disable-rmt was given.
+if test "${enable_rmt+set}" = set; then
+ enableval="$enable_rmt"
+ if test "$enableval" = "no"
+then
+ RMTDIR=""
+ RMTMAKEFILE=""
+ echo "Not compiling rmt"
+else
+ RMTDIR="rmt"
+ RMTMAKEFILE="rmt/Makefile"
+ echo "Compiling rmt"
+fi
+
+else
+ RMTDIR="rmt"
+RMTMAKEFILE="rmt/Makefile"
+echo "Compiling rmt by default"
+
+fi;
+
+
+# Check whether --enable-ermt or --disable-ermt was given.
+if test "${enable_ermt+set}" = set; then
+ enableval="$enable_ermt"
+ if test "$enableval" = "no"
+then
+ ERMT=""
+ CRYPTO=""
+ echo "Not compiling ermt"
+else
+ if test "$RMTDIR" = ""
+ then
+ { { echo "$as_me:$LINENO: error: ermt requires --enable-rmt" >&5
+echo "$as_me: error: ermt requires --enable-rmt" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ERMT="ermt"
+ CRYPTO="-lcrypto"
+ echo "Compiling ermt"
+fi
+
+else
+ ERMT=""
+CRYPTO=""
+echo "Not compiling ermt by default"
+
+fi;
+
+
+
+# Check whether --enable-kerberos or --disable-kerberos was given.
+if test "${enable_kerberos+set}" = set; then
+ enableval="$enable_kerberos"
+ if test "$enableval" = "yes"
+then
+ OPTDEFS="-DKERBEROS"
+ echo "Compiling kerberos extensions"
+else
+ OPTDEFS=""
+ echo "Not compiling kerberos extensions"
+fi
+
+else
+ OPTDEFS=""
+echo "Not compiling kerberos extensions by default"
+
+fi;
+
+
+# Check whether --enable-readline or --disable-readline was given.
+if test "${enable_readline+set}" = set; then
+ enableval="$enable_readline"
+ if test "$enableval" = "no"
+then
+ READLINE=""
+ echo "Not including readline support"
+else
+ READLINE="-lreadline -ltermcap"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_READLINE 1
+_ACEOF
+
+ echo "Including readline support"
+fi
+
+else
+ READLINE="-lreadline -ltermcap"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_READLINE 1
+_ACEOF
+
+echo "Including readline support by default"
+
+fi;
+
+
+# Check whether --enable-oldstylefscript or --disable-oldstylefscript was given.
+if test "${enable_oldstylefscript+set}" = set; then
+ enableval="$enable_oldstylefscript"
+ if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define OLD_STYLE_FSCRIPT 1
+_ACEOF
+
+ echo "Using old style F script"
+else
+ echo "Using new style F script"
+fi
+
+else
+ echo "Using new style F script by default"
+
+fi;
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval="$enable_largefile"
+ if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_LFS 1
+_ACEOF
+
+ echo "Enabling Large File System support"
+else
+ echo "Not enabling Large File System support"
+fi
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_LFS 1
+_ACEOF
+
+echo "Enabling Large File System support by default"
+
+fi;
+
+# Check whether --enable-qfa or --disable-qfa was given.
+if test "${enable_qfa+set}" = set; then
+ enableval="$enable_qfa"
+ if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_QFA 1
+_ACEOF
+
+ echo "Enabling Quick File Access support"
+else
+ echo "Not enabling Quick File Access support"
+fi
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_QFA 1
+_ACEOF
+
+echo "Enabling Quick File Access support by default"
+
+fi;
+
+# Check whether --enable-qfadebug or --disable-qfadebug was given.
+if test "${enable_qfadebug+set}" = set; then
+ enableval="$enable_qfadebug"
+ if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define DEBUG_QFA 1
+_ACEOF
+
+ echo "Including Quick File Access debugging code"
+else
+ echo "Not including Quick File Access debugging code"
+fi
+
+else
+ echo "Not including Quick File Access debugging code by default"
+
+fi;
+
+# Check whether --enable-macosx or --disable-macosx was given.
+if test "${enable_macosx+set}" = set; then
+ enableval="$enable_macosx"
+ if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define DUMP_MACOSX 1
+_ACEOF
+
+ echo "Including Mac OSX restore compatibility code"
+else
+ echo "Not including Mac OSX restore compatibility code"
+fi
+
+else
+ echo "Not including Mac OSX restore compatibility code by default"
+
+fi;
+
+
+
+# Check whether --with-cc or --without-cc was given.
+if test "${with_cc+set}" = set; then
+ withval="$with_cc"
+ echo "$as_me:$LINENO: result: CC=$withval" >&5
+echo "${ECHO_T}CC=$withval" >&6
+CC=$withval
+else
+ if test -z "$CC" ; then CC=cc; fi
+echo "$as_me:$LINENO: result: CC defaults to $CC" >&5
+echo "${ECHO_T}CC defaults to $CC" >&6
+fi; export CC
+
+
+
+# Check whether --with-linker or --without-linker was given.
+if test "${with_linker+set}" = set; then
+ withval="$with_linker"
+ echo "$as_me:$LINENO: result: LD=$withval" >&5
+echo "${ECHO_T}LD=$withval" >&6
+LD=$withval
+else
+ if test -z "$LD" ; then LD=$CC; fi
+echo "$as_me:$LINENO: result: LD defaults to $LD" >&5
+echo "${ECHO_T}LD defaults to $LD" >&6
+fi; export LD
+
+
+
+# Check whether --with-ccopts or --without-ccopts was given.
+if test "${with_ccopts+set}" = set; then
+ withval="$with_ccopts"
+ echo "$as_me:$LINENO: result: CCOPTS is $withval" >&5
+echo "${ECHO_T}CCOPTS is $withval" >&6
+CCOPTS=$withval
+CFLAGS="$CFLAGS $withval"
+else
+ CCOPTS=
+fi;
+
+
+# Check whether --with-ldopts or --without-ldopts was given.
+if test "${with_ldopts+set}" = set; then
+ withval="$with_ldopts"
+ echo "$as_me:$LINENO: result: LDFLAGS is $withval" >&5
+echo "${ECHO_T}LDFLAGS is $withval" >&6
+LDOPTS=$withval
+LDFLAGS="$LDFLAGS $withval"
+else
+ LDOPTS=
+fi;
+
+
+# Check whether --with-binowner or --without-binowner was given.
+if test "${with_binowner+set}" = set; then
+ withval="$with_binowner"
+ echo "$as_me:$LINENO: result: BINOWNER is $withval" >&5
+echo "${ECHO_T}BINOWNER is $withval" >&6
+BINOWNER=$withval
+else
+ BINOWNER=root
+echo "BINOWNER defaults to $BINOWNER"
+
+fi;
+
+
+# Check whether --with-bingrp or --without-bingrp was given.
+if test "${with_bingrp+set}" = set; then
+ withval="$with_bingrp"
+ echo "$as_me:$LINENO: result: BINGRP is $withval" >&5
+echo "${ECHO_T}BINGRP is $withval" >&6
+BINGRP=$withval
+else
+ BINGRP=tty
+echo "BINGRP defaults to $BINGRP"
+
+fi;
+
+
+# Check whether --with-binmode or --without-binmode was given.
+if test "${with_binmode+set}" = set; then
+ withval="$with_binmode"
+ echo "$as_me:$LINENO: result: BINMODE is $withval" >&5
+echo "${ECHO_T}BINMODE is $withval" >&6
+BINMODE=$withval
+else
+ BINMODE=0755
+echo "BINMODE defaults to $BINMODE"
+
+fi;
+
+
+# Check whether --with-manowner or --without-manowner was given.
+if test "${with_manowner+set}" = set; then
+ withval="$with_manowner"
+ echo "$as_me:$LINENO: result: MANOWNER is $withval" >&5
+echo "${ECHO_T}MANOWNER is $withval" >&6
+MANOWNER=$withval
+else
+ MANOWNER=man
+echo "MANOWNER defaults to $MANOWNER"
+
+fi;
+
+
+# Check whether --with-mangrp or --without-mangrp was given.
+if test "${with_mangrp+set}" = set; then
+ withval="$with_mangrp"
+ echo "$as_me:$LINENO: result: MANGRP is $withval" >&5
+echo "${ECHO_T}MANGRP is $withval" >&6
+MANGRP=$withval
+else
+ MANGRP=tty
+echo "MANGRP defaults to $MANGRP"
+
+fi;
+
+
+# Check whether --with-manmode or --without-manmode was given.
+if test "${with_manmode+set}" = set; then
+ withval="$with_manmode"
+ echo "$as_me:$LINENO: result: MANMODE is $withval" >&5
+echo "${ECHO_T}MANMODE is $withval" >&6
+MANMODE=$withval
+else
+ MANMODE=0644
+echo "MANMODE defaults to $MANMODE"
+
+fi;
+
+
+# Check whether --with-dumpdatespath or --without-dumpdatespath was given.
+if test "${with_dumpdatespath+set}" = set; then
+ withval="$with_dumpdatespath"
+ echo "$as_me:$LINENO: result: DUMPDATESPATH is $withval" >&5
+echo "${ECHO_T}DUMPDATESPATH is $withval" >&6
+DUMPDATESPATH=$withval
+else
+ DUMPDATESPATH="${sysconfdir}/dumpdates"
+echo "DUMPDATESPATH defaults to $DUMPDATESPATH"
+
+fi;
+
+echo "$as_me:$LINENO: checking for ext2fs/ext2fs.h" >&5
+echo $ECHO_N "checking for ext2fs/ext2fs.h... $ECHO_C" >&6
+if test "${ac_cv_header_ext2fs_ext2fs_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ext2fs/ext2fs.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_ext2fs_ext2fs_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_ext2fs_ext2fs_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ext2fs_ext2fs_h" >&5
+echo "${ECHO_T}$ac_cv_header_ext2fs_ext2fs_h" >&6
+if test $ac_cv_header_ext2fs_ext2fs_h = yes; then
+ ext2fs_h=yes
+else
+ ext2fs_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for ext2fs_open in -lext2fs" >&5
+echo $ECHO_N "checking for ext2fs_open in -lext2fs... $ECHO_C" >&6
+if test "${ac_cv_lib_ext2fs_ext2fs_open+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lext2fs -lcom_err $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ext2fs_open ();
+int
+main ()
+{
+ext2fs_open ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_ext2fs_ext2fs_open=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ext2fs_ext2fs_open=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ext2fs_ext2fs_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ext2fs_ext2fs_open" >&6
+if test $ac_cv_lib_ext2fs_ext2fs_open = yes; then
+ ext2fs_lib=yes
+else
+ ext2fs_lib=no
+fi
+
+if test "$ext2fs_h" = no -o "$ext2fs_lib" = no; then
+ { { echo "$as_me:$LINENO: error: You need to install the Ext2fs libraries from the E2fsprogs distribution first - hint: make install-libs" >&5
+echo "$as_me: error: You need to install the Ext2fs libraries from the E2fsprogs distribution first - hint: make install-libs" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+for ac_header in ext2fs/ext2_fs.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for ext2_ino_t type in libext2fs headers" >&5
+echo $ECHO_N "checking for ext2_ino_t type in libext2fs headers... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+int
+main ()
+{
+ext2_ino_t ino = 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_EXT2_INO_T 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking for s_journal_inum field in ext2_super_block struct" >&5
+echo $ECHO_N "checking for s_journal_inum field in ext2_super_block struct... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+int
+main ()
+{
+struct ext2_super_block es; es.s_journal_inum = 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_EXT2_JOURNAL_INUM 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking for blkid/blkid.h" >&5
+echo $ECHO_N "checking for blkid/blkid.h... $ECHO_C" >&6
+if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <blkid/blkid.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_blkid_blkid_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_blkid_blkid_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_blkid_blkid_h" >&5
+echo "${ECHO_T}$ac_cv_header_blkid_blkid_h" >&6
+if test $ac_cv_header_blkid_blkid_h = yes; then
+ blkid_h=yes
+else
+ blkid_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for blkid_get_devname in -lblkid" >&5
+echo $ECHO_N "checking for blkid_get_devname in -lblkid... $ECHO_C" >&6
+if test "${ac_cv_lib_blkid_blkid_get_devname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lblkid -luuid $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char blkid_get_devname ();
+int
+main ()
+{
+blkid_get_devname ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_blkid_blkid_get_devname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_blkid_blkid_get_devname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_blkid_blkid_get_devname" >&5
+echo "${ECHO_T}$ac_cv_lib_blkid_blkid_get_devname" >&6
+if test $ac_cv_lib_blkid_blkid_get_devname = yes; then
+ blkid_lib=yes
+else
+ blkid_lib=no
+fi
+
+if test "$blkid_h" = yes -a "$blkid_lib" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BLKID 1
+_ACEOF
+
+ BLKID="-lblkid -luuid"
+fi
+
+
+echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_termcap_tgetent=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+ termcap_lib=yes
+else
+ termcap_lib=no
+fi
+
+if test "$termcap_lib" = no; then
+ if test "$READLINE" = "-lreadline -ltermcap"; then
+ { { echo "$as_me:$LINENO: error: You need to install the GNU termcap library or configure without --enable-readline" >&5
+echo "$as_me: error: You need to install the GNU termcap library or configure without --enable-readline" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+echo "$as_me:$LINENO: checking for readline/readline.h" >&5
+echo $ECHO_N "checking for readline/readline.h... $ECHO_C" >&6
+if test "${ac_cv_header_readline_readline_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <readline/readline.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_readline_readline_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_readline_readline_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_readline_readline_h" >&5
+echo "${ECHO_T}$ac_cv_header_readline_readline_h" >&6
+if test $ac_cv_header_readline_readline_h = yes; then
+ readline_h=yes
+else
+ readline_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
+echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6
+if test "${ac_cv_lib_readline_readline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline "-ltermcap" $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char readline ();
+int
+main ()
+{
+readline ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_readline_readline=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_readline=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6
+if test $ac_cv_lib_readline_readline = yes; then
+ readline_lib=yes
+else
+ readline_lib=no
+fi
+
+if test "$readline_h" = no -o "$readline_lib" = no; then
+ if test "$READLINE" = "-lreadline -ltermcap"; then
+ { { echo "$as_me:$LINENO: error: You need to install the GNU readline library or configure without --enable-readline" >&5
+echo "$as_me: error: You need to install the GNU readline library or configure without --enable-readline" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+echo "$as_me:$LINENO: checking for rl_completion_matches in -lreadline" >&5
+echo $ECHO_N "checking for rl_completion_matches in -lreadline... $ECHO_C" >&6
+if test "${ac_cv_lib_readline_rl_completion_matches+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline "-ltermcap" $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char rl_completion_matches ();
+int
+main ()
+{
+rl_completion_matches ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_readline_rl_completion_matches=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_rl_completion_matches=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_readline_rl_completion_matches" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_rl_completion_matches" >&6
+if test $ac_cv_lib_readline_rl_completion_matches = yes; then
+ rlcm=yes
+else
+ rlcm=no
+fi
+
+if test "$rlcm" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_READLINE_RLCM 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for rl_completion_append_character in -lreadline" >&5
+echo $ECHO_N "checking for rl_completion_append_character in -lreadline... $ECHO_C" >&6
+if test "${ac_cv_lib_readline_rl_completion_append_character+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline "-ltermcap" $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char rl_completion_append_character ();
+int
+main ()
+{
+rl_completion_append_character ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_readline_rl_completion_append_character=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_rl_completion_append_character=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_readline_rl_completion_append_character" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_rl_completion_append_character" >&6
+if test $ac_cv_lib_readline_rl_completion_append_character = yes; then
+ rcac=yes
+else
+ rcac=no
+fi
+
+if test "$rcac" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_READLINE_CAC 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for zlib.h" >&5
+echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <zlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_zlib_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_zlib_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_zlib_h" >&6
+if test $ac_cv_header_zlib_h = yes; then
+ zlib_h=yes
+else
+ zlib_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for compress2 in -lz" >&5
+echo $ECHO_N "checking for compress2 in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress2+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char compress2 ();
+int
+main ()
+{
+compress2 ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_z_compress2=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress2=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress2" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress2" >&6
+if test $ac_cv_lib_z_compress2 = yes; then
+ zlib_lib=yes
+else
+ zlib_lib=no
+fi
+
+if test "$zlib_h" = yes -a "$zlib_lib" = yes; then
+ if test "$STATICZ" = yes; then
+ ZLIB="-Wl,-Bstatic -lz -Wl,-Bdynamic"
+ else
+ ZLIB="-lz"
+ fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ZLIB 1
+_ACEOF
+
+else
+ ZLIB=""
+fi
+
+
+echo "$as_me:$LINENO: checking for bzlib.h" >&5
+echo $ECHO_N "checking for bzlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_bzlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <bzlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_bzlib_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_bzlib_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_bzlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_bzlib_h" >&6
+if test $ac_cv_header_bzlib_h = yes; then
+ bzlib_h=yes
+else
+ bzlib_h=no
+fi
+
+
+echo "$as_me:$LINENO: checking for BZ2_bzBuffToBuffCompress in -lbz2" >&5
+echo $ECHO_N "checking for BZ2_bzBuffToBuffCompress in -lbz2... $ECHO_C" >&6
+if test "${ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbz2 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char BZ2_bzBuffToBuffCompress ();
+int
+main ()
+{
+BZ2_bzBuffToBuffCompress ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&5
+echo "${ECHO_T}$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&6
+if test $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress = yes; then
+ bzlib_lib=yes
+else
+ bzlib_lib=no
+fi
+
+if test "$bzlib_h" = yes -a "$bzlib_lib" = yes; then
+ if test "$STATICZ" = yes; then
+ BZLIB="-Wl,-Bstatic -lbz2 -Wl,-Bdynamic"
+ else
+ BZLIB="-lbz2"
+ fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BZLIB 1
+_ACEOF
+
+else
+ BZLIB=""
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in err errx verr verrx vwarn vwarnx warn warnx realpath lchown
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for glob" >&5
+echo $ECHO_N "checking for glob... $ECHO_C" >&6
+if test "${ac_cv_func_glob+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define glob to an innocuous variant, in case <limits.h> declares glob.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define glob innocuous_glob
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char glob (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef glob
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char glob ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_glob) || defined (__stub___glob)
+choke me
+#else
+char (*f) () = glob;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != glob;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_glob=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_glob=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_glob" >&5
+echo "${ECHO_T}$ac_cv_func_glob" >&6
+
+
+echo "$as_me:$LINENO: checking for extended glob routines" >&5
+echo $ECHO_N "checking for extended glob routines... $ECHO_C" >&6
+if test "$ac_cv_func_glob" = "yes"; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+# include <glob.h>
+# ifdef GLOB_ALTDIRFUNC
+ yes
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GLOB 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ echo "Your system does not support extended glob, will use the internal routines"
+
+fi
+rm -f conftest*
+
+fi
+
+if test "$ERMT" != ""; then
+ if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/evp.h usability" >&5
+echo $ECHO_N "checking openssl/evp.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <openssl/evp.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/evp.h presence" >&5
+echo $ECHO_N "checking openssl/evp.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <openssl/evp.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/evp.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: openssl/evp.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: openssl/evp.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: openssl/evp.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: openssl/evp.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_openssl_evp_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+
+fi
+if test $ac_cv_header_openssl_evp_h = yes; then
+ evp_h=yes
+else
+ evp_h=no
+fi
+
+
+ echo "$as_me:$LINENO: checking for EVP_CIPHER_CTX_set_padding in -lcrypto" >&5
+echo $ECHO_N "checking for EVP_CIPHER_CTX_set_padding in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char EVP_CIPHER_CTX_set_padding ();
+int
+main ()
+{
+EVP_CIPHER_CTX_set_padding ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&6
+if test $ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding = yes; then
+ crypto_lib=yes
+else
+ crypto_lib=no
+fi
+
+ if test "$evp_h" = no -o "$crypto_lib" = no; then
+ { { echo "$as_me:$LINENO: error: You need to install the OpenSSL library (version 0.9.7a or later)" >&5
+echo "$as_me: error: You need to install the OpenSSL library (version 0.9.7a or later)" >&2;}
+ { (exit or configure without --enable-ermt); exit or configure without --enable-ermt; }; }
+ fi
+fi
+
+echo "$as_me:$LINENO: checking for quad_t" >&5
+echo $ECHO_N "checking for quad_t... $ECHO_C" >&6
+if test "${ac_cv_type_quad_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((quad_t *) 0)
+ return 0;
+if (sizeof (quad_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_quad_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_quad_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_quad_t" >&5
+echo "${ECHO_T}$ac_cv_type_quad_t" >&6
+if test $ac_cv_type_quad_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define quad_t int64_t
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for u_quad_t" >&5
+echo $ECHO_N "checking for u_quad_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_quad_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((u_quad_t *) 0)
+ return 0;
+if (sizeof (u_quad_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_u_quad_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_quad_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_quad_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_quad_t" >&6
+if test $ac_cv_type_u_quad_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define u_quad_t uint64_t
+_ACEOF
+
+fi
+
+
+top_builddir=`cd .; pwd`
+
+
+test -d compat || mkdir compat
+test -d compat/lib || mkdir compat/lib
+
+ ac_config_files="$ac_config_files MCONFIG Makefile common/Makefile compat/include/Makefile compat/lib/Makefile dump/Makefile restore/Makefile $RMTMAKEFILE"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "MCONFIG" ) CONFIG_FILES="$CONFIG_FILES MCONFIG" ;;
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "common/Makefile" ) CONFIG_FILES="$CONFIG_FILES common/Makefile" ;;
+ "compat/include/Makefile" ) CONFIG_FILES="$CONFIG_FILES compat/include/Makefile" ;;
+ "compat/lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES compat/lib/Makefile" ;;
+ "dump/Makefile" ) CONFIG_FILES="$CONFIG_FILES dump/Makefile" ;;
+ "restore/Makefile" ) CONFIG_FILES="$CONFIG_FILES restore/Makefile" ;;
+ "$RMTMAKEFILE" ) CONFIG_FILES="$CONFIG_FILES $RMTMAKEFILE" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@LN_S@,$LN_S,;t t
+s,@CP@,$CP,;t t
+s,@MV@,$MV,;t t
+s,@RM@,$RM,;t t
+s,@AR@,$AR,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@PATCH@,$PATCH,;t t
+s,@ac_ct_PATCH@,$ac_ct_PATCH,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@DUMPDEBUG@,$DUMPDEBUG,;t t
+s,@RESTOREDEBUG@,$RESTOREDEBUG,;t t
+s,@STATIC@,$STATIC,;t t
+s,@RMTDIR@,$RMTDIR,;t t
+s,@ERMT@,$ERMT,;t t
+s,@CRYPTO@,$CRYPTO,;t t
+s,@OPTDEFS@,$OPTDEFS,;t t
+s,@READLINE@,$READLINE,;t t
+s,@LD@,$LD,;t t
+s,@CCOPTS@,$CCOPTS,;t t
+s,@LDOPTS@,$LDOPTS,;t t
+s,@BINOWNER@,$BINOWNER,;t t
+s,@BINGRP@,$BINGRP,;t t
+s,@BINMODE@,$BINMODE,;t t
+s,@MANOWNER@,$MANOWNER,;t t
+s,@MANGRP@,$MANGRP,;t t
+s,@MANMODE@,$MANMODE,;t t
+s,@DUMPDATESPATH@,$DUMPDATESPATH,;t t
+s,@BLKID@,$BLKID,;t t
+s,@ZLIB@,$ZLIB,;t t
+s,@BZLIB@,$BZLIB,;t t
+s,@top_builddir@,$top_builddir,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+/@MCONFIG@/r $MCONFIG
+s,@MCONFIG@,,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
--- /dev/null
+AC_INIT(dump/dump.h)
+AC_PREREQ(2.57)
+
+MCONFIG=./MCONFIG
+AC_SUBST_FILE(MCONFIG)
+
+AC_CONFIG_HEADER(config.h)
+
+dnl
+dnl Check for programs
+dnl
+AC_PROG_MAKE_SET
+AC_PROG_LN_S
+AC_PATH_PROG(CP, cp, cp)
+AC_PATH_PROG(MV, mv, mv)
+AC_PATH_PROG(RM, rm, rm)
+AC_CHECK_TOOL(AR, ar, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(PATCH, patch, :)
+AC_PROG_CC
+AC_PROG_INSTALL
+
+AC_CHECK_HEADERS([sys/types.h])
+
+CPPFLAGS="-D_BSD_SOURCE -D_USE_BSD_SIGNAL ${CPPFLAGS}"
+
+dnl
+dnl Handle --enable-debug
+dnl
+AC_ARG_ENABLE([debug],
+[ --enable-debug include debugging code (default is NO)],
+if test "$enableval" = "no"
+then
+ DUMPDEBUG=""
+ RESTOREDEBUG=""
+ echo "Not including debugging code"
+else
+ DUMPDEBUG="-DFDEBUG -DTDEBUG -DWRITEDEBUG -DDIRDEBUG"
+ RESTOREDEBUG="-DDIRDEBUG"
+ echo "Including debugging code"
+fi,
+DUMPDEBUG=""
+RESTOREDEBUG=""
+echo "Not including debugging code by default"
+)
+AC_SUBST(DUMPDEBUG)
+AC_SUBST(RESTOREDEBUG)
+
+dnl
+dnl Handle --enable-static
+dnl
+AC_ARG_ENABLE([static],
+[ --enable-static link dump and restore statically (default is NO)],
+if test "$enableval" = "no"
+then
+ STATIC=""
+ echo "Linking dump and restore dynamically"
+else
+ STATIC="-static"
+ echo "Linking dump and restore statically"
+fi
+,
+STATIC=""
+echo "Linking dump and restore dynamically by default"
+)
+AC_SUBST(STATIC)
+
+dnl
+dnl Handle --enable-staticz
+dnl
+AC_ARG_ENABLE([staticz],
+[ --enable-staticz link libz and libbz2 statically (default is NO)],
+if test "$enableval" = "no"
+then
+ STATICZ="no"
+ echo "Linking libz and libbz2 dynamically"
+else
+ STATICZ="yes"
+ echo "Linking libz and libbz2 statically"
+fi
+,
+STATICZ="no"
+echo "Linking libz and libbz2 dynamically by default"
+)
+
+dnl
+dnl Handle --enable-rmt
+dnl
+AC_ARG_ENABLE([rmt],
+[ --enable-rmt compile and install rmt (default is YES)],
+if test "$enableval" = "no"
+then
+ RMTDIR=""
+ RMTMAKEFILE=""
+ echo "Not compiling rmt"
+else
+ RMTDIR="rmt"
+ RMTMAKEFILE="rmt/Makefile"
+ echo "Compiling rmt"
+fi
+,
+RMTDIR="rmt"
+RMTMAKEFILE="rmt/Makefile"
+echo "Compiling rmt by default"
+)
+AC_SUBST(RMTDIR)
+
+dnl
+dnl Handle --enable-ermt
+dnl
+AC_ARG_ENABLE([ermt],
+[ --enable-ermt compile ermt, an encrypting version of rmt (default is NO)],
+if test "$enableval" = "no"
+then
+ ERMT=""
+ CRYPTO=""
+ echo "Not compiling ermt"
+else
+ if test "$RMTDIR" = ""
+ then
+ AC_MSG_ERROR(ermt requires --enable-rmt)
+ fi
+ ERMT="ermt"
+ CRYPTO="-lcrypto"
+ echo "Compiling ermt"
+fi
+,
+ERMT=""
+CRYPTO=""
+echo "Not compiling ermt by default"
+)
+AC_SUBST(ERMT)
+AC_SUBST(CRYPTO)
+
+dnl
+dnl Handle --enable-kerberos
+dnl
+AC_ARG_ENABLE([kerberos],
+[ --enable-kerberos compile kerberos extensions (default is NO)],
+if test "$enableval" = "yes"
+then
+ OPTDEFS="-DKERBEROS"
+ echo "Compiling kerberos extensions"
+else
+ OPTDEFS=""
+ echo "Not compiling kerberos extensions"
+fi
+,
+OPTDEFS=""
+echo "Not compiling kerberos extensions by default"
+)
+AC_SUBST(OPTDEFS)
+
+dnl
+dnl Handle --enable-readline
+dnl
+AC_ARG_ENABLE([readline],
+[ --enable-readline enable readline support in restore (default is YES)],
+if test "$enableval" = "no"
+then
+ READLINE=""
+ echo "Not including readline support"
+else
+ READLINE="-lreadline -ltermcap"
+ AC_DEFINE([HAVE_READLINE],1,[Define if you want to include readline support.])
+ echo "Including readline support"
+fi
+,
+READLINE="-lreadline -ltermcap"
+AC_DEFINE([HAVE_READLINE],1,[Define if you want to include readline support.])
+echo "Including readline support by default"
+)
+AC_SUBST(READLINE)
+
+dnl
+dnl Handle --enable-oldsylefscript
+dnl
+AC_ARG_ENABLE([oldstylefscript],
+[ --enable-oldstylefscript enable old style F script (no arguments) (default is NO)],
+if test "$enableval" = "yes"
+then
+ AC_DEFINE([OLD_STYLE_FSCRIPT],1,[Define this is you want old style F script (no arguments).])
+ echo "Using old style F script"
+else
+ echo "Using new style F script"
+fi
+,
+echo "Using new style F script by default"
+)
+
+dnl
+dnl Handle --enable-largefile
+dnl
+AC_ARG_ENABLE([largefile],
+[ --enable-largefile enable Large File System support (default is YES)],
+if test "$enableval" = "yes"
+then
+ AC_DEFINE([USE_LFS],1,[Define this if you want Large File System support.])
+ echo "Enabling Large File System support"
+else
+ echo "Not enabling Large File System support"
+fi
+,
+AC_DEFINE([USE_LFS],1,[Define this if you want Large File System support.])
+echo "Enabling Large File System support by default"
+)
+
+dnl
+dnl Handle --enable-qfa
+dnl
+AC_ARG_ENABLE([qfa],
+[ --enable-qfa enable Quick File Access support (default is YES)],
+if test "$enableval" = "yes"
+then
+ AC_DEFINE([USE_QFA],1,[Define this if you want Quick File Access support.])
+ echo "Enabling Quick File Access support"
+else
+ echo "Not enabling Quick File Access support"
+fi
+,
+AC_DEFINE([USE_QFA],1,[Define this if you want Quick File Access support.])
+echo "Enabling Quick File Access support by default"
+)
+
+dnl
+dnl Handle --enable-qfadebug
+dnl
+AC_ARG_ENABLE([qfadebug],
+[ --enable-qfadebug include Quick File Access debugging code (default is NO)],
+if test "$enableval" = "yes"
+then
+ AC_DEFINE([DEBUG_QFA],1,[Define this if you want to include Quick File Access debugging code.])
+ echo "Including Quick File Access debugging code"
+else
+ echo "Not including Quick File Access debugging code"
+fi
+,
+echo "Not including Quick File Access debugging code by default"
+)
+
+dnl
+dnl Handle --enable-macosx
+dnl
+AC_ARG_ENABLE([macosx],
+[ --enable-macosx include Mac OSX restore compatibility (default is NO)],
+if test "$enableval" = "yes"
+then
+ AC_DEFINE([DUMP_MACOSX],1,[Define this if you want to include Mac OSX restore compatibility.])
+ echo "Including Mac OSX restore compatibility code"
+else
+ echo "Not including Mac OSX restore compatibility code"
+fi
+,
+echo "Not including Mac OSX restore compatibility code by default"
+)
+
+
+dnl
+dnl set $(CC) from --with-cc=value
+dnl
+AC_ARG_WITH([cc],
+[ --with-cc=COMPILER select compiler to use],
+AC_MSG_RESULT(CC=$withval)
+CC=$withval,
+if test -z "$CC" ; then CC=cc; fi
+[AC_MSG_RESULT(CC defaults to $CC)])dnl
+export CC
+AC_SUBST([CC])
+
+dnl
+dnl set $(LD) from --with-linker=value
+dnl
+AC_ARG_WITH([linker],
+[ --with-linker=LINKER select linker to use],
+AC_MSG_RESULT(LD=$withval)
+LD=$withval,
+if test -z "$LD" ; then LD=$CC; fi
+[AC_MSG_RESULT(LD defaults to $LD)])dnl
+export LD
+AC_SUBST([LD])
+
+dnl
+dnl set $(CCOPTS) from --with-ccopts=value
+dnl
+AC_ARG_WITH([ccopts],
+[ --with-ccopts=CCOPTS select compiler command line options],
+AC_MSG_RESULT(CCOPTS is $withval)
+CCOPTS=$withval
+CFLAGS="$CFLAGS $withval",
+CCOPTS=)dnl
+AC_SUBST(CCOPTS)
+
+dnl
+dnl set $(LDFLAGS) from --with-ldopts=value
+dnl
+AC_ARG_WITH([ldopts],
+[ --with-ldopts=LDOPTS select linker command line options],
+AC_MSG_RESULT(LDFLAGS is $withval)
+LDOPTS=$withval
+LDFLAGS="$LDFLAGS $withval",
+LDOPTS=)dnl
+AC_SUBST(LDOPTS)
+
+dnl
+dnl set $(BINOWNER) from --with-binowner
+dnl
+AC_ARG_WITH([binowner],
+[ --with-binowner=USER select owner for binaries],
+AC_MSG_RESULT(BINOWNER is $withval)
+BINOWNER=$withval,
+BINOWNER=root
+echo "BINOWNER defaults to $BINOWNER"
+)dnl
+AC_SUBST(BINOWNER)
+
+dnl
+dnl set $(BINGRP) from --with-bingrp
+dnl
+AC_ARG_WITH([bingrp],
+[ --with-bingrp=GROUP select group for binaries],
+AC_MSG_RESULT(BINGRP is $withval)
+BINGRP=$withval,
+BINGRP=tty
+echo "BINGRP defaults to $BINGRP"
+)dnl
+AC_SUBST(BINGRP)
+
+dnl
+dnl set $(BINMODE) from --with-binmode
+dnl
+AC_ARG_WITH([binmode],
+[ --with-binmode=MODE select mode for binaries],
+AC_MSG_RESULT(BINMODE is $withval)
+BINMODE=$withval,
+BINMODE=0755
+echo "BINMODE defaults to $BINMODE"
+)dnl
+AC_SUBST(BINMODE)
+
+dnl
+dnl set $(MANOWNER) from --with-manowner
+dnl
+AC_ARG_WITH([manowner],
+[ --with-manowner=USER select owner for manual pages],
+AC_MSG_RESULT(MANOWNER is $withval)
+MANOWNER=$withval,
+MANOWNER=man
+echo "MANOWNER defaults to $MANOWNER"
+)dnl
+AC_SUBST(MANOWNER)
+
+dnl
+dnl set $(MANGRP) from --with-mangrp
+dnl
+AC_ARG_WITH([mangrp],
+[ --with-mangrp=GROUP select group for manual pages],
+AC_MSG_RESULT(MANGRP is $withval)
+MANGRP=$withval,
+MANGRP=tty
+echo "MANGRP defaults to $MANGRP"
+)dnl
+AC_SUBST(MANGRP)
+
+dnl
+dnl set $(MANMODE) from --with-manmode
+dnl
+AC_ARG_WITH([manmode],
+[ --with-manmode=MODE select mode for manual pages],
+AC_MSG_RESULT(MANMODE is $withval)
+MANMODE=$withval,
+MANMODE=0644
+echo "MANMODE defaults to $MANMODE"
+)dnl
+AC_SUBST(MANMODE)
+
+dnl
+dnl set $(DUMPDATESPATH) from --with-dumpdatespath
+dnl
+AC_ARG_WITH([dumpdatespath],
+[ --with-dumpdatespath=PATH select path for dumpdates file],
+AC_MSG_RESULT(DUMPDATESPATH is $withval)
+DUMPDATESPATH=$withval,
+DUMPDATESPATH="${sysconfdir}/dumpdates"
+echo "DUMPDATESPATH defaults to $DUMPDATESPATH"
+)dnl
+AC_SUBST(DUMPDATESPATH)
+
+dnl
+dnl Check for Ext2fs headers and libraries
+dnl
+AC_CHECK_HEADER(ext2fs/ext2fs.h, [ext2fs_h=yes], [ext2fs_h=no], [-])
+AC_CHECK_LIB(ext2fs, ext2fs_open, [ext2fs_lib=yes], [ext2fs_lib=no], [-lcom_err])
+if test "$ext2fs_h" = no -o "$ext2fs_lib" = no; then
+ AC_MSG_ERROR(You need to install the Ext2fs libraries from the E2fsprogs distribution first - hint: make install-libs)
+fi
+
+dnl
+dnl Try to use ext2_fs.h header from libext2fs instead of from the kernel
+dnl
+AC_CHECK_HEADERS(ext2fs/ext2_fs.h, [], [], [-])
+
+dnl
+dnl Check for ext2_ino_t type
+dnl
+AC_MSG_CHECKING(for ext2_ino_t type in libext2fs headers)
+AC_TRY_COMPILE([#include <stdio.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>],
+[ext2_ino_t ino = 0;],
+[AC_DEFINE([HAVE_EXT2_INO_T],1,[Define if we have the ext2_ino_t type (from e2fsprogs 1.20+).])
+ AC_MSG_RESULT(yes)],
+AC_MSG_RESULT(no))
+
+dnl
+dnl Check for s_journal_inum field in ext2_super_block struct
+dnl
+AC_MSG_CHECKING(for s_journal_inum field in ext2_super_block struct)
+AC_TRY_COMPILE([#include <stdio.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>],
+[struct ext2_super_block es; es.s_journal_inum = 0;],
+[AC_DEFINE([HAVE_EXT2_JOURNAL_INUM],1,[Define if we have the s_journal_inum field in struct ext2_super_block.])
+ AC_MSG_RESULT(yes)],
+AC_MSG_RESULT(no))
+
+dnl
+dnl Check for blkid headers libraries
+dnl
+AC_CHECK_HEADER(blkid/blkid.h, [blkid_h=yes], [blkid_h=no], [-])
+AC_CHECK_LIB(blkid, blkid_get_devname, [blkid_lib=yes], [blkid_lib=no], [-luuid])
+if test "$blkid_h" = yes -a "$blkid_lib" = yes; then
+ AC_DEFINE([HAVE_BLKID],1,[Define this if you have the blkid library.])
+ BLKID="-lblkid -luuid"
+fi
+AC_SUBST(BLKID)
+
+dnl
+dnl Check for termcap libraries
+dnl
+AC_CHECK_LIB(termcap, tgetent, [termcap_lib=yes], [termcap_lib=no])
+if test "$termcap_lib" = no; then
+ if test "$READLINE" = "-lreadline -ltermcap"; then
+ AC_MSG_ERROR(You need to install the GNU termcap library or configure without --enable-readline)
+ fi
+fi
+
+dnl
+dnl Check for readline headers and libraries
+dnl
+AC_CHECK_HEADER(readline/readline.h, [readline_h=yes], [readline_h=no], [-])
+AC_CHECK_LIB(readline, readline, [readline_lib=yes], [readline_lib=no], "-ltermcap")
+if test "$readline_h" = no -o "$readline_lib" = no; then
+ if test "$READLINE" = "-lreadline -ltermcap"; then
+ AC_MSG_ERROR(You need to install the GNU readline library or configure without --enable-readline)
+ fi
+fi
+
+dnl
+dnl Check for rl_completion_matches
+dnl
+AC_CHECK_LIB(readline, rl_completion_matches, [rlcm=yes], [rlcm=no], "-ltermcap")
+if test "$rlcm" = yes; then
+ AC_DEFINE([HAVE_READLINE_RLCM],1,[Define this if your readline libs have the rl_completion_matches library.])
+fi
+
+dnl
+dnl Check for rl_completion_append_character
+dnl
+AC_CHECK_LIB(readline, rl_completion_append_character, [rcac=yes], [rcac=no], "-ltermcap")
+if test "$rcac" = yes; then
+ AC_DEFINE([HAVE_READLINE_CAC],1,[Define this if your readline libs have the rl_completion_append_character variable.])
+fi
+
+dnl
+dnl Check for zlib headers and libraries
+dnl
+AC_CHECK_HEADER(zlib.h, [zlib_h=yes], [zlib_h=no], [-])
+AC_CHECK_LIB(z, compress2, [zlib_lib=yes], [zlib_lib=no])
+if test "$zlib_h" = yes -a "$zlib_lib" = yes; then
+ if test "$STATICZ" = yes; then
+ ZLIB="-Wl,-Bstatic -lz -Wl,-Bdynamic"
+ else
+ ZLIB="-lz"
+ fi
+ AC_DEFINE([HAVE_ZLIB],1,[Define this if you have zlib compression library.])
+else
+ ZLIB=""
+fi
+AC_SUBST(ZLIB)
+
+dnl
+dnl Check for bzlib headers and libraries
+dnl
+AC_CHECK_HEADER(bzlib.h, [bzlib_h=yes], [bzlib_h=no], [-])
+AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, [bzlib_lib=yes], [bzlib_lib=no])
+if test "$bzlib_h" = yes -a "$bzlib_lib" = yes; then
+ if test "$STATICZ" = yes; then
+ BZLIB="-Wl,-Bstatic -lbz2 -Wl,-Bdynamic"
+ else
+ BZLIB="-lbz2"
+ fi
+ AC_DEFINE([HAVE_BZLIB],1,[Define this if you have bzlib compression library.])
+else
+ BZLIB=""
+fi
+AC_SUBST(BZLIB)
+
+dnl
+dnl Check for library functions
+dnl
+AC_CHECK_FUNCS(err errx verr verrx vwarn vwarnx warn warnx realpath lchown)
+AC_CHECK_FUNC(glob)
+
+dnl
+dnl Check for GLOB_ALTDIRFUNC
+dnl
+AC_MSG_CHECKING(for extended glob routines)
+if test "$ac_cv_func_glob" = "yes"; then
+ AC_EGREP_CPP(yes,
+ [
+# include <glob.h>
+# ifdef GLOB_ALTDIRFUNC
+ yes
+# endif
+ ],
+ [
+ AC_DEFINE([HAVE_GLOB],1,[Define if you have the glob function.])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ echo "Your system does not support extended glob, will use the internal routines"
+ ])
+fi
+
+dnl
+dnl Check for OpenSSL, for ermt
+dnl
+if test "$ERMT" != ""; then
+ AC_CHECK_HEADER(openssl/evp.h, [evp_h=yes], [evp_h=no])
+ AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_set_padding, [crypto_lib=yes], [crypto_lib=no])
+ if test "$evp_h" = no -o "$crypto_lib" = no; then
+ AC_MSG_ERROR(You need to install the OpenSSL library (version 0.9.7a or later), or configure without --enable-ermt)
+ fi
+fi
+
+dnl
+dnl Check for types
+dnl
+AC_CHECK_TYPE(quad_t, int64_t)
+AC_CHECK_TYPE(u_quad_t, uint64_t)
+
+dnl
+dnl Compute top_buildir
+dnl
+top_builddir=`cd .; pwd`
+AC_SUBST(top_builddir)
+
+dnl
+dnl Create directories
+dnl
+test -d compat || mkdir compat
+test -d compat/lib || mkdir compat/lib
+
+dnl
+dnl Output files
+dnl
+AC_OUTPUT(MCONFIG Makefile common/Makefile compat/include/Makefile compat/lib/Makefile dump/Makefile restore/Makefile $RMTMAKEFILE)
--- /dev/null
+# $Id: depfix.sed,v 1.2 1999/10/11 13:31:04 stelian Exp $
+#
+# Insert the header.....
+#
+1i\
+# +++ Dependency line eater +++\
+# \
+# Makefile dependencies follow. This must be the last section in\
+# the Makefile.in file\
+#
+
+#
+# Remove line continuations....
+#
+#:FIRST
+#y/ / /
+#s/^ *//
+#/\\$/{
+#N
+#y/ / /
+#s/\\\n */ /
+#bFIRST
+#}
+#s/ */ /g
+
+s;/usr/include/[^ ]* *;;g
+s;/usr/lib/[^ ]* *;;g
+s;/mit/cygnus[^ ]* *;;g
+
+#
+# Now insert a trailing newline...
+#
+$a\
+
--- /dev/null
+Begin3
+Title: dump and restore for Ext2fs
+Version: 0.4b37
+Entered-date: 07JUL04
+Description: Port of the 4.4BSD dump and restore backup suite
+Keywords: backup, filesystem, Ext2fs
+Author: University of California, Berkeley
+Maintained-by: stelian@popies.net (Stelian Pop)
+Primary-site: http://dump.sourceforge.net/
+ 0kB dump-0.4b37.tar.gz
+ 0 dump.lsm
+Original-site: ftp.freebsd.org /pub/bsd-sources/4.4BSD-Lite2/sbin
+ dump/*
+ restore/*
+Platforms: linux 2.0.x, linux 2.2.x, linux 2.4.x, linux 2.6.x
+ e2fsprogs 1.14 or better
+Copying-policy: BSD
+End
--- /dev/null
+%define _sbindir /sbin
+# XXX --enable-kerberos needs krcmd
+%define myoptions --with-binmode=6755 --with-manowner=root --with-mangrp=root --with-manmode=0644 --with-dumpdates="%{_sysconfdir}/dumpdates"
+
+Summary: Programs for backing up and restoring ext2/ext3 filesystems.
+Name: dump
+Version: 0.4b37
+Release: 1
+License: BSD
+URL: http://dump.sourceforge.net
+Group: Applications/Archiving
+Source: dump-%{version}.tar.gz
+BuildPrereq: e2fsprogs-devel >= 1.18
+BuildPrereq: libtermcap-devel, readline-devel
+BuildPrereq: zlib-devel, bzip2-devel
+Requires: rmt
+BuildRoot: %{_tmppath}/%{name}-root
+
+%description
+The dump package contains both dump and restore. Dump examines files
+in a filesystem, determines which ones need to be backed up, and
+copies those files to a specified disk, tape, or other storage medium.
+The restore command performs the inverse function of dump; it can
+restore a full backup of a filesystem. Subsequent incremental backups
+can then be layered on top of the full backup. Single files and
+directory subtrees may also be restored from full or partial backups.
+
+Install dump if you need a system for both backing up filesystems and
+restoring filesystems after backups.
+
+%package -n rmt
+Summary: Provides certain programs with access to remote tape devices.
+Group: Applications/Archiving
+
+%description -n rmt
+The rmt utility provides remote access to tape devices for programs
+like dump (a filesystem backup program), restore (a program for
+restoring files from a backup), and tar (an archiving program).
+
+%package -n dump-static
+Summary: Statically linked versions of dump and restore.
+Group: Applications/Archiving
+
+%description -n dump-static
+The dump package contains both dump and restore. Dump examines files in
+a filesystem, determines which ones need to be backed up, and copies
+those files to a specified disk, tape, or other storage medium. The
+restore command performs the inverse function of dump; it can restore a
+full backup of a filesystem. Subsequent incremental backups can then be
+layered on top of the full backup. Single files and directory subtrees
+may also be restored from full or partial backups.
+
+Install dump if you need a system for both backing up filesystems and
+restoring filesystems after backups.
+
+This package contains statically linked versions of dump and restore.
+
+%prep
+%setup -q
+
+%build
+%configure %{myoptions} --enable-static -disable-rmt
+
+%ifarch alpha
+RPM_OPT_FLAGS=""
+%endif
+make OPT="$RPM_OPT_FLAGS -Wall -Wpointer-arith -Wstrict-prototypes \
+ -Wmissing-prototypes -Wno-char-subscripts"
+
+mv dump/dump dump/dump.static
+mv restore/restore restore/restore.static
+
+make distclean
+
+%configure %{myoptions}
+
+make OPT="$RPM_OPT_FLAGS -Wall -Wpointer-arith -Wstrict-prototypes \
+ -Wmissing-prototypes -Wno-char-subscripts"
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_sbindir}
+mkdir -p %{buildroot}%{_mandir}/man8
+
+%makeinstall SBINDIR=%{buildroot}%{_sbindir} MANDIR=%{buildroot}%{_mandir}/man8 BINOWNER=$(id -un) BINGRP=$(id -gn) MANOWNER=$(id -un) MANGRP=$(id -gn)
+mkdir -p $RPM_BUILD_ROOT/usr/sbin
+
+cp dump/dump.static %{buildroot}%{_sbindir}
+cp restore/restore.static %{buildroot}%{_sbindir}
+
+pushd $RPM_BUILD_ROOT
+ ln -sf dump .%{_sbindir}/rdump
+ ln -sf dump.static .%{_sbindir}/rdump.static
+ ln -sf restore .%{_sbindir}/rrestore
+ ln -sf restore.static .%{_sbindir}/rrestore.static
+ chmod ug-s .%{_sbindir}/rmt
+ mkdir -p .%{_sysconfdir}
+ > .%{_sysconfdir}/dumpdates
+ ln -sf ..%{_sbindir}/rmt .%{_sysconfdir}/rmt
+ # quick workaround :)
+ mv sbin/* usr/sbin/
+ mv usr/sbin/*static sbin/
+ mv usr/sbin/rmt sbin/
+ # somehow, rpm didn't strip these...
+ strip usr/sbin/* sbin/* || :
+popd
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root)
+%doc CHANGES COPYRIGHT KNOWNBUGS MAINTAINERS README REPORTING-BUGS THANKS TODO
+%doc dump.lsm examples
+%attr(0664,root,disk) %config(noreplace) %{_sysconfdir}/dumpdates
+%attr(0755,root,root) /usr/sbin/dump
+/usr/sbin/rdump
+%attr(0755,root,root) /usr/sbin/restore
+/usr/sbin/rrestore
+%{_mandir}/man8/dump.*
+%{_mandir}/man8/rdump.*
+%{_mandir}/man8/restore.*
+%{_mandir}/man8/rrestore.*
+
+%files -n rmt
+%defattr(-,root,root)
+%attr(0755,root,root) %{_sbindir}/rmt
+%{_sysconfdir}/rmt
+%{_mandir}/man8/rmt.*
+
+%files -n dump-static
+%defattr(-,root,root)
+%attr(0755,root,root) %{_sbindir}/dump.static
+%{_sbindir}/rdump.static
+%attr(0755,root,root) %{_sbindir}/restore.static
+%{_sbindir}/rrestore.static
+
+%changelog
+* Wed Jul 7 2004 Stelian Pop <stelian@popies.net>
+- dump 0.4b37 released, first packaging.
+
+* Wed Apr 21 2004 Stelian Pop <stelian@popies.net>
+- dump 0.4b36 released, first packaging.
+
+* Sun Dec 21 2003 Stelian Pop <stelian@popies.net>
+- dump 0.4b35 released, first packaging.
+
+* Fri Apr 18 2003 Stelian Pop <stelian@popies.net>
+- dump 0.4b34 released, first packaging.
+
+* Mon Feb 10 2003 Stelian Pop <stelian@popies.net>
+- dump 0.4b33 released, first packaging.
+
+* Fri Nov 15 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b32 released, first packaging.
+
+* Tue Jul 30 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b31 released, first packaging.
+
+* Thu Jul 25 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b30 released, first packaging.
+
+* Sat Jun 8 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b29 released, first packaging.
+
+* Fri Apr 12 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b28 released, first packaging.
+
+* Fri Feb 15 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b27 released, first packaging.
+
+* Mon Jan 7 2002 Stelian Pop <stelian@popies.net>
+- dump 0.4b26 released, first packaging.
+
+* Sat Nov 17 2001 Stelian Pop <stelian@popies.net>
+- dump 0.4b25 released, first packaging.
+
+* Wed Sep 12 2001 Stelian Pop <stelian@popies.net>
+- dump 0.4b24 released, first packaging.
+
+* Fri Jul 20 2001 Stelian Pop <stelian@popies.net>
+- dump 0.4b23 released, first packaging.
+
+* Sat May 12 2001 Stelian Pop <stelian@popies.net>
+- dump 0.4b22 released, first packaging.
+
+* Sat Jan 30 2001 Stelian Pop <stelian@popies.net>
+- dump 0.4b21 released, first packaging.
+
+* Fri Nov 10 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b20 released, first packaging.
+
+* Sun Aug 20 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b19 released, first packaging.
+
+* Thu Jun 30 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b18 released, first packaging.
+
+* Thu Jun 1 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b17 released, first packaging.
+
+* Sat Mar 11 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b16 released, first packaging.
+
+* Thu Mar 2 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b15 released, first packaging.
+
+* Thu Feb 10 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b14 released, first packaging.
+
+* Fri Jan 21 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b13 released, first packaging.
+
+* Fri Jan 8 2000 Stelian Pop <stelian@popies.net>
+- dump 0.4b12 released, first packaging.
+
+* Sun Dec 5 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b11 released, first packaging.
+
+* Sun Nov 21 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b10 released, first packaging.
+
+* Thu Nov 11 1999 Stelian Pop <stelian@popies.net>
+- make static versions also for rescue purposes.
+
+* Wed Nov 5 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b9 released, first packaging.
+
+* Wed Nov 3 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b8 released, first packaging.
+
+* Thu Oct 8 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b7 released, first packaging.
+
+* Thu Sep 30 1999 Stelian Pop <stelian@popies.net>
+- dump 0.4b6 released, first packaging.
+
+* Fri Sep 10 1999 Jeff Johnson <jbj@redhat.com>
+- recompile with e2fsprogs = 1.15 (#4962).
+
+* Sat Jul 31 1999 Jeff Johnson <jbj@redhat.com>
+- workaround egcs bug (#4281) that caused dump problems (#2989).
+- use sigjmp_buf, not jmp_buf (#3260).
+- invoke /etc/rmt (instead of rmt) like other unices. (#3272).
+- use glibc21 err/glob rather than the internal compatibility routines.
+- wire $(OPT) throughout Makefile's.
+- fix many printf problems, mostly lint clean.
+- merge SuSE, Debian and many OpenBSD fixes.
+
+* Thu Mar 25 1999 Jeff Johnson <jbj@redhat.com>
+- remove setuid/setgid bits from /sbin/rmt (dump/restore are OK).
+
+* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com>
+- auto rebuild in the new build environment (release 6)
+
+* Fri Mar 19 1999 Jeff Johnson <jbj@redhat.com>
+- strip binaries.
+
+* Thu Mar 18 1999 Jeff Johnson <jbj@redhat.com>
+- Fix dangling symlinks (#1551).
+
+* Wed Mar 17 1999 Michael Maher <mike@redhat.com>
+- Top O' the morning, build root's fixed for man pages.
+
+* Fri Feb 19 1999 Preston Brown <pbrown@redhat.com>
+- upgraded to dump 0.4b4, massaged patches.
+
+* Tue Feb 02 1999 Ian A Cameron <I.A.Cameron@open.ac.uk>
+- added patch from Derrick J Brashear for traverse.c to stop bread errors
+
+* Wed Jan 20 1999 Jeff Johnson <jbj@redhat.com>
+- restore original 6755 root.tty to dump/restore, defattr did tty->root (#684).
+- mark /etc/dumpdates as noreplace.
+
+* Tue Jul 14 1998 Jeff Johnson <jbj@redhat.com>
+- add build root.
+
+* Tue May 05 1998 Prospector System <bugs@redhat.com>
+- translations modified for de, fr, tr
+
+* Thu Apr 30 1998 Cristian Gafton <gafton@redhat.com>
+- added a patch for resolving linux/types.h and sys/types.h conflicts
+
+* Wed Dec 31 1997 Erik Troan <ewt@redhat.com>
+- added prototype of llseek() so dump would work on large partitions
+
+* Thu Oct 30 1997 Donnie Barnes <djb@redhat.com>
+- made all symlinks relative instead of absolute
+
+* Thu Jul 10 1997 Erik Troan <ewt@redhat.com>
+- built against glibc
+
+* Thu Mar 06 1997 Michael K. Johnson <johnsonm@redhat.com>
+- Moved rmt to its own package.
+
+* Tue Feb 11 1997 Michael Fulbright <msf@redhat.com>
+- Added endian cleanups for SPARC
+
+* Fri Feb 07 1997 Michael K. Johnson <johnsonm@redhat.com>
+- Made /etc/dumpdates writeable by group disk.
--- /dev/null
+# $Id: Makefile.in,v 1.12 2004/07/05 15:02:36 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ..
+
+@MCONFIG@
+
+INC= -I$(top_srcdir)/dump
+ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @DUMPDEBUG@
+ALL_LDFLAGS= @LDFLAGS@ @LDOPTS@ @STATIC@
+LIBS= $(GLIBS) @ZLIB@ @BZLIB@ @BLKID@
+DEPLIBS= ../compat/lib/libcompat.a
+
+PROG= dump
+RPROG= rdump
+LINKS= ${SBINDIR}/dump ${SBINDIR}/rdump
+SRCS= itime.c main.c optr.c tape.c traverse.c unctime.c
+OBJS= itime.o main.o optr.o tape.o traverse.o unctime.o \
+ ../common/dumprmt.o
+MAN8= dump.8
+RMAN8= rdump.8
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: $(PROG) $(MAN8)
+
+$(PROG): $(OBJS) $(DEPLIBS)
+ $(LD) $(ALL_LDFLAGS) -o $(PROG) $(OBJS) $(LIBS)
+
+$(MAN8): dump.8.in
+ sed -e "s|__DUMPDATES__|$(DUMPDATESPATH)|g" \
+ -e "s|__DATE__|$(DATE)|g" \
+ -e "s|__VERSION__|$(VERSION)|g" $< > $@
+
+install:: all
+ $(INSTALL) -d $(SBINDIR) $(MANDIR)
+ $(INSTALLBIN) $(PROG) $(SBINDIR)
+ $(INSTALLMAN) $(MAN8) $(MANDIR)
+ cd $(SBINDIR) && $(RM) -f $(RPROG) && $(LN_S) $(PROG) $(RPROG)
+ cd $(MANDIR) && $(RM) -f $(RMAN8) && $(LN_S) $(MAN8) $(RMAN8)
+
+clean::
+ $(RM) -f $(PROG) $(MAN8) \#* *.s *.o *.a *~ core
+
+distclean:: clean
+ $(RM) -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+.\" Copyright (c) 1980, 1991, 1993
+.\" Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: dump.8.in,v 1.56 2004/04/21 08:55:48 stelian Exp $
+.\"
+.TH DUMP 8 "version __VERSION__ of __DATE__" BSD "System management commands"
+.SH NAME
+dump \- ext2/3 filesystem backup
+.SH SYNOPSIS
+.B dump
+[\fB\-\fIlevel#\fR]
+[\fB\-ackMnqSuv]
+[\fB\-A \fIfile\fR]
+[\fB\-B \fIrecords\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-d \fIdensity\fR]
+[\fB\-D \fIfile\fR]
+[\fB\-e \fIinode numbers\fR]
+[\fB\-E \fIfile\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-h \fIlevel\fR]
+[\fB\-I \fInr errors\fR]
+[\fB\-j\fIcompression level\fR]
+[\fB\-L \fIlabel\fR]
+[\fB\-Q \fIfile\fR]
+[\fB\-s \fIfeet\fR]
+[\fB\-T \fIdate\fR]
+[\fB\-y\fR]
+[\fB\-z\fIcompression level\fR]
+.I files-to-dump
+.PP
+.B dump
+[\fB\-W \fR| \fB\-w\fR]
+.PP
+(The 4.3BSD option syntax is implemented for backward compatibility but is not
+documented here.)
+.SH DESCRIPTION
+.B Dump
+examines files on an ext2/3 filesystem and determines which files need to be
+backed up. These files are copied to the given disk, tape or other storage
+medium for safe keeping (see the
+.B \-f
+option below for doing remote backups). A dump that is larger than the output
+medium is broken into multiple volumes. On most media the size is determined by
+writing until an end-of-media indication is returned.
+.PP
+On media that cannot reliably return an end-of-media indication (such as some
+cartridge tape drives), each volume is of a fixed size; the actual size is
+determined by specifying cartridge media, or via the tape size, density and/or
+block count options below. By default, the same output file name is used for
+each volume after prompting the operator to change media.
+.PP
+.I files-to-dump
+is either a mountpoint of a filesystem or a list of files and directories to be
+backed up as a subset of a filesystem. In the former case, either the path to a
+mounted filesystem or the device of an unmounted filesystem can be used. In the
+latter case, certain restrictions are placed on the backup:
+.B \-u
+is not allowed, the only dump level that is supported is
+.B 0
+and all the files and directories must reside on the same filesystem.
+.SH OPTIONS
+The following options are supported by
+.B dump:
+.TP
+.BI \-level#
+The dump level (any integer). A level 0, full backup, guarantees the
+entire file system is copied (but see also the
+.B \-h
+option below). A level number above 0, incremental backup, tells
+.B dump
+to
+copy all files new or modified since the last dump of a lower level. The
+default level is 9. Historically only levels 0 to 9 were usable in
+dump, this version is able to understand any integer as a dump level.
+.TP
+.BI \-a
+\*(lqauto-size\*(rq. Bypass all tape length calculations, and write until an
+end-of-media indication is returned. This works best for most modern tape
+drives, and is the default. Use of this option is particularly recommended when
+appending to an existing tape, or using a tape drive with hardware compression
+(where you can never be sure about the compression ratio).
+.TP
+.BI \-A " archive_file"
+Archive a dump table-of-contents in the specified
+.I archive_file
+to be used by
+.BR restore (8)
+to determine whether a file is in the dump file that is being restored.
+.TP
+.BI \-b " blocksize"
+The number of kilobytes per dump record. The default blocksize is 10,
+unless the
+.B \-d
+option has been used to specify a tape density of 6250BPI or more,
+in which case the default blocksize is 32. Th maximal value is 1024.
+Note however that, since the IO system slices all requests into chunks
+of
+.B MAXBSIZE
+(which can be as low as 64kB), you can experience problems with
+.BR dump (8)
+and
+.BR restore (8)
+when using a higher value, depending on your kernel and/or libC versions.
+.TP
+.BI \-B " records"
+The number of 1 kB blocks per volume. Not normally required, as
+.B dump
+can detect end-of-media. When the specified size is reached,
+.B dump
+waits for you to change the volume. This option overrides the calculation of
+tape size based on length and density. If compression is on this limits the
+size of the compressed output per volume. Multiple values may be given
+as a single argument separated by commas. Each value will be used for one
+dump volume in the order listed; if
+.B dump
+creates more volumes than the
+number of values given, the last value will be used for the remaining
+volumes. This is useful for filling up already partially filled media
+(and then continuing with full size volumes on empty media) or mixing media
+of different sizes.
+.TP
+.BI \-c
+Change the defaults for use with a cartridge tape drive, with a density of 8000
+bpi, and a length of 1700 feet. Specifying a cartridge drive overrides the
+end-of-media detection.
+.TP
+.BI \-d " density"
+Set tape density to
+.IR density .
+The default is 1600BPI. Specifying a tape density overrides the end-of-media
+detection.
+.TP
+.BI \-D " file"
+Set the path name of the file storing the information about the previous
+full and incremental dumps. The default location is
+.IR __DUMPDATES__ .
+.TP
+.BI \-e " inodes"
+Exclude
+.I inodes
+from the dump. The
+.I inodes
+parameter is a comma separated list of inode numbers (you can use
+.BR stat (1)
+to find the inode number for a file or directory).
+.TP
+.BI \-E " file"
+Read list of inodes to be excluded from the dump from the text file
+.IR file .
+The file
+.I file
+should be an ordinary file containing inode numbers separated by newlines.
+.TP
+.BI \-f " file"
+Write the backup to
+.IR file ;
+.I file
+may be a special device file like
+.I /dev/st0
+(a tape drive),
+.I /dev/rsd1c
+(a floppy disk drive), an ordinary file, or
+.I \-
+(the standard output). Multiple file names may be given as a single argument
+separated by commas. Each file will be used for one dump volume in the order
+listed; if the dump requires more volumes than the number of names given,
+the last file name will used for all remaining volumes after prompting for
+media changes. If the name of the file is of the form
+.I host:file
+or
+.I user@host:file
+.B dump
+writes to the named file on the remote host (which should already
+exist, dump doesn't create a new remote file) using
+.BR rmt (8).
+The default path name of the remote
+.BR rmt (8)
+program is
+.IR /etc/rmt ;
+this can be overridden by the environment variable
+.BR RMT .
+.TP
+.BI \-F " script"
+Run script at the end of each tape (except for the last one).
+The device name and the current volume number are passed on the
+command line. The script must return 0 if
+.B dump
+should continue without asking the user to change the tape, 1 if
+.B dump
+should continue but ask the user to change the tape. Any other exit code will
+cause
+.B dump
+to abort. For security reasons,
+.B dump
+reverts back to the real user ID and the real group ID before running the
+script.
+.TP
+.BI \-h " level"
+Honor the user
+.B nodump
+flag
+.B UF_NODUMP
+only for dumps at or above the given
+.IR level .
+The default honor level is 1, so that incremental backups omit such files but
+full backups retain them.
+.TP
+.BI \-I " nr errors"
+By default,
+.B dump
+will ignore the first 32 read errors on the file system before asking for
+operator intervention. You can change this using this flag to any value. This
+is useful when running
+.B dump
+on an active filesystem where read errors simply indicate an inconsistency
+between the mapping and dumping passes.
+.IP
+A value of 0 means that all read errors will be ignored.
+.TP
+.BI \-j "compression level"
+Compress every block to be written on the tape using bzlib library. This option
+will work only when dumping to a file or pipe or, when dumping to a tape drive,
+if the tape drive is capable of writing variable length blocks. You will need
+at least the 0.4b24 version of
+.B restore
+in order to extract compressed tapes. Tapes written using compression will not
+be compatible with the BSD tape format. The (optional) parameter specifies the
+compression level bzlib will use. The default compression level is 2. If the
+optional parameter is specified, there should be no white space between the
+option letter and the parameter.
+.TP
+.BI \-k
+Use Kerberos authentication to talk to remote tape servers. (Only available if
+this option was enabled when
+.B dump
+was compiled.)
+.TP
+.BI \-L " label"
+The user-supplied text string
+.I label
+is placed into the dump header, where tools like
+.BR restore (8)
+and
+.BR file (8)
+can access it. Note that this label is limited to be at most
+.B LBLSIZE
+(currently 16) characters, which must include the terminating \e0.
+.TP
+.BI \-m
+If this flag is specified,
+.B dump
+will optimise the output for inodes having been changed but not modified since
+the last dump ('changed' and 'modified' have the meaning defined in
+.BR stat (2)
+). For those inodes,
+.B dump
+will save only the metadata, instead of saving the entire inode contents.
+Inodes which are either directories or have been modified since the last dump
+are saved in a regular way. Uses of this flag must be consistent, meaning that
+either every dump in an incremental dump set have the flag, or no one has it.
+.IP
+Tapes written using such 'metadata only' inodes will not be compatible with the
+BSD tape format or older versions of
+.B restore.
+.TP
+.BI \-M
+Enable the multi-volume feature. The name specified with
+.B f
+is treated as a prefix and
+.B dump
+writes in sequence to
+.I <prefix>001, <prefix>002
+etc. This can be useful when dumping to files on an ext2 partition, in order to
+bypass the 2GB file size limitation.
+.TP
+.BI \-n
+Whenever
+.B dump
+requires operator attention, notify all operators in the group
+.B operator
+by means similar to a
+.BR wall (1).
+.TP
+.BI \-q
+Make
+.B dump
+abort immediately whenever operator attention is required, without prompting in
+case of write errors, tape changes etc.
+.TP
+.BI \-Q " file"
+Enable the Quick File Access support. Tape positions for each inode are stored
+into the file
+.I file
+which is used by
+.B restore
+(if called with parameter
+.B \-Q
+and the filename) to directly position the tape at the file
+.B restore
+is currently working on. This saves hours when restoring single files from
+large backups, saves the tapes and the drive's head.
+.IP
+It is recommended to set up the st driver to return logical tape positions
+rather than physical before calling
+.B dump/restore
+with parameter
+.BR \-Q .
+Since not all tape devices support physical tape positions those tape devices
+return an error during
+.B dump/restore
+when the st driver is set to the default physical setting. Please see the
+.BR st (4)
+man page, option
+.B MTSETDRVBUFFER
+, or the
+.BR mt (1)
+man page, on how to set the driver to return logical tape positions.
+.IP
+Before calling
+.B restore
+with parameter
+.BR \-Q ,
+always make sure the st driver is set to return the same type of tape position
+used during the call to
+.BR dump .
+Otherwise
+.B restore
+may be confused.
+.IP
+This option can be used when dumping to local tapes (see above) or to local
+files.
+.TP
+.BI \-s " feet"
+Attempt to calculate the amount of tape needed at a particular density. If this
+amount is exceeded,
+.B dump
+prompts for a new tape. It is recommended to be a bit conservative on this
+option. The default tape length is 2300 feet. Specifying the tape size
+overrides end-of-media detection.
+.TP
+.BI \-S
+Size estimate. Determine the amount of space that is needed to perform the dump
+without actually doing it, and display the estimated number of bytes it will
+take. This is useful with incremental dumps to determine how many volumes of
+media will be needed.
+.TP
+.BI \-T " date"
+Use the specified date as the starting time for the dump instead of the time
+determined from looking in
+.I __DUMPDATES__ .
+The format of
+.I date
+is the same as that of
+.BR ctime (3)
+followed by an rfc822 timezone specification: either a plus or minus sign
+followed by two digits for the number of hours and two digits for the minutes.
+For example, -0800 for eight hours west of Greenwich or +0230 for two hours
+and a half east of Greenwich. This timezone offset takes into account
+daylight savings time (if applicable to the timezone): UTC offsets
+when daylight savings time is in effect will be different than offsets
+when daylight savings time is not in effect. For backward
+compatibility, if no timezone is specified, a local time is assumed.
+This option is useful for automated dump scripts that wish to dump over a
+specific period of time. The
+.B \-T
+option is mutually exclusive from the
+.B \-u
+option.
+.TP
+.BI \-u
+Update the file
+.I __DUMPDATES__
+after a successful dump. The format of
+.I __DUMPDATES__
+is readable by people, consisting of one free format record per line:
+filesystem name, increment level and
+.BR ctime (3)
+format dump date followed by a rfc822 timezone specification (see the
+.B \-u
+option for details). If no timezone offset is specified, times are interpreted
+as local. Whenever the file is written, all dates in the file are converted
+to the local time zone, without changing the UTC times. There
+may be only one entry per filesystem at each level. The file
+.I __DUMPDATES__
+may be edited to change any of the fields, if necessary.
+.TP
+.BI \-v
+The
+.B \-v
+(verbose) makes
+.B dump
+to print extra information which could be helpful in debug sessions.
+.TP
+.BI \-W
+.B Dump
+tells the operator what file systems need to be dumped. This information is
+gleaned from the files
+.I __DUMPDATES__
+and
+.IR /etc/fstab .
+The
+.B \-W
+option causes
+.B dump
+to print out, for all file systems in
+.I __DUMPDATES__ ,
+and regognized file systems in
+.I /etc/mtab
+and
+.IR /etc/fstab .
+the most recent dump date and level, and highlights those that should be
+dumped. If the
+.B \-W
+option is set, all other options are ignored, and
+.B dump
+exits immediately.
+.TP
+.BI \-w
+Is like
+.BR \-W ,
+but prints only recognized filesystems in
+.I /etc/mtab
+and
+.I /etc/fstab
+which need to be dumped.
+.TP
+.BI \-y
+Compress every block to be written to the tape using the lzo library.
+This doesn't compress as well as the zlib library but it's much faster.
+This option will work only when dumping to a file or pipe or, when dumping to
+a tape drive, if the tape drive is capable of writing variable length blocks.
+You will need at least the 0.4b34 version of
+.B restore
+in order to extract compressed tapes. Tapes written using compression will not
+be compatible with the BSD tape format.
+.TP
+.BI \-z "compression level"
+Compress every block to be written on the tape using zlib library. This option
+will work only when dumping to a file or pipe or, when dumping to a tape drive,
+if the tape drive is capable of writing variable length blocks. You will need
+at least the 0.4b22 version of
+.B restore
+in order to extract compressed tapes. Tapes written using compression will not
+be compatible with the BSD tape format. The (optional) parameter specifies the
+compression level zlib will use. The default compression level is 2. If the
+optional parameter is specified, there should be no white space between the
+option letter and the parameter.
+.PP
+.B Dump
+requires operator intervention on these conditions: end of tape, end of dump,
+tape write error, tape open error or disk read error (if there is more than a
+threshold of nr errors). In addition to alerting all operators implied by the
+.B \-n
+key,
+.B dump
+interacts with the operator on dump's control terminal at times when
+.B dump
+can no longer proceed, or if something is grossly wrong. All questions
+.B dump
+poses
+.I must
+be answered by typing \*(lqyes\*(rq or \*(lqno\*(rq, appropriately.
+.PP
+Since making a dump involves a lot of time and effort for full dumps,
+.B dump
+checkpoints itself at the start of each tape volume. If writing that volume
+fails for some reason,
+.B dump
+will, with operator permission, restart itself from the checkpoint after the
+old tape has been rewound and removed, and a new tape has been mounted.
+.PP
+.B Dump
+tells the operator what is going on at periodic intervals, including usually
+low estimates of the number of blocks to write, the number of tapes it will
+take, the time to completion, and the time to the tape change. The output is
+verbose, so that others know that the terminal controlling
+.B dump
+is busy, and will be for some time.
+.PP
+In the event of a catastrophic disk event, the time required to restore all the
+necessary backup tapes or files to disk can be kept to a minimum by staggering
+the incremental dumps. An efficient method of staggering incremental dumps to
+minimize the number of tapes follows:
+.IP \(em
+Always start with a level 0 backup, for example:
+.RS 14
+.B /sbin/dump -0u -f /dev/st0 /usr/src
+.RE
+.IP
+This should be done at set intervals, say once a month or once every two months,
+and on a set of fresh tapes that is saved forever.
+.IP \(em
+After a level 0, dumps of active file systems are taken on a daily basis, using
+a modified Tower of Hanoi algorithm, with this sequence of dump levels:
+.RS 14
+.B 3 2 5 4 7 6 9 8 9 9 ...
+.RE
+.IP
+For the daily dumps, it should be possible to use a fixed number of tapes for
+each day, used on a weekly basis. Each week, a level 1 dump is taken, and the
+daily Hanoi sequence repeats beginning with 3. For weekly dumps, another fixed
+set of tapes per dumped file system is used, also on a cyclical basis.
+.PP
+After several months or so, the daily and weekly tapes should get rotated out
+of the dump cycle and fresh tapes brought in.
+.SH ENVIRONMENT
+.TP
+.B TAPE
+If no
+.B \-f
+option was specified,
+.B dump
+will use the device specified via
+.B TAPE
+as the dump device.
+.B TAPE
+may be of the form
+.IR tapename ,
+.IR host:tapename ,
+or
+.IR user@host:tapename .
+.TP
+.B RMT
+The environment variable
+.B RMT
+will be used to determine the pathname of the remote
+.BR rmt (8)
+program.
+.TP
+.B RSH
+.B Dump
+uses the contents of this variable to determine the name of the remote shell
+command to use when doing remote backups (rsh, ssh etc.). If this variable is
+not set,
+.BR rcmd (3)
+will be used, but only root will be able to do remote backups.
+.SH FILES
+.TP
+.I /dev/st0
+default tape unit to dump to
+.TP
+.I __DUMPDATES__
+dump date records
+.TP
+.I /etc/fstab
+dump table: file systems and frequency
+.TP
+.I /etc/mtab
+dump table: mounted file systems
+.TP
+.I /etc/group
+to find group
+.I operator
+.SH SEE ALSO
+.BR fstab (5),
+.BR restore (8),
+.BR rmt (8)
+.SH DIAGNOSTICS
+Many, and verbose.
+.SH COMPATIBILITY
+The format of the
+.I __DUMPDATES__
+file has changed in release 0.4b34, however, the file will be read
+correctly with either pre-0.4b34 or 0.4b34 and later versions of
+.B dump
+provided that the machine on which
+.B dump
+is run did not change timezones (which should be a fairly rare occurence).
+.SH EXIT STATUS
+.B Dump
+exits with zero status on success. Startup errors are indicated with an exit
+code of 1; abnormal termination is indicated with an exit code of 3.
+.SH BUGS
+It might be considered a bug that this version of dump can only handle ext2/3
+filesystems. Specifically, it does not work with FAT filesystems.
+.PP
+Fewer than 32 read errors (change this with
+.BR \-I )
+on the filesystem are ignored. If noticing read errors is important, the output
+from dump can be parsed to look for lines that contain the text 'read error'.
+.PP
+When a read error occurs,
+.B dump
+prints out the corresponding physical disk block and sector number and the
+ext2/3 logical block number. It doesn't print out the corresponing file name or
+even the inode number. The user has to use
+.BR debugfs (8),
+commands
+.B ncheck
+and
+.B icheck
+to translate the
+.B ext2blk
+number printed out by
+.B dump
+into an inode number, then into a file name.
+.PP
+Each reel requires a new process, so parent processes for reels already written
+just hang around until the entire tape is written.
+.PP
+The estimated number of tapes is not correct if compression is on.
+.PP
+It would be nice if
+.B dump
+knew about the dump sequence, kept track of the tapes scribbled on, told the
+operator which tape to mount when, and provided more assistance for the
+operator running
+.BR restore .
+.PP
+.B Dump
+cannot do remote backups without being run as root, due to its security history.
+Presently, it works if you set it setuid (like it used to be), but this might
+constitute a security risk. Note that you can set
+.B RSH
+to use a remote shell program instead.
+.SH AUTHOR
+The
+.B dump/restore
+backup suite was ported to Linux's Second Extended File System by Remy Card
+<card@Linux.EU.Org>. He maintained the initial versions of
+.B dump
+(up and including 0.4b4, released in january 1997).
+.PP
+Starting with 0.4b5, the new maintainer is Stelian Pop <stelian@popies.net>.
+.SH AVAILABILITY
+The
+.B dump/restore
+backup suite is available from <http://dump.sourceforge.net>
+.SH HISTORY
+A
+.B dump
+command appeared in
+.B Version 6 AT&T UNIX.
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: dump.h,v 1.49 2004/07/01 09:14:49 stelian Exp $
+ */
+
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <protocols/dumprestore.h>
+#include <compatlfs.h>
+
+#define MAXINOPB (MAXBSIZE / sizeof(struct dinode))
+#define MAXNINDIR (MAXBSIZE / sizeof(blk_t))
+#define NUM_STR_SIZE 32 /* a generic number buffer size */
+
+/*
+ * Dump maps used to describe what is to be dumped.
+ */
+extern int mapsize; /* size of the state maps */
+extern char *usedinomap; /* map of allocated inodes */
+extern char *dumpdirmap; /* map of directories to be dumped */
+extern char *dumpinomap; /* map of files to be dumped */
+extern char *metainomap; /* which of the inodes in dumpinomap
+ will get only their metadata dumped */
+/*
+ * Map manipulation macros.
+ */
+#define SETINO(ino, map) \
+ map[(u_int)((ino) - 1) / NBBY] |= 1 << ((u_int)((ino) - 1) % NBBY)
+#define CLRINO(ino, map) \
+ map[(u_int)((ino) - 1) / NBBY] &= ~(1 << ((u_int)((ino) - 1) % NBBY))
+#define TSTINO(ino, map) \
+ (map[(u_int)((ino) - 1) / NBBY] & (1 << ((u_int)((ino) - 1) % NBBY)))
+
+/*
+ * All calculations done in 0.1" units!
+ */
+extern char *host; /* name of the remote host */
+extern const char *disk; /* name of the disk file */
+extern char tape[MAXPATHLEN];/* name of the tape file */
+extern char *tapeprefix; /* prefix of the tape file */
+extern char *dumpdates; /* name of the file containing dump date information*/
+extern char lastlevel[NUM_STR_SIZE];/* dump level of previous dump */
+extern char level[NUM_STR_SIZE];/* dump level of this dump */
+extern int Afile; /* archive file descriptor */
+extern int AfileActive; /* Afile flag */
+extern int zipflag; /* which compression method */
+extern int uflag; /* update flag */
+extern int mflag; /* dump metadata only if possible flag */
+extern int Mflag; /* multi-volume flag */
+extern int qflag; /* quit on errors flag */
+extern int vflag; /* verbose flag */
+extern int breademax; /* maximum number of bread errors before we quit */
+extern char *eot_script; /* end of volume script fiag */
+extern int diskfd; /* disk file descriptor */
+extern int tapefd; /* tape file descriptor */
+extern int pipeout; /* true => output to standard output */
+extern int fifoout; /* true => output to fifo */
+extern dump_ino_t curino; /* current inumber; used globally */
+extern int newtape; /* new tape flag */
+extern int density; /* density in 0.1" units */
+extern long tapesize; /* estimated tape size, blocks */
+extern long tsize; /* tape size in 0.1" units */
+extern long asize; /* number of 0.1" units written on current tape */
+extern int etapes; /* estimated number of tapes */
+extern int nonodump; /* if set, do not honor UF_NODUMP user flags */
+extern int unlimited; /* if set, write to end of medium */
+extern int compressed; /* if set, dump is to be compressed */
+extern long long bytes_written;/* total bytes written to tape */
+extern long uncomprblks; /* uncompressed blocks written to tape */
+extern int notify; /* notify operator flag */
+extern int blockswritten; /* number of blocks written on current tape */
+extern int tapeno; /* current tape number */
+extern time_t tstart_writing; /* when started writing the first tape block */
+extern time_t tend_writing; /* after writing the last tape block */
+#ifdef __linux__
+extern ext2_filsys fs;
+#else
+extern struct fs *sblock; /* the file system super block */
+extern char sblock_buf[MAXBSIZE];
+#endif
+extern long xferrate; /* averaged transfer rate of all volumes */
+extern long dev_bsize; /* block size of underlying disk device */
+extern int dev_bshift; /* log2(dev_bsize) */
+extern int tp_bshift; /* log2(TP_BSIZE) */
+extern dump_ino_t volinfo[]; /* which inode on which volume archive info */
+
+#ifdef USE_QFA
+#define QFA_MAGIC "495115637697"
+#define QFA_VERSION "1.0"
+extern int gTapeposfd;
+extern char *gTapeposfile;
+extern char gTps[255];
+extern int32_t gThisDumpDate;
+#endif /* USE_QFA */
+
+#ifndef __P
+#include <sys/cdefs.h>
+#endif
+
+/* operator interface functions */
+void broadcast __P((const char *message));
+time_t do_stats __P((void));
+void lastdump __P((char arg));
+void msg __P((const char *fmt, ...));
+void msgtail __P((const char *fmt, ...));
+int query __P((const char *question));
+void quit __P((const char *fmt, ...));
+void set_operators __P((void));
+#if defined(SIGINFO)
+void statussig __P((int signo));
+#endif
+void timeest __P((void));
+time_t unctime __P((const char *str));
+
+/* mapping rouintes */
+struct dinode;
+long blockest __P((struct dinode const *dp));
+int mapfiles __P((dump_ino_t maxino, long *tapesize));
+#ifdef __linux__
+int mapfilesfromdir __P((dump_ino_t maxino, long *tapesize, char *directory));
+int maponefile __P((dump_ino_t maxino, long *tapesize, char *directory));
+#endif
+int mapdirs __P((dump_ino_t maxino, long *tapesize));
+
+/* file dumping routines */
+void blksout __P((blk_t *blkp, int frags, dump_ino_t ino));
+void bread __P((ext2_loff_t blkno, char *buf, int size));
+void dumpino __P((struct dinode *dp, dump_ino_t ino, int metaonly));
+#ifdef __linux__
+void dumpdirino __P((struct dinode *dp, dump_ino_t ino));
+#endif
+void dumpmap __P((char *map, int type, dump_ino_t ino));
+void writeheader __P((dump_ino_t ino));
+void mkchecksum __P((union u_spcl *tmpspcl));
+
+/* tape writing routines */
+int alloctape __P((void));
+void close_rewind __P((void));
+void dumpblock __P((blk_t blkno, int size));
+void startnewtape __P((int top));
+time_t trewind __P((void));
+void writerec __P((const void *dp, int isspcl));
+char *mktimeest __P((time_t tnow));
+
+void Exit __P((int status));
+void dumpabort __P((int signo));
+void getfstab __P((void));
+
+const char *rawname __P((const char *cp));
+struct dinode *getino __P((dump_ino_t inum));
+
+/* rdump routines */
+#ifdef RDUMP
+int rmthost __P((const char *host));
+int rmtopen __P((const char *tape, const int mode));
+void rmtclose __P((void));
+int rmtread __P((char *buf, size_t count));
+int rmtwrite __P((const char *buf, size_t count));
+OFF_T rmtseek __P((OFF_T offset, int pos));
+struct mtget * rmtstatus __P((void));
+int rmtioctl __P((int cmd, int count));
+#endif /* RDUMP */
+
+void interrupt __P((int signo)); /* in case operator bangs on console */
+int exclude_ino __P((dump_ino_t ino));
+void do_exclude_ino __P((dump_ino_t ino, const char *));
+
+/*
+ * Exit status codes
+ */
+#define X_FINOK 0 /* normal exit */
+#define X_STARTUP 1 /* startup error */
+#define X_REWRITE 2 /* restart writing from the check point */
+#define X_ABORT 3 /* abort dump; don't attempt checkpointing */
+
+#define OPGRENT "operator" /* group entry to notify */
+#ifdef __linux__
+#define DIALUP "ttyS" /* prefix for dialups */
+#else
+#define DIALUP "ttyd" /* prefix for dialups */
+#endif
+
+#include <mntent.h>
+
+struct mntent *fstabsearch __P((const char *key)); /* search fs_file and fs_spec */
+#ifdef __linux__
+struct mntent *fstabsearchdir __P((const char *key, char *dir)); /* search fs_file and fs_spec */
+#endif
+
+/*
+ * The contents of the file _PATH_DUMPDATES is maintained both on
+ * a linked list, and then (eventually) arrayified.
+ */
+struct dumpdates {
+ char dd_name[MAXPATHLEN+3];
+ struct mntent *dd_fstab;
+ int dd_level;
+ time_t dd_ddate;
+};
+struct dumptime {
+ struct dumpdates dt_value;
+ struct dumptime *dt_next;
+};
+extern struct dumptime *dthead; /* head of the list version */
+extern int nddates; /* number of records (might be zero) */
+extern int ddates_in; /* we have read the increment file */
+extern struct dumpdates **ddatev; /* the arrayfied version */
+void initdumptimes __P((int));
+void getdumptime __P((int));
+void putdumptime __P((void));
+#define ITITERATE(i, ddp) \
+ for (ddp = ddatev[i = 0]; i < nddates; ddp = ddatev[++i])
+
+void sig __P((int signo));
+
+/*
+ * Compatibility with old systems.
+ */
+#ifdef COMPAT
+#include <sys/file.h>
+#define strchr(a,b) index(a,b)
+#define strrchr(a,b) rindex(a,b)
+extern char *strdup(), *ctime();
+extern int read(), write();
+extern int errno;
+#endif
+
+#ifdef __linux__
+#define DUMP_CURRENT_REV 1
+
+int dump_fs_open(const char *disk, ext2_filsys *fs);
+#endif
+
+#ifndef __linux__
+#ifndef _PATH_UTMP
+#define _PATH_UTMP "/etc/utmp"
+#endif
+#ifndef _PATH_FSTAB
+#define _PATH_FSTAB "/etc/fstab"
+#endif
+#endif
+
+#ifdef sunos
+extern char *calloc();
+extern char *malloc();
+extern long atol();
+extern char *strcpy();
+extern char *strncpy();
+extern char *strcat();
+extern time_t time();
+extern void endgrent();
+extern void exit();
+extern off_t lseek();
+extern const char *strerror();
+#endif
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: itime.c,v 1.28 2004/06/17 09:01:15 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <time.h>
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#include <sys/file.h>
+#include <unistd.h>
+#elif defined sunos
+#include <sys/vnode.h>
+
+#include <ufs/fsdir.h>
+#include <ufs/inode.h>
+#include <ufs/fs.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+
+#include <protocols/dumprestore.h>
+
+#include "dump.h"
+
+struct dumpdates **ddatev;
+int nddates;
+int ddates_in;
+struct dumptime *dthead;
+
+static void dumprecout __P((FILE *, struct dumpdates *));
+static int getrecord __P((FILE *, struct dumpdates *));
+static int makedumpdate __P((struct dumpdates *, char *));
+static void readdumptimes __P((FILE *));
+
+void
+initdumptimes(int createdumpdates)
+{
+ FILE *df;
+ struct flock lock;
+
+ if ((df = fopen(dumpdates, "r")) == NULL) {
+ if (errno != ENOENT) {
+ quit("cannot read %s: %s\n", dumpdates,
+ strerror(errno));
+ /* NOTREACHED */
+ }
+ if (createdumpdates) {
+ /*
+ * Dumpdates does not exist, make an empty one.
+ */
+ msg("WARNING: no file `%s', making an empty one\n", dumpdates);
+ if ((df = fopen(dumpdates, "w")) == NULL) {
+ quit("cannot create %s: %s\n", dumpdates,
+ strerror(errno));
+ /* NOTREACHED */
+ }
+ (void) fclose(df);
+ if ((df = fopen(dumpdates, "r")) == NULL) {
+ quit("cannot read %s even after creating it: %s\n",
+ dumpdates, strerror(errno));
+ /* NOTREACHED */
+ }
+ }
+ else
+ msg("WARNING: no file `%s'\n", dumpdates);
+ }
+ if (df != NULL) {
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_RDLCK;
+ if (fcntl(fileno(df), F_SETLKW, &lock) < 0)
+ quit("cannot set read lock on %s: %s\n",
+ dumpdates, strerror(errno));
+ readdumptimes(df);
+ (void) fclose(df);
+ }
+}
+
+static void
+readdumptimes(FILE *df)
+{
+ int i;
+ struct dumptime *dtwalk;
+
+ for (;;) {
+ dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
+ if (getrecord(df, &(dtwalk->dt_value)) < 0)
+ break;
+ nddates++;
+ dtwalk->dt_next = dthead;
+ dthead = dtwalk;
+ }
+
+ ddates_in = 1;
+ /*
+ * arrayify the list, leaving enough room for the additional
+ * record that we may have to add to the ddate structure
+ */
+ ddatev = (struct dumpdates **)
+ calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
+ dtwalk = dthead;
+ for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
+ ddatev[i] = &dtwalk->dt_value;
+}
+
+void
+getdumptime(int createdumpdates)
+{
+ struct dumpdates *ddp;
+ int i;
+
+#ifdef FDEBUG
+ msg("Looking for name %s in dumpdates = %s for level = %s\n",
+ disk, dumpdates, level);
+#endif
+ spcl.c_ddate = 0;
+ memset(&lastlevel, 0, NUM_STR_SIZE);
+
+ /* If this is a level 0 dump, and we're not updating
+ dumpdates, there's no point in trying to read
+ dumpdates. It may not exist yet, or may not be mounted. For
+ incrementals, we *must* read dumpdates (fail if it's not there!) */
+ if ( (!strcmp(level, lastlevel)) && !createdumpdates)
+ return;
+ initdumptimes(createdumpdates);
+ if (ddatev == NULL)
+ return;
+ /*
+ * Go find the entry with the same name for a lower increment
+ * and older date
+ */
+ ITITERATE(i, ddp) {
+ if (strncmp(disk, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
+ continue;
+ if (ddp->dd_level >= atoi(level))
+ continue;
+ if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
+ continue;
+ spcl.c_ddate = ddp->dd_ddate;
+ snprintf(lastlevel, NUM_STR_SIZE, "%d", ddp->dd_level);
+ }
+}
+
+void
+putdumptime(void)
+{
+ FILE *df;
+ struct dumpdates *dtwalk;
+ int i;
+ int fd;
+ struct flock lock;
+
+ if(uflag == 0)
+ return;
+ if ((df = fopen(dumpdates, "r+")) == NULL)
+ quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
+ fd = fileno(df);
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ if (fcntl(fd, F_SETLKW, &lock) < 0)
+ quit("cannot set write lock on %s: %s\n", dumpdates, strerror(errno));
+ free((char *)ddatev);
+ ddatev = 0;
+ nddates = 0;
+ dthead = 0;
+ ddates_in = 0;
+ readdumptimes(df);
+ if (fseek(df, 0L, 0) < 0)
+ quit("fseek: %s\n", strerror(errno));
+ spcl.c_ddate = 0;
+ ITITERATE(i, dtwalk) {
+ if (strncmp(disk, dtwalk->dd_name,
+ sizeof (dtwalk->dd_name)) != 0)
+ continue;
+ if (dtwalk->dd_level != atoi(level))
+ continue;
+ goto found;
+ }
+ /*
+ * construct the new upper bound;
+ * Enough room has been allocated.
+ */
+ dtwalk = ddatev[nddates] =
+ (struct dumpdates *)calloc(1, sizeof (struct dumpdates));
+ nddates += 1;
+ found:
+ (void) strncpy(dtwalk->dd_name, disk, sizeof (dtwalk->dd_name));
+ dtwalk->dd_level = atoi(level);
+ dtwalk->dd_ddate = spcl.c_date;
+
+ ITITERATE(i, dtwalk) {
+ dumprecout(df, dtwalk);
+ }
+ if (fflush(df))
+ quit("%s: %s\n", dumpdates, strerror(errno));
+ if (ftruncate(fd, ftell(df)))
+ quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
+ (void) fclose(df);
+}
+
+static void
+dumprecout(FILE *file, struct dumpdates *what)
+{
+ char buf[26];
+ struct tm *tms;
+
+ tms = localtime(&what->dd_ddate);
+ strncpy(buf, asctime(tms), sizeof(buf));
+ if (buf[24] != '\n' || buf[25] != '\0')
+ quit("asctime returned an unexpected string\n");
+ buf[24] = 0;
+ if (fprintf(file, "%s %d %s %c%2.2d%2.2d\n",
+ what->dd_name,
+ what->dd_level,
+ buf,
+ (tms->tm_gmtoff < 0 ? '-' : '+'),
+ abs(tms->tm_gmtoff) / 3600,
+ abs(tms->tm_gmtoff) % 3600 / 60) < 0)
+ quit("%s: %s\n", dumpdates, strerror(errno));
+}
+
+int recno;
+
+static int
+getrecord(FILE *df, struct dumpdates *ddatep)
+{
+ char tbuf[BUFSIZ];
+
+ recno = 0;
+ if (fgets(tbuf, sizeof (tbuf), df) == NULL)
+ return(-1);
+ recno++;
+ if (makedumpdate(ddatep, tbuf) < 0) {
+ msg("Unknown format in %s, line %d\n",
+ dumpdates, recno);
+ return(-1);
+ }
+
+#ifdef FDEBUG
+ msg("getrecord: %s %d %s", ddatep->dd_name, ddatep->dd_level,
+ ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
+#endif
+ return(0);
+}
+
+static int
+makedumpdate(struct dumpdates *ddp, char *tbuf)
+{
+ char *tok;
+ /* device name */
+ if ( NULL == (tok = strsep( &tbuf, " ")) )
+ return(-1);
+ if ( !tbuf || strlen(tok) > MAXPATHLEN )
+ return(-1);
+ strcpy(ddp->dd_name, tok);
+
+ /* eat whitespace */
+ for( ; *tbuf == ' ' ; tbuf++);
+
+ /* dump level */
+ ddp->dd_level = atoi(tbuf);
+ /* eat the rest of the numbers*/
+ for( ; *tbuf >= '0' && *tbuf <= '9' ; tbuf++);
+
+ /* eat whitespace */
+ for( ; *tbuf == ' ' ; tbuf++);
+
+ /* dump date */
+ ddp->dd_ddate = unctime(tbuf);
+ if (ddp->dd_ddate < 0)
+ return(-1);
+ /* fstab entry */
+ ddp->dd_fstab = fstabsearch(ddp->dd_name);
+ return(0);
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: main.c,v 1.94 2004/07/05 15:12:45 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <ctype.h>
+#include <compaterr.h>
+#include <fcntl.h>
+#include <fstab.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <mntent.h>
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <time.h>
+#ifdef __linux__
+#include <linux/types.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <sys/stat.h>
+#include <bsdcompat.h>
+#include <linux/fs.h> /* for definition of BLKFLSBUF */
+#elif defined sunos
+#include <sys/vnode.h>
+
+#include <ufs/inode.h>
+#include <ufs/fs.h>
+#else
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#endif
+
+#include <protocols/dumprestore.h>
+
+#include "dump.h"
+#include "pathnames.h"
+#include "bylabel.h"
+
+#ifndef SBOFF
+#define SBOFF (SBLOCK * DEV_BSIZE)
+#endif
+
+int abortifconnerr = 1; /* set to 1 if lib dumprmt.o should exit on connection errors
+ otherwise just print a message using msg */
+/*
+ * Dump maps used to describe what is to be dumped.
+ */
+int mapsize; /* size of the state maps */
+char *usedinomap; /* map of allocated inodes */
+char *dumpdirmap; /* map of directories to be dumped */
+char *dumpinomap; /* map of files to be dumped */
+char *metainomap; /* which of the inodes in dumpinomap will get
+ only their metadata dumped */
+
+const char *disk; /* name of the disk file */
+char tape[MAXPATHLEN];/* name of the tape file */
+char *tapeprefix; /* prefix of the tape file */
+char *dumpdates; /* name of the file containing dump date information*/
+char lastlevel[NUM_STR_SIZE];/* dump level of previous dump */
+char level[NUM_STR_SIZE];/* dump level of this dump */
+int zipflag; /* which compression method */
+int Afile = -1; /* archive file descriptor */
+int AfileActive = 1;/* Afile flag */
+int uflag; /* update flag */
+int mflag; /* dump metadata only if possible */
+int Mflag; /* multi-volume flag */
+int qflag; /* quit on errors flag */
+int vflag; /* verbose flag */
+int breademax = 32; /* maximum number of bread errors before we quit */
+char *eot_script; /* end of volume script fiag */
+int diskfd; /* disk file descriptor */
+int tapefd; /* tape file descriptor */
+int pipeout; /* true => output to standard output */
+int fifoout; /* true => output to fifo */
+dump_ino_t curino; /* current inumber; used globally */
+int newtape; /* new tape flag */
+int density; /* density in 0.1" units */
+long tapesize; /* estimated tape size, blocks */
+long tsize; /* tape size in 0.1" units */
+long asize; /* number of 0.1" units written on current tape */
+int etapes; /* estimated number of tapes */
+int nonodump; /* if set, do not honor UF_NODUMP user flags */
+int unlimited; /* if set, write to end of medium */
+int compressed; /* if set, dump is to be compressed */
+long long bytes_written;/* total bytes written to tape */
+long uncomprblks; /* uncompressed blocks written to tape */
+int notify; /* notify operator flag */
+int blockswritten; /* number of blocks written on current tape */
+int tapeno; /* current tape number */
+time_t tstart_writing; /* when started writing the first tape block */
+time_t tend_writing; /* after writing the last tape block */
+#ifdef __linux__
+ext2_filsys fs;
+#else
+struct fs *sblock; /* the file system super block */
+char sblock_buf[MAXBSIZE];
+#endif
+long xferrate; /* averaged transfer rate of all volumes */
+long dev_bsize; /* block size of underlying disk device */
+int dev_bshift; /* log2(dev_bsize) */
+int tp_bshift; /* log2(TP_BSIZE) */
+dump_ino_t volinfo[TP_NINOS];/* which inode on which volume archive info */
+
+#ifdef USE_QFA
+int gTapeposfd;
+char *gTapeposfile;
+char gTps[255];
+int32_t gThisDumpDate;
+#endif /* USE_QFA */
+
+struct dumptime *dthead; /* head of the list version */
+int nddates; /* number of records (might be zero) */
+int ddates_in; /* we have read the increment file */
+struct dumpdates **ddatev; /* the arrayfied version */
+
+int notify = 0; /* notify operator flag */
+int blockswritten = 0; /* number of blocks written on current tape */
+int tapeno = 0; /* current tape number */
+int density = 0; /* density in bytes/0.1" " <- this is for hilit19 */
+int ntrec = NTREC; /* # blocks in each tape record */
+int cartridge = 0; /* Assume non-cartridge tape */
+#ifdef USE_QFA
+int tapepos = 0; /* assume no QFA tapeposition needed by user */
+#endif /* USE_QFA */
+int dokerberos = 0; /* Use Kerberos authentication */
+long dev_bsize = 1; /* recalculated below */
+long *blocksperfiles = NULL; /* output blocks per file(s) */
+char *host = NULL; /* remote host (if any) */
+int sizest = 0; /* return size estimate only */
+int compressed = 0; /* use zlib to compress the output, compress level 1-9 */
+long long bytes_written = 0; /* total bytes written */
+long uncomprblks = 0;/* uncompressed blocks written */
+
+long smtc_errno;
+
+#ifdef __linux__
+char *__progname;
+#endif
+
+int maxbsize = 1024*1024; /* XXX MAXBSIZE from sys/param.h */
+static long numarg __P((const char *, long, long));
+static long *numlistarg __P((const char *, long, long));
+static void obsolete __P((int *, char **[]));
+static void usage __P((void));
+static void do_exclude_from_file __P((char *));
+static void do_exclude_ino_str __P((char *));
+static void incompat_flags __P((int, char, char));
+
+static char* iexclude_bitmap = NULL; /* the inode exclude bitmap */
+static unsigned int iexclude_bitmap_bytes = 0; /* size of bitmap in bytes */
+
+int
+main(int argc, char *argv[])
+{
+ dump_ino_t ino;
+ int dirty;
+ struct dinode *dp;
+ struct mntent *dt;
+ char *map;
+ int ch, pch = 0;
+ int i, anydirskipped;
+ int aflag = 0, bflag = 0, Tflag = 0, honorlevel = 1;
+ dump_ino_t maxino;
+ struct STAT statbuf;
+ dev_t filedev = 0;
+#ifdef __linux__
+ errcode_t retval;
+ char directory[MAXPATHLEN];
+ char pathname[MAXPATHLEN];
+#endif
+ time_t tnow;
+ char *diskparam;
+ char *Apath = NULL;
+
+ spcl.c_label[0] = '\0';
+ spcl.c_date = time(NULL);
+
+#ifdef __linux__
+ __progname = argv[0];
+ directory[0] = 0;
+ initialize_ext2_error_table();
+#endif
+
+ tsize = 0; /* Default later, based on 'c' option for cart tapes */
+ unlimited = 1;
+ eot_script = NULL;
+ if ((tapeprefix = getenv("TAPE")) == NULL)
+ tapeprefix = _PATH_DEFTAPE;
+ dumpdates = _PATH_DUMPDATES;
+ if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0)
+ quit("TP_BSIZE must be a multiple of DEV_BSIZE\n");
+ memset(&lastlevel, 0, NUM_STR_SIZE);
+ memset(&level, 0, NUM_STR_SIZE);
+
+ if (argc < 2)
+ usage();
+
+ obsolete(&argc, &argv);
+
+#ifdef USE_QFA
+ gTapeposfd = -1;
+#endif /* USE_QFA */
+
+ while ((ch = getopt(argc, argv,
+ "0123456789A:aB:b:cd:D:e:E:f:F:h:I:"
+#ifdef HAVE_BZLIB
+ "j::"
+#endif
+ "L:"
+#ifdef KERBEROS
+ "k"
+#endif
+ "mMnq"
+#ifdef USE_QFA
+ "Q:"
+#endif
+ "s:ST:uvWw"
+#ifdef HAVE_LZO
+ "y"
+#endif
+#ifdef HAVE_ZLIB
+ "z::"
+#endif
+ )) != -1)
+ switch (ch) {
+ /* dump level */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if ((pch >= '0') && (pch <= '9') && (strlen(level) < NUM_STR_SIZE))
+ level[strlen(level)] = ch;
+ else
+ level[0] = ch;
+ pch = ch;
+ break;
+
+ case 'A': /* archive file */
+ Apath = optarg;
+ break;
+
+ case 'a': /* `auto-size', Write to EOM. */
+ unlimited = 1;
+ aflag = 1;
+ break;
+
+ case 'B': /* blocks per output file */
+ unlimited = 0;
+ blocksperfiles = numlistarg("number of blocks per file",
+ 1L, 0L);
+ break;
+
+ case 'b': /* blocks per tape write */
+ ntrec = numarg("number of blocks per write",
+ 1L, 1048576L);
+ if (ntrec > maxbsize/1024) {
+ msg("Please choose a blocksize <= %dkB\n",
+ maxbsize/1024);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ bflag = 1;
+ break;
+
+ case 'c': /* Tape is cart. not 9-track */
+ unlimited = 0;
+ cartridge = 1;
+ break;
+
+ case 'd': /* density, in bits per inch */
+ unlimited = 0;
+ density = numarg("density", 10L, 327670L) / 10;
+ if (density >= 625 && !bflag)
+ ntrec = HIGHDENSITYTREC;
+ break;
+
+ case 'D': /* path of dumpdates file */
+ dumpdates = optarg;
+ break;
+
+ /* 04-Feb-00 ILC */
+ case 'e': /* exclude an inode */
+ {
+ char *p = optarg, *q;
+ while ((q = strchr(p, ','))) {
+ *q = '\0';
+ do_exclude_ino_str(p);
+ p = q + 1;
+ }
+ do_exclude_ino_str(p);
+ }
+ break;
+
+ case 'E': /* exclude inodes read from file */
+ do_exclude_from_file(optarg);
+ break;
+
+ case 'f': /* output file */
+ tapeprefix = optarg;
+ break;
+
+ case 'F': /* end of tape script */
+ eot_script = optarg;
+ break;
+
+ case 'h':
+ honorlevel = numarg("honor level", 0L, 10L);
+ break;
+
+#ifdef HAVE_BZLIB
+ case 'j':
+ compressed = 2;
+ zipflag = COMPRESS_BZLIB;
+ if (optarg)
+ compressed = numarg("compress level", 1L, 9L);
+ break;
+#endif /* HAVE_BZLIB */
+
+ case 'I':
+ breademax =
+ numarg ("number of errors to ignore", 0L, 0L);
+ break;
+
+#ifdef KERBEROS
+ case 'k':
+ dokerberos = 1;
+ break;
+#endif
+
+ case 'L':
+ /*
+ * Note that although there are LBLSIZE characters,
+ * the last must be '\0', so the limit on strlen()
+ * is really LBLSIZE-1.
+ */
+ strncpy(spcl.c_label, optarg, LBLSIZE);
+ spcl.c_label[LBLSIZE-1] = '\0';
+ if (strlen(optarg) > LBLSIZE-1) {
+ msg(
+ "WARNING Label `%s' is larger than limit of %d characters.\n",
+ optarg, LBLSIZE-1);
+ msg("WARNING: Using truncated label `%s'.\n",
+ spcl.c_label);
+ }
+ break;
+
+ case 'm': /* metadata only flag */
+ mflag = 1;
+ break;
+
+ case 'M': /* multi-volume flag */
+ Mflag = 1;
+ break;
+
+ case 'n': /* notify operators */
+ notify = 1;
+ break;
+
+ case 'q':
+ qflag = 1;
+ break;
+
+#ifdef USE_QFA
+ case 'Q': /* create tapeposfile */
+ gTapeposfile = optarg;
+ tapepos = 1;
+ break;
+#endif /* USE_QFA */
+
+ case 's': /* tape size, feet */
+ unlimited = 0;
+ tsize = numarg("tape size", 1L, 0L) * 12 * 10;
+ break;
+
+ case 'S':
+ sizest = 1; /* return size estimate only */
+ break;
+
+ case 'T': /* time of last dump */
+ spcl.c_ddate = unctime(optarg);
+ if (spcl.c_ddate < 0) {
+ msg("bad time \"%s\"\n", optarg);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ Tflag = 1;
+ lastlevel[0] = '?'; lastlevel[1] = '\0';
+ break;
+
+ case 'u': /* update dumpdates */
+ uflag = 1;
+ break;
+
+ case 'v': /* verbose */
+ vflag = 1;
+ break;
+
+ case 'W': /* what to do */
+ case 'w':
+ lastdump(ch);
+ exit(X_FINOK); /* do nothing else */
+#ifdef HAVE_LZO
+ case 'y':
+ compressed = 2;
+ zipflag = COMPRESS_LZO;
+ break;
+#endif /* HAVE_LZO */
+
+#ifdef HAVE_ZLIB
+ case 'z':
+ compressed = 2;
+ zipflag = COMPRESS_ZLIB;
+ if (optarg)
+ compressed = numarg("compress level", 1L, 9L);
+ break;
+#endif /* HAVE_ZLIB */
+
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ msg("Must specify disk or filesystem\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ diskparam = *argv++;
+ if (strlen(diskparam) >= MAXPATHLEN) {
+ msg("Disk or filesystem name too long: %s\n", diskparam);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ argc--;
+ incompat_flags(Tflag && uflag, 'T', 'u');
+ incompat_flags(aflag && blocksperfiles, 'a', 'B');
+ incompat_flags(aflag && cartridge, 'a', 'c');
+ incompat_flags(aflag && density, 'a', 'd');
+ incompat_flags(aflag && tsize, 'a', 's');
+
+ if (strcmp(tapeprefix, "-") == 0) {
+ pipeout++;
+ tapeprefix = "standard output";
+ }
+
+ if (blocksperfiles && !compressed)
+ for (i = 1; i <= *blocksperfiles; i++)
+ blocksperfiles[i] = blocksperfiles[i] / ntrec * ntrec; /* round down */
+ else if (!unlimited) {
+ /*
+ * Determine how to default tape size and density
+ *
+ * density tape size
+ * 9-track 1600 bpi (160 bytes/.1") 2300 ft.
+ * 9-track 6250 bpi (625 bytes/.1") 2300 ft.
+ * cartridge 8000 bpi (100 bytes/.1") 1700 ft.
+ * (450*4 - slop)
+ * hilit19 hits again: "
+ */
+ if (density == 0)
+ density = cartridge ? 100 : 160;
+ if (tsize == 0)
+ tsize = cartridge ? 1700L*120L : 2300L*120L;
+ }
+
+ {
+ int i;
+ char *n;
+
+ if ((n = strchr(tapeprefix, ':'))) {
+ for (i = 0; i < (n - tapeprefix); i++) {
+ if (tapeprefix[i] == '/')
+ break;
+ }
+ if (tapeprefix[i] != '/') {
+ host = tapeprefix;
+ tapeprefix = strchr(host, ':');
+ *tapeprefix++ = '\0';
+#ifdef RDUMP
+ if (index(tapeprefix, '\n')) {
+ msg("invalid characters in tape\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ if (rmthost(host) == 0)
+ exit(X_STARTUP);
+#else
+ msg("remote dump not enabled\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+#endif
+ }
+ }
+ }
+
+ (void)setuid(getuid()); /* rmthost() is the only reason to be setuid */
+ if (Apath && (Afile = open(Apath, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP |
+ S_IWGRP | S_IROTH | S_IWOTH)) < 0) {
+ msg("Cannot open %s for writing: %s\n",
+ optarg, strerror(errno));
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+
+ if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+ signal(SIGHUP, sig);
+ if (signal(SIGTRAP, SIG_IGN) != SIG_IGN)
+ signal(SIGTRAP, sig);
+ if (signal(SIGFPE, SIG_IGN) != SIG_IGN)
+ signal(SIGFPE, sig);
+ if (signal(SIGBUS, SIG_IGN) != SIG_IGN)
+ signal(SIGBUS, sig);
+ if (signal(SIGSEGV, SIG_IGN) != SIG_IGN)
+ signal(SIGSEGV, sig);
+ if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
+ signal(SIGTERM, sig);
+ if (signal(SIGINT, interrupt) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+#ifdef SIGXCPU
+ signal(SIGXCPU, SIG_IGN);
+#endif /* SIGXCPU */
+#ifdef SIGXFSZ
+ signal(SIGXFSZ, SIG_IGN);
+#endif /* SIGXFSZ */
+
+ set_operators(); /* /etc/group snarfed */
+ getfstab(); /* /etc/fstab snarfed */
+
+ /*
+ * disk may end in / and this can confuse
+ * fstabsearch.
+ */
+ i = strlen(diskparam) - 1;
+ if (i > 1 && diskparam[i] == '/')
+ if (!(i == 6 && !strcmp(diskparam, "LABEL=/")))
+ diskparam[i] = '\0';
+
+ disk = get_device_name(diskparam);
+ if (!disk)
+ disk = strdup(diskparam);
+
+ /*
+ * disk can be either the full special file name,
+ * the suffix of the special file name,
+ * the special name missing the leading '/',
+ * the file system name with or without the leading '/'.
+ */
+ if ((dt = fstabsearch(disk)) != NULL) {
+ /* if found then only one parameter (i.e. partition)
+ * is allowed */
+ if (argc >= 1) {
+ (void)fprintf(stderr, "Unknown arguments to dump:");
+ while (argc--)
+ (void)fprintf(stderr, " %s", *argv++);
+ (void)fprintf(stderr, "\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ disk = rawname(dt->mnt_fsname);
+ (void)strncpy(spcl.c_dev, dt->mnt_fsname, NAMELEN);
+ (void)strncpy(spcl.c_filesys, dt->mnt_dir, NAMELEN);
+ } else {
+#ifdef __linux__
+#ifdef HAVE_REALPATH
+ if (realpath(disk, pathname) == NULL)
+#endif
+ strcpy(pathname, disk);
+ /*
+ * The argument could be now a mountpoint of
+ * a filesystem specified in fstab. Search for it.
+ */
+ if ((dt = fstabsearch(pathname)) != NULL) {
+ disk = rawname(dt->mnt_fsname);
+ (void)strncpy(spcl.c_dev, dt->mnt_fsname, NAMELEN);
+ (void)strncpy(spcl.c_filesys, dt->mnt_dir, NAMELEN);
+ } else {
+ /*
+ * The argument was not found in the fstab
+ * assume that this is a subtree and search for it
+ */
+ dt = fstabsearchdir(pathname, directory);
+ if (dt != NULL) {
+ char name[MAXPATHLEN];
+ (void)strncpy(spcl.c_dev, dt->mnt_fsname, NAMELEN);
+ (void)snprintf(name, sizeof(name), "%s (dir %s)",
+ dt->mnt_dir, directory);
+ (void)strncpy(spcl.c_filesys, name, NAMELEN);
+ disk = rawname(dt->mnt_fsname);
+ } else {
+ (void)strncpy(spcl.c_dev, disk, NAMELEN);
+ (void)strncpy(spcl.c_filesys, "an unlisted file system",
+ NAMELEN);
+ }
+ }
+#else
+ (void)strncpy(spcl.c_dev, disk, NAMELEN);
+ (void)strncpy(spcl.c_filesys, "an unlisted file system",
+ NAMELEN);
+#endif
+ }
+
+ if (directory[0] != 0) {
+ if (atoi(level) != 0) {
+ msg("Only level 0 dumps are allowed on a subdirectory\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ if (uflag) {
+ msg("You can't update the dumpdates file when dumping a subdirectory\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ }
+ spcl.c_dev[NAMELEN-1] = '\0';
+ spcl.c_filesys[NAMELEN-1] = '\0';
+ (void)gethostname(spcl.c_host, NAMELEN);
+ spcl.c_host[NAMELEN-1] = '\0';
+ spcl.c_level = atoi(level);
+ spcl.c_type = TS_TAPE;
+ if (!Tflag)
+ getdumptime(uflag); /* dumpdates snarfed */
+
+ if (spcl.c_ddate == 0 && spcl.c_level) {
+ msg("WARNING: There is no inferior level dump on this filesystem\n");
+ msg("WARNING: Assuming a level 0 dump by default\n");
+ level[0] = '0'; level[1] = '\0';
+ spcl.c_level = 0;
+ }
+
+ if (Mflag)
+ snprintf(tape, MAXPATHLEN, "%s%03d", tapeprefix, tapeno + 1);
+ else
+ strncpy(tape, tapeprefix, MAXPATHLEN);
+ tape[MAXPATHLEN - 1] = '\0';
+
+ if (!pipeout) {
+ if (STAT(tape, &statbuf) != -1)
+ fifoout= statbuf.st_mode & S_IFIFO;
+ }
+
+ if (!sizest) {
+
+ msg("Date of this level %s dump: %s", level,
+ ctime4(&spcl.c_date));
+#ifdef USE_QFA
+ gThisDumpDate = spcl.c_date;
+#endif
+ if (spcl.c_ddate)
+ msg("Date of last level %s dump: %s", lastlevel,
+ ctime4(&spcl.c_ddate));
+ msg("Dumping %s (%s) ", disk, spcl.c_filesys);
+ if (host)
+ msgtail("to %s on host %s\n", tape, host);
+ else
+ msgtail("to %s\n", tape);
+ } /* end of size estimate */
+
+#ifdef __linux__
+ if ((diskfd = OPEN(disk, O_RDONLY)) < 0) {
+ msg("Cannot open %s\n", disk);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+#ifdef BLKFLSBUF
+ (void)ioctl(diskfd, BLKFLSBUF, 0);
+#endif
+ retval = dump_fs_open(disk, &fs);
+ if (retval) {
+ com_err(disk, retval, "while opening filesystem");
+ if (retval == EXT2_ET_REV_TOO_HIGH)
+ msg("Get a newer version of dump!\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ if (fs->super->s_rev_level > DUMP_CURRENT_REV) {
+ com_err(disk, retval, "while opening filesystem");
+ msg("Get a newer version of dump!\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ /* if no user label specified, use ext2 filesystem label if available */
+ if (spcl.c_label[0] == '\0') {
+ const char *lbl;
+ if ( (lbl = get_device_label(disk)) != NULL) {
+ strncpy(spcl.c_label, lbl, LBLSIZE);
+ spcl.c_label[LBLSIZE-1] = '\0';
+ }
+ else
+ strcpy(spcl.c_label, "none"); /* safe strcpy. */
+ }
+ sync();
+ dev_bsize = DEV_BSIZE;
+ dev_bshift = ffs(dev_bsize) - 1;
+ if (dev_bsize != (1 << dev_bshift))
+ quit("dev_bsize (%d) is not a power of 2", dev_bsize);
+ tp_bshift = ffs(TP_BSIZE) - 1;
+ if (TP_BSIZE != (1 << tp_bshift))
+ quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE);
+ maxino = fs->super->s_inodes_count + 1;
+ spcl.c_flags |= DR_NEWINODEFMT;
+#else /* __linux __*/
+ if ((diskfd = open(disk, O_RDONLY)) < 0) {
+ msg("Cannot open %s\n", disk);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ sync();
+ sblock = (struct fs *)sblock_buf;
+ bread(SBOFF, (char *) sblock, SBSIZE);
+ if (sblock->fs_magic != FS_MAGIC)
+ quit("bad sblock magic number\n");
+ dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
+ dev_bshift = ffs(dev_bsize) - 1;
+ if (dev_bsize != (1 << dev_bshift))
+ quit("dev_bsize (%d) is not a power of 2", dev_bsize);
+ tp_bshift = ffs(TP_BSIZE) - 1;
+ if (TP_BSIZE != (1 << tp_bshift))
+ quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE);
+#ifdef FS_44INODEFMT
+ if (sblock->fs_inodefmt >= FS_44INODEFMT)
+ spcl.c_flags |= DR_NEWINODEFMT;
+#endif
+ maxino = sblock->fs_ipg * sblock->fs_ncg;
+#endif /* __linux__ */
+ mapsize = roundup(howmany(maxino, NBBY), TP_BSIZE);
+ usedinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
+ dumpdirmap = (char *)calloc((unsigned) mapsize, sizeof(char));
+ dumpinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
+ metainomap = (char *)calloc((unsigned) mapsize, sizeof(char));
+ if (usedinomap == NULL || dumpdirmap == NULL ||
+ dumpinomap == NULL || metainomap == NULL)
+ quit("out of memory allocating inode maps\n");
+ tapesize = 2 * (howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
+
+ nonodump = spcl.c_level < honorlevel;
+
+ if (!sizest) {
+ msg("Label: %s\n", spcl.c_label);
+
+ msg("Writing %d Kilobyte records\n", ntrec);
+
+ if (compressed) {
+ if (zipflag == COMPRESS_LZO)
+ msg("Compressing output (lzo)\n");
+ else
+ msg("Compressing output at compression level %d (%s)\n",
+ compressed, zipflag == COMPRESS_ZLIB ? "zlib" : "bzlib");
+ }
+ }
+
+#if defined(SIGINFO)
+ (void)signal(SIGINFO, statussig);
+#endif
+
+ if (!sizest)
+ msg("mapping (Pass I) [regular files]\n");
+#ifdef __linux__
+ if (directory[0] == 0)
+ anydirskipped = mapfiles(maxino, &tapesize);
+ else {
+ if (LSTAT(pathname, &statbuf) == -1) {
+ msg("File cannot be accessed (%s).\n", pathname);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ filedev = statbuf.st_dev;
+ if (!(statbuf.st_mode & S_IFDIR)) /* is a file */
+ anydirskipped = maponefile(maxino, &tapesize,
+ directory);
+ else
+ anydirskipped = mapfilesfromdir(maxino, &tapesize,
+ directory);
+ }
+ while (argc--) {
+ int anydirskipped2;
+ char *p = *argv;
+ /* check if file is available */
+ if (LSTAT(p, &statbuf) == -1) {
+ msg("File cannot be accessed (%s).\n", p);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ /* check if file is on same unix partiton as the first
+ * argument */
+ if (statbuf.st_dev != filedev) {
+ msg("Files are not on same file system (%s).\n", p);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ /* check if file is a directory */
+ if (!(statbuf.st_mode & S_IFDIR))
+ anydirskipped2 = maponefile(maxino, &tapesize,
+ p+strlen(dt->mnt_dir));
+ else
+ /* read directory inodes.
+ * NOTE: nested directories are not recognized
+ * so inodes may be umped twice!
+ */
+ anydirskipped2 = mapfilesfromdir(maxino, &tapesize,
+ p+strlen(dt->mnt_dir));
+ if (!anydirskipped)
+ anydirskipped = anydirskipped2;
+ argv++;
+ }
+#else
+ anydirskipped = mapfiles(maxino, &tapesize);
+#endif
+
+ if (!sizest)
+ msg("mapping (Pass II) [directories]\n");
+ while (anydirskipped) {
+ anydirskipped = mapdirs(maxino, &tapesize);
+ }
+
+ if (sizest) {
+ printf("%.0f\n", ((double)tapesize + 1 + ntrec) * TP_BSIZE);
+ exit(X_FINOK);
+ } /* stop here for size estimate */
+
+ if (pipeout || unlimited) {
+ tapesize += 1 + ntrec; /* 1 map header + trailer blocks */
+ msg("estimated %ld blocks.\n", tapesize);
+ } else {
+ double fetapes;
+
+ if (blocksperfiles) {
+ long tapesize_left;
+
+ tapesize_left = tapesize;
+ fetapes = 0;
+ for (i = 1; i < *blocksperfiles && tapesize_left; i++) {
+ fetapes++;
+ if (tapesize_left > blocksperfiles[i])
+ tapesize_left -= blocksperfiles[i];
+ else
+ tapesize_left = 0;
+ }
+ if (tapesize_left)
+ fetapes += (double)tapesize_left / blocksperfiles[*blocksperfiles];
+ } else if (cartridge) {
+ /* Estimate number of tapes, assuming streaming stops at
+ the end of each block written, and not in mid-block.
+ Assume no erroneous blocks; this can be compensated
+ for with an artificially low tape size. */
+ fetapes =
+ ( (double) tapesize /* blocks */
+ * TP_BSIZE /* bytes/block */
+ * (1.0/density) /* 0.1" / byte " */
+ +
+ (double) tapesize /* blocks */
+ * (1.0/ntrec) /* streaming-stops per block */
+ * 15.48 /* 0.1" / streaming-stop " */
+ ) * (1.0 / tsize ); /* tape / 0.1" " */
+ } else {
+ /* Estimate number of tapes, for old fashioned 9-track
+ tape */
+ int tenthsperirg = (density == 625) ? 3 : 7;
+ fetapes =
+ ( (double) tapesize /* blocks */
+ * TP_BSIZE /* bytes / block */
+ * (1.0/density) /* 0.1" / byte " */
+ +
+ (double) tapesize /* blocks */
+ * (1.0/ntrec) /* IRG's / block */
+ * tenthsperirg /* 0.1" / IRG " */
+ ) * (1.0 / tsize ); /* tape / 0.1" " */
+ }
+ etapes = fetapes; /* truncating assignment */
+ etapes++;
+ /* count the dumped inodes map on each additional tape */
+ tapesize += (etapes - 1) *
+ (howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
+ tapesize += etapes + ntrec; /* headers + trailer blks */
+ msg("estimated %ld blocks on %3.2f tape(s).\n",
+ tapesize, fetapes);
+ }
+
+#ifdef USE_QFA
+ if (tapepos) {
+ msg("writing QFA positions to %s\n", gTapeposfile);
+ if ((gTapeposfd = open(gTapeposfile,
+ O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
+ | S_IROTH | S_IWOTH)) < 0)
+ quit("can't open tapeposfile\n");
+ /* print QFA-file header */
+ snprintf(gTps, sizeof(gTps), "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
+ gTps[sizeof(gTps) - 1] = '\0';
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
+ quit("can't write tapeposfile\n");
+ sprintf(gTps, "ino\ttapeno\ttapepos\n");
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
+ quit("can't write tapeposfile\n");
+ }
+#endif /* USE_QFA */
+
+ /*
+ * Allocate tape buffer.
+ */
+ if (!alloctape())
+ quit(
+ "can't allocate tape buffers - try a smaller blocking factor.\n");
+
+ startnewtape(1);
+ tstart_writing = time(NULL);
+ dumpmap(usedinomap, TS_CLRI, maxino - 1);
+
+ msg("dumping (Pass III) [directories]\n");
+ dirty = 0; /* XXX just to get gcc to shut up */
+ for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
+ if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
+ dirty = *map++;
+ else
+ dirty >>= 1;
+ if ((dirty & 1) == 0)
+ continue;
+ /*
+ * Skip directory inodes deleted and maybe reallocated
+ */
+ dp = getino(ino);
+ if ((dp->di_mode & IFMT) != IFDIR)
+ continue;
+#ifdef __linux__
+ /*
+ * Skip directory inodes deleted and not yes reallocated...
+ */
+ if (dp->di_nlink == 0 || dp->di_dtime != 0)
+ continue;
+ if (vflag)
+ msg("dumping directory inode %lu\n", ino);
+ (void)dumpdirino(dp, ino);
+#else
+ (void)dumpino(dp, ino);
+#endif
+ }
+
+ msg("dumping (Pass IV) [regular files]\n");
+ for (map = dumpinomap, ino = 1; ino < maxino; ino++) {
+ if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
+ dirty = *map++;
+ else
+ dirty >>= 1;
+ if ((dirty & 1) == 0)
+ continue;
+ /*
+ * Skip inodes deleted and reallocated as directories.
+ */
+ dp = getino(ino);
+ if ((dp->di_mode & IFMT) == IFDIR)
+ continue;
+#ifdef __linux__
+ /*
+ * No need to check here for deleted and not yet reallocated
+ * inodes since this is done in dumpino().
+ */
+#endif
+ if (vflag) {
+ if (mflag && TSTINO(ino, metainomap))
+ msg("dumping regular inode %lu (meta only)\n", ino);
+ else
+ msg("dumping regular inode %lu\n", ino);
+ }
+ (void)dumpino(dp, ino, mflag && TSTINO(ino, metainomap));
+ }
+
+ tend_writing = time(NULL);
+ spcl.c_type = TS_END;
+
+ if (Afile >= 0) {
+ volinfo[1] = ROOTINO;
+ memcpy(spcl.c_inos, volinfo, TP_NINOS * sizeof(dump_ino_t));
+ spcl.c_flags |= DR_INODEINFO;
+ }
+
+ /*
+ * Finish off the current tape record with trailer blocks, to ensure
+ * at least the data in the last partial record makes it to tape.
+ * Also make sure we write at least 1 trailer block.
+ */
+ for (i = ntrec - (spcl.c_tapea % ntrec); i; --i)
+ writeheader(maxino - 1);
+
+ tnow = trewind();
+
+ if (pipeout || fifoout)
+ msg("%ld blocks (%.2fMB)\n", spcl.c_tapea,
+ ((double)spcl.c_tapea * TP_BSIZE / 1048576));
+ else
+ msg("%ld blocks (%.2fMB) on %d volume(s)\n",
+ spcl.c_tapea,
+ ((double)spcl.c_tapea * TP_BSIZE / 1048576),
+ spcl.c_volume);
+
+ /* report dump performance, avoid division by zero */
+ if (tend_writing - tstart_writing == 0)
+ msg("finished in less than a second\n");
+ else
+ msg("finished in %d seconds, throughput %d kBytes/sec\n",
+ tend_writing - tstart_writing,
+ spcl.c_tapea / (tend_writing - tstart_writing));
+
+ putdumptime();
+ msg("Date of this level %s dump: %s", level,
+ spcl.c_date == 0 ? "the epoch\n" : ctime4(&spcl.c_date));
+ msg("Date this dump completed: %s", ctime(&tnow));
+
+ msg("Average transfer rate: %ld kB/s\n", xferrate / tapeno);
+ if (compressed) {
+ long tapekb = bytes_written / 1024;
+ double rate = .0005 + (double) spcl.c_tapea / tapekb;
+ msg("Wrote %ldkB uncompressed, %ldkB compressed, %1.3f:1\n",
+ spcl.c_tapea, tapekb, rate);
+ }
+
+ if (Afile >= 0)
+ msg("Archiving dump to %s\n", Apath);
+
+ broadcast("DUMP IS DONE!\7\7\n");
+ msg("DUMP IS DONE\n");
+ Exit(X_FINOK);
+ /* NOTREACHED */
+ return 0; /* gcc - shut up */
+}
+
+static void
+usage(void)
+{
+ char white[MAXPATHLEN];
+ const char *ext2ver, *ext2date;
+
+ memset(white, ' ', MAXPATHLEN);
+ white[MIN(strlen(__progname), MAXPATHLEN - 1)] = '\0';
+
+#ifdef __linux__
+ ext2fs_get_library_version(&ext2ver, &ext2date);
+ fprintf(stderr, "%s %s (using libext2fs %s of %s)\n",
+ __progname, _DUMP_VERSION, ext2ver, ext2date);
+#else
+ fprintf(stderr, "%s %s\n", __progname, _DUMP_VERSION);
+#endif
+ fprintf(stderr,
+ "usage:\t%s [-level#] [-ac"
+#ifdef KERBEROS
+ "k"
+#endif
+ "mMnqSuv"
+ "] [-A file] [-B records] [-b blocksize]\n"
+ "\t%s [-d density] [-D file] [-e inode#,inode#,...] [-E file]\n"
+ "\t%s [-f file] [-h level] [-I nr errors] "
+#ifdef HAVE_BZLIB
+ "[-j zlevel] "
+#endif
+#ifdef USE_QFA
+ "[-Q file]\n"
+#endif
+ "\t%s [-s feet] "
+ "[-T date] "
+#ifdef HAVE_LZO
+ "[-y] "
+#endif
+#ifdef HAVE_ZLIB
+ "[-z zlevel] "
+#endif
+ "filesystem\n"
+ "\t%s [-W | -w]\n",
+ __progname, white, white, white, __progname);
+ exit(X_STARTUP);
+}
+
+/*
+ * Pick up a numeric argument. It must be nonnegative and in the given
+ * range (except that a vmax of 0 means unlimited).
+ */
+static long
+numarg(const char *meaning, long vmin, long vmax)
+{
+ char *p;
+ long val;
+
+ val = strtol(optarg, &p, 10);
+ if (*p)
+ errx(X_STARTUP, "illegal %s -- %s", meaning, optarg);
+ if (val < vmin || (vmax && val > vmax))
+ errx(X_STARTUP, "%s must be between %ld and %ld", meaning, vmin, vmax);
+ return (val);
+}
+
+/*
+ * The same as numarg, just that it expects a comma separated list of numbers
+ * and returns an array of longs with the first element containing the number
+ * values in that array.
+ */
+static long *
+numlistarg(const char *meaning, long vmin, long vmax)
+{
+ char *p;
+ long *vals,*curval;
+ long valnum;
+
+ p = optarg;
+ vals = NULL;
+ valnum = 0;
+ do {
+ valnum++;
+ if ( !(vals = realloc(vals, (valnum + 1) * sizeof(*vals))) )
+ errx(X_STARTUP, "allocating memory failed");
+ curval = vals + valnum;
+ *curval = strtol(p, &p, 10);
+ if (*p && *p!=',')
+ errx(X_STARTUP, "illegal %s -- %s", meaning, optarg);
+ if (*curval < vmin || (vmax && *curval > vmax))
+ errx(X_STARTUP, "%s must be between %ld and %ld", meaning, vmin, vmax);
+ *vals = valnum;
+ if (*p) p++;
+ } while(*p);
+ return (vals);
+}
+
+void
+sig(int signo)
+{
+ switch(signo) {
+ case SIGALRM:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGHUP:
+ case SIGTERM:
+ case SIGTRAP:
+ if (pipeout || fifoout)
+ quit("Signal on pipe: cannot recover\n");
+ msg("Rewriting attempted as response to unknown signal: %d.\n", signo);
+ (void)fflush(stderr);
+ (void)fflush(stdout);
+ close_rewind();
+ exit(X_REWRITE);
+ /* NOTREACHED */
+ case SIGSEGV:
+ msg("SIGSEGV: ABORTING!\n");
+ (void)signal(SIGSEGV, SIG_DFL);
+ (void)kill(0, SIGSEGV);
+ /* NOTREACHED */
+ }
+}
+
+const char *
+rawname(const char *cp)
+{
+#ifdef __linux__
+ return cp;
+#else /* __linux__ */
+ static char rawbuf[MAXPATHLEN];
+ char *dp = strrchr(cp, '/');
+
+ if (dp == NULL)
+ return (NULL);
+ (void)strncpy(rawbuf, cp, min(dp-cp, MAXPATHLEN - 1));
+ rawbuf[min(dp-cp, MAXPATHLEN-1)] = '\0';
+ (void)strncat(rawbuf, "/r", MAXPATHLEN - 1 - strlen(rawbuf));
+ (void)strncat(rawbuf, dp + 1, MAXPATHLEN - 1 - strlen(rawbuf));
+ return (rawbuf);
+#endif /* __linux__ */
+}
+
+/*
+ * obsolete --
+ * Change set of key letters and ordered arguments into something
+ * getopt(3) will like.
+ */
+static void
+obsolete(int *argcp, char **argvp[])
+{
+ int argc, flags;
+ char *ap, **argv, *flagsp=NULL, **nargv, *p=NULL;
+
+ /* Setup. */
+ argv = *argvp;
+ argc = *argcp;
+
+ /* Return if no arguments or first argument has leading dash. */
+ ap = argv[1];
+ if (argc == 1 || *ap == '-')
+ return;
+
+ /* Allocate space for new arguments. */
+ if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
+ (p = flagsp = malloc(strlen(ap) + 2)) == NULL)
+ err(X_STARTUP, "malloc new args");
+
+ *nargv++ = *argv;
+ argv += 2;
+
+ for (flags = 0; *ap; ++ap) {
+ switch (*ap) {
+ case 'A':
+ case 'B':
+ case 'b':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'h':
+ case 'L':
+ case 'Q':
+ case 's':
+ case 'T':
+ if (*argv == NULL) {
+ warnx("option requires an argument -- %c", *ap);
+ usage();
+ }
+ if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
+ err(X_STARTUP, "malloc arg");
+ nargv[0][0] = '-';
+ nargv[0][1] = *ap;
+ (void)strcpy(&nargv[0][2], *argv);
+ ++argv;
+ ++nargv;
+ break;
+ default:
+ if (!flags) {
+ *p++ = '-';
+ flags = 1;
+ }
+ *p++ = *ap;
+ break;
+ }
+ }
+
+ /* Terminate flags. */
+ if (flags) {
+ *p = '\0';
+ *nargv++ = flagsp;
+ }
+
+ /* Copy remaining arguments. */
+ while ((*nargv++ = *argv++));
+
+ /* Update argument count. */
+ *argcp = nargv - *argvp - 1;
+}
+
+/*
+ * This tests whether an inode is in the exclude bitmap
+ */
+int
+exclude_ino(dump_ino_t ino)
+{
+ /* if the inode exclude bitmap exists and covers given inode */
+ if (iexclude_bitmap && iexclude_bitmap_bytes > ino / 8) {
+ /* then check this inode against it */
+ int idx = iexclude_bitmap[ino / 8];
+ if (idx & (1 << (ino % 8)))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * This adds an inode to the exclusion bitmap if it isn't already there
+ */
+void
+do_exclude_ino(dump_ino_t ino, const char *reason)
+{
+ if (exclude_ino(ino))
+ return;
+
+ if (vflag) {
+ if (reason)
+ msg("Excluding inode %u (%s) from dump\n", ino, reason);
+ else
+ msg("Excluding inode %u from dump\n", ino);
+ }
+
+ /* check for enough mem; initialize */
+ if ((ino/8 + 1) > iexclude_bitmap_bytes) {
+ if (iexclude_bitmap_bytes == 0) {
+ unsigned int j;
+ iexclude_bitmap_bytes = 2 * (ino/8 + 1);
+ iexclude_bitmap = (char*) malloc(iexclude_bitmap_bytes);
+ if (iexclude_bitmap == NULL) {
+ msg("allocating memory failed\n");
+ exit(X_STARTUP);
+ }
+ for (j = 0; j < iexclude_bitmap_bytes; j++)
+ iexclude_bitmap[j] = 0;
+ }
+ else {
+ unsigned int oldsize = iexclude_bitmap_bytes;
+ iexclude_bitmap_bytes *=
+ (ino / 8 + 1) / iexclude_bitmap_bytes + 1;
+ iexclude_bitmap = (char*) realloc(iexclude_bitmap,
+ iexclude_bitmap_bytes);
+ if (iexclude_bitmap == NULL) {
+ msg("allocating memory failed\n");
+ exit(X_STARTUP);
+ }
+ for( ; oldsize < iexclude_bitmap_bytes; oldsize++)
+ iexclude_bitmap[oldsize] = 0;
+ }
+ }
+
+ iexclude_bitmap[ino / 8] |= 1 << (ino % 8);
+}
+
+static void
+do_exclude_ino_str(char * ino) {
+ char *r;
+ unsigned long inod;
+
+ inod = strtoul(ino, &r, 10);
+ if (( *r != '\0' && !isspace(*r) ) || inod <= ROOTINO) {
+ msg("Invalid inode argument %s\n", ino);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ do_exclude_ino(inod, NULL);
+}
+
+/*
+ * This reads a file containing one inode number per line and exclude them all
+ */
+static void
+do_exclude_from_file(char *file) {
+ FILE *f;
+ char *p, fname[MAXPATHLEN];
+
+
+ if (!( f = fopen(file, "r")) ) {
+ msg("Cannot open file for reading: %s\n", file);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ while (( p = fgets(fname, MAXPATHLEN, f))) {
+ if ( *p && *(p + strlen(p) - 1) == '\n' ) /* possible null string */
+ *(p + strlen(p) - 1) = '\0';
+ if ( !*p ) /* skip empty lines */
+ continue;
+ do_exclude_ino_str(p);
+ }
+ fclose(f);
+}
+
+static void incompat_flags(int cond, char flag1, char flag2) {
+ if (cond) {
+ msg("You cannot use the %c and %c flags together.\n",
+ flag1, flag2);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: optr.c,v 1.39 2004/07/05 15:12:45 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <errno.h>
+#include <mntent.h>
+#include <paths.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#include <signal.h>
+#endif
+
+#include "dump.h"
+#include "pathnames.h"
+#include "bylabel.h"
+
+static void alarmcatch __P((int));
+int datesort __P((const void *, const void *));
+static void sendmes __P((const char *, const char *));
+
+/* List of filesystem types that we can dump (same ext2 on-disk format) */
+static char *fstypes[] = { "ext2", "ext3", "InterMezzo", NULL };
+
+/*
+ * Query the operator; This previously-fascist piece of code
+ * no longer requires an exact response.
+ * It is intended to protect dump aborting by inquisitive
+ * people banging on the console terminal to see what is
+ * happening which might cause dump to croak, destroying
+ * a large number of hours of work.
+ *
+ * Every 2 minutes we reprint the message, alerting others
+ * that dump needs attention.
+ */
+static int timeout;
+static const char *attnmessage; /* attention message */
+
+int
+query(const char *question)
+{
+ char replybuffer[64];
+ int back, errcount;
+ FILE *mytty;
+ time_t firstprompt, when_answered;
+
+ if (qflag) {
+ msg("%s - forced abort\n", question);
+ dumpabort(0);
+ /* NOTREACHED */
+ }
+
+ firstprompt = time(NULL);
+
+ if ((mytty = fopen(_PATH_TTY, "r")) == NULL)
+ quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno));
+ attnmessage = question;
+ timeout = 0;
+ alarmcatch(0);
+ back = -1;
+ errcount = 0;
+ do {
+ if (fgets(replybuffer, 63, mytty) == NULL) {
+ clearerr(mytty);
+ if (++errcount > 30) /* XXX ugly */
+ quit("excessive operator query failures\n");
+ } else if (replybuffer[0] == 'y' || replybuffer[0] == 'Y') {
+ back = 1;
+ } else if (replybuffer[0] == 'n' || replybuffer[0] == 'N') {
+ back = 0;
+ } else {
+ (void) fprintf(stderr,
+ " DUMP: \"Yes\" or \"No\"?\n");
+ (void) fprintf(stderr,
+ " DUMP: %s: (\"yes\" or \"no\") ", question);
+ }
+ } while (back < 0);
+
+ /*
+ * Turn off the alarm, and reset the signal to trap out..
+ */
+ (void) alarm(0);
+ if (signal(SIGALRM, sig) == SIG_IGN)
+ signal(SIGALRM, SIG_IGN);
+ (void) fclose(mytty);
+ when_answered = time(NULL);
+ /*
+ * Adjust the base for time estimates to ignore time we spent waiting
+ * for operator input.
+ */
+ if (tstart_writing != 0)
+ tstart_writing += (when_answered - firstprompt);
+ return(back);
+}
+
+char lastmsg[BUFSIZ];
+
+/*
+ * Alert the console operator, and enable the alarm clock to
+ * sleep for 2 minutes in case nobody comes to satisfy dump
+ */
+static void
+alarmcatch(UNUSED(int signo))
+{
+ int save_errno = errno;
+ if (notify == 0) {
+ if (timeout == 0)
+ (void) fprintf(stderr,
+ " DUMP: %s: (\"yes\" or \"no\") ",
+ attnmessage);
+ else
+ msgtail("\7\7");
+ } else {
+ if (timeout) {
+ msgtail("\n");
+ broadcast(""); /* just print last msg */
+ }
+ (void) fprintf(stderr," DUMP: %s: (\"yes\" or \"no\") ",
+ attnmessage);
+ }
+ signal(SIGALRM, alarmcatch);
+ (void) alarm(120);
+ timeout = 1;
+ errno = save_errno;
+}
+
+/*
+ * Here if an inquisitive operator interrupts the dump program
+ */
+void
+interrupt(UNUSED(int signo))
+{
+ msg("Interrupt received.\n");
+ if (query("Do you want to abort dump?"))
+ dumpabort(0);
+}
+
+/*
+ * The following variables and routines manage alerting
+ * operators to the status of dump.
+ * This works much like wall(1) does.
+ */
+struct group *gp;
+
+/*
+ * Get the names from the group entry "operator" to notify.
+ */
+void
+set_operators(void)
+{
+ if (!notify) /*not going to notify*/
+ return;
+ gp = getgrnam(OPGRENT);
+ (void) endgrent();
+ if (gp == NULL) {
+ msg("No group entry for %s.\n", OPGRENT);
+ notify = 0;
+ return;
+ }
+}
+
+struct tm *localclock;
+
+/*
+ * We fork a child to do the actual broadcasting, so
+ * that the process control groups are not messed up
+ */
+void
+broadcast(const char *message)
+{
+ time_t clock;
+ FILE *f_utmp;
+ struct utmp utmp;
+ char **np;
+ int pid, s;
+
+ if (!notify || gp == NULL)
+ return;
+
+ switch (pid = fork()) {
+ case -1:
+ return;
+ case 0:
+ break;
+ default:
+ while (wait(&s) != pid)
+ continue;
+ return;
+ }
+
+ clock = time(NULL);
+ localclock = localtime(&clock);
+
+ if ((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) {
+ msg("Cannot open %s: %s\n", _PATH_UTMP, strerror(errno));
+ return;
+ }
+
+ while (!feof(f_utmp)) {
+ if (fread((char *) &utmp, sizeof (struct utmp), 1, f_utmp) != 1)
+ break;
+ if (utmp.ut_name[0] == 0)
+ continue;
+ for (np = gp->gr_mem; *np; np++) {
+ if (strncmp(*np, utmp.ut_name, sizeof(utmp.ut_name)) != 0)
+ continue;
+ /*
+ * Do not send messages to operators on dialups
+ */
+ if (strncmp(utmp.ut_line, DIALUP, strlen(DIALUP)) == 0)
+ continue;
+#ifdef DEBUG
+ msg("Message to %s at %s\n", *np, utmp.ut_line);
+#endif
+ sendmes(utmp.ut_line, message);
+ }
+ }
+ (void) fclose(f_utmp);
+ Exit(0); /* the wait in this same routine will catch this */
+ /* NOTREACHED */
+}
+
+static void
+sendmes(const char *tty, const char *message)
+{
+ char t[MAXPATHLEN], buf[BUFSIZ];
+ const char *cp;
+ int lmsg = 1;
+ FILE *f_tty;
+
+ (void) strcpy(t, _PATH_DEV);
+ (void) strncat(t, tty, sizeof t - strlen(_PATH_DEV) - 1);
+
+ if ((f_tty = fopen(t, "w")) != NULL) {
+ setbuf(f_tty, buf);
+ (void) fprintf(f_tty,
+ "\n\
+\7\7\7Message from the dump program to all operators at %d:%02d ...\r\n\n\
+DUMP: NEEDS ATTENTION: ",
+ localclock->tm_hour, localclock->tm_min);
+ for (cp = lastmsg; ; cp++) {
+ if (*cp == '\0') {
+ if (lmsg) {
+ cp = message;
+ if (!(cp && *cp != '\0'))
+ break;
+ lmsg = 0;
+ } else
+ break;
+ }
+ if (*cp == '\n')
+ (void) putc('\r', f_tty);
+ (void) putc(*cp, f_tty);
+ }
+ (void) fclose(f_tty);
+ }
+}
+
+/*
+ * print out an estimate of the amount of time left to do the dump
+ */
+
+time_t tschedule = 0;
+
+void
+timeest(void)
+{
+ time_t tnow = time(NULL);
+
+ if (tnow >= tschedule) {
+ char *buf = mktimeest(tnow);
+ tschedule = tnow + 300;
+ if (buf) {
+ fprintf(stderr, " DUMP: ");
+ fwrite(buf, strlen(buf), 1, stderr);
+ fflush(stderr);
+ }
+ }
+}
+
+void
+#ifdef __STDC__
+msg(const char *fmt, ...)
+#else
+msg(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+ (void) fprintf(stderr," DUMP: ");
+#ifdef TDEBUG
+ (void) fprintf(stderr, "pid=%d ", getpid());
+#endif
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void) vsnprintf(lastmsg, sizeof(lastmsg), fmt, ap);
+ va_end(ap);
+}
+
+void
+#ifdef __STDC__
+msgtail(const char *fmt, ...)
+#else
+msgtail(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+void
+#ifdef __STDC__
+quit(const char *fmt, ...)
+#else
+quit(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+ (void) fprintf(stderr," DUMP: ");
+#ifdef TDEBUG
+ (void) fprintf(stderr, "pid=%d ", getpid());
+#endif
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+ dumpabort(0);
+}
+
+/*
+ * Tell the operator what has to be done;
+ * we don't actually do it
+ */
+
+struct pfstab {
+ struct pfstab *pf_next;
+ struct dumpdates *pf_dd;
+ struct mntent *pf_mntent;
+};
+
+static struct pfstab *table;
+
+static struct mntent *
+allocfsent(struct mntent *fs)
+{
+ struct mntent *new;
+ const char *disk;
+ struct stat buf, tabbuf;
+ struct pfstab *tabpf;
+ struct mntent *tabfs;
+
+ new = (struct mntent *)malloc(sizeof (*fs));
+ if (new == NULL)
+ quit("%s\n", strerror(errno));
+
+ /* Translade UUID=, LABEL= ... */
+ disk = get_device_name(fs->mnt_fsname);
+ if (disk == NULL)
+ disk = strdup(fs->mnt_fsname);
+
+ /* Discard non block devices */
+ if (stat(disk, &buf) != 0 || !S_ISBLK(buf.st_mode)) {
+ free(new);
+ return NULL;
+ }
+
+ /* Discard same major/minor devices */
+ for (tabpf = table; tabpf != NULL; tabpf = tabpf->pf_next) {
+ tabfs = tabpf->pf_mntent;
+ if (stat(tabfs->mnt_fsname, &tabbuf) != 0)
+ /* should not happen */
+ quit("Cannot access %s\n", tabfs->mnt_fsname);
+ if (tabbuf.st_rdev == buf.st_rdev) {
+ free(new);
+ /* Copy passno and freq from /etc/fstab because
+ * /etc/mtab does always have them as 0 0 */
+ if (!tabfs->mnt_passno)
+ tabfs->mnt_passno = fs->mnt_passno;
+ if (!tabfs->mnt_freq)
+ tabfs->mnt_freq = fs->mnt_freq;
+ return NULL;
+ }
+ }
+
+ if (strlen(fs->mnt_dir) > 1 && fs->mnt_dir[strlen(fs->mnt_dir) - 1] == '/')
+ fs->mnt_dir[strlen(fs->mnt_dir) - 1] = '\0';
+ if ((new->mnt_dir = strdup(fs->mnt_dir)) == NULL ||
+ (new->mnt_type = strdup(fs->mnt_type)) == NULL ||
+ (new->mnt_opts = strdup(fs->mnt_opts)) == NULL ||
+ (new->mnt_fsname = strdup(disk)) == NULL)
+ quit("%s\n", strerror(errno));
+ new->mnt_passno = fs->mnt_passno;
+ new->mnt_freq = fs->mnt_freq;
+ return (new);
+}
+
+void
+getfstab(void)
+{
+ struct mntent *fs;
+ struct pfstab *pf;
+ struct pfstab *pfold = NULL;
+ FILE *mntfp;
+ char *mnttables[] = { _PATH_MOUNTED, _PATH_MNTTAB, 0 };
+ int i;
+
+ for (i = 0; mnttables[i]; i++) {
+ mntfp = setmntent(mnttables[i], "r");
+ if (mntfp == NULL) {
+ msg("Can't open %s for dump table information: %s\n",
+ mnttables[i], strerror(errno));
+ continue;
+ }
+ while ((fs = getmntent(mntfp)) != NULL) {
+ fs = allocfsent(fs);
+ if (!fs)
+ continue;
+ fs->mnt_passno = 0;
+ if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
+ quit("%s\n", strerror(errno));
+ pf->pf_mntent = fs;
+ pf->pf_next = NULL;
+
+ /* keep table in /etc/fstab order for use with -w and -W */
+ if (pfold) {
+ pfold->pf_next = pf;
+ pfold = pf;
+ } else
+ pfold = table = pf;
+ }
+ (void) endmntent(mntfp);
+ }
+}
+
+/*
+ * Search in the fstab for a file name.
+ * This file name can be either the special or the path file name.
+ *
+ * The entries in the fstab are the BLOCK special names, not the
+ * character special names.
+ * The caller of fstabsearch assures that the character device
+ * is dumped (that is much faster)
+ *
+ * The file name can omit the leading '/'.
+ */
+struct mntent *
+fstabsearch(const char *key)
+{
+ struct pfstab *pf;
+ struct mntent *fs;
+ const char *rn;
+
+ for (pf = table; pf != NULL; pf = pf->pf_next) {
+ fs = pf->pf_mntent;
+ if (strcmp(fs->mnt_dir, key) == 0 ||
+ strcmp(fs->mnt_fsname, key) == 0)
+ return (fs);
+ rn = rawname(fs->mnt_fsname);
+ if (rn != NULL && strcmp(rn, key) == 0)
+ return (fs);
+ if (key[0] != '/') {
+ if (*fs->mnt_fsname == '/' &&
+ strcmp(fs->mnt_fsname + 1, key) == 0)
+ return (fs);
+ if (*fs->mnt_dir == '/' &&
+ strcmp(fs->mnt_dir + 1, key) == 0)
+ return (fs);
+ }
+ }
+ return (NULL);
+}
+
+#ifdef __linux__
+struct mntent *
+fstabsearchdir(const char *key, char *directory)
+{
+ struct pfstab *pf;
+ struct mntent *fs;
+ struct mntent *found_fs = NULL;
+ unsigned int size = 0;
+ struct stat buf;
+
+ if (stat(key, &buf) == 0 && S_ISBLK(buf.st_mode))
+ return NULL;
+
+ for (pf = table; pf != NULL; pf = pf->pf_next) {
+ fs = pf->pf_mntent;
+ if (strlen(fs->mnt_dir) > size &&
+ strlen(key) > strlen(fs->mnt_dir) &&
+ strncmp(fs->mnt_dir, key, strlen(fs->mnt_dir)) == 0 &&
+ (key[strlen(fs->mnt_dir)] == '/' ||
+ fs->mnt_dir[strlen(fs->mnt_dir) - 1] == '/')) {
+ found_fs = fs;
+ size = strlen(fs->mnt_dir);
+ }
+ }
+ if (found_fs != NULL) {
+ /*
+ * Ok, we have found a fstab entry which matches the argument
+ * We have to split the argument name into:
+ * - a device name (from the fstab entry)
+ * - a directory name on this device
+ */
+ strcpy(directory, key + size);
+ }
+ return(found_fs);
+}
+#endif
+
+static void
+print_wmsg(char arg, int dumpme, const char *dev, int level,
+ const char *mtpt, time_t ddate)
+{
+#ifdef FDEBUG
+ printf("checking dev %s: lvl %d, mtpt %s\n", dev, level, mtpt);
+#endif
+ if (!dumpme && arg == 'w')
+ return;
+
+ (void) printf("%c %8s\t(%6s) Last dump: ",
+ dumpme && (arg != 'w') ? '>' : ' ',
+ dev,
+ mtpt ? mtpt : "");
+
+ /*
+ * Check ddate > 365 to avoid issues with fs in stab but not dumpdates.
+ * Not a problem, because ddate is in seconds since the epoch anyways.
+ */
+ if (ddate > 365) {
+ char *date, *d;
+
+ date = (char *)ctime(&ddate);
+ d = strchr(date, '\n');
+ if (d) *d = '\0';
+ printf("Level %d, Date %s\n", level, date);
+ } else
+ printf("never\n");
+}
+
+/*
+ * Tell the operator what to do
+ */
+void
+lastdump(char arg) /* w ==> just what to do; W ==> most recent dumps */
+{
+ struct pfstab *pf;
+ time_t tnow;
+
+ tnow = time(NULL);
+ getfstab(); /* /etc/fstab input */
+ initdumptimes(0); /* dumpdates input */
+ if (ddatev == NULL && table == NULL) {
+ (void) printf("No %s or %s file found\n",
+ _PATH_MNTTAB, dumpdates);
+ return;
+ }
+
+ if (arg == 'w')
+ (void) printf("Dump these file systems:\n");
+ else
+ (void) printf("Last dump(s) done (Dump '>' file systems):\n");
+
+ /* For files in dumpdates, get the last dump level and date */
+ if (ddatev != NULL) {
+ struct dumpdates *dtwalk = NULL;
+ int i;
+ char *lastname;
+
+ qsort((char *) ddatev, nddates, sizeof(struct dumpdates *), datesort);
+
+ lastname = "??";
+ ITITERATE(i, dtwalk) {
+ struct mntent *dt;
+ if (strncmp(lastname, dtwalk->dd_name,
+ sizeof(dtwalk->dd_name)) == 0)
+ continue;
+ lastname = dtwalk->dd_name;
+ if ((dt = dtwalk->dd_fstab) != NULL) {
+ /* Overload fs_freq as dump level and
+ * fs_passno as date, because we can't
+ * change struct fstab format.
+ * A positive fs_freq means this
+ * filesystem needs to be dumped.
+ */
+ dt->mnt_passno = dtwalk->dd_ddate;
+ if (dt->mnt_freq > 0 && (dtwalk->dd_ddate <
+ tnow - (dt->mnt_freq * 86400)))
+ dt->mnt_freq = dtwalk->dd_level;
+ else
+ dt->mnt_freq = -dtwalk->dd_level;
+#ifdef FDEBUG
+ printf("%s fs_freq set to %d\n", lastname,
+ dt->mnt_freq);
+#endif
+ }
+ }
+ }
+
+ /* print in /etc/fstab order only those filesystem types we can dump */
+ for (pf = table; pf != NULL; pf = pf->pf_next) {
+ struct mntent *dt = pf->pf_mntent;
+ char **type;
+
+ for (type = fstypes; *type != NULL; type++) {
+ if (strncmp(dt->mnt_type, *type,
+ sizeof(dt->mnt_type)) == 0) {
+ const char *disk = get_device_name(dt->mnt_fsname);
+ print_wmsg(arg, dt->mnt_freq > 0,
+ disk ? disk : dt->mnt_fsname,
+ dt->mnt_freq < 0 ? -dt->mnt_freq :
+ dt->mnt_freq,
+ dt->mnt_dir,
+ dt->mnt_passno);
+ }
+ }
+ }
+
+ /* print in /etc/dumpdates order if not in /etc/fstab */
+ if (ddatev != NULL) {
+ struct dumpdates *dtwalk = NULL;
+ char *lastname;
+ int i;
+
+ lastname = "??";
+ ITITERATE(i, dtwalk) {
+ if (strncmp(lastname, dtwalk->dd_name,
+ sizeof(dtwalk->dd_name)) == 0 ||
+ dtwalk->dd_fstab != NULL)
+ continue;
+ lastname = dtwalk->dd_name;
+ print_wmsg(arg, 0, dtwalk->dd_name,
+ dtwalk->dd_level, NULL, dtwalk->dd_ddate);
+ }
+ }
+}
+
+int
+datesort(const void *a1, const void *a2)
+{
+ struct dumpdates *d1 = *(struct dumpdates **)a1;
+ struct dumpdates *d2 = *(struct dumpdates **)a2;
+ int diff;
+
+ diff = strncmp(d1->dd_name, d2->dd_name, sizeof(d1->dd_name));
+ if (diff == 0)
+ return (d2->dd_ddate - d1->dd_ddate);
+ return (diff);
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: tape.c,v 1.86 2004/07/07 11:07:29 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <compaterr.h>
+#include <system.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#else
+int write(), read();
+#endif
+
+#ifdef __linux__
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h> /* for definition of BLKFLSBUF */
+#ifndef BLKFLSBUF /* last resort... */
+#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */
+#endif
+#include <time.h>
+#endif
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/mtio.h>
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <sys/stat.h>
+#include <bsdcompat.h>
+#elif defined sunos
+#include <sys/vnode.h>
+
+#include <ufs/fs.h>
+#include <ufs/inode.h>
+#else
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#endif /* __linux__ */
+
+#include <protocols/dumprestore.h>
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif /* HAVE_ZLIB */
+
+#ifdef HAVE_BZLIB
+#include <bzlib.h>
+#endif /* HAVE_BZLIB */
+
+#ifdef HAVE_LZO
+#include <minilzo.h>
+#endif /* HAVE_LZO */
+
+#include "dump.h"
+
+int writesize; /* size of malloc()ed buffer for tape */
+long lastspclrec = -1; /* tape block number of last written header */
+int trecno = 0; /* next record to write in current block */
+extern long *blocksperfiles; /* number of blocks per output file(s) */
+long blocksperfiles_current; /* current position in blocksperfiles */
+long blocksthisvol; /* number of blocks on current output file */
+extern int ntrec; /* blocking factor on tape */
+extern int cartridge;
+char *nexttape;
+extern pid_t rshpid;
+int eot_code = 1;
+long long tapea_bytes = 0; /* bytes_written at start of current volume */
+static int magtapeout; /* output is really a tape */
+
+static ssize_t dump_atomic_read __P((int, char *, size_t));
+static ssize_t dump_atomic_write __P((int, const char *, size_t));
+#ifdef WRITEDEBUG
+static void doslave __P((int, int, int));
+#else
+static void doslave __P((int, int));
+#endif
+static void enslave __P((void));
+static void flushtape __P((void));
+static void killall __P((void));
+static void rollforward __P((void));
+#ifdef USE_QFA
+static int GetTapePos __P((long long *));
+static int MkTapeString __P((struct s_spcl *, long long));
+#define FILESQFAPOS 20
+#endif
+
+/*
+ * Concurrent dump mods (Caltech) - disk block reading and tape writing
+ * are exported to several slave processes. While one slave writes the
+ * tape, the others read disk blocks; they pass control of the tape in
+ * a ring via signals. The parent process traverses the filesystem and
+ * sends writeheader()'s and lists of daddr's to the slaves via pipes.
+ * The following structure defines the instruction packets sent to slaves.
+ */
+struct req {
+ ext2_loff_t dblk;
+ int count;
+};
+int reqsiz;
+
+struct slave_results {
+ ssize_t unclen; /* uncompressed length */
+ ssize_t clen; /* compressed length */
+};
+
+#define SLAVES 3 /* 1 slave writing, 1 reading, 1 for slack */
+struct slave {
+ int tapea; /* header number at start of this chunk */
+ int count; /* count to next header (used for TS_TAPE */
+ /* after EOT) */
+ int inode; /* inode that we are currently dealing with */
+ int fd; /* FD for this slave */
+ int pid; /* PID for this slave */
+ int sent; /* 1 == we've sent this slave requests */
+ int firstrec; /* record number of this block */
+ char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
+ struct req *req; /* buffer for requests */
+} slaves[SLAVES+1];
+struct slave *slp;
+
+char (*nextblock)[TP_BSIZE];
+
+static time_t tstart_volume; /* time of volume start */
+static int tapea_volume; /* value of spcl.c_tapea at volume start */
+
+int master; /* pid of master, for sending error signals */
+int tenths; /* length of tape overhead per block written */
+static int caught; /* have we caught the signal to proceed? */
+static int ready; /* have we reached the lock point without having */
+ /* received the SIGUSR2 signal from the prev slave? */
+static sigjmp_buf jmpbuf; /* where to jump to if we are ready when the */
+ /* SIGUSR2 arrives from the previous slave */
+#ifdef USE_QFA
+static int gtperr = 0;
+#endif
+
+int
+alloctape(void)
+{
+ int pgoff = getpagesize() - 1;
+ char *buf;
+ int i;
+
+ writesize = ntrec * TP_BSIZE;
+ reqsiz = (ntrec + 1) * sizeof(struct req);
+ /*
+ * CDC 92181's and 92185's make 0.8" gaps in 1600-bpi start/stop mode
+ * (see DEC TU80 User's Guide). The shorter gaps of 6250-bpi require
+ * repositioning after stopping, i.e, streaming mode, where the gap is
+ * variable, 0.30" to 0.45". The gap is maximal when the tape stops.
+ */
+ if (!blocksperfiles && !unlimited)
+ tenths = (cartridge ? 16 : density == 625 ? 5 : 8);
+ else {
+ tenths = 0;
+ density = 1;
+ }
+ /*
+ * Allocate tape buffer contiguous with the array of instruction
+ * packets, so flushtape() can write them together with one write().
+ * Align tape buffer on page boundary to speed up tape write().
+ */
+ for (i = 0; i <= SLAVES; i++) {
+ buf = (char *)
+ malloc((unsigned)(reqsiz + writesize + pgoff + TP_BSIZE));
+ if (buf == NULL)
+ return(0);
+ slaves[i].tblock = (char (*)[TP_BSIZE])
+#ifdef __linux__
+ (((long)&buf[reqsiz] + pgoff) &~ pgoff);
+#else
+ (((long)&buf[ntrec + 1] + pgoff) &~ pgoff);
+#endif
+ slaves[i].req = (struct req *)slaves[i].tblock - ntrec - 1;
+ }
+ slp = &slaves[0];
+ slp->count = 1;
+ slp->tapea = 0;
+ slp->firstrec = 0;
+ nextblock = slp->tblock;
+ return(1);
+}
+
+void
+writerec(const void *dp, int isspcl)
+{
+
+ slp->req[trecno].dblk = (ext2_loff_t)0;
+ slp->req[trecno].count = 1;
+ /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */
+ *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp;
+
+ /* Need to write it to the archive file */
+ if (! AfileActive && isspcl && (spcl.c_type == TS_END))
+ AfileActive = 1;
+ if (AfileActive && Afile >= 0) {
+ /* When we dump an inode which is not a directory,
+ * it means we ended the archive contents */
+ if (isspcl && (spcl.c_type == TS_INODE) &&
+ ((spcl.c_dinode.di_mode & S_IFMT) != IFDIR))
+ AfileActive = 0;
+ else {
+ union u_spcl tmp;
+ tmp = *(union u_spcl *)dp;
+ /* Write the record, _uncompressed_ */
+ if (isspcl) {
+ tmp.s_spcl.c_flags &= ~DR_COMPRESSED;
+ mkchecksum(&tmp);
+ }
+ if (write(Afile, &tmp, TP_BSIZE) != TP_BSIZE)
+ msg("error writing archive file: %s\n",
+ strerror(errno));
+ }
+ }
+
+ nextblock++;
+ if (isspcl)
+ lastspclrec = spcl.c_tapea;
+ trecno++;
+ spcl.c_tapea++;
+ if (trecno >= ntrec)
+ flushtape();
+}
+
+void
+dumpblock(blk_t blkno, int size)
+{
+ int avail, tpblks;
+ ext2_loff_t dblkno;
+
+ dblkno = fsbtodb(sblock, blkno);
+ tpblks = size >> tp_bshift;
+ while ((avail = MIN(tpblks, ntrec - trecno)) > 0) {
+ slp->req[trecno].dblk = dblkno;
+ slp->req[trecno].count = avail;
+ trecno += avail;
+ spcl.c_tapea += avail;
+ if (trecno >= ntrec)
+ flushtape();
+ dblkno += avail << (tp_bshift - dev_bshift);
+ tpblks -= avail;
+ }
+}
+
+int nogripe = 0;
+
+static void
+tperror(int errnum)
+{
+
+ if (pipeout) {
+ msg("write error on %s: %s\n", tape, strerror(errnum));
+ quit("Cannot recover\n");
+ /* NOTREACHED */
+ }
+ msg("write error %d blocks into volume %d: %s\n",
+ blocksthisvol, tapeno, strerror(errnum));
+ broadcast("DUMP WRITE ERROR!\n");
+ if (query("Do you want to rewrite this volume?")) {
+ msg("Closing this volume. Prepare to restart with new media;\n");
+ msg("this dump volume will be rewritten.\n");
+ killall();
+ nogripe = 1;
+ close_rewind();
+ Exit(X_REWRITE);
+ }
+ if (query("Do you want to start the next tape?"))
+ return;
+ dumpabort(0);
+}
+
+static void
+sigpipe(UNUSED(int signo))
+{
+
+ quit("Broken pipe\n");
+}
+
+/*
+ * do_stats --
+ * Update xferrate stats
+ */
+time_t
+do_stats(void)
+{
+ time_t tnow, ttaken;
+ int blocks;
+
+ tnow = time(NULL);
+ ttaken = tnow - tstart_volume;
+ blocks = spcl.c_tapea - tapea_volume;
+ msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
+ if (! compressed)
+ msg("Volume %d %ld blocks (%.2fMB)\n", tapeno,
+ blocks, ((double)blocks * TP_BSIZE / 1048576));
+ if (ttaken > 0) {
+ long volkb = (bytes_written - tapea_bytes) / 1024;
+ long txfrate = volkb / ttaken;
+ msg("Volume %d took %d:%02d:%02d\n", tapeno,
+ ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
+ msg("Volume %d transfer rate: %ld kB/s\n", tapeno,
+ txfrate);
+ xferrate += txfrate;
+ if (compressed) {
+ double rate = .0005 + (double) blocks / (double) volkb;
+ msg("Volume %d %ldkB uncompressed, %ldkB compressed,"
+ " %1.3f:1\n",
+ tapeno, blocks, volkb, rate);
+ }
+ }
+ return(tnow);
+}
+
+char *
+mktimeest(time_t tnow)
+{
+ static char msgbuf[128];
+ time_t deltat;
+
+ msgbuf[0] = '\0';
+
+ if (blockswritten < 500)
+ return NULL;
+ if (blockswritten > tapesize)
+ tapesize = blockswritten;
+ deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
+ / blockswritten * tapesize;
+ if (tnow > tstart_volume)
+ (void)snprintf(msgbuf, sizeof(msgbuf),
+ "%3.2f%% done at %ld kB/s, finished in %d:%02d\n",
+ (blockswritten * 100.0) / tapesize,
+ (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
+ (int)(deltat / 3600), (int)((deltat % 3600) / 60));
+ else
+ (void)snprintf(msgbuf, sizeof(msgbuf),
+ "%3.2f%% done, finished in %d:%02d\n",
+ (blockswritten * 100.0) / tapesize,
+ (int)(deltat / 3600), (int)((deltat % 3600) / 60));
+
+ return msgbuf;
+}
+
+#if defined(SIGINFO)
+/*
+ * statussig --
+ * information message upon receipt of SIGINFO
+ */
+void
+statussig(int notused)
+{
+ int save_errno = errno;
+ char *buf;
+
+ buf = mktimeest(time(NULL));
+ if (buf)
+ write(STDERR_FILENO, buf, strlen(buf));
+ errno = save_errno;
+}
+#endif
+
+static void
+flushtape(void)
+{
+ int i, blks, got;
+ long lastfirstrec;
+ struct slave_results returned;
+
+ int siz = (char *)nextblock - (char *)slp->req;
+
+ slp->req[trecno].count = 0; /* Sentinel */
+
+ if (dump_atomic_write( slp->fd, (char *)slp->req, siz) != siz)
+ quit("error writing command pipe: %s\n", strerror(errno));
+ slp->sent = 1; /* we sent a request, read the response later */
+
+ lastfirstrec = slp->firstrec;
+
+ if (++slp >= &slaves[SLAVES])
+ slp = &slaves[0];
+
+ /* Read results back from next slave */
+ if (slp->sent) {
+ if (dump_atomic_read( slp->fd, (char *)&returned, sizeof returned)
+ != sizeof returned) {
+ perror(" DUMP: error reading command pipe in master");
+ dumpabort(0);
+ }
+ got = returned.unclen;
+ bytes_written += returned.clen;
+ if (returned.unclen == returned.clen)
+ uncomprblks++;
+ slp->sent = 0;
+
+ /* Check for errors or end of tape */
+ if (got <= 0) {
+ /* Check for errors */
+ if (got < 0)
+ tperror(-got);
+ else
+ msg("End of tape detected\n");
+
+ /*
+ * Drain the results, don't care what the values were.
+ * If we read them here then trewind won't...
+ */
+ for (i = 0; i < SLAVES; i++) {
+ if (slaves[i].sent) {
+ if (dump_atomic_read( slaves[i].fd,
+ (char *)&returned, sizeof returned)
+ != sizeof returned) {
+ perror(" DUMP: error reading command pipe in master");
+ dumpabort(0);
+ }
+ slaves[i].sent = 0;
+ }
+ }
+
+ close_rewind();
+ rollforward();
+ return;
+ }
+ }
+
+ blks = 0;
+ if (spcl.c_type != TS_END) {
+ for (i = 0; i < spcl.c_count; i++)
+ if (spcl.c_addr[i] != 0)
+ blks++;
+ }
+ slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
+ slp->tapea = spcl.c_tapea;
+ slp->firstrec = lastfirstrec + ntrec;
+ slp->inode = curino;
+ nextblock = slp->tblock;
+ trecno = 0;
+ asize += tenths + returned.clen / density;
+ blockswritten += ntrec;
+ blocksthisvol += ntrec;
+ if (!pipeout && !unlimited) {
+ if (blocksperfiles && blocksperfiles[blocksperfiles_current]) {
+ if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfiles[blocksperfiles_current]) * 1024)
+ : blocksthisvol >= blocksperfiles[blocksperfiles_current] ) {
+ close_rewind();
+ startnewtape(0);
+ }
+ }
+ else if (asize > tsize) {
+ close_rewind();
+ startnewtape(0);
+ }
+ }
+ timeest();
+}
+
+time_t
+trewind(void)
+{
+ int f;
+ int got;
+ struct slave_results returned;
+
+ for (f = 0; f < SLAVES; f++) {
+ /*
+ * Drain the results, but unlike EOT we DO (or should) care
+ * what the return values were, since if we detect EOT after
+ * we think we've written the last blocks to the tape anyway,
+ * we have to replay those blocks with rollforward.
+ *
+ * fixme: punt for now.
+ */
+ if (slaves[f].sent) {
+ if (dump_atomic_read( slaves[f].fd, (char *)&returned, sizeof returned)
+ != sizeof returned) {
+ perror(" DUMP: error reading command pipe in master");
+ dumpabort(0);
+ }
+ got = returned.unclen;
+ bytes_written += returned.clen;
+ if (returned.unclen == returned.clen)
+ uncomprblks++;
+ slaves[f].sent = 0;
+
+ if (got < 0)
+ tperror(-got);
+
+ if (got == 0) {
+ msg("EOT detected in last 2 tape records!\n");
+ msg("Use a longer tape, decrease the size estimate\n");
+ quit("or use no size estimate at all.\n");
+ }
+ }
+ (void) close(slaves[f].fd);
+ }
+ while (wait((int *)NULL) >= 0) /* wait for any signals from slaves */
+ /* void */;
+
+ if (!pipeout) {
+
+ msg("Closing %s\n", tape);
+
+#ifdef RDUMP
+ if (host) {
+ rmtclose();
+ while (rmtopen(tape, O_RDONLY) < 0)
+ sleep(10);
+ rmtclose();
+ }
+ else
+#endif
+ {
+ (void) close(tapefd);
+ if (!fifoout) {
+ while ((f = OPEN(tape, O_RDONLY)) < 0)
+ sleep (10);
+ (void) close(f);
+ }
+ }
+ }
+ return do_stats();
+}
+
+
+void
+close_rewind(void)
+{
+ int eot_code = 1;
+ (void)trewind();
+ if (eot_script) {
+ msg("Launching %s\n", eot_script);
+ eot_code = system_command(eot_script, tape, tapeno);
+ }
+ if (eot_code != 0 && eot_code != 1) {
+ msg("Dump aborted by the end of tape script\n");
+ dumpabort(0);
+ }
+ if (eot_code == 0)
+ return;
+ if (nexttape || Mflag)
+ return;
+ if (!nogripe) {
+ msg("Change Volumes: Mount volume #%d\n", tapeno+1);
+ broadcast("CHANGE DUMP VOLUMES!\7\7\n");
+ }
+ while (!query("Is the new volume mounted and ready to go?"))
+ if (query("Do you want to abort?")) {
+ dumpabort(0);
+ /*NOTREACHED*/
+ }
+}
+
+void
+rollforward(void)
+{
+ struct req *p, *q = NULL, *prev;
+ struct slave *tslp;
+ int i, size, savedtapea, got;
+ union u_spcl *ntb, *otb;
+ struct slave_results returned;
+#ifdef __linux__
+ int blks;
+ long lastfirstrec;
+#endif
+ tslp = &slaves[SLAVES];
+ ntb = (union u_spcl *)tslp->tblock[1];
+
+ /*
+ * Each of the N slaves should have requests that need to
+ * be replayed on the next tape. Use the extra slave buffers
+ * (slaves[SLAVES]) to construct request lists to be sent to
+ * each slave in turn.
+ */
+ for (i = 0; i < SLAVES; i++) {
+ q = &tslp->req[1];
+ otb = (union u_spcl *)slp->tblock;
+
+ /*
+ * For each request in the current slave, copy it to tslp.
+ */
+
+ prev = NULL;
+ for (p = slp->req; p->count > 0; p += p->count) {
+ *q = *p;
+ if (p->dblk == 0)
+ *ntb++ = *otb++; /* copy the datablock also */
+ prev = q;
+ q += q->count;
+ }
+ if (prev == NULL)
+ quit("rollforward: protocol botch");
+ if (prev->dblk != 0)
+ prev->count -= 1;
+ else
+ ntb--;
+ q -= 1;
+ q->count = 0;
+ q = &tslp->req[0];
+ if (i == 0) {
+ q->dblk = 0;
+ q->count = 1;
+ trecno = 0;
+ nextblock = tslp->tblock;
+ savedtapea = spcl.c_tapea;
+ spcl.c_tapea = slp->tapea;
+ startnewtape(0);
+ spcl.c_tapea = savedtapea;
+ lastspclrec = savedtapea - 1;
+ }
+ size = (char *)ntb - (char *)q;
+ if (dump_atomic_write( slp->fd, (char *)q, size) != size) {
+ perror(" DUMP: error writing command pipe");
+ dumpabort(0);
+ }
+ slp->sent = 1;
+#ifdef __linux__
+ lastfirstrec = slp->firstrec;
+#endif
+ if (++slp >= &slaves[SLAVES])
+ slp = &slaves[0];
+
+ q->count = 1;
+
+ if (prev->dblk != 0) {
+ /*
+ * If the last one was a disk block, make the
+ * first of this one be the last bit of that disk
+ * block...
+ */
+ q->dblk = prev->dblk +
+ prev->count * (TP_BSIZE / DEV_BSIZE);
+ ntb = (union u_spcl *)tslp->tblock;
+ } else {
+ /*
+ * It wasn't a disk block. Copy the data to its
+ * new location in the buffer.
+ */
+ q->dblk = 0;
+ *((union u_spcl *)tslp->tblock) = *ntb;
+ ntb = (union u_spcl *)tslp->tblock[1];
+ }
+ }
+ slp->req[0] = *q;
+ nextblock = slp->tblock;
+ if (q->dblk == 0) {
+#ifdef __linux__
+ /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */
+ *(union u_spcl *)(*nextblock) = *(union u_spcl *)tslp->tblock;
+#endif
+ nextblock++;
+ }
+ trecno = 1;
+
+ /*
+ * Clear the first slaves' response. One hopes that it
+ * worked ok, otherwise the tape is much too short!
+ */
+ if (slp->sent) {
+ if (dump_atomic_read( slp->fd, (char *)&returned, sizeof returned)
+ != sizeof returned) {
+ perror(" DUMP: error reading command pipe in master");
+ dumpabort(0);
+ }
+ got = returned.unclen;
+ bytes_written += returned.clen;
+ if (returned.clen == returned.unclen)
+ uncomprblks++;
+ slp->sent = 0;
+
+ if (got < 0)
+ tperror(-got);
+
+ if (got == 0) {
+ quit("EOT detected at start of the tape!\n");
+ }
+ }
+
+#ifdef __linux__
+ blks = 0;
+ if (spcl.c_type != TS_END) {
+ for (i = 0; i < spcl.c_count; i++)
+ if (spcl.c_addr[i] != 0)
+ blks++;
+ }
+
+ slp->firstrec = lastfirstrec + ntrec;
+ slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
+ slp->inode = curino;
+ asize += tenths + returned.clen / density;
+ blockswritten += ntrec;
+ blocksthisvol += ntrec;
+#endif
+}
+
+/*
+ * We implement taking and restoring checkpoints on the tape level.
+ * When each tape is opened, a new process is created by forking; this
+ * saves all of the necessary context in the parent. The child
+ * continues the dump; the parent waits around, saving the context.
+ * If the child returns X_REWRITE, then it had problems writing that tape;
+ * this causes the parent to fork again, duplicating the context, and
+ * everything continues as if nothing had happened.
+ */
+void
+startnewtape(int top)
+{
+ int parentpid;
+ int childpid;
+ int status;
+ int waitpid;
+ char *p;
+
+#ifdef __linux__
+ sigset_t sigs;
+ sigemptyset(&sigs);
+ sigaddset(&sigs, SIGINT);
+ sigprocmask(SIG_BLOCK, &sigs, NULL);
+#else /* __linux__ */
+#ifdef sunos
+ void (*interrupt_save)();
+#else
+ sig_t interrupt_save;
+#endif
+ interrupt_save = signal(SIGINT, SIG_IGN);
+#endif /* __linux__ */
+
+ parentpid = getpid();
+ tapea_volume = spcl.c_tapea;
+ tapea_bytes = bytes_written;
+ tstart_volume = time(NULL);
+
+restore_check_point:
+#ifdef __linux__
+ sigprocmask(SIG_UNBLOCK, &sigs, NULL);
+#else
+ (void)signal(SIGINT, interrupt_save);
+#endif
+ /*
+ * All signals are inherited...
+ */
+ childpid = fork();
+ if (childpid < 0) {
+ msg("Context save fork fails in parent %d\n", parentpid);
+ Exit(X_ABORT);
+ }
+ if (childpid != 0) {
+ /*
+ * PARENT:
+ * save the context by waiting
+ * until the child doing all of the work returns.
+ * don't catch the interrupt
+ */
+#ifdef __linux__
+ sigprocmask(SIG_BLOCK, &sigs, NULL);
+#else
+ signal(SIGINT, SIG_IGN);
+#endif
+#ifdef TDEBUG
+ msg("Tape: %d; parent process: %d child process %d\n",
+ tapeno+1, parentpid, childpid);
+#endif /* TDEBUG */
+ while ((waitpid = wait(&status)) != childpid)
+ if (waitpid != rshpid)
+ msg("Parent %d waiting for child %d has another child %d return\n",
+ parentpid, childpid, waitpid);
+ if (status & 0xFF) {
+ msg("Child %d returns LOB status %o\n",
+ childpid, status&0xFF);
+ }
+ status = (status >> 8) & 0xFF;
+#ifdef TDEBUG
+ switch(status) {
+ case X_FINOK:
+ msg("Child %d finishes X_FINOK\n", childpid);
+ break;
+ case X_ABORT:
+ msg("Child %d finishes X_ABORT\n", childpid);
+ break;
+ case X_REWRITE:
+ msg("Child %d finishes X_REWRITE\n", childpid);
+ break;
+ default:
+ msg("Child %d finishes unknown %d\n",
+ childpid, status);
+ break;
+ }
+#endif /* TDEBUG */
+ switch(status) {
+ case X_FINOK:
+ Exit(X_FINOK);
+ case X_ABORT:
+ Exit(X_ABORT);
+ case X_REWRITE:
+ goto restore_check_point;
+ default:
+ msg("Bad return code from dump: %d\n", status);
+ Exit(X_ABORT);
+ }
+ /*NOTREACHED*/
+ } else { /* we are the child; just continue */
+#ifdef TDEBUG
+ sleep(4); /* allow time for parent's message to get out */
+ msg("Child on Tape %d has parent %d, my pid = %d\n",
+ tapeno+1, parentpid, getpid());
+#endif /* TDEBUG */
+ /*
+ * If we have a name like "/dev/rmt0,/dev/rmt1",
+ * use the name before the comma first, and save
+ * the remaining names for subsequent volumes.
+ */
+ tapeno++; /* current tape sequence */
+ if (Mflag) {
+ snprintf(tape, MAXPATHLEN, "%s%03d", tapeprefix, tapeno);
+ tape[MAXPATHLEN - 1] = '\0';
+ msg("Dumping volume %d on %s\n", tapeno, tape);
+ }
+ else if (nexttape || strchr(tapeprefix, ',')) {
+ if (nexttape && *nexttape)
+ tapeprefix = nexttape;
+ if ((p = strchr(tapeprefix, ',')) != NULL) {
+ *p = '\0';
+ nexttape = p + 1;
+ } else
+ nexttape = NULL;
+ strncpy(tape, tapeprefix, MAXPATHLEN);
+ tape[MAXPATHLEN - 1] = '\0';
+ msg("Dumping volume %d on %s\n", tapeno, tape);
+ }
+ if (blocksperfiles && blocksperfiles_current < *blocksperfiles)
+ blocksperfiles_current++;
+#ifdef RDUMP
+ while ((tapefd = (host ? rmtopen(tape, O_WRONLY|O_CREAT|O_TRUNC) : pipeout ?
+ fileno(stdout) :
+ OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0)
+#else
+ while ((tapefd = (pipeout ? fileno(stdout) :
+ OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0)
+#endif
+ {
+ msg("Cannot open output \"%s\": %s\n", tape,
+ strerror(errno));
+ if (!query("Do you want to retry the open?"))
+ dumpabort(0);
+ }
+#ifdef RDUMP
+ if (!host)
+#endif
+ {
+ struct mtget mt_stat;
+ magtapeout = ioctl(tapefd, MTIOCGET, (char *)&mt_stat) == 0;
+ /*
+ msg("Output is to %s\n",
+ magtapeout ? "tape" : "file/pipe");
+ */
+ }
+
+ enslave(); /* Share open tape file descriptor with slaves */
+
+ asize = 0;
+ blocksthisvol = 0;
+ if (top)
+ newtape++; /* new tape signal */
+ spcl.c_count = slp->count;
+ /*
+ * measure firstrec in TP_BSIZE units since restore doesn't
+ * know the correct ntrec value...
+ */
+ spcl.c_firstrec = slp->firstrec;
+ spcl.c_volume++;
+ spcl.c_type = TS_TAPE;
+ spcl.c_flags |= DR_NEWHEADER;
+ spcl.c_ntrec = ntrec;
+ if (compressed)
+ spcl.c_flags |= DR_COMPRESSED;
+ writeheader((dump_ino_t)slp->inode);
+ spcl.c_flags &=~ DR_NEWHEADER;
+ msg("Volume %d started with block %ld at: %s", tapeno,
+ spcl.c_tapea, ctime(&tstart_volume));
+ if (tapeno > 1)
+ msg("Volume %d begins with blocks from inode %d\n",
+ tapeno, slp->inode);
+ if (tapeno < (int)TP_NINOS)
+ volinfo[tapeno] = slp->inode;
+ }
+}
+
+void
+dumpabort(UNUSED(int signo))
+{
+
+ if (master != 0 && master != getpid())
+ /* Signals master to call dumpabort */
+ (void) kill(master, SIGTERM);
+ else {
+ killall();
+ msg("The ENTIRE dump is aborted.\n");
+ }
+#ifdef RDUMP
+ rmtclose();
+#endif
+ Exit(X_ABORT);
+}
+
+void
+Exit(int status)
+{
+
+#ifdef TDEBUG
+ msg("pid = %d exits with status %d\n", getpid(), status);
+#endif /* TDEBUG */
+ exit(status);
+}
+
+/*
+ * proceed - handler for SIGUSR2, used to synchronize IO between the slaves.
+ */
+static void
+proceed(UNUSED(int signo))
+{
+ if (ready)
+ siglongjmp(jmpbuf, 1);
+ caught++;
+}
+
+void
+enslave(void)
+{
+ int cmd[2];
+#ifdef LINUX_FORK_BUG
+ int i, j;
+#else
+ int i, j;
+#endif
+
+ master = getpid();
+
+ { struct sigaction sa;
+ memset(&sa, 0, sizeof sa);
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = dumpabort;
+ sigaction(SIGTERM, &sa, NULL); /* Slave sends SIGTERM on dumpabort() */
+ sa.sa_handler = sigpipe;
+ sigaction(SIGPIPE, &sa, NULL);
+ sa.sa_handler = proceed;
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGUSR2, &sa, NULL); /* Slave sends SIGUSR2 to next slave */
+ }
+
+ for (i = 0; i < SLAVES; i++) {
+ if (i == slp - &slaves[0]) {
+ caught = 1;
+ } else {
+ caught = 0;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd) < 0 ||
+ (slaves[i].pid = fork()) < 0)
+ quit("too many slaves, %d (recompile smaller): %s\n",
+ i, strerror(errno));
+
+ slaves[i].fd = cmd[1];
+ slaves[i].sent = 0;
+ if (slaves[i].pid == 0) { /* Slave starts up here */
+ sigset_t sigs;
+ for (j = 0; j <= i; j++)
+ (void) close(slaves[j].fd);
+ sigemptyset(&sigs);
+ sigaddset(&sigs, SIGINT); /* Master handles this */
+#if defined(SIGINFO)
+ sigaddset(&sigs, SIGINFO);
+#endif
+ sigprocmask(SIG_BLOCK, &sigs, NULL);
+
+#ifdef LINUX_FORK_BUG
+ if (dump_atomic_write( cmd[0], (char *) &i, sizeof i)
+ != sizeof i)
+ quit("master/slave protocol botched 3\n");
+#endif
+ doslave(cmd[0],
+#ifdef WRITEDEBUG
+ i,
+#endif
+ (slaves[i].pid == slp->pid));
+ Exit(X_FINOK);
+ }
+ else
+ close(cmd[0]);
+ }
+
+#ifdef LINUX_FORK_BUG
+ /*
+ * Wait for all slaves to _actually_ start to circumvent a bug in
+ * Linux kernels >= 2.1.3 where a signal sent to a child that hasn't
+ * returned from fork() causes a SEGV in the child process
+ */
+ for (i = 0; i < SLAVES; i++)
+ if (dump_atomic_read( slaves[i].fd, (char *) &j, sizeof j) != sizeof j)
+ quit("master/slave protocol botched 4\n");
+#endif
+
+ for (i = 0; i < SLAVES; i++)
+ (void) dump_atomic_write( slaves[i].fd,
+ (char *) &slaves[(i + 1) % SLAVES].pid,
+ sizeof slaves[0].pid);
+
+ master = 0;
+}
+
+void
+killall(void)
+{
+ int i;
+
+ for (i = 0; i < SLAVES; i++)
+ if (slaves[i].pid > 0) {
+ (void) kill(slaves[i].pid, SIGKILL);
+ slaves[i].sent = 0;
+ }
+}
+
+/*
+ * Synchronization - each process waits for a SIGUSR2 from the
+ * previous process before writing to the tape, and sends SIGUSR2
+ * to the next process when the tape write completes. On tape errors
+ * a SIGUSR1 is sent to the master which then terminates all of the
+ * slaves.
+ */
+static void
+doslave(int cmd,
+#ifdef WRITEDEBUG
+ int slave_number,
+#endif
+ int first)
+{
+ int nread;
+ int nextslave;
+ volatile int wrote = 0, size, eot_count, bufsize;
+ char * volatile buffer;
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+ struct tapebuf * volatile comp_buf = NULL;
+ int compresult;
+ volatile int do_compress = !first;
+ unsigned long worklen;
+#ifdef HAVE_LZO
+ lzo_align_t __LZO_MMODEL *LZO_WorkMem;
+#endif
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+ struct slave_results returns;
+#ifdef __linux__
+ errcode_t retval;
+#endif
+#ifdef USE_QFA
+ long long curtapepos;
+ union u_spcl *uspclptr;
+ struct s_spcl *spclptr;
+ /* long maxntrecs = 300000000 / (ntrec * 1024); last tested: 50 000 000 */
+ long maxntrecs = 50000; /* every 50MB */
+ long cntntrecs = maxntrecs;
+#endif /* USE_QFA */
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ sigemptyset(&set);
+
+ /*
+ * Need our own seek pointer.
+ */
+ (void) close(diskfd);
+ if ((diskfd = OPEN(disk, O_RDONLY)) < 0)
+ quit("slave couldn't reopen disk: %s\n", strerror(errno));
+#ifdef __linux__
+#ifdef BLKFLSBUF
+ (void)ioctl(diskfd, BLKFLSBUF, 0);
+#endif
+ ext2fs_close(fs);
+ retval = dump_fs_open(disk, &fs);
+ if (retval)
+ quit("slave couldn't reopen disk: %s\n", error_message(retval));
+#endif /* __linux__ */
+
+ /*
+ * Need the pid of the next slave in the loop...
+ */
+ if ((nread = dump_atomic_read( cmd, (char *)&nextslave, sizeof nextslave))
+ != sizeof nextslave) {
+ quit("master/slave protocol botched - didn't get pid of next slave.\n");
+ }
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+ /* if we're doing a compressed dump, allocate the compress buffer */
+ if (compressed) {
+ int bsiz = sizeof(struct tapebuf) + writesize;
+ /* Add extra space to deal with compression enlarging the buffer */
+ if (TP_BSIZE > writesize/16 + 67)
+ bsiz += TP_BSIZE;
+ else
+ bsiz += writesize/16 + 67;
+ comp_buf = malloc(bsiz);
+ if (comp_buf == NULL)
+ quit("couldn't allocate a compress buffer.\n");
+ if (zipflag == COMPRESS_ZLIB)
+ comp_buf->flags = COMPRESS_ZLIB;
+ else if (zipflag == COMPRESS_BZLIB)
+ comp_buf->flags = COMPRESS_BZLIB;
+ else if (zipflag == COMPRESS_LZO) {
+ comp_buf->flags = COMPRESS_LZO;
+ if (lzo_init() != LZO_E_OK) quit("lzo_init failed\n");
+ } else
+ quit("internal error - unknown compression method: %d\n", zipflag);
+ }
+#ifdef HAVE_LZO
+ LZO_WorkMem = malloc(LZO1X_1_MEM_COMPRESS);
+ if (!LZO_WorkMem)
+ quit("couldn't allocate a compress buffer.\n");
+#endif
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+
+ /*
+ * Get list of blocks to dump, read the blocks into tape buffer
+ */
+ while ((nread = dump_atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) {
+ struct req *p = slp->req;
+
+ for (trecno = 0; trecno < ntrec;
+ trecno += p->count, p += p->count) {
+ if (p->dblk) { /* read a disk block */
+ bread(p->dblk, slp->tblock[trecno],
+ p->count * TP_BSIZE);
+ } else { /* read record from pipe */
+ if (p->count != 1 || dump_atomic_read( cmd,
+ (char *)slp->tblock[trecno],
+ TP_BSIZE) != TP_BSIZE)
+ quit("master/slave protocol botched.\n");
+ }
+ }
+
+ /* Try to write the data... */
+ wrote = 0;
+ eot_count = 0;
+ size = 0;
+ buffer = (char *) slp->tblock[0]; /* set write pointer */
+ bufsize = writesize; /* length to write */
+ returns.clen = returns.unclen = bufsize;
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+ /*
+ * When writing a compressed dump, each block except
+ * the first one on each tape is written
+ * from struct tapebuf with an 4 byte prefix
+ * followed by the data. This can be less than
+ * writesize. Restore, on a short read, can compare the
+ * length read to the compressed length in the header
+ * to verify that the read was good. Blocks which don't
+ * compress well are written uncompressed.
+ * The first block written by each slave is not compressed
+ * and does not have a prefix.
+ */
+
+ if (compressed && do_compress) {
+ comp_buf->length = bufsize;
+ worklen = TP_BSIZE + writesize;
+ compresult = 1;
+#ifdef HAVE_ZLIB
+ if (zipflag == COMPRESS_ZLIB) {
+ compresult = compress2(comp_buf->buf,
+ &worklen,
+ (char *)slp->tblock[0],
+ writesize,
+ compressed);
+ if (compresult == Z_OK)
+ compresult = 1;
+ else
+ compresult = 0;
+ }
+#endif /* HAVE_ZLIB */
+#ifdef HAVE_BZLIB
+ if (zipflag == COMPRESS_BZLIB) {
+ unsigned int worklen2 = worklen;
+ compresult = BZ2_bzBuffToBuffCompress(
+ comp_buf->buf,
+ &worklen2,
+ (char *)slp->tblock[0],
+ writesize,
+ compressed,
+ 0, 30);
+ worklen = worklen2;
+ if (compresult == BZ_OK)
+ compresult = 1;
+ else
+ compresult = 0;
+ }
+
+#endif /* HAVE_BZLIB */
+#ifdef HAVE_LZO
+ if (zipflag == COMPRESS_LZO) {
+ lzo_uint worklen2 = worklen;
+ compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize,
+ comp_buf->buf,
+ &worklen2,
+ LZO_WorkMem);
+ worklen = worklen2;
+ if (compresult == LZO_E_OK)
+ compresult = 1;
+ else
+ compresult = 0;
+ }
+#endif /* HAVE_LZO */
+ if (compresult && worklen <= ((unsigned long)writesize - 16)) {
+ /* write the compressed buffer */
+ comp_buf->length = worklen;
+ comp_buf->compressed = 1;
+ buffer = (char *) comp_buf;
+ returns.clen = bufsize = worklen + sizeof(struct tapebuf);
+ }
+ else {
+ /* write the data uncompressed */
+ comp_buf->length = writesize;
+ comp_buf->compressed = 0;
+ buffer = (char *) comp_buf;
+ returns.clen = bufsize = writesize + sizeof(struct tapebuf);
+ returns.unclen = returns.clen;
+ memcpy(comp_buf->buf, (char *)slp->tblock[0], writesize);
+ }
+ }
+ /* compress the remaining blocks if we're compressing */
+ do_compress = compressed;
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+
+ if (sigsetjmp(jmpbuf, 1) == 0) {
+ ready = 1;
+ if (!caught)
+ sigsuspend(&set);
+ }
+ ready = 0;
+ caught = 0;
+
+#ifdef USE_QFA
+ if (gTapeposfd >= 0) {
+ int i;
+ int foundone = 0;
+
+ for (i = 0; (i < ntrec) && !foundone; ++i) {
+ uspclptr = (union u_spcl *)&slp->tblock[i];
+ spclptr = &uspclptr->s_spcl;
+ if ((spclptr->c_magic == NFS_MAGIC) &&
+ (spclptr->c_type == TS_INODE) &&
+ (spclptr->c_date == gThisDumpDate) &&
+ !(spclptr->c_dinode.di_mode & S_IFDIR)
+ ) {
+ foundone = 1;
+ /* if (cntntrecs >= maxntrecs) { only write every maxntrecs amount of data */
+ cntntrecs = 0;
+ if (gtperr == 0)
+ gtperr = GetTapePos(&curtapepos);
+ /* if an error occured previously don't
+ * try again */
+ if (gtperr == 0) {
+#ifdef DEBUG_QFA
+ msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos);
+#endif
+ gtperr = MkTapeString(spclptr, curtapepos);
+ }
+ /* } */
+ }
+ }
+ }
+#endif /* USE_QFA */
+
+ while (eot_count < 10 && size < bufsize) {
+#ifdef RDUMP
+ if (host)
+ wrote = rmtwrite(buffer + size, bufsize - size);
+ else
+#endif
+ wrote = write(tapefd, buffer + size, bufsize - size);
+#ifdef WRITEDEBUG
+ printf("slave %d wrote %d\n", slave_number, wrote);
+#endif
+ if (wrote < 0 && errno != ENOSPC)
+ break;
+ if (wrote == 0 || (wrote < 0 && errno == ENOSPC))
+ eot_count++;
+ else
+ size += wrote;
+ }
+
+#ifdef WRITEDEBUG
+ if (size != bufsize)
+ printf("slave %d only wrote %d out of %d bytes and gave up.\n",
+ slave_number, size, bufsize);
+#endif
+
+ /*
+ * Handle ENOSPC as an EOT condition.
+ */
+ if (wrote < 0 && errno == ENOSPC) {
+ wrote = 0;
+ eot_count++;
+ }
+
+ if (eot_count > 0)
+ returns.clen = returns.unclen = 0;
+
+ /*
+ * pass errno back to master for special handling
+ */
+ if (wrote < 0)
+ returns.unclen = -errno;
+
+ /*
+ * pass size of data and size of write back to master
+ * (for EOT handling)
+ */
+ (void) dump_atomic_write( cmd, (char *)&returns, sizeof returns);
+
+ /*
+ * Signal the next slave to go.
+ */
+ (void) kill(nextslave, SIGUSR2);
+#ifdef USE_QFA
+ if (gTapeposfd >= 0) {
+ cntntrecs += ntrec;
+ }
+#endif /* USE_QFA */
+ }
+ if (nread != 0)
+ quit("error reading command pipe: %s\n", strerror(errno));
+}
+
+/*
+ * Since a read from a pipe may not return all we asked for,
+ * or a write may not write all we ask if we get a signal,
+ * loop until the count is satisfied (or error).
+ */
+static ssize_t
+dump_atomic_read(int fd, char *buf, size_t count)
+{
+ int got, need = count;
+
+ do {
+ while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0)
+ buf += got;
+ } while (got == -1 && errno == EINTR);
+ return (got < 0 ? got : (ssize_t)count - need);
+}
+
+/*
+ * Since a read from a pipe may not return all we asked for,
+ * or a write may not write all we ask if we get a signal,
+ * loop until the count is satisfied (or error).
+ */
+static ssize_t
+dump_atomic_write(int fd, const char *buf, size_t count)
+{
+ int got, need = count;
+
+ do {
+ while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
+ buf += got;
+ } while (got == -1 && errno == EINTR);
+ return (got < 0 ? got : (ssize_t)count - need);
+}
+
+
+/*
+int
+SetLogicalPos(void)
+{
+ int err = 0;
+ struct mt_pos buf;
+
+ buf.mt_op = MTSETDRVBUFFER;
+ buf.mt_count = MT_ST_BOOLEANS | MT_ST_SCSI2LOGICAL;
+ if (ioctl(tapefd, MTIOCTOP, &buf) == -1) {
+ err = errno;
+ msg("[%ld] error: %d (setting logical)\n",
+ (unsigned long)getpid(), err);
+ }
+ return err;
+}
+*/
+
+#ifdef USE_QFA
+#define LSEEK_GET_TAPEPOS 10
+#define LSEEK_GO2_TAPEPOS 11
+/*
+ * read the current tape position
+ */
+static int
+GetTapePos(long long *pos)
+{
+ int err = 0;
+
+#ifdef RDUMP
+ if (host) {
+ *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS);
+ err = *pos < 0;
+ }
+ else
+#endif
+ {
+ if (magtapeout) {
+ long mtpos;
+ *pos = 0;
+ err = (ioctl(tapefd, MTIOCPOS, &mtpos) < 0);
+ *pos = (long long)mtpos;
+ }
+ else {
+ *pos = LSEEK(tapefd, 0, SEEK_CUR);
+ err = (*pos < 0);
+ }
+ }
+ if (err) {
+ err = errno;
+ msg("[%ld] error: %d (getting tapepos: %lld)\n", getpid(),
+ err, *pos);
+ return err;
+ }
+ return err;
+}
+
+static int
+MkTapeString(struct s_spcl *spclptr, long long curtapepos)
+{
+ int err = 0;
+
+#ifdef DEBUG_QFA
+ msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos);
+#endif
+
+ snprintf(gTps, sizeof(gTps), "%ld\t%d\t%lld\n",
+ (unsigned long)spclptr->c_inumber,
+ tapeno,
+ curtapepos);
+ gTps[sizeof(gTps) - 1] = '\0';
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) {
+ err = errno;
+ warn("error writing tapepos file. (error %d)\n", errno);
+ }
+ return err;
+}
+#endif /* USE_QFA */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: traverse.c,v 1.61 2004/07/01 09:14:49 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <sys/types.h>
+#ifdef __STDC__
+#include <string.h>
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#include <compaterr.h>
+#include <stdlib.h>
+#elif defined sunos
+#include <sys/vnode.h>
+
+#include <ufs/fs.h>
+#include <ufs/fsdir.h>
+#include <ufs/inode.h>
+#else
+#include <ufs/ufs/dir.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#endif /* __linux__ */
+
+#include <protocols/dumprestore.h>
+
+#include "dump.h"
+
+#define HASDUMPEDFILE 0x1
+#define HASSUBDIRS 0x2
+
+#ifdef __linux__
+typedef u_quad_t fsizeT;
+#else
+#ifdef FS_44INODEFMT
+typedef quad_t fsizeT;
+#else
+typedef long fsizeT;
+#endif
+#endif
+
+#ifdef __linux__
+static int searchdir __P((struct ext2_dir_entry *dp, int offset,
+ int blocksize, char *buf, void *private));
+#else
+static int dirindir __P((dump_ino_t ino, daddr_t blkno, int level, long *size));
+static void dmpindir __P((dump_ino_t ino, daddr_t blk, int level, fsizeT *size));
+static int searchdir __P((dump_ino_t ino, daddr_t blkno, long size, long filesize));
+#endif
+static void mapfileino __P((dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped));
+
+#ifdef HAVE_EXT2_JOURNAL_INUM
+#define ext2_journal_ino(sb) (sb->s_journal_inum)
+#else
+#define ext2_journal_ino(sb) (*((u_int32_t *)sb + 0x38))
+#endif
+#ifndef HAVE_EXT2_INO_T
+typedef ino_t ext2_ino_t;
+#endif
+
+#ifndef EXT3_FEATURE_COMPAT_HAS_JOURNAL
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+#endif
+#ifndef EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#endif
+#ifndef EXT3_FEATURE_INCOMPAT_RECOVER
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
+#endif
+#ifndef EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
+#endif
+
+#ifndef EXT2_LIB_FEATURE_INCOMPAT_SUPP
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_RECOVER | \
+ EXT2_FEATURE_INCOMPAT_FILETYPE)
+#endif
+#ifndef EXT2_RESIZE_INO
+#define EXT2_RESIZE_INO 7
+#endif
+#ifndef EXT2_FT_UNKNOWN
+#define EXT2_FT_UNKNOWN 0
+#define EXT2_FT_REG_FILE 1
+#define EXT2_FT_DIR 2
+#define EXT2_FT_CHRDEV 3
+#define EXT2_FT_BLKDEV 4
+#define EXT2_FT_FIFO 5
+#define EXT2_FT_SOCK 6
+#define EXT2_FT_SYMLINK 7
+#define EXT2_FT_MAX 8
+#endif
+
+int dump_fs_open(const char *disk, ext2_filsys *fs)
+{
+ int retval;
+
+ retval = ext2fs_open(disk, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, fs);
+ if (!retval) {
+ struct ext2_super_block *es = (*fs)->super;
+ dump_ino_t journal_ino = ext2_journal_ino(es);
+
+ if (es->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV){
+ msg("This is a journal, not a filesystem!\n");
+ retval = EXT2_ET_UNSUPP_FEATURE;
+ ext2fs_close(*fs);
+ }
+ else if ((retval = es->s_feature_incompat &
+ ~(EXT2_LIB_FEATURE_INCOMPAT_SUPP |
+ EXT3_FEATURE_INCOMPAT_RECOVER))) {
+ msg("Unsupported feature(s) 0x%x in filesystem\n",
+ retval);
+ retval = EXT2_ET_UNSUPP_FEATURE;
+ ext2fs_close(*fs);
+ }
+ else {
+ if (es->s_feature_compat &
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
+ journal_ino)
+ do_exclude_ino(journal_ino, "journal inode");
+ do_exclude_ino(EXT2_RESIZE_INO, "resize inode");
+ }
+ }
+ return retval;
+}
+
+/*
+ * This is an estimation of the number of TP_BSIZE blocks in the file.
+ * It estimates the number of blocks in files with holes by assuming
+ * that all of the blocks accounted for by di_blocks are data blocks
+ * (when some of the blocks are usually used for indirect pointers);
+ * hence the estimate may be high.
+ */
+long
+blockest(struct dinode const *dp)
+{
+ long blkest, sizeest;
+ u_quad_t i_size;
+
+ /*
+ * dp->di_size is the size of the file in bytes.
+ * dp->di_blocks stores the number of sectors actually in the file.
+ * If there are more sectors than the size would indicate, this just
+ * means that there are indirect blocks in the file or unused
+ * sectors in the last file block; we can safely ignore these
+ * (blkest = sizeest below).
+ * If the file is bigger than the number of sectors would indicate,
+ * then the file has holes in it. In this case we must use the
+ * block count to estimate the number of data blocks used, but
+ * we use the actual size for estimating the number of indirect
+ * dump blocks (sizeest vs. blkest in the indirect block
+ * calculation).
+ */
+ blkest = howmany((u_quad_t)dp->di_blocks * 512, fs->blocksize) * (fs->blocksize / TP_BSIZE);
+ i_size = dp->di_size + ((u_quad_t) dp->di_size_high << 32);
+ sizeest = howmany(i_size, fs->blocksize) * (fs->blocksize / TP_BSIZE);
+ if (blkest > sizeest)
+ blkest = sizeest;
+#ifdef __linux__
+ if ((dp->di_mode & IFMT) == IFDIR) {
+ /*
+ * for directories, assume only half of space is filled
+ * with entries.
+ */
+ blkest = blkest / 2;
+ sizeest = sizeest / 2;
+ }
+ if (i_size > (u_quad_t)fs->blocksize * NDADDR) {
+ /* calculate the number of indirect blocks on the dump tape */
+ blkest +=
+ howmany(sizeest - NDADDR * fs->blocksize / TP_BSIZE,
+ TP_NINDIR);
+ }
+#else
+ if (i_size > sblock->fs_bsize * NDADDR) {
+ /* calculate the number of indirect blocks on the dump tape */
+ blkest +=
+ howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE,
+ TP_NINDIR);
+ }
+#endif
+ return (blkest + 1);
+}
+
+/* Auxiliary macro to pick up files changed since previous dump. */
+#define CSINCE(dp, t) \
+ ((dp)->di_ctime >= (t))
+#define MSINCE(dp, t) \
+ ((dp)->di_mtime >= (t))
+#define CHANGEDSINCE(dp, t) \
+ (CSINCE(dp, t) || MSINCE(dp, t))
+
+/* The NODUMP_FLAG macro tests if a file has the nodump flag. */
+#ifdef UF_NODUMP
+#define NODUMP_FLAG(dp) (!nonodump && (((dp)->di_flags & UF_NODUMP) == UF_NODUMP))
+#else
+#define NODUMP_FLAG(dp) 0
+#endif
+
+/* The WANTTODUMP macro decides whether a file should be dumped. */
+#define WANTTODUMP(dp, ino) \
+ (CHANGEDSINCE(dp, ((u_int32_t)spcl.c_ddate)) && \
+ (!NODUMP_FLAG(dp)) && \
+ (!exclude_ino(ino)))
+
+/*
+ * Determine if given inode should be dumped. "dp" must either point to a
+ * copy of the given inode, or be NULL (in which case it is fetched.)
+ */
+static void
+mapfileino(dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped)
+{
+ int mode;
+
+ /*
+ * Skip inode if we've already marked it for dumping
+ */
+ if (TSTINO(ino, usedinomap))
+ return;
+ if (!dp)
+ dp = getino(ino);
+ if ((mode = (dp->di_mode & IFMT)) == 0)
+ return;
+#ifdef __linux__
+ if (dp->di_nlink == 0 || dp->di_dtime != 0)
+ return;
+#endif
+ /*
+ * Put all dirs in dumpdirmap, inodes that are to be dumped in the
+ * used map. All inode but dirs who have the nodump attribute go
+ * to the usedinomap.
+ */
+ SETINO(ino, usedinomap);
+
+ if (mode == IFDIR)
+ SETINO(ino, dumpdirmap);
+ if (WANTTODUMP(dp, ino)) {
+ SETINO(ino, dumpinomap);
+ if (!MSINCE(dp, (u_int32_t)spcl.c_ddate))
+ SETINO(ino, metainomap);
+ if (mode != IFREG && mode != IFDIR && mode != IFLNK)
+ *tapesize += 1;
+ else
+ *tapesize += blockest(dp);
+ return;
+ }
+ if (mode == IFDIR) {
+ if ( NODUMP_FLAG(dp) || exclude_ino(ino) )
+ CLRINO(ino, usedinomap);
+ *dirskipped = 1;
+ }
+}
+
+/*
+ * Dump pass 1.
+ *
+ * Walk the inode list for a filesystem to find all allocated inodes
+ * that have been modified since the previous dump time. Also, find all
+ * the directories in the filesystem.
+ */
+#ifdef __linux__
+int
+mapfiles(UNUSED(dump_ino_t maxino), long *tapesize)
+{
+ ext2_ino_t ino;
+ int anydirskipped = 0;
+ ext2_inode_scan scan;
+ errcode_t err;
+ struct ext2_inode inode;
+
+ /*
+ * We use libext2fs's inode scanning routines, which are particularly
+ * robust. (Note that getino cannot return an error.)
+ */
+ err = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (err) {
+ com_err(disk, err, "while opening inodes\n");
+ exit(X_ABORT);
+ }
+ for (;;) {
+ err = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (err == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
+ continue;
+ if (err) {
+ com_err(disk, err, "while scanning inode #%ld\n",
+ (long)ino);
+ exit(X_ABORT);
+ }
+ if (ino == 0)
+ break;
+
+ curino = ino;
+ mapfileino(ino, (struct dinode const *)&inode, tapesize,
+ &anydirskipped);
+ }
+ ext2fs_close_inode_scan(scan);
+
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpinomap);
+ return (anydirskipped);
+}
+#else
+int
+mapfiles(dump_ino_t maxino, long *tapesize)
+{
+ dump_ino_t ino;
+ int anydirskipped = 0;
+
+ for (ino = ROOTINO; ino < maxino; ino++)
+ mapfileino(ino, tapesize, &anydirskipped);
+
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpinomap);
+ return (anydirskipped);
+}
+#endif /* __linux__ */
+
+#ifdef __linux__
+int
+maponefile(UNUSED(dump_ino_t maxino), long *tapesize, char *directory)
+{
+ errcode_t retval;
+ ext2_ino_t dir_ino;
+ char dir_name [MAXPATHLEN];
+ int i, anydirskipped = 0;
+
+ /*
+ * Mark every directory in the path as being dumped
+ */
+ for (i = 0; i < (int)strlen (directory); i++) {
+ if (directory[i] == '/') {
+ strncpy (dir_name, directory, i);
+ dir_name[i] = '\0';
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO,
+ dir_name, &dir_ino);
+ if (retval) {
+ com_err(disk, retval,
+ "while translating %s", dir_name);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t) dir_ino, 0,
+ tapesize, &anydirskipped);
+ }
+ }
+ /*
+ * Mark the final directory
+ */
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino);
+ if (retval) {
+ com_err(disk, retval, "while translating %s", directory);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t)dir_ino, 0, tapesize, &anydirskipped);
+
+ mapfileino(ROOTINO, 0, tapesize, &anydirskipped);
+
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpdirmap);
+ return anydirskipped;
+}
+#endif /* __linux__ */
+
+#ifdef __linux__
+struct mapfile_context {
+ long *tapesize;
+ int *anydirskipped;
+};
+
+static int
+mapfilesindir(struct ext2_dir_entry *dirent, UNUSED(int offset),
+ UNUSED(int blocksize), UNUSED(char *buf), void *private)
+{
+ struct dinode const *dp;
+ int mode;
+ errcode_t retval;
+ struct mapfile_context *mfc;
+ ext2_ino_t ino;
+
+ ino = dirent->inode;
+ mfc = (struct mapfile_context *)private;
+ dp = getino(dirent->inode);
+
+ mapfileino(dirent->inode, dp, mfc->tapesize, mfc->anydirskipped);
+
+ mode = dp->di_mode & IFMT;
+ if (mode == IFDIR && dp->di_nlink != 0 && dp->di_dtime == 0) {
+ if ((dirent->name[0] != '.' || ( dirent->name_len & 0xFF ) != 1) &&
+ (dirent->name[0] != '.' || dirent->name[1] != '.' ||
+ ( dirent->name_len & 0xFF ) != 2)) {
+ retval = ext2fs_dir_iterate(fs, ino, 0, NULL,
+ mapfilesindir, private);
+ if (retval)
+ return retval;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Dump pass 1.
+ *
+ * Walk the inode list for a filesystem to find all allocated inodes
+ * that have been modified since the previous dump time. Also, find all
+ * the directories in the filesystem.
+ */
+int
+mapfilesfromdir(UNUSED(dump_ino_t maxino), long *tapesize, char *directory)
+{
+ errcode_t retval;
+ struct mapfile_context mfc;
+ ext2_ino_t dir_ino;
+ char dir_name [MAXPATHLEN];
+ int i, anydirskipped = 0;
+
+ /*
+ * Mark every directory in the path as being dumped
+ */
+ for (i = 0; i < (int)strlen (directory); i++) {
+ if (directory[i] == '/') {
+ strncpy (dir_name, directory, i);
+ dir_name[i] = '\0';
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO, dir_name,
+ &dir_ino);
+ if (retval) {
+ com_err(disk, retval, "while translating %s",
+ dir_name);
+ exit(X_ABORT);
+ }
+ mapfileino(dir_ino, 0, tapesize, &anydirskipped);
+ }
+ }
+ /*
+ * Mark the final directory
+ */
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino);
+ if (retval) {
+ com_err(disk, retval, "while translating %s", directory);
+ exit(X_ABORT);
+ }
+ mapfileino(dir_ino, 0, tapesize, &anydirskipped);
+
+ mfc.tapesize = tapesize;
+ mfc.anydirskipped = &anydirskipped;
+ retval = ext2fs_dir_iterate(fs, dir_ino, 0, NULL, mapfilesindir,
+ (void *)&mfc);
+
+ if (retval) {
+ com_err(disk, retval, "while mapping files in %s", directory);
+ exit(X_ABORT);
+ }
+ /*
+ * Ensure that the root inode actually appears in the file list
+ * for a subdir
+ */
+ mapfileino(ROOTINO, 0, tapesize, &anydirskipped);
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpinomap);
+ return anydirskipped;
+}
+#endif
+
+#ifdef __linux__
+struct mapdirs_context {
+ int *ret;
+ int nodump;
+ long *tapesize;
+};
+#endif
+
+/*
+ * Dump pass 2.
+ *
+ * Scan each directory on the filesystem to see if it has any modified
+ * files in it. If it does, and has not already been added to the dump
+ * list (because it was itself modified), then add it. If a directory
+ * has not been modified itself, contains no modified files and has no
+ * subdirectories, then it can be deleted from the dump list and from
+ * the list of directories. By deleting it from the list of directories,
+ * its parent may now qualify for the same treatment on this or a later
+ * pass using this algorithm.
+ */
+int
+mapdirs(dump_ino_t maxino, long *tapesize)
+{
+ struct dinode *dp;
+ int isdir;
+ char *map;
+ dump_ino_t ino;
+#ifndef __linux__
+ int i;
+ long filesize;
+#else
+ struct mapdirs_context mdc;
+#endif
+ int ret, change = 0, nodump;
+
+ isdir = 0; /* XXX just to get gcc to shut up */
+ for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
+ if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
+ isdir = *map++;
+ else
+ isdir >>= 1;
+ /*
+ * If dir has been removed from the used map, it's either
+ * because it had the nodump flag, or it herited it from
+ * its parent. A directory can't be in dumpinomap if not
+ * in usedinomap, but we have to go through it anyway
+ * to propagate the nodump attribute.
+ */
+ nodump = (TSTINO(ino, usedinomap) == 0);
+ if ((isdir & 1) == 0 ||
+ (TSTINO(ino, dumpinomap) && nodump == 0))
+ continue;
+ dp = getino(ino);
+#ifdef __linux__
+ ret = 0;
+ mdc.ret = &ret;
+ mdc.nodump = nodump;
+ mdc.tapesize = tapesize;
+ ext2fs_dir_iterate(fs, ino, 0, NULL, searchdir, (void *) &mdc);
+#else /* __linux__ */
+ filesize = dp->di_size;
+ for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
+ if (dp->di_db[i] != 0)
+ ret |= searchdir(ino, dp->di_db[i],
+ (long)dblksize(sblock, dp, i),
+ filesize);
+ if (ret & HASDUMPEDFILE)
+ filesize = 0;
+ else
+ filesize -= sblock->fs_bsize;
+ }
+ for (i = 0; filesize > 0 && i < NIADDR; i++) {
+ if (dp->di_ib[i] == 0)
+ continue;
+ ret |= dirindir(ino, dp->di_ib[i], i, &filesize);
+ }
+#endif /* __linux__ */
+ if (ret & HASDUMPEDFILE) {
+ SETINO(ino, dumpinomap);
+ *tapesize += blockest(dp);
+ change = 1;
+ continue;
+ }
+ if (nodump) {
+ if (ret & HASSUBDIRS)
+ change = 1; /* subdirs have inherited nodump */
+ CLRINO(ino, dumpdirmap);
+ } else if ((ret & HASSUBDIRS) == 0) {
+ if (!TSTINO(ino, dumpinomap)) {
+ CLRINO(ino, dumpdirmap);
+ change = 1;
+ }
+ }
+ }
+ return (change);
+}
+
+#ifndef __linux__
+/*
+ * Read indirect blocks, and pass the data blocks to be searched
+ * as directories. Quit as soon as any entry is found that will
+ * require the directory to be dumped.
+ */
+static int
+dirindir(dump_ino_t ino, daddr_t blkno, int ind_level, long *filesize)
+{
+ int ret = 0;
+ int i;
+ daddr_t idblk[MAXNINDIR];
+
+ bread(fsbtodb(sblock, blkno), (char *)idblk, (int)sblock->fs_bsize);
+ if (ind_level <= 0) {
+ for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
+ blkno = idblk[i];
+ if (blkno != 0)
+ ret |= searchdir(ino, blkno, sblock->fs_bsize,
+ *filesize);
+ if (ret & HASDUMPEDFILE)
+ *filesize = 0;
+ else
+ *filesize -= sblock->fs_bsize;
+ }
+ return (ret);
+ }
+ ind_level--;
+ for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
+ blkno = idblk[i];
+ if (blkno != 0)
+ ret |= dirindir(ino, blkno, ind_level, filesize);
+ }
+ return (ret);
+}
+#endif /* !__linux__ */
+
+/*
+ * Scan a disk block containing directory information looking to see if
+ * any of the entries are on the dump list and to see if the directory
+ * contains any subdirectories.
+ */
+#ifdef __linux__
+static int
+searchdir(struct ext2_dir_entry *dp, UNUSED(int offset),
+ UNUSED(int blocksize), UNUSED(char *buf), void *private)
+{
+ struct mapdirs_context *mdc;
+ int *ret;
+ long *tapesize;
+ struct dinode *ip;
+
+ mdc = (struct mapdirs_context *)private;
+ ret = mdc->ret;
+ tapesize = mdc->tapesize;
+
+ if (dp->inode == 0)
+ return 0;
+ if (dp->name[0] == '.') {
+ if (( dp->name_len & 0xFF ) == 1)
+ return 0;
+ if (dp->name[1] == '.' && ( dp->name_len & 0xFF ) == 2)
+ return 0;
+ }
+ if (mdc->nodump) {
+ ip = getino(dp->inode);
+ if (TSTINO(dp->inode, dumpinomap)) {
+ CLRINO(dp->inode, dumpinomap);
+ *tapesize -= blockest(ip);
+ }
+ /* Add dir back to the dir map and remove from
+ * usedinomap to propagate nodump */
+ if ((ip->di_mode & IFMT) == IFDIR) {
+ SETINO(dp->inode, dumpdirmap);
+ CLRINO(dp->inode, usedinomap);
+ *ret |= HASSUBDIRS;
+ }
+ } else {
+ if (TSTINO(dp->inode, dumpinomap)) {
+ *ret |= HASDUMPEDFILE;
+ if (*ret & HASSUBDIRS)
+ return DIRENT_ABORT;
+ }
+ if (TSTINO(dp->inode, dumpdirmap)) {
+ *ret |= HASSUBDIRS;
+ if (*ret & HASDUMPEDFILE)
+ return DIRENT_ABORT;
+ }
+ }
+ return 0;
+}
+
+#else /* __linux__ */
+
+static int
+searchdir(dump_ino_t ino, daddr_t blkno, long size, long filesize)
+{
+ struct direct *dp;
+ long loc, ret = 0;
+ char dblk[MAXBSIZE];
+
+ bread(fsbtodb(sblock, blkno), dblk, (int)size);
+ if (filesize < size)
+ size = filesize;
+ for (loc = 0; loc < size; ) {
+ dp = (struct direct *)(dblk + loc);
+ if (dp->d_reclen == 0) {
+ msg("corrupted directory, inumber %d\n", ino);
+ break;
+ }
+ loc += dp->d_reclen;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_name[0] == '.') {
+ if (dp->d_name[1] == '\0')
+ continue;
+ if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
+ continue;
+ }
+ if (TSTINO(dp->d_ino, dumpinomap)) {
+ ret |= HASDUMPEDFILE;
+ if (ret & HASSUBDIRS)
+ break;
+ }
+ if (TSTINO(dp->d_ino, dumpdirmap)) {
+ ret |= HASSUBDIRS;
+ if (ret & HASDUMPEDFILE)
+ break;
+ }
+ }
+ return (ret);
+}
+#endif /* __linux__ */
+
+#ifdef __linux__
+
+struct block_context {
+ ext2_ino_t ino;
+ int *buf;
+ int cnt;
+ int max;
+ int next_block;
+};
+
+/*
+ * Dump a block to the tape
+ */
+static int
+dumponeblock(UNUSED(ext2_filsys fs), blk_t *blocknr, e2_blkcnt_t blockcnt,
+ UNUSED(blk_t ref_block), UNUSED(int ref_offset), void * private)
+{
+ struct block_context *p;
+ e2_blkcnt_t i;
+
+ if (blockcnt < NDADDR)
+ return 0;
+ p = (struct block_context *)private;
+ for (i = p->next_block; i < blockcnt; i++) {
+ p->buf[p->cnt++] = 0;
+ if (p->cnt == p->max) {
+ blksout (p->buf, p->cnt, p->ino);
+ p->cnt = 0;
+ }
+ }
+ p->buf[p->cnt++] = *blocknr;
+ if (p->cnt == p->max) {
+ blksout (p->buf, p->cnt, p->ino);
+ p->cnt = 0;
+ }
+ p->next_block = blockcnt + 1;
+ return 0;
+}
+#endif
+
+/*
+ * Dump passes 3 and 4.
+ *
+ * Dump the contents of an inode to tape.
+ */
+void
+dumpino(struct dinode *dp, dump_ino_t ino, int metaonly)
+{
+ unsigned long cnt;
+ fsizeT size, remaining;
+ char buf[TP_BSIZE];
+ struct new_bsd_inode nbi;
+ int i;
+#ifdef __linux__
+ struct block_context bc;
+#else
+ int ind_level;
+#endif
+ u_quad_t i_size;
+
+ if (metaonly)
+ i_size = 0;
+ else
+ i_size = dp->di_size + ((u_quad_t) dp->di_size_high << 32);
+
+ if (newtape) {
+ newtape = 0;
+ dumpmap(dumpinomap, TS_BITS, ino);
+ }
+ CLRINO(ino, dumpinomap);
+#ifdef __linux__
+ memset(&nbi, 0, sizeof(nbi));
+ nbi.di_mode = dp->di_mode;
+ nbi.di_nlink = dp->di_nlink;
+ nbi.di_ouid = dp->di_uid;
+ nbi.di_ogid = dp->di_gid;
+ nbi.di_size = i_size;
+ nbi.di_atime.tv_sec = dp->di_atime;
+ nbi.di_mtime.tv_sec = dp->di_mtime;
+ nbi.di_ctime.tv_sec = dp->di_ctime;
+ memmove(&nbi.di_db, &dp->di_db, (NDADDR + NIADDR) * sizeof(daddr_t));
+ nbi.di_flags = dp->di_flags;
+ nbi.di_blocks = dp->di_blocks;
+ nbi.di_gen = dp->di_gen;
+ nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid;
+ nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid;
+ if (dp->di_file_acl)
+ msg("ACLs in inode #%ld won't be dumped\n", (long)ino);
+ memmove(&spcl.c_dinode, &nbi, sizeof(nbi));
+#else /* __linux__ */
+ spcl.c_dinode = *dp;
+#endif /* __linux__ */
+ spcl.c_type = TS_INODE;
+ spcl.c_count = 0;
+
+ if (metaonly && (dp->di_mode & S_IFMT)) {
+ spcl.c_flags |= DR_METAONLY;
+ spcl.c_count = 0;
+ writeheader(ino);
+ spcl.c_flags &= ~DR_METAONLY;
+ return;
+ }
+
+ switch (dp->di_mode & S_IFMT) {
+
+ case 0:
+ /*
+ * Freed inode.
+ */
+ return;
+
+#ifdef __linux__
+ case S_IFDIR:
+ msg("Warning: dumpino called on a directory (ino %d)\n", ino);
+ return;
+#endif
+
+ case S_IFLNK:
+ /*
+ * Check for short symbolic link.
+ */
+#ifdef __linux__
+ if (i_size > 0 &&
+ i_size < EXT2_N_BLOCKS * sizeof (daddr_t)) {
+ spcl.c_addr[0] = 1;
+ spcl.c_count = 1;
+ writeheader(ino);
+ memmove(buf, dp->di_db, (u_long)dp->di_size);
+ buf[dp->di_size] = '\0';
+ writerec(buf, 0);
+ return;
+ }
+#endif /* __linux__ */
+#ifdef FS_44INODEFMT
+ if (dp->di_size > 0 &&
+ dp->di_size < sblock->fs_maxsymlinklen) {
+ spcl.c_addr[0] = 1;
+ spcl.c_count = 1;
+ writeheader(ino);
+ memmove(buf, dp->di_shortlink, (u_long)dp->di_size);
+ buf[dp->di_size] = '\0';
+ writerec(buf, 0);
+ return;
+ }
+#endif
+ /* fall through */
+
+#ifndef __linux__
+ case S_IFDIR:
+#endif
+ case S_IFREG:
+ if (i_size)
+ break;
+ /* fall through */
+
+ case S_IFIFO:
+ case S_IFSOCK:
+ case S_IFCHR:
+ case S_IFBLK:
+ writeheader(ino);
+ return;
+
+ default:
+ msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT);
+ return;
+ }
+ if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize)
+#ifdef __linux__
+ cnt = NDADDR * EXT2_FRAGS_PER_BLOCK(fs->super);
+#else
+ cnt = NDADDR * sblock->fs_frag;
+#endif
+ else
+ cnt = howmany(i_size, sblock->fs_fsize);
+ blksout(&dp->di_db[0], cnt, ino);
+ if ((quad_t) (size = i_size - NDADDR * sblock->fs_bsize) <= 0)
+ return;
+#ifdef __linux__
+ bc.max = NINDIR(sblock) * EXT2_FRAGS_PER_BLOCK(fs->super);
+ bc.buf = (int *)malloc (bc.max * sizeof (int));
+ bc.cnt = 0;
+ bc.ino = ino;
+ bc.next_block = NDADDR;
+
+ ext2fs_block_iterate2(fs, (ext2_ino_t)ino, 0, NULL, dumponeblock, (void *)&bc);
+ /* deal with holes at the end of the inode */
+ if (i_size > ((u_quad_t)bc.next_block) * sblock->fs_fsize) {
+ remaining = i_size - ((u_quad_t)bc.next_block) * sblock->fs_fsize;
+ for (i = 0; i < (int)howmany(remaining, sblock->fs_fsize); i++) {
+ bc.buf[bc.cnt++] = 0;
+ if (bc.cnt == bc.max) {
+ blksout (bc.buf, bc.cnt, bc.ino);
+ bc.cnt = 0;
+ }
+ }
+ }
+ if (bc.cnt > 0) {
+ blksout (bc.buf, bc.cnt, bc.ino);
+ }
+ free(bc.buf);
+#else
+ for (ind_level = 0; ind_level < NIADDR; ind_level++) {
+ dmpindir(ino, dp->di_ib[ind_level], ind_level, &size);
+ if (size <= 0)
+ return;
+ }
+#endif
+}
+
+#ifdef __linux__
+
+struct convert_dir_context {
+ char *buf;
+ int prev_offset;
+ int offset;
+ int bs;
+};
+
+/*
+ * This function converts an ext2fs directory entry to the BSD format.
+ *
+ * Basically, it adds a null-character at the end of the name, recomputes the
+ * size of the entry, and creates it in a temporary buffer
+ */
+static int
+convert_dir(struct ext2_dir_entry *dirent, UNUSED(int offset),
+ UNUSED(int blocksize), UNUSED(char *buf), void *private)
+{
+ struct convert_dir_context *p;
+ struct direct *dp;
+ int reclen;
+
+ p = (struct convert_dir_context *)private;
+
+ reclen = EXT2_DIR_REC_LEN((dirent->name_len & 0xFF) + 1);
+ if (((p->offset + reclen - 1) / p->bs) != (p->offset / p->bs)) {
+ dp = (struct direct *)(p->buf + p->prev_offset);
+ dp->d_reclen += p->bs - (p->offset % p->bs);
+ p->offset += p->bs - (p->offset % p->bs);
+ }
+
+ dp = (struct direct *)(p->buf + p->offset);
+ dp->d_ino = dirent->inode;
+ dp->d_reclen = reclen;
+ dp->d_namlen = dirent->name_len & 0xFF;
+ switch ((dirent->name_len & 0xFF00) >> 8) {
+ default:
+ dp->d_type = DT_UNKNOWN;
+ break;
+ case EXT2_FT_REG_FILE:
+ dp->d_type = DT_REG;
+ break;
+ case EXT2_FT_DIR:
+ dp->d_type = DT_DIR;
+ break;
+ case EXT2_FT_CHRDEV:
+ dp->d_type = DT_CHR;
+ break;
+ case EXT2_FT_BLKDEV:
+ dp->d_type = DT_BLK;
+ break;
+ case EXT2_FT_FIFO:
+ dp->d_type = DT_FIFO;
+ break;
+ case EXT2_FT_SOCK:
+ dp->d_type = DT_SOCK;
+ break;
+ case EXT2_FT_SYMLINK:
+ dp->d_type = DT_LNK;
+ break;
+ }
+ strncpy(dp->d_name, dirent->name, dp->d_namlen);
+ dp->d_name[dp->d_namlen] = '\0';
+ p->prev_offset = p->offset;
+ p->offset += reclen;
+
+ return 0;
+}
+
+/*
+ * Dump pass 3
+ *
+ * Dumps a directory to tape after converting it to the BSD format
+ */
+void
+dumpdirino(struct dinode *dp, dump_ino_t ino)
+{
+ fsizeT size;
+ char buf[TP_BSIZE];
+ struct new_bsd_inode nbi;
+ struct convert_dir_context cdc;
+ errcode_t retval;
+ struct ext2_dir_entry *de;
+ fsizeT dir_size;
+
+ if (newtape) {
+ newtape = 0;
+ dumpmap(dumpinomap, TS_BITS, ino);
+ }
+ CLRINO(ino, dumpinomap);
+
+ /*
+ * Convert the directory to the BSD format
+ */
+ /* Allocate a buffer for the conversion (twice the size of the
+ ext2fs directory to avoid problems ;-) */
+ cdc.buf = (char *)malloc(dp->di_size * 2 * sizeof(char));
+ if (cdc.buf == NULL)
+ err(1, "Cannot allocate buffer to convert directory #%lu\n",
+ (unsigned long)ino);
+ cdc.offset = 0;
+ cdc.prev_offset = 0;
+ cdc.bs = MIN(DIRBLKSIZ, TP_BSIZE);
+ /* Do the conversion */
+ retval = ext2fs_dir_iterate(fs, (ext2_ino_t)ino, 0, NULL, convert_dir, (void *)&cdc);
+ if (retval) {
+ com_err(disk, retval, "while converting directory #%ld\n", (long)ino);
+ exit(X_ABORT);
+ }
+ /* Fix the last entry */
+ if ((cdc.offset % cdc.bs) != 0) {
+ de = (struct ext2_dir_entry *)(cdc.buf + cdc.prev_offset);
+ de->rec_len += cdc.bs - (cdc.offset % cdc.bs);
+ cdc.offset += cdc.bs - (cdc.offset % cdc.bs);
+ }
+
+ dir_size = cdc.offset;
+
+#ifdef __linux__
+ memset(&nbi, 0, sizeof(nbi));
+ nbi.di_mode = dp->di_mode;
+ nbi.di_nlink = dp->di_nlink;
+ nbi.di_ouid = dp->di_uid;
+ nbi.di_ogid = dp->di_gid;
+ nbi.di_size = dir_size; /* (u_quad_t)dp->di_size; */
+ nbi.di_atime.tv_sec = dp->di_atime;
+ nbi.di_mtime.tv_sec = dp->di_mtime;
+ nbi.di_ctime.tv_sec = dp->di_ctime;
+ memmove(&nbi.di_db, &dp->di_db, (NDADDR + NIADDR) * sizeof(daddr_t));
+ nbi.di_flags = dp->di_flags;
+ nbi.di_blocks = dp->di_blocks;
+ nbi.di_gen = dp->di_gen;
+ nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid;
+ nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid;
+ if (dp->di_file_acl)
+ msg("ACLs in inode #%ld won't be dumped\n", (long)ino);
+ memmove(&spcl.c_dinode, &nbi, sizeof(nbi));
+#else /* __linux__ */
+ spcl.c_dinode = *dp;
+#endif /* __linux__ */
+ spcl.c_type = TS_INODE;
+ spcl.c_count = 0;
+ switch (dp->di_mode & S_IFMT) {
+
+ case 0:
+ /*
+ * Freed inode.
+ */
+ return;
+
+ case S_IFDIR:
+ if (dir_size > 0)
+ break;
+ msg("Warning: size of directory inode #%d is <= 0 (%d)!\n",
+ ino, dir_size);
+ return;
+
+ default:
+ msg("Warning: dumpdirino called with file type 0%o (inode #%d)\n",
+ dp->di_mode & IFMT, ino);
+ return;
+ }
+ for (size = 0; size < dir_size; size += TP_BSIZE) {
+ spcl.c_addr[0] = 1;
+ spcl.c_count = 1;
+ writeheader(ino);
+ memmove(buf, cdc.buf + size, TP_BSIZE);
+ writerec(buf, 0);
+ spcl.c_type = TS_ADDR;
+ }
+
+ (void)free(cdc.buf);
+}
+#endif /* __linux__ */
+
+#ifndef __linux__
+/*
+ * Read indirect blocks, and pass the data blocks to be dumped.
+ */
+static void
+dmpindir(dump_ino_t ino, daddr_t blk, int ind_level, fsizeT *size)
+{
+ int i, cnt;
+#ifdef __linux__
+ int max;
+ blk_t *swapme;
+#endif
+ daddr_t idblk[MAXNINDIR];
+
+ if (blk != 0) {
+ bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize);
+#ifdef __linux__
+ /*
+ * My RedHat 4.0 system doesn't have these flags; I haven't
+ * upgraded e2fsprogs yet
+ */
+#if defined(EXT2_FLAG_SWAP_BYTES)
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+#endif
+ {
+ max = sblock->fs_bsize >> 2;
+ swapme = (blk_t *) idblk;
+ for (i = 0; i < max; i++, swapme++)
+ *swapme = ext2fs_swab32(*swapme);
+ }
+#endif /* __linux__ */
+ else
+ memset(idblk, 0, (int)sblock->fs_bsize);
+ if (ind_level <= 0) {
+ if (*size < NINDIR(sblock) * sblock->fs_bsize)
+ cnt = howmany(*size, sblock->fs_fsize);
+ else
+#ifdef __linux__
+ cnt = NINDIR(sblock) * EXT2_FRAGS_PER_BLOCK(fs->super);
+#else
+ cnt = NINDIR(sblock) * sblock->fs_frag;
+#endif
+ *size -= NINDIR(sblock) * sblock->fs_bsize;
+ blksout(&idblk[0], cnt, ino);
+ return;
+ }
+ ind_level--;
+ for (i = 0; i < NINDIR(sblock); i++) {
+ dmpindir(ino, idblk[i], ind_level, size);
+ if (*size <= 0)
+ return;
+ }
+}
+#endif
+
+/*
+ * Collect up the data into tape record sized buffers and output them.
+ */
+void
+blksout(blk_t *blkp, int frags, dump_ino_t ino)
+{
+ blk_t *bp;
+ int i, j, count, blks, tbperdb;
+
+ blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
+ tbperdb = sblock->fs_bsize >> tp_bshift;
+ for (i = 0; i < blks; i += TP_NINDIR) {
+ if (i + TP_NINDIR > blks)
+ count = blks;
+ else
+ count = i + TP_NINDIR;
+ for (j = i; j < count; j++)
+ if (blkp[j / tbperdb] != 0)
+ spcl.c_addr[j - i] = 1;
+ else
+ spcl.c_addr[j - i] = 0;
+ spcl.c_count = count - i;
+ writeheader(ino);
+ bp = &blkp[i / tbperdb];
+ for (j = i; j < count; j += tbperdb, bp++) {
+ if (*bp != 0) {
+ if (j + tbperdb <= count)
+ dumpblock(*bp, (int)sblock->fs_bsize);
+ else
+ dumpblock(*bp, (count - j) * TP_BSIZE);
+ }
+ }
+ spcl.c_type = TS_ADDR;
+ }
+}
+
+/*
+ * Dump a map to the tape.
+ */
+void
+dumpmap(char *map, int type, dump_ino_t ino)
+{
+ int i;
+ char *cp;
+
+ spcl.c_type = type;
+ spcl.c_count = howmany(mapsize * sizeof(char), TP_BSIZE);
+ writeheader(ino);
+ for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
+ writerec(cp, 0);
+}
+
+#if defined(__linux__) && !defined(int32_t)
+#define int32_t __s32
+#endif
+
+/*
+ * Compute and fill in checksum information.
+ */
+void
+mkchecksum(union u_spcl *tmpspcl)
+{
+ int32_t sum, cnt, *lp;
+
+ tmpspcl->s_spcl.c_checksum = 0;
+ lp = (int32_t *)&tmpspcl->s_spcl;
+ sum = 0;
+ cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t));
+ while (--cnt >= 0) {
+ sum += *lp++;
+ sum += *lp++;
+ sum += *lp++;
+ sum += *lp++;
+ }
+ tmpspcl->s_spcl.c_checksum = CHECKSUM - sum;
+}
+
+/*
+ * Write a header record to the dump tape.
+ */
+void
+writeheader(dump_ino_t ino)
+{
+ spcl.c_inumber = ino;
+ spcl.c_magic = NFS_MAGIC;
+ mkchecksum((union u_spcl *)&spcl);
+ writerec((char *)&spcl, 1);
+}
+
+#ifdef __linux__
+struct dinode *
+getino(dump_ino_t inum)
+{
+ static struct dinode dinode;
+ errcode_t err;
+
+ curino = inum;
+ err = ext2fs_read_inode(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode);
+ if (err) {
+ com_err(disk, err, "while reading inode #%ld\n", (long)inum);
+ exit(X_ABORT);
+ }
+ return &dinode;
+}
+#else /* __linux__ */
+struct dinode *
+getino(dump_ino_t inum)
+{
+ static daddr_t minino, maxino;
+ static struct dinode inoblock[MAXINOPB];
+
+ curino = inum;
+ if (inum >= minino && inum < maxino)
+ return (&inoblock[inum - minino]);
+ bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock,
+ (int)sblock->fs_bsize);
+ minino = inum - (inum % INOPB(sblock));
+ maxino = minino + INOPB(sblock);
+ return (&inoblock[inum - minino]);
+}
+#endif /* __linux__ */
+
+/*
+ * Read a chunk of data from the disk.
+ * Try to recover from hard errors by reading in sector sized pieces.
+ * Error recovery is attempted at most BREADEMAX times before seeking
+ * consent from the operator to continue.
+ */
+int breaderrors = 0;
+
+void
+bread(ext2_loff_t blkno, char *buf, int size)
+{
+ int cnt, i;
+
+loop:
+#ifdef __linux__
+ if (ext2fs_llseek(diskfd, (blkno << dev_bshift), 0) !=
+ (blkno << dev_bshift))
+#else
+ if (lseek(diskfd, ((off_t)blkno << dev_bshift), 0) !=
+ ((off_t)blkno << dev_bshift))
+#endif
+ msg("bread: lseek fails\n");
+ if ((cnt = read(diskfd, buf, size)) == size)
+ return;
+ if (blkno + (size / dev_bsize) > fsbtodb(sblock, sblock->fs_size)) {
+ /*
+ * Trying to read the final fragment.
+ *
+ * NB - dump only works in TP_BSIZE blocks, hence
+ * rounds `dev_bsize' fragments up to TP_BSIZE pieces.
+ * It should be smarter about not actually trying to
+ * read more than it can get, but for the time being
+ * we punt and scale back the read only when it gets
+ * us into trouble. (mkm 9/25/83)
+ */
+ size -= dev_bsize;
+ goto loop;
+ }
+ if (cnt == -1)
+ msg("read error from %s: %s: [block %d, ext2blk %d]: count=%d\n",
+ disk, strerror(errno), blkno,
+ dbtofsb(sblock, blkno), size);
+ else
+ msg("short read error from %s: [block %d, ext2blk %d]: count=%d, got=%d\n",
+ disk, blkno, dbtofsb(sblock, blkno), size, cnt);
+ if (breademax && ++breaderrors > breademax) {
+ msg("More than %d block read errors from %d\n",
+ breademax, disk);
+ broadcast("DUMP IS AILING!\n");
+ msg("This is an unrecoverable error.\n");
+ if (!query("Do you want to attempt to continue?")){
+ dumpabort(0);
+ /*NOTREACHED*/
+ } else
+ breaderrors = 0;
+ }
+ /*
+ * Zero buffer, then try to read each sector of buffer separately.
+ */
+ memset(buf, 0, size);
+ for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) {
+#ifdef __linux__
+ if (ext2fs_llseek(diskfd, (blkno << dev_bshift), 0) !=
+ (blkno << dev_bshift))
+#else
+ if (lseek(diskfd, ((off_t)blkno << dev_bshift), 0) !=
+ ((off_t)blkno << dev_bshift))
+#endif
+ msg("bread: lseek2 fails!\n");
+ if ((cnt = read(diskfd, buf, (int)dev_bsize)) == dev_bsize)
+ continue;
+ if (cnt == -1) {
+ msg("read error from %s: %s: [sector %d, ext2blk %d]: count=%d\n",
+ disk, strerror(errno), blkno,
+ dbtofsb(sblock, blkno), dev_bsize);
+ continue;
+ }
+ msg("short read error from %s: [sector %d, ext2blk %d]: count=%d, got=%d\n",
+ disk, blkno, dbtofsb(sblock, blkno), dev_bsize, cnt);
+ }
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: unctime.c,v 1.16 2003/03/30 15:40:37 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/time.h>
+#include <time.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <sys/param.h>
+#include <stdio.h>
+
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#endif
+
+#include "dump.h"
+
+/*
+ * Convert a ctime(3) format string into a system format date.
+ * Return the date thus calculated.
+ *
+ * Return -1 if the string is not in ctime format.
+ */
+
+/*
+ * Offsets into the ctime string to various parts.
+ */
+
+#define E_MONTH 4
+#define E_DAY 8
+#define E_HOUR 11
+#define E_MINUTE 14
+#define E_SECOND 17
+#define E_YEAR 20
+#define E_TZOFFSET 25
+
+static int lookup __P((const char *));
+
+
+time_t
+unctime(const char *str)
+{
+ struct tm then;
+ char dbuf[32];
+ time_t rtime;
+ int tzoffset;
+
+ (void) strncpy(dbuf, str, sizeof(dbuf) - 1);
+ dbuf[sizeof(dbuf) - 1] = '\0';
+ dbuf[E_MONTH+3] = '\0';
+ if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
+ return (-1);
+ then.tm_mday = atoi(&dbuf[E_DAY]);
+ then.tm_hour = atoi(&dbuf[E_HOUR]);
+ then.tm_min = atoi(&dbuf[E_MINUTE]);
+ then.tm_sec = atoi(&dbuf[E_SECOND]);
+ then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
+ then.tm_isdst = -1;
+ if (strlen(str) >= E_TZOFFSET+5) {
+ rtime = timegm(&then);
+ /* add timezone offset */
+ tzoffset = atoi(&dbuf[E_TZOFFSET]);
+ rtime -= (tzoffset / 100 * 3600) + (tzoffset % 100) * 60;
+ } else {
+ rtime = timelocal(&then);
+ }
+ return(rtime);
+}
+
+static char months[] =
+ "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+static int
+lookup(const char *str)
+{
+ const char *cp, *cp2;
+
+ for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
+ if (strncmp(cp, cp2, 3) == 0)
+ return((cp-months) / 3);
+ return(-1);
+}
--- /dev/null
+Here is how to use these backup scripts:
+
+1. Create a separate backup partition big enough to hold all the filesystems you want to backup + any changes. Preferably, get a big inexpensive ide drive, and dedicate it as a backup drive.
+
+2. Create the mount point for the partition as /backup (otherwise, modify the config parameters at the top of the scripts).
+
+3. Mount the partition read-write, cd into /backup, and extract the backupskel.tar.gz there. This will create the directory structure needed by the scripts.
+
+4. Set the partition to be mounted as read-only in your /etc/fstab. This will protect your precious backup from software crashes.
+
+5. Copy the backup scripts "backup" and "backup_rotate" to a suitable directory in cron's path; "/usr/bin" is a good location. alternatively, you can place them anywhere, and modify the crontab entries to match, or run it manually.
+
+6. Modify your /etc/crontab file to add these entries, and be sure to modify the times to suit your preferences, and the performance of your machine:
+
+----------%<---------------------------------%<--------------------------------
+
+# Perform Nightly Backup (nightly incremental + weekly full + monthly full)
+02 06 * * 1-6 root backup_rotate ; nice -1 backup inc
+02 06 * * sun root backup_rotate ; nice -1 backup full
+07 00 01 * * root backup_rotate monthly ; backup full nodumpdate
+
+----------%<---------------------------------%<--------------------------------
+
+Any questions? Send me and email to getnito@yahoo.com.
+
+And that is it. Have fun!
+
+--
+nito
+
+getnito@yahoo.com
--- /dev/null
+#!/bin/bash
+#
+# This script will make a simple backup of the most critical partitions,
+# using the "dump" facility, into the backup partition. It will stop the
+# webserver, and recurse the sites directories making a tar mini-backup of
+# the database dirs. It will the restart the webserver, and start the
+# "dump" backup.
+#
+
+if [ "$2" = "nodumpdate" ]; then
+ UPDATEDDATE=""
+else
+ UPDATEDDATE="-u"
+fi
+
+if [ "$1" = "full" ]; then
+ DLEVEL="0"
+ BTYPE="full"
+elif [ "$1" = "inc" ]; then
+ DLEVEL="1"
+ BTYPE="inc"
+else
+ echo "Usage: $0 full|inc [nodumpdate]"
+ exit 1
+fi
+
+
+#
+# Configuration Parameters
+#
+
+BACKUPPART="/backup"
+BACKUPDIR="current"
+DUMPLOGARCH="$BACKUPPART/backup.dump.log.gz"
+FSTODUMP="/ /var /home /mnt/hdb1 /usr"
+DUMPFILESMODE="0644"
+DUMPFILESOWN="root.root"
+
+#
+# Start
+#
+
+echo
+echo "#####################################################################"
+echo "Starting backup."
+echo "#####################################################################"
+echo
+
+
+#
+# Make full system backup
+#
+
+echo "Phase 1: ### Full System Dump Backup ###"
+echo "Phase 1: Using backup partition: $BACKUPPART"
+echo "Phase 1: Filesystems to dump: $FSTODUMP"
+
+echo -n "Phase 1: Remounting backup partition read-write ... "
+if ( mount $BACKUPPART -o remount,rw &> /dev/null ) then
+ echo "done."
+else
+ echo "failure!"
+ echo "Phase 1: There were problems remounting $BACKUPPART in read-write mode!"
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+fi
+
+echo -n "Phase 1: Checking backup partition for correct dir structure ... "
+if [ -d $BACKUPPART/$BACKUPDIR -a -w $BACKUPPART/$BACKUPDIR ]; then
+ echo "done."
+
+ echo -n "Phase 1: Checking backup partition for available space ... "
+ SREQ=`for i in $FSTODUMP;do dump -$DLEVEL -S $i 2> /dev/null;done|awk '{x=x+$1/1048576} END {printf "%6.0f\n", x}'`
+ SAVAILFREE=`df --block-size=1048576 |grep -Ew $BACKUPPART|awk '{printf "%6.0f\n", $4}'`
+ SAVAILDEL=`du -s --block-size=1048576 $BACKUPPART/$BACKUPDIR/. |awk '{printf "%6.0f\n", $1}'`
+ SAVAIL=`expr $SAVAILFREE + $SAVAILDEL`
+
+ if [ `expr $SAVAIL - $SREQ` -gt "0" ]; then
+ echo "done."
+ echo "Phase 1: Available: $SAVAIL MB Required: $SREQ MB."
+ else
+ echo "no enough space!"
+ echo "Phase 1: There is not enough space left in $BACKUPPART for the backup!"
+ echo "Phase 1: Available: $SAVAIL MB Required: $SREQ MB."
+ echo -n "Phase 1: Remounting backup partition read-only ... "
+ if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+ else
+ echo "failure!"
+ echo "Phase 1: There were problems remounting $BACKUPPART in read-only mode!"
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+ fi
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+ fi
+
+ echo -n "Phase 1: Deleting old files ... "
+ if [ `ls -la $BACKUPPART/$BACKUPDIR/|wc -l` -gt "3" ]; then
+ rm -f $BACKUPPART/$BACKUPDIR/* &> /dev/null
+ echo "done."
+ else
+ echo "no old files to delete."
+ fi
+
+ echo "Phase 1: Dumping filesystems ... "
+ for FS in $FSTODUMP
+ do
+ if [ "$FS" = "/" ]; then
+ FSNAME="root"
+ else
+ FSNAME=`echo $FS|tr / _|cut -b 2-`
+ fi
+ sync
+ echo -n "Phase 1: Starting dump of $FSNAME ( $FS ) ... "
+ if ( dump -$DLEVEL $UPDATEDDATE -z -M -s 27306 -f $BACKUPPART/$BACKUPDIR/$FSNAME.$BTYPE. $FS &> $BACKUPPART/$BACKUPDIR/$FSNAME.log ) then
+ echo "done."
+ else
+ echo "problems!"
+ echo "Phase 1: There where problems with the dump of $FSNAME ( $FS )."
+ echo "Phase 1: Check logfile $BACKUPPART/$BACKUPDIR/$FSNAME.log for more info"
+ echo "Phase 1: Also check log archive file $DUMPLOGARCH."
+ fi
+ cat $BACKUPPART/$BACKUPDIR/$FSNAME.log |gzip >> $DUMPLOGARCH
+ echo "-------------------------------------------------------------------------------" |gzip >> $DUMPLOGARCH
+ done
+
+ echo -n "Phase 1: Setting ownership and permissions of dump files ... "
+ chmod $DUMPFILESMODE $BACKUPPART/$BACKUPDIR/* $DUMPLOGARCH &> /dev/null
+ chown $DUMPFILESOWN $BACKUPPART/$BACKUPDIR/* $DUMPLOGARCH &> /dev/null
+ echo "done."
+
+ echo -n "Phase 1: Compressing dump log files ... "
+ gzip $BACKUPPART/$BACKUPDIR/*.log &> /dev/null
+ echo "done."
+ sync
+
+else
+ echo "problems!"
+ echo "Phase 1: There are problems with the directory structure."
+ echo "Phase 1: Check dirs: $BACKUPPART/$BACKUPDIR"
+ echo -n "Phase 1: Remounting backup partition read-only ... "
+ if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+ else
+ echo "failure!"
+ echo "Phase 1: There were problems remounting $BACKUPPART in read-only mode!"
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+ fi
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+fi
+
+echo -n "Phase 1: Remounting backup partition read-only ... "
+if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+else
+ echo "failure!"
+ echo "Phase 1: There were problems remounting $BACKUPPART in read-only mode!"
+ echo "Phase 1: Aborting Full System Dump Backup."
+ echo "Phase 1: Aborted, done."
+ echo "-------------------------------------------------------------------------------"
+ exit 1
+fi
+
+echo "Phase 1: End of Full System Dump Backup."
+echo "Phase 1: Done."
+echo "-------------------------------------------------------------------------------"
--- /dev/null
+#!/bin/bash
+#
+# This script will redirect the backup directory to implement desired backup
+# schedules.
+#
+# Currently we will use just a seven day format were we just move a link
+# that represents the backup directory, to point to the day of the week.
+#
+
+#
+# Configuration Parameters
+#
+
+if [ "$1" = "monthly" ]; then
+ REALDIR="monthly"
+else
+ REALDIR=`date +%A`
+fi
+
+BACKUPPART="/backup"
+BACKUPDIR="current"
+
+echo "### Start of Backup Rotation ###"
+echo "Using backup partition: $BACKUPPART"
+
+echo -n "Remounting backup partition read-write ... "
+if ( mount $BACKUPPART -o remount,rw &> /dev/null ) then
+ echo "done."
+else
+ echo "failure!"
+ echo " There were problems remounting $BACKUPPART in read-write mode!"
+ echo "Rotation not made!"
+ echo "### End of Backup Rotation ###"
+ exit 1
+fi
+
+echo -n "Checking that no directory named \"$BACKUPDIR\" exists ... "
+if [ -d $BACKUPPART/$BACKUPDIR -a ! -L $BACKUPPART/$BACKUPDIR ]; then
+ echo "failure!"
+ echo " Directory \"$BACKUPDIR\" exists. Can't create link!"
+ echo "Rotation not made!"
+
+ echo -n "Remounting backup partition read-only ... "
+ if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+ else
+ echo "failure!"
+ echo " There were problems remounting $BACKUPPART in read-only mode!"
+ echo "### End of Backup Rotation ###"
+ exit 1
+ fi
+ echo "### End of Backup Rotation ###"
+ exit 1
+else
+ echo "done."
+fi
+
+cd $BACKUPPART
+
+echo -n "Creating link: $BACKUPDIR --> $REALDIR ... "
+if ( ln -snf $REALDIR $BACKUPDIR &> /dev/null ) then
+ echo "done."
+else
+ echo "failure!"
+ echo " There were problems creating link!"
+ echo "Rotation not made!"
+
+ echo -n "Remounting backup partition read-only ... "
+ if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+ else
+ echo "failure!"
+ echo " There were problems remounting $BACKUPPART in read-only mode!"
+ echo "### End of Backup Rotation ###"
+ exit 1
+ fi
+ echo "### End of Backup Rotation ###"
+ exit 1
+fi
+
+echo -n "Remounting backup partition read-only ... "
+if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then
+ echo "done."
+else
+ echo "failure!"
+ echo " There were problems remounting $BACKUPPART in read-only mode!"
+ echo "### End of Backup Rotation ###"
+ exit 1
+fi
+echo "### End of Backup Rotation ###"
--- /dev/null
+# Perform Nightly Backup (nightly incremental + weekly full + monthly full)
+02 06 * * 1-6 root backup_rotate ; nice -1 backup inc
+02 06 * * sun root backup_rotate ; nice -1 backup full
+07 00 01 * * root backup_rotate monthly ; backup full nodumpdate
--- /dev/null
+ Experimental dump to CDROMs
+ ===========================
+
+Starting with dump/restore version 0.4b24 or later versions of
+dump/restore you can dump to CDROMs.
+
+You need a (successfully installed) CD-writing software like
+ cdrecord (tested with versions 1.11a04 onwards)
+
+These scripts use the new switch ('V') to restore
+which signals a multi-volume (non-tape) medium like CDROMs
+
+I have used the shell scripts below to generate/verify the dump
+
+YOU MUST MODIFY these - especially
+
+- adapt FS to the filesystem to be dumped
+- UserExit to the path to the user exit function like UserInfo below
+- FiFo to the path to a named pipe (better not on the same filesystem)
+- your cd device(s) ( I have /dev/cdrom a symlink to /dev/sr0 and
+ /dev/cdrw a symlink to /dev/sr1 )
+- your path to cdrecord and
+- - cdrecord's dev parameter must be adapted to your CD burner
+- - cdrecord's fs (= input fifo size), use less than 64m if you
+ are short of memory
+- - cdrecord's speed parameter : this parameter not only depends on the
+ capabilities of your CD burner BUT also on the speed of your CPU !!!
+ With the dump -z6 compression on a 900 MHz Pentium III I had no problems
+ with speed=4 which is the maximum speed for my burner.
+ It looks as if at least speed=6 would be possible on a 900 MHz Pentium III.
+ If speed is to large, cdrecord's input fifo gets empty (as
+ shown by cdrecord) and then you have a buffer underrun.
+
+- replace the wayplay command with something which alerts you if you
+ have to change CDROMS
+
+- for restore or verification replace /dev/cdrom by something
+ which applies for you (device for the CDreader)
+
+
+DON'T FORGET to generate a boot-CD which has the 0.4b24 restore
+ or a newer version of restore on board
+
+I prefer timos_Rescue_Cd_Set-0.6.1 see http://rescuecd.sourceforge.net
+
+
+Please Cc bug-reports to jarausch@igpm.rwth-aachen.de
+
+-----------------------------------------------------------------
+This file and the scripts were slightly edited when the
+Helmut Jarausch patch was integrated in dump-0.4b24.
+ Stelian.
+
--- /dev/null
+#!/bin/bash
+# $1 = filename
+# $2 = sequence number
+
+wavplay -q /root/alert.wav
+num=$[$2+1]
+echo "insert next CD (number $num) "
+read -p "CD number $num ready? " Ans
+
+xterm -hold -T cdrecord_$num -e \
+ /usr/local/bin/cdrecord dev=0,1,0 fs=64m \
+ -v speed=4 -eject -pad -data $1 &
--- /dev/null
+#!/bin/bash
+if [ `id -u` != 0 ]; then
+ echo "root priviledges are required"
+ exit 1
+fi
+Level=0
+Label=`date -I`
+#CD_Cap=650
+CD_Cap=700
+eval Cap=$(($CD_Cap*1024))
+FS=/
+UserExit=/root/dump_userinfo.sh
+FiFo=/tmp/dump.fifo
+rm -f $FiFo
+mkfifo $FiFo
+xterm -T cdrecord_1 -hold -e cdrecord dev=0,1,0 fs=64m \
+ -v speed=4 -eject -pad -data $FiFo &
+
+/sbin/dump -z6 -b64 -B$Cap -F $UserExit \
+ -$Level -L $Label -f $FiFo $FS
+
+wavplay -q /root/alert.wav
+rm -f $FiFo
+
--- /dev/null
+#!/bin/bash
+
+if [ `id -u` != 0 ]; then
+ echo "root priviledges are required"
+ exit 1
+fi
+cd /
+/sbin/restore -V -b64 -C -f /dev/cdrom
--- /dev/null
+#!/bin/bash
+# This script dumps the specified Filesystem via dump on a CD/DVD
+# CD_CAPACITY defines the capacity in MB per CD
+# The script for the next volume is passed via the -F option of dump
+# !!! do NOT forget to change CD_CAPACITY in $EXITSCRIPT !!!
+COMPRESSION_LEVEL=2
+RECORD_BIN="/usr/bin/cdrecord dev=0,0,0 speed=10 fs=64M -v -dao -eject -pad "
+EXITSCRIPT="/root/bin/cd_dump_userexit"
+FILESYSTEM="/home"
+LEVEL=0
+LABEL="`date -I`"
+# !!! do NOT forget to change CD_CAPACITY in $EXITSCRIPT !!!
+# CD_CAPACITY=650
+CD_CAPACITY=700
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+BSIZE="$(echo "$CD_CAPACITY*1024" | bc -l )"
+FIFO="/tmp/dump.fifo"
+DUMP_BIN="/usr/sbin/dump -z$COMPRESSION_LEVEL -b64 -B$BSIZE -F $EXITSCRIPT -$LEVEL -L $LABEL -f $FIFO $FILESYSTEM"
+
+rm -f $FIFO
+mkfifo $FIFO
+ANSWER=""
+while [ "$ANSWER" != "j" ] ; do
+ read -p "Ist die CD No. 1 eingelegt? (j/n)" ANSWER
+ if [ "$ANSWER" == "j" ] ; then
+ $RECORD_BIN -tsize=$TSIZE -data $FIFO &
+ $DUMP_BIN
+ rm -f $FIFO
+ exit 0
+ else
+ EXIT=""
+ read -p "Wollen Sie abbrechen? (j/n)" EXIT
+ if [ "$EXIT" == "j" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# This script dumps the specified Filesystem via dump on a CD/DVD
+# CD_CAPACITY defines the capacity in MB per CD
+# The script for the next volume is passed via the -F option of dump
+# At least for my DVD-Recorder (a PHILIPS DVR-A03) it is necessary
+# to define the tracksize for the next track before the DVD is written.
+# This is done via the -tsize option of cdrecord. Since tsize takes its
+# arguments in Bytes, the shell cannot compute the value correctly
+# anymore (value too high), so I use bc.
+
+# !!! If you plan to write DVD's with other sizes, please correct the
+# CD_CAPACITY in the dump_userexit_DVD script, too !!!
+
+COMPRESSION_LEVEL=2
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+EXITSCRIPT="/root/bin/dvd_dump_userexit"
+FILESYSTEM="/home"
+LEVEL=0
+LABEL="`date -I`"
+CD_CAPACITY=4300
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+BSIZE="$(echo "$CD_CAPACITY*1024" | bc -l )"
+FIFO="/tmp/dump.fifo"
+DUMP_BIN="/usr/sbin/dump -z$COMPRESSION_LEVEL -b64 -B$BSIZE -F $EXITSCRIPT -$LEVEL -L $LABEL -f $FIFO $FILESYSTEM"
+
+rm -f $FIFO
+mkfifo $FIFO
+ANSWER=""
+while [ "$ANSWER" != "j" ] ; do
+ read -p "Ist die DVD No. 1 eingelegt? (j/n)" ANSWER
+ if [ "$ANSWER" == "j" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -eject -dao -pad -tsize=$TSIZE -data $FIFO &
+ $DUMP_BIN
+ rm -f $FIFO
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Wollen Sie abbrechen? (j/n)" EXIT
+ if [ "$EXIT" == "j" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# supplied info from "dump -F":
+# $1 = filename
+# $2 = sequence number
+
+NUM=$(($2+1))
+RECORD_BIN="/usr/bin/cdrecord speed=10 dev=0,0,0 fs=64M "
+# CD_CAPACITY=700
+# TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+echo -e "Bitte die naechste CD einlegen (No. $NUM)\n"
+ANSWER=""
+while [ "$ANSWER" != "j" ] ; do
+ read -p "Ist die CD bereit? (j/n)" ANSWER
+ if [ "$ANSWER" == "j" ] ; then
+ $RECORD_BIN -eject -pad -data $1 &
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Wollen Sie abbrechen? (j/n)" EXIT
+ if [ "$EXIT" == "j" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# supplied info from "dump -F":
+# $1 = filename
+# $2 = sequence number
+
+NUM=$(($2+1))
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+CD_CAPACITY=4300
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+echo "Bitte die naechste DVD einlegen (No. $NUM)"
+ANSWER=""
+while [ "$ANSWER" != "j" ] ; do
+ read -p "Ist die DVD bereit? (j/n)" ANSWER
+ if [ "$ANSWER" == "j" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -dao -eject -pad -tsize=$TSIZE -data $1 &
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Wollen Sie abbrechen? (j/n)" EXIT
+ if [ "$EXIT" == "j" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# This script dumps the specified Filesystem via dump on a CD/DVD
+# CD_CAPACITY defines the capacity in MB per CD
+# The script for the next volume is passed via the -F option of dump
+# FILESYSTEM defines the filesystem to back up
+COMPRESSION_LEVEL=2
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+EXITSCRIPT="/root/bin/dvd_dump_userexit"
+FILESYSTEM="/home"
+LEVEL=0
+LABEL="`date -I`"
+CD_CAPACITY=700
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+BSIZE="$(echo "$CD_CAPACITY*1024" | bc -l )"
+FIFO="/tmp/dump.fifo"
+DUMP_BIN="/usr/sbin/dump -z$COMPRESSION_LEVEL -b64 -B$BSIZE -F $EXITSCRIPT -$LEVEL -L $LABEL -f $FIFO $FILESYSTEM"
+
+rm -f $FIFO
+mkfifo $FIFO
+ANSWER=""
+while [ "$ANSWER" != "y" ] ; do
+ read -p "Did you insert CD No. 1? (y/n)" ANSWER
+ if [ "$ANSWER" == "y" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -eject -pad -tsize=$TSIZE -data $FIFO &
+ $DUMP_BIN
+ rm -f $FIFO
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Do you really want to exit? (y/n)" EXIT
+ if [ "$EXIT" == "y" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# This script dumps the specified Filesystem via dump on a CD/DVD
+# CD_CAPACITY defines the capacity in MB per CD
+# The script for the next volume is passed via the -F option of dump
+# At least for my DVD-Recorder (a PHILIPS DVR-A03) it is necessary
+# to define the tracksize for the next track before the DVD is written.
+# This is done via the -tsize option of cdrecord. Since tsize takes its
+# arguments in Bytes, the shell cannot compute the value correctly
+# anymore (value too high), so I use bc.
+
+# !!! If you plan to write DVD's with other sizes, please correct the
+# CD_CAPACITY in the dump_userexit_DVD script, too !!!
+
+COMPRESSION_LEVEL=2
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+EXITSCRIPT="/root/bin/dvd_dump_userexit"
+FILESYSTEM="/home"
+LEVEL=0
+LABEL="`date -I`"
+CD_CAPACITY=4300
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+BSIZE="$(echo "$CD_CAPACITY*1024" | bc -l )"
+FIFO="/tmp/dump.fifo"
+DUMP_BIN="/usr/sbin/dump -z$COMPRESSION_LEVEL -b64 -B$BSIZE -F $EXITSCRIPT -$LEVEL -L $LABEL -f $FIFO $FILESYSTEM"
+
+rm -f $FIFO
+mkfifo $FIFO
+ANSWER=""
+while [ "$ANSWER" != "y" ] ; do
+ read -p "Did you insert DVD No. 1? (y/n)" ANSWER
+ if [ "$ANSWER" == "y" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -eject -dao -pad -tsize=$TSIZE -data $FIFO &
+ $DUMP_BIN
+ rm -f $FIFO
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Do you really want to exit? (y/n)" EXIT
+ if [ "$EXIT" == "y" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# supplied info from "dump -F":
+# $1 = filename
+# $2 = sequence number
+
+NUM=$(($2+1))
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+echo "Please insert the next CD (No. $NUM)"
+ANSWER=""
+while [ "$ANSWER" != "y" ] ; do
+ read -p "Is the CD ready? (y/n)" ANSWER
+ if [ "$ANSWER" == "y" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -eject -pad -data $1 &
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Do you really want to exit? (y/n)" EXIT
+ if [ "$EXIT" == "y" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+#!/bin/bash
+# supplied info from "dump -F":
+# $1 = filename
+# $2 = sequence number
+
+NUM=$(($2+1))
+RECORD_BIN="/usr/bin/dvdrecord dev=0,0,0 fs=64M speed=2 "
+CD_CAPACITY=4300
+TSIZE="$(echo "$CD_CAPACITY*1024*1024" | bc -l )"
+echo "Please insert the next DVD (No. $NUM)"
+ANSWER=""
+while [ "$ANSWER" != "y" ] ; do
+ read -p "Is the DVD ready? (y/n)" ANSWER
+ if [ "$ANSWER" == "y" ] ; then
+ $RECORD_BIN -blank=fast
+ $RECORD_BIN -dao -eject -pad -tsize=$TSIZE -data $1 &
+ exit 0
+ elif [ "$ANSWER" == "n" ] ; then
+ EXIT=""
+ read -p "Do you really want to exit? (y/n)" EXIT
+ if [ "$EXIT" == "y" ] ; then
+ exit 1
+ fi
+ fi
+done
--- /dev/null
+[...]
+Since I modified the dump_on_cd scripts [...by adding the
+possibility to dump to DVD media...] and thereby
+translated them to german, I attached them here.
+
+Furthermore, I think I improved the useability a bit.
+
+I hope you find them useful,
+
+Yours,
+
+Georg Lippold <g_lippold@sourceforge.net>
--- /dev/null
+> I'll be more than happy to put a copy of your scripts in the dump
+> distribution once you'll get this work :-)
+
+So you may have a look at the enclosed scripts.
+
+I use rsh in both directions. This may easily be changed to ssh.
+
+Basically three scripts are now necessary. The first wraps around the
+dump-command, the second acts as user exit when CD has to be changed
+and the third has to be run on the remote box.
+
+To make things easier I put the first two into one file called
+dump-to-remote-cd. The second file called get-dumpdata-to-cdrecord must
+be copied to the box with the CD-Burner. There is a small
+configuration section in it to get cdrecord to work.
+
+dump-to-remote-cd may be called with the capacity of the media which
+is used and / or a filesystem argument passed to dump.
+
+Usage is:
+
+dump-to-remote-cd [ -c <CD_capacity> ] [files to dump ...]
+
+There are defaults in the scripts which are used if any of these
+arguments are missing. The hostname of the box with the CD-burner
+has to be edited in any case.
+
+Kind regards
+
+Gerd
+
+------------------------------------------------------------------------
+Gerd Bavendiek Linux Laptop Users check out:
+bav@epost.de http://netenv.sourceforge.net
+------------------------------------------------------------------------
--- /dev/null
+#!/bin/bash
+#ident "@(#) dump-to-remote-cd Time-stamp: <02/05/06 15:12:29 bav> "
+#******************************************************************
+# dump-to-remote-cd
+#******************************************************************
+# Gerd Bavendiek bav@epost.de 02-05-02
+#
+# Script used to dump to a remote box with a CD-Burner. There is a
+# companion script called get-dumpdata-to-cdrecord.
+#
+# Usage: dump-to-remote-cd [ -c <CD_capacity> ] [files to dump ...]
+#
+# If called without arguments, it will dump / assuming 650 MB Media on
+# host kiki (see DEFAULT_ below).
+#
+# You must be able to do an rsh as root to BURN_HOST and vice versa,
+# see get-dumpdata-to-cdrecord. You may use ssh instead.
+#------------------------------------------------------------------
+
+#--- Customize to fit your needs ----------------------------------
+
+PATH_TO_GET_DUMPDATA_TO_CDRECORD=/root/tools/get-dumpdata-to-cdrecord
+PATH_TO_XTERM=/usr/X11R6/bin/xterm
+
+FIFO_NAME=/tmp/get-dumpdata-to-cdrecord.fifo
+
+BURN_HOST=kiki
+
+DEFAULT_CD_CAPACITY=650
+DEFAULT_FS=/
+
+#--- End of customizing -------------------------------------------
+
+USER_EXIT=$0
+
+Usage(){
+echo >&2 "Usage: `basename $0` [ -c <CD_capacity> ] [files to dump ...]"
+ exit 1
+}
+
+if [ `id -u` != 0 ]; then
+ echo "$0: ERROR: root priviledges are required ..."
+ exit 1
+fi
+
+# Check whether first argument is a named pipe
+if [ -p "$1" ]; then
+ # We are called internally either from ourselves or from dump
+ FIFO_NAME=$1
+ num=$[$2+1]
+ tput bel;sleep 1; tput bel
+ echo "Insert next CD (number $num) ..."
+ read -p "CD number $num ready ? " Ans
+ DUMP_HOST=`uname -n`
+ rsh $BURN_HOST \
+ $PATH_TO_XTERM -hold -T "Dump_CD_number_$num" -cr red -fn 6x10 -e \
+ $PATH_TO_GET_DUMPDATA_TO_CDRECORD -d $DUMP_HOST -f $FIFO_NAME &
+ exit 0
+fi
+
+CD_CAPACITY=$DEFAULT_CD_CAPACITY
+FS=$DEFAULT_FS
+
+# We will reach this code only when not called internally
+while getopts "b:c:h" c; do
+ case $c in
+ c) # Media Capacity
+ CD_CAPACITY=$OPTARG
+ ;;
+ h) # help those who ask for help
+ Usage
+ ;;
+ '?') # any other switch
+ Usage
+ ;;
+ esac
+done
+
+shift `expr $OPTIND - 1`
+
+if [ -n "$*" ]; then FS="$*"; fi
+
+DumpLevel=0 # level 0 dump
+Label=`date -I` # Take today's date as label, e.g. 2002-05-02
+
+eval Capacity=$(($CD_CAPACITY*1024))
+
+# Remove the fifo on the server and make a new one
+rm -f $FIFO_NAME; mkfifo $FIFO_NAME
+
+# Call user exit for the very first time, all further calls will be
+# done via dump
+$USER_EXIT $FIFO_NAME 0
+sleep 2
+
+# Run dump
+dump -z -B$Capacity -F $USER_EXIT -$DumpLevel -L $Label -f $FIFO_NAME $FS
+
--- /dev/null
+#!/bin/bash
+#ident "@(#) get-dumpdata-to-cdrecord Time-stamp: <02/05/06 13:49:28 bav> "
+#******************************************************************
+# get-dumpdata-to-cdrecord
+#******************************************************************
+# Gerd Bavendiek bav@epost.de 02-05-02
+#
+# This script runs on the box which has the CD-Burner. It starts an
+# rsh on the box where dump is started and feeds the data to
+# cdrecord. You should have copied it to
+# PATH_TO_GET_DUMPDATA_TO_CDRECORD, see script dump-to-remote-cd.
+#
+# You definitely may wish to customize the cdrecords arguments below !
+#
+# If rsh is not appropiate for you, change to ssh.
+#------------------------------------------------------------------
+
+CDRECORD_TESTMODE="" # This means: burn !
+###CDRECORD_TESTMODE="-dummy" # and this: not really ...
+CDRECORD_DEVICE="1,0" # Run cdrecord --scanbus if in doubt
+CDRECORD_SPEED=2 # Speed of your burner
+CDRECORD_BUFFERSIZE=16m # Buffersize in MByte
+
+#------------------------------------------------------------------
+Usage()
+{
+ echo >&2 "Usage: `basename $0` -d <dump_host> -f <fifo_name>"
+ exit 1
+}
+
+CDRECORD_ARGLIST="-v $CDRECORD_TESTMODE dev=$CDRECORD_DEVICE speed=$CDRECORD_SPEED fs=$CDRECORD_BUFFERSIZE"
+
+while getopts "d:f:h" c; do
+ case $c in
+ d) # the dump host
+ DUMP_HOST=$OPTARG
+ ;;
+ f) # name of the fifo cdrecord has to read the data from
+ FIFO_NAME=$OPTARG
+ ;;
+ h) # help those who ask for help
+ Usage
+ ;;
+ '?') # any other switch
+ Usage
+ ;;
+ esac
+done
+
+if [ -z "$DUMP_HOST" -o -z "$FIFO_NAME" ]; then Usage; fi
+
+rsh $DUMP_HOST dd if=$FIFO_NAME | cdrecord $CDRECORD_ARGLIST -eject -pad -data -
+if [ $? -ne 0 ]; then
+ echo $0: `date '+%T'`: ERROR: Check cdrecords messages
+ exit 1
+fi
+
+# Local Variables:
+# rcpbuf-todo: ("/[root@kiki]/root/tools")
+# End:
--- /dev/null
+This is a set of changes to the Linux "rmt" utility
+to support transparent encryption.
+Data is encrypted before it is written to tape, and decrypted when read.
+We use no padding or salt, so the data size doesn't change.
+Tools that use rmt for remote tape access (such as dump, restore
+and tar) can manipulate encrypted data without modification.
+
+The symmetric cipher is currently hardwired as Blowfish.
+
+[...]
+
+Building ermt:
+- Ensure that openssl-0.9.7a or later is installed.
+- Configure and build the package, enabling ermt support:
+ ./configure --enable-ermt
+ make
+ This will build an extra binary: rmt/ermt, the encrypting version.
+ If ermt fails to link because EVP_CIPHER_CTX_set_padding
+ is undefined, you must upgrade to openssl-0.9.7a or later.
+
+Run-time setup:
+- Create a user for remote tape access, which we will call "dump":
+ useradd -m dump
+- ermt reads the secret key from ".ermt.key".
+ Generate a random key in ~dump/.ermt.key:
+ su - dump
+ openssl rand -out .ermt.key 32
+ chmod 400 .ermt.key
+ Due to the way "openssl enc -kfile $file" reads the key file,
+ you should ensure that the key contains no \0 or \r or \n characters,
+ which would prematurely truncate the key length.
+- Protect the key: copy to many floppies, "od -x .ermt.key|lpr", etc.
+- Set up rsh access from root (or whoever you run dump as)
+ to dump@localhost:
+ # still running as user dump here
+ echo localhost root > .rhosts
+ chmod 400 .rhosts
+ Or use ssh if you prefer; details left as an exercise.
+- Check that it works: run "rsh localhost -l dump date" as root.
+- Copy the ermt binary you built above to ~dump,
+ and change dump's shell to ~dump/ermt.
+
+Backup usage: just dump remotely to localhost:
+
+ dump -0u -f dump@localhost:/dev/st0 /
+ restore -i -f dump@localhost:/dev/st0
+ # You can use GNU tar too
+
+If your device is doing hardware compression, it's best to turn
+it off, since encrypted data compresses very poorly.
+
+Emergency decrypting: if you need to restore a tape and
+don't have access to a host running ermt,
+you have two choices:
+- If you have a copy of the ermt binary, run it with the -d switch
+ to decrypt stdin to stdout:
+ dd if=/dev/st0 bs=10k |
+ (cd ~dump; ./ermt -d) | # assuming ermt is in ~dump
+ restore -i -f -
+- If not, use the OpenSSL "openssl" command, which does the same thing:
+ dd if=/dev/st0 bs=10k |
+ openssl enc -d -kfile ~dump/.ermt.key -blowfish -nosalt -nopad |
+ restore -i -f -
+ Versions of OpenSSL before 0.9.7a don't understand -nopad,
+ so they won't work.
+
+How much does encryption slow down backups?
+In my tests, the network hop is the bottleneck:
+dumping unencrypted (i.e. standard rmt) to localhost is 38%
+slower than dumping directly to tape.
+Adding encryption makes no difference, which isn't surprising.
+
+Change log:
+ 2003-04-08: added configure --enable-ermt, separate ermt binary
+ 2003-04-06: Initial release
+
+-- Ken Lalonde <ken@globalremit.com>
--- /dev/null
+Dump/Restore Ultra-Mini-FAQ
+
+Document v1.1
+
+Disclaimer: I am not an expert in dump/restore. In
+fact, I'm a newbie. But I've been picking things up as
+I implement it here and I wanted to pass some of those
+things along in the form of a very basic FAQ.
+
+-Patrick Walsh
+
+1) Introduction/ Non-rewinding device
+2) Dump command line
+3) Sending 2 or more filesystems to a tape
+4) Compressing dumps on the fly
+5) The "nodump" file and directory attribute.
+6) Restoring your dumps (including compressed).
+7) How to confirm a backup (highly recommended)
+8) What are the best buffer size options?
+9) Experiencing bread, lseek, lseek2 errors.
+10) Example backup script
+
+ 1) Introduction/ Non-rewinding device
+
+You use dump to backup to a file or a tape device. If
+you're backing up to a tape device, then the first
+thing you need to understand is that there are two
+devices that refer to your tape drive. There is the
+"rewinding" device and the "non-rewinding" device.
+
+I wish I could tell you an easy way to figure out what
+your device names are, but I don't know one. On my
+local box I had a /dev/tape device that linked to
+/dev/st0. It turns out that /dev/st0 is my "rewinding"
+tape drive. If I write to this device it will always
+rewind before starting to write. This means that if
+you try to dump two filesystems, only the second one
+will be stored. If your tape device is /dev/st0, like
+mine, then your non-rewinding tape device is probably
+/dev/nst0.
+
+Anyway, through the rest of this I will refer to $TAPE
+and $RWTAPE. $TAPE is the non-rewinding device (in my
+case /dev/nst0) and $RWTAPE is the rewinding tape (in
+my case /dev/st0 and /dev/tape). $FS is the filesystem
+you are backing up, such as /dev/hda1.
+
+ 2) What options should I use?
+
+Use the man page to figure out what options to send
+to dump. I use "dump 0uanf $TAPE $FS".
+
+ u=update /etc/dumpdates after a successful dump
+ a=auto-size -- bypass all tape length calculations
+ and write until eof
+ n=notify 'operators' group when dump needs attention
+ f=backup to file or device specified, or - for stdout
+
+ 3) You want to send two or more filesystems to tape.
+
+OK, rewind using the mt command, then dump multiple
+times to the non-rewinding device, and you're done:
+
+mt -f $TAPE rewind
+dump 0uanf $TAPE $FS1
+dump 0uanf $TAPE $FS2
+etc.
+
+Check the man page of mt if you want to know how to
+eject the tape or retension it or anything.
+
+ 4) You want to compress your dumps on the fly. No
+problem. Send your backup to STDOUT and manipulate it
+from there. It's easier if you're sending your output
+to the hard drive:
+
+dump 0uanf - $FS | gzip -c > /backup/outfile.dump.gz
+
+You want that to be written to the tape on the fly?
+Try this:
+
+mt -f $TAPE rewind
+dump 0uanf - $FS |gzip -c |dd if=- of=$TAPE
+
+[ You can also use the -z or -J options of dump in the
+ recent versions to enable internal compression - stelian ]
+
+ 5) You read the man page and you're wondering what the
+heck a "nodump" flag is. For example, how can you get
+dump to stop backing up /tmp or ~/.netscape/cache. You
+have two options: either exclude the inode in your dump
+command, or flag the files and directories with the
+"nodump" flag. To flag /tmp, for example, do this:
+
+chattr -R +d /tmp
+
+Want more details? Try 'man chattr' and 'man lsattr'.
+
+ 6) You want to know how to restore your backup.
+
+Read the restore man page. But barring that, the easy
+way is to use restore in interactive mode. If you have
+three filesystems on one tape and you want to restore
+files from the second one, you need to do this:
+
+mt -f $TAPE rewind
+mt -f $TAPE fsf 1 # skip forward one file
+restore -if $TAPE
+
+OK, suppose now that you used the commands in section 4
+to compress the dump file before it was written to
+disk. Use this command:
+
+mt -f $TAPE rewind
+mt -f $TAPE fsf 1
+dd if=$TAPE of=- |gzip -dc |restore -rf -
+
+Obviously if you dumped to a file instead of a tape it
+is much easier:
+
+gzip -dc $filename |restore -rf -
+
+ 7) How to confirm your backup
+
+ Check out the restore man page and read up on the -C
+option.
+
+ 8) What are the best buffer size options?
+
+ Bernhard R. Erdmann answered this question on the
+dump-users mailing list. His excellent response
+follows:
+
+>> While I was doing google searches, there seems to be
+>> an issue regarding the default buffer size writing
+>> to tape. According to some, the default buffer size
+>> of 512 can harm modern drives. I have a Seagate
+>> DDS3 unit and am wondering what the best mt/dump
+>> options are. I am using datacompression in
+>> hardware. Should I go with a large buffer (mt
+>> setblk 10240) or variable (mt setblk 0). If I
+>> change these sizes, does dump need to know about it?
+>
+>Dump/restore uses a default blocksize of 10 KB. You
+>can change it with the "-b" option or use dd for
+>(re-)blocking.
+>
+>dump 0ab 32 /
+>dump 0af - / | dd obs=32k of=$TAPE
+>ssh host "/sbin/dump 0af - /" | dd obs=32k of=$TAPE
+>restore rb 32
+>dd ibs=32k if=$TAPE | restore rf -
+>ssh host "dd if=/dev/nst0 ibs=32k" | restore rf -
+>
+>Personally, I'd stick with variable blocksize on the
+>drive and use 32 KB as the application's blocksize as
+>Amanda uses that size, too.
+>
+>Rumours told using 64 KB or 128 KB blocksize yields to
+>increase performance (maybe on the mtx list from an
+>Arkeia developer) didn't had any effects in my own
+>tests with blocksizes ranging from 10 to 64 KB some
+>months ago on a DDS-2 drive.
+>
+>Regarding tape drive performance at different block
+>sizes you may want to read
+>http://www.rs6000.ibm.com/support/micro/tapewhdr.html#Header_133
+>
+>- Block size, can effect the time for backup/restore.
+>Using large blocksizes may improve performance. Using
+>small block sizes can increase system overhead but
+>before changing to a large blocksize it is necessary
+>to be sure the user application supports the larger
+>blocksize chosen.
+>- Very long restore times due to blocksize. If a
+>backup is done with a fixed block length then the
+>restore should be done with the same fixed block
+>length. If a backup is done with a fixed block length
+>and the restore is done with variable block length,
+>the restore may work successfully but it may take many
+>more hours to restore than it took to back up the
+>data. The reason for this is that when AIX reads fixed
+>block length data in variable block mode, a check
+>condition is issued by the tape drive on every read.
+>AIX must interpret every check condition and determine
+>the proper action to take. This often will put the
+>tape drive into a mode of reading that will require
+>the tape drive to stop tape motion, rewind the tape
+>some distance, then start reading again. This will
+>reduce the life expectancy of the tape and increase
+>the time it takes to backup data.
+
+ 9) Experiencing bread, lseek, and lseek2 errors.
+
+ These errors are caused by inodes being changed
+during the backup. This is normal because dump and
+the Linux kernel are both acessing the filesystem
+and there is no consistence checking. By "calming"
+the system (killing unnecessary processes), you
+decrease the likelihood of having these
+errors. Read up on the bug on Sourcefourge:
+
+http://sourceforge.net/tracker/index.php?func=detail&aid=204909&group_id=1306&atid=101306
+
+Note that the only "real" solution to this problem
+is to dump a unmounted filesystem or use a filesystem
+snapshot feature (like in LVM).
+
+ 10) That about sums up my knowledge on the matter, but
+I feel better having written something for other peopleto look at so it doesn't take them quite so long to
+learn the things I did. I've included my backup script
+below. There are much better ones floating around, so
+go find someone else's and use theirs if mine won't
+work for you or you don't understand it.
+
+
+#!/bin/csh
+# System backup script for NARNIA
+
+# This is a script that will backup the entire hard drive
+# to the NT server (not my choice) \\fs1.
+#
+# On each Sunday night, a full backup will be made
+# of the hard drive and each day of the week thereafter an incremental
+# backup will be made that captures only those changes since the night
+# before.
+# Each full backup will be sent to the local tape as well as to the
+# NT machine.
+#
+# The files will be stored in partition-specific files with integer
+# endings that specify the day of the week they were saved. Files
+# with zero on the end will always be full backups.
+
+# Dump options:
+# a=auto-size -- bypass all tape length calculations and write until eof
+# f=write the backup to file or device specified or - for stdout
+# n=notify operators group when dump needs attention
+# u=update /etc/dumpdates after a successful dump
+
+# Set variables that control the script.
+setenv MOUNTPOINT '/root/fs1backup'
+setenv OUTDIR '/root/fs1backup/narnia'
+setenv TAPE '/dev/nst0' # non-rewinding tape
+
+# Auto-set variable that determines level of backup.
+setenv DAY `date +'%w'`
+
+# Mount the backup partition to /root/fs1backup
+/usr/bin/smbmount \\\\fs1\\backup $MOUNTPOINT -o
+"username=uname,password=pword"
+
+# Delete files created on this day last week
+rm -f $OUTDIR/*$DAY.dump.gz
+
+# Do the actual backing up, one filesystem at a time.
+
+# /dev/hda1 = /boot
+/sbin/dump $DAY'uanf' - /dev/hda1 | gzip -c >$OUTDIR/boot-$DAY.dump.gz
+
+# /dev/hda2 = /
+/sbin/dump $DAY'uanf' - /dev/hda2 | gzip -c >$OUTDIR/root-$DAY.dump.gz
+
+# /dev/hda3 = /usr
+/sbin/dump $DAY'uanf' - /dev/hda3 | gzip -c >$OUTDIR/usr-$DAY.dump.gz
+
+# /dev/hdb2 = /u1
+/sbin/dump $DAY'uanf' - /dev/hdb2 | gzip -c >$OUTDIR/u1-$DAY.dump.gz
+
+
+# OK, presumably everything is now backed up to \\fs1. On level 0
+# dumps, lets backup to the local drive too.
+if ($DAY == 0) then
+ mt -f $TAPE retension
+ foreach i ($OUTDIR/*0.dump.gz)
+ dd if=$i of=$TAPE
+ end
+ mt -f $TAPE rewind
+endif
+
+
+# Unmount the backup partition, not needed outside of script
+umount /root/fs1backup
+
+# Explicitly free up the temporary variables
+unsetenv DAY
+unsetenv MOUNTPOINT
+unsetenv OUTDIR
+unsetenv TAPE
+
+
+# RESTORE DIRECTIONS:
+# If from tape:
+# dd if=$TAPE of=- | gzip -dc | restore -rf -
+# or dd if=$TAPE |gzip -dc |restore -rf -
+#
+# Note: must queue tape to proper position first. This
+# is done by first rewinding then advancing to the proper
+# file. The order that files are written to tape is
+# *probably* 0=/boot 1=/ 2=/usr 3=/u1
+#
+# Use mt to skip between them:
+# mt -f $TAPE rewind
+# restore -if $TAPE #now restoring /boot, probably
+# mt -f $TAPE fsf 1
+# restore -if $TAPE #now restoring /
+# mt -f $TAPE fsf 1
+# restore -if $TAPE #now restoring /usr
+# #etc.
+#
+# Otherwise:
+# gzip -dc $filename | restore -rf -
+
+
+
--- /dev/null
+#!/bin/sh
+
+#
+# This script will backup local drives to a remote tape drive over ssh.
+# written by David B. Peterson <dave@toppledwagon.com>
+#
+# Follow these steps before using it the first time:
+# 1. Configure the env variables below, especially OPERATOR, TAPEHOST
+# TAPEDEV, and FILESYSTEMS
+# 2. run the following commands as root (on the machine to be backed up):
+# ssh-keygen -t dsa
+# cat ~/.ssh/id_dsa.pub | ssh OPERATOR@TAPEHOST 'cat - >> ~/.ssh/authorized_keys2'
+#
+# where OPERATOR and TAPEHOST are as you have defined below.
+
+# We will run under screen so you can come back to the backup, if you need to.
+if [ ! "$WINDOW" ]; then
+ exec screen $0
+ exit
+fi
+
+# ssh-agent allows us to backup securely without entering the passphrase so
+# many times. This version uses openssh v2.9
+if [ ! $SSH_AGENT_PID ]; then
+ echo Starting ssh-agent...
+ exec ssh-agent -- /bin/sh $0
+ exit
+fi
+
+OPERATOR=backup
+TAPEHOST=tapehost.example.com
+TAPEDEV=/dev/nst0
+RMT=/sbin/rmt
+RSH='/usr/bin/ssh'
+DATE=`date +%Y%m%d`
+DUMP='/sbin/dump 0auf'
+LOGDIR=/var/log/backup
+FILESYSTEMS='hda1 hda7 hda6 hda5 hda10'
+
+#### config above ####
+# backup FILESYSTEMS to the TAPEDEV on TAPEHOST with DUMP as OPERATOR using RSH
+
+export RMT RSH
+mkdir -p $LOGDIR &> /dev/null
+ssh-add ~/.ssh/id_dsa
+
+echo "Rewinding tape..."
+REWIND="mt -f $TAPEDEV rewind"
+$RSH $OPERATOR@$TAPEHOST $REWIND
+
+for FS in $FILESYSTEMS
+do
+ $DUMP $OPERATOR@$TAPEHOST:$TAPEDEV /dev/$FS 2>&1 | tee $LOGDIR/$FS.$DATE
+done
+
+echo "Rewinding and ejecting tape..."
+OFFLINE="mt -f $TAPEDEV offline"
+$RSH $OPERATOR@$TAPEHOST $OFFLINE
+
--- /dev/null
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
--- /dev/null
+--- fs/read_write.c.orig Sun Aug 27 15:41:29 1995
++++ fs/read_write.c Sun Aug 27 15:42:39 1995
+@@ -112,9 +112,11 @@
+ }
+ if (tmp < 0)
+ return -EINVAL;
+- file->f_pos = tmp;
+- file->f_reada = 0;
+- file->f_version = ++event;
++ if (tmp != file->f_pos) {
++ file->f_pos = tmp;
++ file->f_reada = 0;
++ file->f_version = ++event;
++ }
+ memcpy_tofs(result, &file->f_pos, sizeof(loff_t));
+ return 0;
+ }
--- /dev/null
+# $Id: Makefile.in,v 1.12 2003/05/08 21:11:39 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ..
+
+@MCONFIG@
+
+INC= -I$(top_srcdir)/restore
+ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @RESTOREDEBUG@
+ALL_LDFLAGS= @LDFLAGS@ @LDOPTS@ @STATIC@
+LIBS= $(GLIBS) -le2p @READLINE@ @ZLIB@ @BZLIB@
+DEPLIBS= ../compat/lib/libcompat.a
+
+PROG= restore
+RPROG= rrestore
+LINKS= ${SBINDIR}/restore ${SBINDIR}/rrestore
+SRCS= dirs.c interactive.c main.c restore.c symtab.c tape.c \
+ utilities.c
+OBJS= dirs.o interactive.o main.o restore.o symtab.o tape.o \
+ utilities.o ../common/dumprmt.o
+MAN8= restore.8
+RMAN8= rrestore.8
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: $(PROG) $(MAN8)
+
+$(PROG): $(OBJS) $(DEPLIBS)
+ $(CC) $(ALL_LDFLAGS) -o $(PROG) $(OBJS) $(LIBS)
+
+$(MAN8): restore.8.in
+ sed -e "s|__DATE__|$(DATE)|g" \
+ -e "s|__VERSION__|$(VERSION)|g" $< > $@
+
+install:: all
+ $(INSTALL) -d $(SBINDIR) $(MANDIR)
+ $(INSTALLBIN) $(PROG) $(SBINDIR)
+ $(INSTALLMAN) $(MAN8) $(MANDIR)
+ cd $(SBINDIR) && $(RM) -f $(RPROG) && $(LN_S) $(PROG) $(RPROG)
+ cd $(MANDIR) && $(RM) -f $(RMAN8) && $(LN_S) $(MAN8) $(RMAN8)
+
+clean::
+ $(RM) -f $(PROG) $(MAN8) \#* *.s *.o *.a *~ core
+
+distclean:: clean
+ $(RM) -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: dirs.c,v 1.28 2004/05/25 10:39:30 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#endif
+#endif /* __linux__ */
+#include <protocols/dumprestore.h>
+
+#include <compaterr.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __linux__
+#include <endian.h>
+#else
+#ifdef sunos
+#include <arpa/nameser_compat.h>
+#else
+#include <machine/endian.h>
+#endif
+#endif
+
+#include "pathnames.h"
+#include "restore.h"
+#include "extern.h"
+
+/*
+ * Symbol table of directories read from tape.
+ */
+#define HASHSIZE 1000
+#define INOHASH(val) (val % HASHSIZE)
+struct inotab {
+ struct inotab *t_next;
+ dump_ino_t t_ino;
+ OFF_T t_seekpt;
+ OFF_T t_size;
+};
+static struct inotab *inotab[HASHSIZE];
+
+/*
+ * Information retained about directories.
+ */
+struct modeinfo {
+ dump_ino_t ino;
+ struct timeval timep[2];
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ unsigned int flags;
+};
+
+/*
+ * Definitions for library routines operating on directories.
+ */
+#undef DIRBLKSIZ
+#define DIRBLKSIZ 1024
+struct rstdirdesc {
+ int dd_fd;
+ int32_t dd_loc;
+ int32_t dd_size;
+ char dd_buf[DIRBLKSIZ];
+};
+
+/*
+ * Global variables for this file.
+ */
+static OFF_T seekpt;
+static FILE *df, *mf;
+static RST_DIR *dirp;
+static char dirfile[MAXPATHLEN] = "#"; /* No file */
+static char modefile[MAXPATHLEN] = "#"; /* No file */
+static char dot[2] = "."; /* So it can be modified */
+
+/*
+ * Format of old style directories.
+ */
+#define ODIRSIZ 14
+struct odirect {
+ u_short d_ino;
+ char d_name[ODIRSIZ];
+};
+
+#if defined(__linux__) || defined(sunos)
+static struct inotab *allocinotab __P((dump_ino_t, struct new_bsd_inode *, OFF_T));
+#else
+static struct inotab *allocinotab __P((dump_ino_t, struct dinode *, OFF_T));
+#endif
+static void dcvt __P((struct odirect *, struct direct *));
+static void flushent __P((void));
+static struct inotab *inotablookup __P((dump_ino_t));
+static RST_DIR *opendirfile __P((const char *));
+static void putdir __P((char *, size_t));
+static void putent __P((struct direct *));
+static void rst_seekdir __P((RST_DIR *, OFF_T, OFF_T));
+static OFF_T rst_telldir __P((RST_DIR *));
+static struct direct *searchdir __P((dump_ino_t, char *));
+
+#ifdef sunos
+extern int fdsmtc;
+#endif
+
+/*
+ * Extract directory contents, building up a directory structure
+ * on disk for extraction by name.
+ * If genmode is requested, save mode, owner, and times for all
+ * directories on the tape.
+ */
+void
+extractdirs(int genmode)
+{
+ int i;
+#if defined(__linux__) || defined(sunos)
+ struct new_bsd_inode *ip;
+#else
+ struct dinode *ip;
+#endif
+ struct inotab *itp;
+ struct direct nulldir;
+ int fd;
+
+ Vprintf(stdout, "Extract directories from tape\n");
+ (void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%ld", tmpdir,
+ (long)dumpdate);
+ if (command != 'r' && command != 'R') {
+ (void) strncat(dirfile, "-XXXXXX",
+ sizeof(dirfile) - strlen(dirfile));
+ fd = MKSTEMP(dirfile);
+ } else
+ fd = OPEN(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666);
+ if (fd == -1 || (df = fdopen(fd, "w")) == NULL) {
+ if (fd != -1)
+ close(fd);
+ err(1, "cannot create directory temporary %s", dirfile);
+ }
+ if (genmode != 0) {
+ (void) snprintf(modefile, sizeof(modefile), "%s/rstmode%ld", tmpdir, (long)dumpdate);
+ if (command != 'r' && command != 'R') {
+ (void) strncat(modefile, "-XXXXXX",
+ sizeof(modefile) - strlen(modefile));
+ fd = MKSTEMP(modefile);
+ } else
+ fd = OPEN(modefile, O_RDWR|O_CREAT|O_EXCL, 0666);
+ if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) {
+ if (fd != -1)
+ close(fd);
+ err(1, "cannot create modefile %s", modefile);
+ }
+ }
+ nulldir.d_ino = 0;
+ nulldir.d_type = DT_DIR;
+ nulldir.d_namlen = 1;
+ nulldir.d_name[0] = '/';
+ nulldir.d_name[1] = '\0';
+ nulldir.d_reclen = DIRSIZ(0, &nulldir);
+ for (;;) {
+ curfile.name = "<directory file - name unknown>";
+ curfile.action = USING;
+ ip = curfile.dip;
+ if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {
+ if ( fclose(df) == EOF )
+ err(1, "cannot write to file %s", dirfile);
+ dirp = opendirfile(dirfile);
+ if (dirp == NULL)
+ warn("opendirfile");
+ if (mf != NULL && fclose(mf) == EOF )
+ err(1, "cannot write to file %s", dirfile);
+ i = dirlookup(dot);
+ if (i == 0)
+ panic("Root directory is not on tape\n");
+ return;
+ }
+ itp = allocinotab(curfile.ino, ip, seekpt);
+ getfile(putdir, xtrnull);
+ putent(&nulldir);
+ flushent();
+ itp->t_size = seekpt - itp->t_seekpt;
+ }
+}
+
+/*
+ * skip over all the directories on the tape
+ */
+void
+skipdirs(void)
+{
+
+ while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) {
+ skipfile();
+ }
+}
+
+/*
+ * Recursively find names and inumbers of all files in subtree
+ * pname and pass them off to be processed.
+ */
+void
+treescan(char *pname, dump_ino_t ino, long (*todo) __P((char *, dump_ino_t, int)))
+{
+ struct inotab *itp;
+ struct direct *dp;
+ int namelen;
+ OFF_T bpt;
+ char locname[MAXPATHLEN + 1];
+
+ itp = inotablookup(ino);
+ if (itp == NULL) {
+ /*
+ * Pname is name of a simple file or an unchanged directory.
+ */
+ (void) (*todo)(pname, ino, LEAF);
+ return;
+ }
+ /*
+ * Pname is a dumped directory name.
+ */
+ if ((*todo)(pname, ino, NODE) == FAIL)
+ return;
+ /*
+ * begin search through the directory
+ * skipping over "." and ".."
+ */
+ namelen = snprintf(locname, sizeof(locname), "%s/", pname);
+ if (namelen >= (int)sizeof(locname))
+ namelen = sizeof(locname) - 1;
+ rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);
+ dp = rst_readdir(dirp); /* "." */
+ if (dp != NULL && strcmp(dp->d_name, ".") == 0)
+ dp = rst_readdir(dirp); /* ".." */
+ else
+ fprintf(stderr, "Warning: `.' missing from directory %s\n",
+ pname);
+ if (dp != NULL && strcmp(dp->d_name, "..") == 0)
+ dp = rst_readdir(dirp); /* first real entry */
+ else
+ fprintf(stderr, "Warning: `..' missing from directory %s\n",
+ pname);
+ bpt = rst_telldir(dirp);
+ /*
+ * a zero inode signals end of directory
+ */
+ while (dp != NULL) {
+ locname[namelen] = '\0';
+ if (namelen + dp->d_namlen >= (int)sizeof(locname)) {
+ fprintf(stderr, "%s%s: name exceeds %ld char\n",
+ locname, dp->d_name, (long)sizeof(locname) - 1);
+ } else {
+ (void) strncat(locname, dp->d_name, (int)dp->d_namlen);
+ treescan(locname, dp->d_ino, todo);
+ rst_seekdir(dirp, bpt, itp->t_seekpt);
+ }
+ dp = rst_readdir(dirp);
+ bpt = rst_telldir(dirp);
+ }
+}
+
+/*
+ * Lookup a pathname which is always assumed to start from the ROOTINO.
+ */
+struct direct *
+pathsearch(const char *pathname)
+{
+ dump_ino_t ino;
+ struct direct *dp;
+ char *path, *name, buffer[MAXPATHLEN];
+
+ strcpy(buffer, pathname);
+ path = buffer;
+ ino = ROOTINO;
+ while (*path == '/')
+ path++;
+ dp = NULL;
+#ifdef __linux__
+ while ((name = strsep(&path, "/")) != NULL && *name /* != NULL */) {
+#else
+ while ((name = strtok_r(NULL, "/", &path)) != NULL && *name /* != NULL */) {
+#endif
+ if ((dp = searchdir(ino, name)) == NULL)
+ return (NULL);
+ ino = dp->d_ino;
+ }
+ return (dp);
+}
+
+/*
+ * Lookup the requested name in directory inum.
+ * Return its inode number if found, zero if it does not exist.
+ */
+static struct direct *
+searchdir(dump_ino_t inum, char *name)
+{
+ struct direct *dp;
+ struct inotab *itp;
+ int len;
+
+ itp = inotablookup(inum);
+ if (itp == NULL)
+ return (NULL);
+ rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);
+ len = strlen(name);
+ do {
+ dp = rst_readdir(dirp);
+ if (dp == NULL)
+ return (NULL);
+ } while (dp->d_namlen != len || strncmp(dp->d_name, name, len) != 0);
+ return (dp);
+}
+
+/*
+ * Put the directory entries in the directory file
+ */
+static void
+putdir(char *buf, size_t size)
+{
+ struct direct cvtbuf;
+ struct odirect *odp;
+ struct odirect *eodp;
+ struct direct *dp;
+ long loc, i;
+
+ if (cvtflag && !ufs2flag) {
+ eodp = (struct odirect *)&buf[size];
+ for (odp = (struct odirect *)buf; odp < eodp; odp++)
+ if (odp->d_ino != 0) {
+ dcvt(odp, &cvtbuf);
+ putent(&cvtbuf);
+ }
+ } else {
+ for (loc = 0; loc < (long)size; ) {
+ dp = (struct direct *)(buf + loc);
+#ifdef DIRDEBUG
+ printf ("reclen = %d, namlen = %d, type = %d\n",
+ dp->d_reclen, dp->d_namlen, dp->d_type);
+#endif
+ if (Bcvt)
+ swabst((u_char *)"is", (u_char *) dp);
+ if (oldinofmt && dp->d_ino != 0) {
+# if BYTE_ORDER == BIG_ENDIAN
+ if (Bcvt)
+ dp->d_namlen = dp->d_type;
+# else
+ if (!Bcvt)
+ dp->d_namlen = dp->d_type;
+# endif
+ if (dp->d_namlen == 0 && dp->d_type != 0)
+ dp->d_namlen = dp->d_type;
+ dp->d_type = DT_UNKNOWN;
+ }
+#ifdef DIRDEBUG
+ printf ("reclen = %d, namlen = %d, type = %d\n",
+ dp->d_reclen, dp->d_namlen, dp->d_type);
+#endif
+ i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
+ if ((dp->d_reclen & 0x3) != 0 ||
+ dp->d_reclen > i ||
+ dp->d_reclen < DIRSIZ(0, dp)
+#if MAXNAMLEN < 255
+ || dp->d_namlen > MAXNAMLEN
+#endif
+ ) {
+ Vprintf(stdout, "Mangled directory: ");
+ if ((dp->d_reclen & 0x3) != 0)
+ Vprintf(stdout,
+ "reclen not multiple of 4 ");
+ if (dp->d_reclen < DIRSIZ(0, dp))
+ Vprintf(stdout,
+ "reclen less than DIRSIZ (%d < %d) ",
+ dp->d_reclen, DIRSIZ(0, dp));
+#if MAXNAMLEN < 255
+ if (dp->d_namlen > MAXNAMLEN)
+ Vprintf(stdout,
+ "reclen name too big (%d > %d) ",
+ dp->d_namlen, MAXNAMLEN);
+#endif
+ Vprintf(stdout, "\n");
+ loc += i;
+ continue;
+ }
+ loc += dp->d_reclen;
+ if (dp->d_ino != 0) {
+ putent(dp);
+ }
+ }
+ }
+}
+
+/*
+ * These variables are "local" to the following two functions.
+ */
+static char dirbuf[DIRBLKSIZ];
+static long dirloc = 0;
+static long prev = 0;
+
+/*
+ * add a new directory entry to a file.
+ */
+static void
+putent(struct direct *dp)
+{
+ dp->d_reclen = DIRSIZ(0, dp);
+ if (dirloc + dp->d_reclen > DIRBLKSIZ) {
+ ((struct direct *)(dirbuf + prev))->d_reclen =
+ DIRBLKSIZ - prev;
+ if ( fwrite(dirbuf, 1, DIRBLKSIZ, df) != DIRBLKSIZ )
+ err(1,"cannot write to file %s", dirfile);
+ dirloc = 0;
+ }
+ memmove(dirbuf + dirloc, dp, (size_t)dp->d_reclen);
+ prev = dirloc;
+ dirloc += dp->d_reclen;
+}
+
+/*
+ * flush out a directory that is finished.
+ */
+static void
+flushent(void)
+{
+ ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev;
+ if ( fwrite(dirbuf, (int)dirloc, 1, df) != 1 )
+ err(1, "cannot write to file %s", dirfile);
+ seekpt = FTELL(df);
+ if (seekpt == -1)
+ err(1, "cannot write to file %s", dirfile);
+ dirloc = 0;
+}
+
+static void
+dcvt(struct odirect *odp, struct direct *ndp)
+{
+
+ memset(ndp, 0, (size_t)(sizeof *ndp));
+ ndp->d_ino = odp->d_ino;
+ ndp->d_type = DT_UNKNOWN;
+ (void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ);
+ ndp->d_namlen = strlen(ndp->d_name);
+ ndp->d_reclen = DIRSIZ(0, ndp);
+}
+
+/*
+ * Seek to an entry in a directory.
+ * Only values returned by rst_telldir should be passed to rst_seekdir.
+ * This routine handles many directories in a single file.
+ * It takes the base of the directory in the file, plus
+ * the desired seek offset into it.
+ */
+static void
+rst_seekdir(RST_DIR *dirp, OFF_T loc, OFF_T base)
+{
+
+ if (loc == rst_telldir(dirp))
+ return;
+ loc -= base;
+ if (loc < 0)
+ fprintf(stderr, "bad seek pointer to rst_seekdir %lld\n", (long long int)loc);
+ (void) LSEEK(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), SEEK_SET);
+ dirp->dd_loc = loc & (DIRBLKSIZ - 1);
+ if (dirp->dd_loc != 0)
+ dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ);
+}
+
+/*
+ * get next entry in a directory.
+ */
+struct direct *
+rst_readdir(RST_DIR *dirp)
+{
+ struct direct *dp;
+
+ for (;;) {
+ if (dirp->dd_loc == 0) {
+ dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
+ DIRBLKSIZ);
+ if (dirp->dd_size <= 0) {
+ Dprintf(stderr, "error reading directory\n");
+ return (NULL);
+ }
+ }
+ if (dirp->dd_loc >= dirp->dd_size) {
+ dirp->dd_loc = 0;
+ continue;
+ }
+ dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc);
+ if (dp->d_reclen == 0 ||
+ dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) {
+ Dprintf(stderr, "corrupted directory: bad reclen %d\n",
+ dp->d_reclen);
+ return (NULL);
+ }
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_ino == 0 && strcmp(dp->d_name, "/") == 0)
+ return (NULL);
+ if (dp->d_ino >= maxino) {
+ Dprintf(stderr, "corrupted directory: bad inum %d\n",
+ dp->d_ino);
+ continue;
+ }
+ return (dp);
+ }
+}
+
+/*
+ * Simulate the opening of a directory
+ */
+RST_DIR *
+rst_opendir(const char *name)
+{
+ struct inotab *itp;
+ RST_DIR *dirp;
+ dump_ino_t ino;
+
+ if ((ino = dirlookup(name)) > 0 &&
+ (itp = inotablookup(ino)) != NULL) {
+ dirp = opendirfile(dirfile);
+ rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);
+ return (dirp);
+ }
+ return (NULL);
+}
+
+/*
+ * In our case, there is nothing to do when closing a directory.
+ */
+void
+rst_closedir(RST_DIR *dirp)
+{
+
+ (void)close(dirp->dd_fd);
+ free(dirp);
+ return;
+}
+
+/*
+ * Simulate finding the current offset in the directory.
+ */
+static OFF_T
+rst_telldir(RST_DIR *dirp)
+{
+ return ((OFF_T)LSEEK(dirp->dd_fd,
+ (OFF_T)0, SEEK_CUR) - dirp->dd_size + dirp->dd_loc);
+}
+
+/*
+ * Open a directory file.
+ */
+static RST_DIR *
+opendirfile(const char *name)
+{
+ RST_DIR *dirp;
+ int fd;
+
+ if ((fd = OPEN(name, O_RDONLY)) == -1)
+ return (NULL);
+ if ((dirp = malloc(sizeof(RST_DIR))) == NULL) {
+ (void)close(fd);
+ return (NULL);
+ }
+ dirp->dd_fd = fd;
+ dirp->dd_loc = 0;
+ return (dirp);
+}
+
+/*
+ * Set the mode, owner, and times for all new or changed directories
+ */
+void
+setdirmodes(int flags)
+{
+ FILE *mf;
+ struct modeinfo node;
+ struct entry *ep;
+ char *cp;
+
+ Vprintf(stdout, "Set directory mode, owner, and times.\n");
+ if (command == 'r' || command == 'R')
+ (void) snprintf(modefile, sizeof(modefile), "%s/rstmode%lu", tmpdir, (long)dumpdate);
+ if (modefile[0] == '#') {
+ panic("modefile not defined\n");
+ fprintf(stderr, "directory mode, owner, and times not set\n");
+ return;
+ }
+ mf = fopen(modefile, "r");
+ if (mf == NULL) {
+ warn("fopen");
+ fprintf(stderr, "cannot open mode file %s\n", modefile);
+ fprintf(stderr, "directory mode, owner, and times not set\n");
+ return;
+ }
+ clearerr(mf);
+ for (;;) {
+ (void) fread((char *)&node, 1, sizeof(struct modeinfo), mf);
+ if (feof(mf))
+ break;
+ ep = lookupino(node.ino);
+ if (command == 'i' || command == 'x') {
+ if (ep == NULL)
+ continue;
+ if ((flags & FORCE) == 0 && ep->e_flags & EXISTED) {
+ ep->e_flags &= ~NEW;
+ continue;
+ }
+ if ((flags & FORCE) == 0 &&
+ node.ino == ROOTINO &&
+ reply("set owner/mode for '.'") == FAIL)
+ continue;
+ }
+ if (ep == NULL) {
+ panic("cannot find directory inode %d\n", node.ino);
+ } else {
+ cp = myname(ep);
+ (void) chown(cp, node.uid, node.gid);
+ (void) chmod(cp, node.mode);
+ if (node.flags)
+#ifdef __linux__
+ (void) fsetflags(cp, node.flags);
+#else
+#ifdef sunos
+#else
+ (void) chflags(cp, node.flags);
+#endif
+#endif
+ utimes(cp, node.timep);
+ ep->e_flags &= ~NEW;
+ }
+ }
+ if (ferror(mf))
+ panic("error setting directory modes\n");
+ (void) fclose(mf);
+}
+
+/*
+ * Generate a literal copy of a directory.
+ */
+int
+genliteraldir(char *name, dump_ino_t ino)
+{
+ struct inotab *itp;
+ int ofile, dp, i, size;
+ char buf[BUFSIZ];
+
+ itp = inotablookup(ino);
+ if (itp == NULL)
+ panic("Cannot find directory inode %d named %s\n", ino, name);
+ if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+ warn("%s: cannot create file\n", name);
+ return (FAIL);
+ }
+ rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);
+ dp = dup(dirp->dd_fd);
+ for (i = itp->t_size; i > 0; i -= BUFSIZ) {
+ size = i < BUFSIZ ? i : BUFSIZ;
+ if (read(dp, buf, (int) size) == -1) {
+ warnx("write error extracting inode %lu, name %s\n",
+ (unsigned long)curfile.ino, curfile.name);
+ err(1, "read");
+ }
+ if (!Nflag && write(ofile, buf, (int) size) == -1) {
+ warnx("write error extracting inode %lu, name %s\n",
+ (unsigned long)curfile.ino, curfile.name);
+ err(1, "write");
+ }
+ }
+ (void) close(dp);
+ (void) close(ofile);
+ return (GOOD);
+}
+
+/*
+ * Determine the type of an inode
+ */
+int
+inodetype(dump_ino_t ino)
+{
+ struct inotab *itp;
+
+ itp = inotablookup(ino);
+ if (itp == NULL)
+ return (LEAF);
+ return (NODE);
+}
+
+/*
+ * Allocate and initialize a directory inode entry.
+ * If requested, save its pertinent mode, owner, and time info.
+ */
+static struct inotab *
+#if defined(__linux__) || defined(sunos)
+allocinotab(dump_ino_t ino, struct new_bsd_inode *dip, OFF_T seekpt)
+#else
+allocinotab(dump_ino_t ino, struct dinode *dip, OFF_T seekpt)
+#endif
+{
+ struct inotab *itp;
+ struct modeinfo node;
+
+ itp = calloc(1, sizeof(struct inotab));
+ if (itp == NULL)
+ panic("no memory directory table\n");
+ itp->t_next = inotab[INOHASH(ino)];
+ inotab[INOHASH(ino)] = itp;
+ itp->t_ino = ino;
+ itp->t_seekpt = seekpt;
+ if (mf == NULL)
+ return (itp);
+ node.ino = ino;
+#if defined(__linux__) || defined(sunos)
+ node.timep[0].tv_sec = dip->di_atime.tv_sec;
+ node.timep[0].tv_usec = dip->di_atime.tv_usec;
+ node.timep[1].tv_sec = dip->di_mtime.tv_sec;
+ node.timep[1].tv_usec = dip->di_mtime.tv_usec;
+#else /* __linux__ || sunos */
+ node.timep[0].tv_sec = dip->di_atime;
+ node.timep[0].tv_usec = dip->di_atimensec / 1000;
+ node.timep[1].tv_sec = dip->di_mtime;
+ node.timep[1].tv_usec = dip->di_mtimensec / 1000;
+#endif /* __linux__ || sunos */
+ node.mode = dip->di_mode;
+ node.flags = dip->di_flags;
+ node.uid = dip->di_uid;
+ node.gid = dip->di_gid;
+ if ( fwrite((char *)&node, 1, sizeof(struct modeinfo), mf) != sizeof(struct modeinfo) )
+ err(1,"cannot write to file %s", modefile);
+ return (itp);
+}
+
+/*
+ * Look up an inode in the table of directories
+ */
+static struct inotab *
+inotablookup(dump_ino_t ino)
+{
+ struct inotab *itp;
+
+ for (itp = inotab[INOHASH(ino)]; itp != NULL; itp = itp->t_next)
+ if (itp->t_ino == ino)
+ return (itp);
+ return (NULL);
+}
+
+/*
+ * Clean up and exit
+ */
+void
+cleanup(void)
+{
+ closemt();
+ if (modefile[0] != '#')
+ (void) unlink(modefile);
+ if (dirfile[0] != '#')
+ (void) unlink(dirfile);
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: extern.h,v 1.23 2003/10/26 16:05:48 stelian Exp $
+ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <compatlfs.h>
+#ifndef __P
+#include <sys/cdefs.h>
+#endif
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
+
+struct entry *addentry __P((char *, dump_ino_t, int));
+long addfile __P((char *, dump_ino_t, int));
+int addwhiteout __P((char *));
+void badentry __P((struct entry *, const char *));
+void canon __P((char *, char *, int));
+void checkrestore __P((void));
+void closemt __P((void));
+void cleanup __P((void));
+void comparefile __P((char *));
+void compareleaves __P((void));
+void createfiles __P((void));
+void createleaves __P((char *));
+void createlinks __P((void));
+long deletefile __P((char *, dump_ino_t, int));
+void deleteino __P((dump_ino_t));
+void delwhiteout __P((struct entry *));
+dump_ino_t dirlookup __P((const char *));
+void dumpsymtable __P((char *, long));
+void extractdirs __P((int));
+int extractfile __P((struct entry *, int));
+void findunreflinks __P((void));
+char *flagvalues __P((struct entry *));
+void freeentry __P((struct entry *));
+void freename __P((char *));
+int genliteraldir __P((char *, dump_ino_t));
+char *gentempname __P((struct entry *));
+void getfile __P((void (*)(char *, size_t), void (*)(char *, size_t)));
+void getvol __P((long));
+void initsymtable __P((char *));
+int inodetype __P((dump_ino_t));
+int linkit __P((char *, char *, int));
+struct entry *lookupino __P((dump_ino_t));
+struct entry *lookupname __P((char *));
+long listfile __P((char *, dump_ino_t, int));
+dump_ino_t lowerbnd __P((dump_ino_t));
+void mktempname __P((struct entry *));
+void moveentry __P((struct entry *, char *));
+void msg __P((const char *, ...));
+char *myname __P((struct entry *));
+void newnode __P((struct entry *));
+void newtapebuf __P((long));
+long nodeupdates __P((char *, dump_ino_t, int));
+void onintr __P((int));
+void panic __P((const char *, ...));
+void pathcheck __P((char *));
+struct direct *pathsearch __P((const char *));
+void printdumpinfo __P((void));
+void printvolinfo __P((void));
+void removeleaf __P((struct entry *));
+void removenode __P((struct entry *));
+void removeoldleaves __P((void));
+void removeoldnodes __P((void));
+void renameit __P((char *, char *));
+int reply __P((const char *));
+void resizemaps __P((dump_ino_t, dump_ino_t));
+RST_DIR *rst_opendir __P((const char *));
+struct direct *rst_readdir __P((RST_DIR *));
+void rst_closedir __P((RST_DIR *dirp));
+void runcmdshell __P((void));
+char *savename __P((char *));
+void setdirmodes __P((int));
+void setinput __P((char *));
+void setup __P((void));
+void skipdirs __P((void));
+void skipfile __P((void));
+void skipmaps __P((void));
+void swabst __P((u_char *, u_char *));
+void treescan __P((char *, dump_ino_t, long (*)(char *, dump_ino_t, int)));
+dump_ino_t upperbnd __P((dump_ino_t));
+long verifyfile __P((char *, dump_ino_t, int));
+void xtrnull __P((char *, size_t));
+
+/* From ../dump/dumprmt.c */
+void rmtclose __P((void));
+int rmthost __P((const char *));
+int rmtioctl __P((int, int));
+int rmtopen __P((const char *, const int));
+int rmtread __P((const char *, int));
+OFF_T rmtseek __P((OFF_T, int));
+
+/* From e2fsprogs */
+int fsetflags __P((const char *, unsigned long));
+int fgetflags __P((const char *, unsigned long *));
+int setflags __P((int, unsigned long));
+
+#ifdef USE_QFA
+int Inode2Tapepos __P((dump_ino_t, long *, long long *, int));
+int GetTapePos __P((long long *));
+int GotoTapePos __P((long long));
+void ReReadFromTape __P((void));
+void ReReadInodeFromTape __P((dump_ino_t));
+void GetPathFile __P((char *, char *, char *));
+
+#ifdef sunos
+int GetSCSIIDFromPath __P((char *, long *));
+int OpenSMTCmt(char *);
+#endif
+#endif
+void RequestVol __P((long));
+
+#ifdef DUMP_MACOSX
+int extractfinderinfoufs __P((char *));
+int extractresourceufs __P((char *));
+int CreateAppleDoubleFileRes __P((char *, FndrFileInfo *, mode_t, int, struct timeval *, u_int32_t, u_int32_t));
+#endif
+
+
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: interactive.c,v 1.27 2003/10/26 16:05:48 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#endif
+#endif /* __linux__ */
+#include <protocols/dumprestore.h>
+
+#include <setjmp.h>
+#include <compaterr.h>
+#include <errno.h>
+#include <compatglob.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __linux__
+#include <ext2fs/ext2fs.h>
+#endif
+
+#if defined(__linux__) || defined(sunos)
+extern char * __progname;
+#endif
+
+#include "restore.h"
+#include "extern.h"
+
+#if HAVE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+
+static char *rl_gets (char *prompt);
+static void initialize_readline(void);
+static char **restore_completion (const char *text, int start, int end);
+static char *command_generator(const char *text, int state);
+static char *filename_generator(const char *text, int state);
+#endif
+
+#define round(a, b) (((a) + (b) - 1) / (b) * (b))
+
+/*
+ * Things to handle interruptions.
+ */
+static int runshell;
+static jmp_buf reset;
+static char *nextarg = NULL;
+static int pflag = 0; /* prompt mode */
+/*
+ * Structure and routines associated with listing directories.
+ */
+struct afile {
+ dump_ino_t fnum; /* inode number of file */
+ char *fname; /* file name */
+ short len; /* name length */
+ char prefix; /* prefix character */
+ char postfix; /* postfix character */
+};
+struct arglist {
+ int freeglob; /* glob structure needs to be freed */
+ int argcnt; /* next globbed argument to return */
+ glob_t glob; /* globbing information */
+ char *cmd; /* the current command */
+};
+
+static char *copynext __P((char *, char *));
+static int fcmp __P((const void *, const void *));
+static void formatf __P((struct afile *, int));
+static void getcmd __P((char *, char *, char *, int, struct arglist *));
+struct dirent *glob_readdir __P((RST_DIR *dirp));
+static int glob_stat __P((const char *, struct stat *));
+static void mkentry __P((char *, struct direct *, struct afile *));
+static void printlist __P((char *, char *));
+
+/*
+ * Read and execute commands from the terminal.
+ */
+void
+runcmdshell(void)
+{
+ struct entry *np;
+ dump_ino_t ino;
+ struct arglist arglist;
+ char curdir[MAXPATHLEN];
+ char name[MAXPATHLEN];
+ char cmd[BUFSIZ];
+
+#if HAVE_READLINE
+ initialize_readline();
+#endif
+ arglist.freeglob = 0;
+ arglist.argcnt = 0;
+ arglist.glob.gl_flags = GLOB_ALTDIRFUNC;
+ arglist.glob.gl_opendir = (void *)rst_opendir;
+ arglist.glob.gl_readdir = (void *)glob_readdir;
+ arglist.glob.gl_closedir = (void *)rst_closedir;
+ arglist.glob.gl_lstat = (int (*)(const char *, void *))glob_stat;
+ arglist.glob.gl_stat = (int (*)(const char *, void *))glob_stat;
+ canon("/", curdir, sizeof(curdir));
+loop:
+ if (setjmp(reset) != 0) {
+ if (arglist.freeglob != 0) {
+ arglist.freeglob = 0;
+ arglist.argcnt = 0;
+ globfree(&arglist.glob);
+ }
+ nextarg = NULL;
+ volno = 0;
+ }
+ runshell = 1;
+ getcmd(curdir, cmd, name, sizeof(name), &arglist);
+ switch (cmd[0]) {
+ /*
+ * Add elements to the extraction list.
+ */
+ case 'a':
+ if (strncmp(cmd, "add", strlen(cmd)) != 0)
+ goto bad;
+ ino = dirlookup(name);
+ if (ino == 0)
+ break;
+ if (mflag)
+ pathcheck(name);
+ treescan(name, ino, addfile);
+ break;
+ /*
+ * Change working directory.
+ */
+ case 'c':
+ if (strncmp(cmd, "cd", strlen(cmd)) != 0)
+ goto bad;
+ ino = dirlookup(name);
+ if (ino == 0)
+ break;
+ if (inodetype(ino) == LEAF) {
+ fprintf(stderr, "%s: not a directory\n", name);
+ break;
+ }
+ (void) strncpy(curdir, name, sizeof(curdir));
+ curdir[sizeof(curdir) - 1] = '\0';
+ break;
+ /*
+ * Delete elements from the extraction list.
+ */
+ case 'd':
+ if (strncmp(cmd, "delete", strlen(cmd)) != 0)
+ goto bad;
+ np = lookupname(name);
+ if (np == NULL || (np->e_flags & NEW) == 0) {
+ fprintf(stderr, "%s: not on extraction list\n", name);
+ break;
+ }
+ treescan(name, np->e_ino, deletefile);
+ break;
+ /*
+ * Extract the requested list.
+ */
+ case 'e':
+ if (strncmp(cmd, "extract", strlen(cmd)) != 0)
+ goto bad;
+ createfiles();
+ createlinks();
+ setdirmodes(oflag ? FORCE : 0);
+ if (dflag)
+ checkrestore();
+ volno = 0;
+ break;
+ /*
+ * List available commands.
+ */
+ case 'h':
+ if (strncmp(cmd, "help", strlen(cmd)) != 0)
+ goto bad;
+ case '?':
+ fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "Available commands are:\n",
+ "\tls [arg] - list directory\n",
+ "\tcd arg - change directory\n",
+ "\tpwd - print current directory\n",
+ "\tadd [arg] - add `arg' to list of",
+ " files to be extracted\n",
+ "\tdelete [arg] - delete `arg' from",
+ " list of files to be extracted\n",
+ "\textract - extract requested files\n",
+ "\tsetmodes - set modes of requested directories\n",
+ "\tquit - immediately exit program\n",
+ "\twhat - list dump header information\n",
+ "\tverbose - toggle verbose flag",
+ " (useful with ``ls'')\n",
+ "\tprompt - toggle the prompt display\n",
+ "\thelp or `?' - print this list\n",
+ "If no `arg' is supplied, the current",
+ " directory is used\n");
+ break;
+ /*
+ * List a directory.
+ */
+ case 'l':
+ if (strncmp(cmd, "ls", strlen(cmd)) != 0)
+ goto bad;
+ printlist(name, curdir);
+ break;
+ /*
+ * Print current directory.
+ */
+ case 'p':
+ if (strncmp(cmd, "pwd", strlen(cmd)) == 0) {
+ if (curdir[1] == '\0')
+ fprintf(stderr, "/\n");
+ else
+ fprintf(stderr, "%s\n", &curdir[1]);
+ }
+ /*
+ * Toggle prompt mode.
+ */
+ else if (strncmp(cmd, "prompt", strlen(cmd)) == 0) {
+ if (pflag) {
+ fprintf(stderr, "prompt mode off\n");
+ pflag = 0;
+ break;
+ }
+ fprintf(stderr, "prompt mode on\n");
+ pflag++;
+ break;
+ }
+ else goto bad;
+ break;
+ /*
+ * Quit.
+ */
+ case 'q':
+ if (strncmp(cmd, "quit", strlen(cmd)) != 0)
+ goto bad;
+ return;
+ case 'x':
+ if (strncmp(cmd, "xit", strlen(cmd)) != 0)
+ goto bad;
+ return;
+ /*
+ * Toggle verbose mode.
+ */
+ case 'v':
+ if (strncmp(cmd, "verbose", strlen(cmd)) != 0)
+ goto bad;
+ if (vflag) {
+ fprintf(stderr, "verbose mode off\n");
+ vflag = 0;
+ break;
+ }
+ fprintf(stderr, "verbose mode on\n");
+ vflag++;
+ break;
+ /*
+ * Just restore requested directory modes.
+ */
+ case 's':
+ if (strncmp(cmd, "setmodes", strlen(cmd)) != 0)
+ goto bad;
+ setdirmodes(FORCE);
+ break;
+ /*
+ * Print out dump header information.
+ */
+ case 'w':
+ if (strncmp(cmd, "what", strlen(cmd)) != 0)
+ goto bad;
+ printdumpinfo();
+ printvolinfo();
+ break;
+ /*
+ * Turn on debugging.
+ */
+ case 'D':
+ if (strncmp(cmd, "Debug", strlen(cmd)) != 0)
+ goto bad;
+ if (dflag) {
+ fprintf(stderr, "debugging mode off\n");
+ dflag = 0;
+ break;
+ }
+ fprintf(stderr, "debugging mode on\n");
+ dflag++;
+ break;
+ /*
+ * Unknown command.
+ */
+ default:
+ bad:
+ fprintf(stderr, "%s: unknown command; type ? for help\n", cmd);
+ break;
+ }
+ goto loop;
+}
+
+/*
+ * Read and parse an interactive command.
+ * The first word on the line is assigned to "cmd". If
+ * there are no arguments on the command line, then "curdir"
+ * is returned as the argument. If there are arguments
+ * on the line they are returned one at a time on each
+ * successive call to getcmd. Each argument is first assigned
+ * to "name". If it does not start with "/" the pathname in
+ * "curdir" is prepended to it. Finally "canon" is called to
+ * eliminate any embedded ".." components.
+ */
+static void
+getcmd(char *curdir, char *cmd, char *name, int size, struct arglist *ap)
+{
+ char *cp;
+ static char input[BUFSIZ];
+ char output[BUFSIZ];
+# define rawname input /* save space by reusing input buffer */
+
+ /*
+ * Check to see if still processing arguments.
+ */
+ if (ap->argcnt > 0)
+ goto retnext;
+ if (nextarg != NULL)
+ goto getnext;
+ /*
+ * Read a command line and trim off trailing white space.
+ */
+#if HAVE_READLINE
+ snprintf(input, BUFSIZ, "%s\n", rl_gets(curdir));
+#else
+ do {
+ if (pflag)
+ fprintf(stderr, "%s:%s:%s > ",
+ __progname,
+ spcl.c_filesys,
+ curdir[1] ? &curdir[1] : "/");
+ else
+ fprintf(stderr, "%s > ", __progname);
+ (void) fflush(stderr);
+ (void) fgets(input, BUFSIZ, terminal);
+ } while (!feof(terminal) && input[0] == '\n');
+ if (feof(terminal)) {
+ (void) strcpy(cmd, "quit");
+ return;
+ }
+#endif
+ for (cp = &input[strlen(input) - 2]; *cp == ' ' || *cp == '\t'; cp--)
+ /* trim off trailing white space and newline */;
+ *++cp = '\0';
+ /*
+ * Copy the command into "cmd".
+ */
+ cp = copynext(input, cmd);
+ ap->cmd = cmd;
+ /*
+ * If no argument, use curdir as the default.
+ */
+ if (*cp == '\0') {
+ (void) strncpy(name, curdir, size);
+ name[size - 1] = '\0';
+ return;
+ }
+ nextarg = cp;
+ /*
+ * Find the next argument.
+ */
+getnext:
+ cp = copynext(nextarg, rawname);
+ if (*cp == '\0')
+ nextarg = NULL;
+ else
+ nextarg = cp;
+ /*
+ * If it is an absolute pathname, canonicalize it and return it.
+ */
+ if (rawname[0] == '/') {
+ canon(rawname, name, size);
+ } else {
+ /*
+ * For relative pathnames, prepend the current directory to
+ * it then canonicalize and return it.
+ */
+ snprintf(output, sizeof(output), "%s/%s", curdir, rawname);
+ canon(output, name, size);
+ }
+ if (glob(name, GLOB_ALTDIRFUNC, NULL, &ap->glob) < 0)
+ fprintf(stderr, "%s: out of memory\n", ap->cmd);
+ if (ap->glob.gl_pathc == 0)
+ return;
+ ap->freeglob = 1;
+ ap->argcnt = ap->glob.gl_pathc;
+
+retnext:
+ strncpy(name, ap->glob.gl_pathv[ap->glob.gl_pathc - ap->argcnt], size);
+ name[size - 1] = '\0';
+ if (--ap->argcnt == 0) {
+ ap->freeglob = 0;
+ globfree(&ap->glob);
+ }
+# undef rawname
+}
+
+/*
+ * Strip off the next token of the input.
+ */
+static char *
+copynext(char *input, char *output)
+{
+ char *cp, *bp;
+ char quote;
+
+ for (cp = input; *cp == ' ' || *cp == '\t'; cp++)
+ /* skip to argument */;
+ bp = output;
+ while (*cp != ' ' && *cp != '\t' && *cp != '\0') {
+ /*
+ * Handle back slashes.
+ */
+ if (*cp == '\\') {
+ if (*++cp == '\0') {
+ fprintf(stderr,
+ "command lines cannot be continued\n");
+ continue;
+ }
+ *bp++ = *cp++;
+ continue;
+ }
+ /*
+ * The usual unquoted case.
+ */
+ if (*cp != '\'' && *cp != '"') {
+ *bp++ = *cp++;
+ continue;
+ }
+ /*
+ * Handle single and double quotes.
+ */
+ quote = *cp++;
+ while (*cp != quote && *cp != '\0')
+ *bp++ = *cp++;
+ if (*cp++ == '\0') {
+ fprintf(stderr, "missing %c\n", quote);
+ cp--;
+ continue;
+ }
+ }
+ *bp = '\0';
+ return (cp);
+}
+
+/*
+ * Canonicalize file names to always start with ``./'' and
+ * remove any embedded "." and ".." components.
+ */
+void
+canon(char *rawname, char *canonname, int len)
+{
+ char *cp, *np;
+
+ if (strcmp(rawname, ".") == 0 || strncmp(rawname, "./", 2) == 0)
+ (void) strcpy(canonname, "");
+ else if (rawname[0] == '/')
+ (void) strcpy(canonname, ".");
+ else
+ (void) strcpy(canonname, "./");
+ if (strlen(canonname) + strlen(rawname) >= (unsigned)len)
+ errx(1, "canonname: not enough buffer space");
+
+ (void) strcat(canonname, rawname);
+ /*
+ * Eliminate multiple and trailing '/'s
+ */
+ for (cp = np = canonname; *np != '\0'; cp++) {
+ *cp = *np++;
+ while (*cp == '/' && *np == '/')
+ np++;
+ }
+ *cp = '\0';
+ if (*--cp == '/')
+ *cp = '\0';
+ /*
+ * Eliminate extraneous "." and ".." from pathnames.
+ */
+ for (np = canonname; *np != '\0'; ) {
+ np++;
+ cp = np;
+ while (*np != '/' && *np != '\0')
+ np++;
+ if (np - cp == 1 && *cp == '.') {
+ cp--;
+ (void) strcpy(cp, np);
+ np = cp;
+ }
+ if (np - cp == 2 && strncmp(cp, "..", 2) == 0) {
+ cp--;
+ while (cp > &canonname[1] && *--cp != '/')
+ /* find beginning of name */;
+ (void) strcpy(cp, np);
+ np = cp;
+ }
+ }
+}
+
+/*
+ * Do an "ls" style listing of a directory
+ */
+static void
+printlist(char *name, char *basename)
+{
+ struct afile *fp, *list, *listp = NULL;
+ struct direct *dp;
+ struct afile single;
+ RST_DIR *dirp;
+ int entries, len, namelen;
+ char locname[MAXPATHLEN + 1];
+
+ dp = pathsearch(name);
+ if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
+ (!vflag && dp->d_ino == WINO))
+ return;
+ if ((dirp = rst_opendir(name)) == NULL) {
+ entries = 1;
+ list = &single;
+ mkentry(name, dp, list);
+ len = strlen(basename) + 1;
+ if (strlen(name) - len > (unsigned)single.len) {
+ freename(single.fname);
+ single.fname = savename(&name[len]);
+ single.len = strlen(single.fname);
+ }
+ } else {
+ entries = 0;
+ while ((dp = rst_readdir(dirp)))
+ entries++;
+ rst_closedir(dirp);
+ list = (struct afile *)malloc(entries * sizeof(struct afile));
+ if (list == NULL) {
+ fprintf(stderr, "ls: out of memory\n");
+ return;
+ }
+ if ((dirp = rst_opendir(name)) == NULL)
+ panic("directory reopen failed\n");
+ fprintf(stderr, "%s:\n", name);
+ entries = 0;
+ listp = list;
+ namelen = snprintf(locname, sizeof(locname), "%s/", name);
+ if (namelen >= (int)sizeof(locname))
+ namelen = sizeof(locname) - 1;
+ while ((dp = rst_readdir(dirp))) {
+ if (dp == NULL)
+ break;
+ if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0)
+ continue;
+ if (!vflag && (dp->d_ino == WINO ||
+ strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0))
+ continue;
+ locname[namelen] = '\0';
+ if (namelen + strlen(dp->d_name) >= MAXPATHLEN) {
+ fprintf(stderr, "%s%s: name exceeds %d char\n",
+ locname, dp->d_name, MAXPATHLEN);
+ } else {
+ (void) strncat(locname, dp->d_name,
+ (int)strlen(dp->d_name));
+ mkentry(locname, dp, listp++);
+ entries++;
+ }
+ }
+ rst_closedir(dirp);
+ if (entries == 0) {
+ fprintf(stderr, "\n");
+ free(list);
+ return;
+ }
+ qsort((char *)list, entries, sizeof(struct afile), fcmp);
+ }
+ formatf(list, entries);
+ if (dirp != NULL) {
+ for (fp = listp - 1; fp >= list; fp--)
+ freename(fp->fname);
+ fprintf(stderr, "\n");
+ free(list);
+ }
+}
+
+/*
+ * Read the contents of a directory.
+ */
+static void
+mkentry(char *name, struct direct *dp, struct afile *fp)
+{
+ char *cp;
+ struct entry *np;
+
+ fp->fnum = dp->d_ino;
+ fp->fname = savename(dp->d_name);
+ for (cp = fp->fname; *cp; cp++)
+ if (!vflag && (*cp < ' ' || *cp >= 0177))
+ *cp = '?';
+ fp->len = cp - fp->fname;
+ if (dflag && TSTINO(fp->fnum, dumpmap) == 0)
+ fp->prefix = '^';
+ else if ((np = lookupname(name)) != NULL && (np->e_flags & NEW))
+ fp->prefix = '*';
+ else
+ fp->prefix = ' ';
+ switch(dp->d_type) {
+
+ default:
+ fprintf(stderr, "Warning: undefined file type %d\n",
+ dp->d_type);
+ /* fall through */
+ case DT_REG:
+ fp->postfix = ' ';
+ break;
+
+ case DT_LNK:
+ fp->postfix = '@';
+ break;
+
+ case DT_FIFO:
+ case DT_SOCK:
+ fp->postfix = '=';
+ break;
+
+ case DT_CHR:
+ case DT_BLK:
+ fp->postfix = '#';
+ break;
+
+#ifndef __linux__
+ /* no need for this */
+ case DT_WHT:
+ fp->postfix = '%';
+ break;
+#endif
+
+ case DT_UNKNOWN:
+ case DT_DIR:
+ if (inodetype(dp->d_ino) == NODE)
+ fp->postfix = '/';
+ else
+ fp->postfix = ' ';
+ break;
+ }
+ return;
+}
+
+/*
+ * Print out a pretty listing of a directory
+ */
+static void
+formatf(struct afile *list, int nentry)
+{
+ struct afile *fp, *endlist;
+ int width, bigino, haveprefix, havepostfix;
+ int i, j, w, precision = 0, columns, lines;
+
+ width = 0;
+ haveprefix = 0;
+ havepostfix = 0;
+ bigino = ROOTINO;
+ endlist = &list[nentry];
+ for (fp = &list[0]; fp < endlist; fp++) {
+ if (bigino < (int)fp->fnum)
+ bigino = fp->fnum;
+ if (width < fp->len)
+ width = fp->len;
+ if (fp->prefix != ' ')
+ haveprefix = 1;
+ if (fp->postfix != ' ')
+ havepostfix = 1;
+ }
+ if (haveprefix)
+ width++;
+ if (havepostfix)
+ width++;
+ if (vflag) {
+ for (precision = 0, i = bigino; i > 0; i /= 10)
+ precision++;
+ width += precision + 1;
+ }
+ width++;
+ columns = 81 / width;
+ if (columns == 0)
+ columns = 1;
+ lines = (nentry + columns - 1) / columns;
+ for (i = 0; i < lines; i++) {
+ for (j = 0; j < columns; j++) {
+ fp = &list[j * lines + i];
+ if (vflag) {
+ fprintf(stderr, "%*ld ", precision, (long)fp->fnum);
+ fp->len += precision + 1;
+ }
+ if (haveprefix) {
+ putc(fp->prefix, stderr);
+ fp->len++;
+ }
+ fprintf(stderr, "%s", fp->fname);
+ if (havepostfix) {
+ putc(fp->postfix, stderr);
+ fp->len++;
+ }
+ if (fp + lines >= endlist) {
+ fprintf(stderr, "\n");
+ break;
+ }
+ for (w = fp->len; w < width; w++)
+ putc(' ', stderr);
+ }
+ }
+}
+
+/*
+ * Skip over directory entries that are not on the tape
+ *
+ * First have to get definition of a dirent.
+ *
+ * For Linux the dirent struct is now included from bsdcompat.h
+ */
+#ifndef __linux__
+#undef DIRBLKSIZ
+#include <dirent.h>
+#undef d_ino
+#endif /* ! __linux__ */
+
+struct dirent *
+glob_readdir(RST_DIR *dirp)
+{
+ struct direct *dp;
+ static struct dirent adirent;
+
+ while ((dp = rst_readdir(dirp)) != NULL) {
+ if (!vflag && dp->d_ino == WINO)
+ continue;
+ if (dflag || TSTINO(dp->d_ino, dumpmap))
+ break;
+ }
+ if (dp == NULL)
+ return (NULL);
+ adirent.d_fileno = dp->d_ino;
+ memmove(adirent.d_name, dp->d_name, dp->d_namlen + 1);
+ return (&adirent);
+}
+
+/*
+ * Return st_mode information in response to stat or lstat calls
+ */
+static int
+glob_stat(const char *name, struct stat *stp)
+{
+ struct direct *dp;
+ dp = pathsearch(name);
+ if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
+ (!vflag && dp->d_ino == WINO))
+ return (-1);
+ if (inodetype(dp->d_ino) == NODE)
+ stp->st_mode = IFDIR;
+ else
+ stp->st_mode = IFREG;
+ return (0);
+}
+
+/*
+ * Comparison routine for qsort.
+ */
+static int
+fcmp(const void *f1, const void *f2)
+{
+ return (strcmp(((struct afile *)f1)->fname,
+ ((struct afile *)f2)->fname));
+}
+
+/*
+ * respond to interrupts
+ */
+void
+onintr(UNUSED(int signo))
+{
+ int save_errno = errno;
+
+ if (command == 'i' && runshell)
+ longjmp(reset, 1);
+ if (reply("restore interrupted, continue") == FAIL)
+ exit(1);
+ errno = save_errno;
+}
+
+
+#if HAVE_READLINE
+
+#if !HAVE_READLINE_RLCM
+#define rl_completion_matches completion_matches
+#endif
+
+/* A static variable for holding the line. */
+static char *line_read = NULL;
+
+static char completion_curdir[MAXPATHLEN];
+
+static char *commands[] = {
+ "add ", "cd ", "delete ", "extract ", "help ",
+ "? ", "ls ", "pwd ", "prompt ", "quit ", "xit ",
+ "verbose ", "setmodes ", "what ", "Debug ",
+ NULL };
+
+static char *files = NULL;
+
+static char *
+rl_gets (char *dir)
+{
+ char *prompt;
+ int sz;
+
+ snprintf(completion_curdir, MAXPATHLEN, "%s", dir);
+ completion_curdir[MAXPATHLEN - 1] = '\0';
+
+ if (pflag) {
+ sz = 6 + strlen(__progname) + strlen(spcl.c_filesys) + strlen((completion_curdir + 1 ? completion_curdir + 1 : "/"));
+ prompt = (char *)malloc(sz);
+ if (!prompt)
+ return NULL;
+ snprintf(prompt, sz, "%s:%s:%s > ",
+ __progname,
+ spcl.c_filesys,
+ (completion_curdir + 1 ? completion_curdir + 1 : "/"));
+ }
+ else {
+ sz = 4 + strlen(__progname);
+ prompt = (char *)malloc(sz);
+ if (!prompt)
+ return NULL;
+ snprintf(prompt, sz, "%s > ", __progname);
+ }
+ prompt[sz - 1] = '\0';
+
+ if (line_read) {
+ free (line_read);
+ line_read = (char *)NULL;
+ }
+
+ do {
+ line_read = readline (prompt);
+ } while (line_read && !*line_read);
+
+ free(prompt);
+
+ if (!line_read) {
+ printf("\n");
+ return strdup("quit");
+ }
+
+ add_history (line_read);
+
+ return (line_read);
+}
+
+static char *
+command_generator(const char *text, int state)
+{
+ static int list_index, len;
+ char *name;
+
+ if (!state) {
+ list_index = 0;
+ len = strlen(text);
+ }
+
+ while ( (name = commands[list_index]) != NULL) {
+
+ list_index ++;
+
+ if (strncmp(name, text, len) == 0)
+ return strdup(name);
+ }
+
+ return NULL;
+}
+
+static char *
+filename_generator(const char *text, int state)
+{
+ static int list_index;
+ char *name;
+ RST_DIR *dirp;
+ struct direct *dp;
+ static int entries;
+ char pname[MAXPATHLEN];
+ char fname[MAXPATHLEN];
+ char *slash;
+ char ppname[MAXPATHLEN];
+
+ if (!state) {
+ list_index = 0;
+
+ if (files != NULL) {
+ free(files);
+ entries = 0;
+ files = NULL;
+ }
+ if ((slash = strrchr(text, '/')) != NULL) {
+ int idx = slash - text;
+ if (idx > MAXPATHLEN - 2)
+ idx = MAXPATHLEN - 2;
+ strncpy(ppname, text, MAXPATHLEN);
+ ppname[MAXPATHLEN - 1] = '\0';
+ ppname[idx] = '\0';
+ if (text[0] == '/')
+ snprintf(pname, MAXPATHLEN, ".%s", ppname);
+ else
+ snprintf(pname, MAXPATHLEN, "%s/%s", completion_curdir, ppname);
+ strncpy(fname, ppname + idx + 1, MAXPATHLEN);
+ ppname[idx] = '/';
+ ppname[idx + 1] = '\0';
+ }
+ else {
+ strncpy(pname, completion_curdir, MAXPATHLEN);
+ strncpy(fname, text, MAXPATHLEN);
+ ppname[0] = '\0';
+ }
+ pname[MAXPATHLEN - 1] = '\0';
+ fname[MAXPATHLEN - 1] = '\0';
+ if ((dirp = rst_opendir(pname)) == NULL)
+ return NULL;
+ entries = 0;
+ while ((dp = rst_readdir(dirp)))
+ entries++;
+ rst_closedir(dirp);
+ files = (char *)malloc(entries * MAXPATHLEN);
+ if (files == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ entries = 0;
+ return NULL;
+ }
+ if ((dirp = rst_opendir(pname)) == NULL)
+ panic("directory reopen failed\n");
+ entries = 0;
+ while ((dp = rst_readdir(dirp))) {
+ if (TSTINO(dp->d_ino, dumpmap) == 0)
+ continue;
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ if (strncmp(dp->d_name, fname, strlen(fname)) == 0) {
+ if (inodetype(dp->d_ino) == NODE)
+ snprintf(files + entries * MAXPATHLEN, MAXPATHLEN, "%s%s/", ppname, dp->d_name);
+ else
+ snprintf(files + entries * MAXPATHLEN, MAXPATHLEN, "%s%s ", ppname, dp->d_name);
+ *(files + (entries + 1) * MAXPATHLEN - 1) = '\0';
+ ++entries;
+ }
+ }
+ rst_closedir(dirp);
+ }
+
+ if (list_index >= entries)
+ return NULL;
+
+ name = strdup(files + list_index * MAXPATHLEN);
+ list_index ++;
+
+ return name;
+}
+
+static char **
+restore_completion (const char *text, int start, UNUSED(int end))
+{
+ char **matches;
+
+ if (start == 0)
+ matches = rl_completion_matches (text, command_generator);
+ else
+ matches = rl_completion_matches (text, filename_generator);
+
+ return (matches);
+}
+
+static void
+initialize_readline(void)
+{
+ rl_readline_name = "dump";
+ rl_attempted_completion_function = restore_completion;
+ rl_completion_entry_function = NULL;
+#if HAVE_READLINE_CAC /* compile with readline 2.0 */
+ rl_completion_append_character = '\0';
+#endif
+ rl_instream = terminal;
+}
+
+#endif /* HAVE_READLINE */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: main.c,v 1.46 2004/04/13 13:04:33 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#ifdef __linux__
+#include <sys/time.h>
+#include <time.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#include <signal.h>
+#include <string.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <signal.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#include <sys/mtio.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+#endif /* __linux__ */
+#include <protocols/dumprestore.h>
+
+#include <compaterr.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef __linux__
+#include <ext2fs/ext2fs.h>
+#include <getopt.h>
+#endif
+
+#include "pathnames.h"
+#include "restore.h"
+#include "extern.h"
+
+int abortifconnerr = 1; /* set to 1 if lib dumprmt.o should exit on connection errors
+ otherwise just print a message using msg */
+
+int aflag = 0, bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
+int hflag = 1, mflag = 1, Mflag = 0, Nflag = 0, Vflag = 0, zflag = 0;
+int uflag = 0, lflag = 0, Lflag = 0, oflag = 0;
+int ufs2flag = 0;
+char *Afile = NULL;
+int dokerberos = 0;
+char command = '\0';
+long dumpnum = 1;
+long volno = 0;
+long ntrec;
+char *dumpmap = NULL;
+char *usedinomap = NULL;
+dump_ino_t maxino;
+time_t dumptime;
+time_t dumpdate;
+FILE *terminal;
+char *tmpdir;
+int compare_ignore_not_found;
+int compare_errors;
+char filesys[NAMELEN];
+static const char *stdin_opt = NULL;
+char *bot_script = NULL;
+dump_ino_t volinfo[TP_NINOS];
+
+#ifdef USE_QFA
+FILE *gTapeposfp;
+char *gTapeposfile;
+char gTps[255];
+long gSeekstart;
+int tapeposflag;
+int gTapeposfd;
+int createtapeposflag;
+unsigned long qfadumpdate;
+long long curtapepos;
+#endif /* USE_QFA */
+
+long smtc_errno;
+
+#if defined(__linux__) || defined(sunos)
+char *__progname;
+#endif
+
+static void obsolete __P((int *, char **[]));
+static void usage __P((void));
+static void use_stdin __P((const char *));
+
+#define FORCED_UMASK (077)
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ dump_ino_t ino;
+ char *inputdev = _PATH_DEFTAPE;
+ char *symtbl = "./restoresymtable";
+ char *p, name[MAXPATHLEN];
+ FILE *filelist = NULL;
+ char fname[MAXPATHLEN];
+ mode_t orig_umask;
+#ifdef DEBUG_QFA
+ time_t tistart, tiend, titaken;
+#endif
+#ifdef USE_QFA
+ tapeposflag = 0;
+ createtapeposflag = 0;
+#endif /* USE_QFA */
+
+ /* Temp files should *not* be readable. We set permissions later. */
+ orig_umask = umask(FORCED_UMASK);
+ filesys[0] = '\0';
+#if defined(__linux__) || defined(sunos)
+ __progname = argv[0];
+#endif
+
+ if (argc < 2)
+ usage();
+
+ if ((inputdev = getenv("TAPE")) == NULL)
+ inputdev = _PATH_DEFTAPE;
+ if ((tmpdir = getenv("TMPDIR")) == NULL)
+ tmpdir = _PATH_TMP;
+ if ((tmpdir = strdup(tmpdir)) == NULL)
+ err(1, "malloc tmpdir");
+ for (p = tmpdir + strlen(tmpdir) - 1; p >= tmpdir && *p == '/'; p--)
+ ;
+ obsolete(&argc, &argv);
+ while ((ch = getopt(argc, argv,
+ "aA:b:CcdD:f:F:hi"
+#ifdef KERBEROS
+ "k"
+#endif
+ "lL:mMNo"
+#ifdef USE_QFA
+ "P:Q:"
+#endif
+ "Rrs:tT:uvVxX:y")) != -1)
+ switch(ch) {
+ case 'a':
+ aflag = 1;
+ break;
+ case 'A':
+ Afile = optarg;
+ aflag = 1;
+ break;
+ case 'b':
+ /* Change default tape blocksize. */
+ bflag = 1;
+ ntrec = strtol(optarg, &p, 10);
+ if (*p)
+ errx(1, "illegal blocksize -- %s", optarg);
+ if (ntrec <= 0)
+ errx(1, "block size must be greater than 0");
+ break;
+ case 'c':
+ cvtflag = 1;
+ break;
+ case 'D':
+ strncpy(filesys, optarg, NAMELEN);
+ filesys[NAMELEN - 1] = '\0';
+ break;
+ case 'T':
+ tmpdir = optarg;
+ break;
+ case 'd':
+ dflag = 1;
+ break;
+ case 'f':
+ if( !strcmp(optarg,"-") )
+ use_stdin("-f");
+ inputdev = optarg;
+ break;
+ case 'F':
+ bot_script = optarg;
+ break;
+ case 'h':
+ hflag = 0;
+ break;
+#ifdef KERBEROS
+ case 'k':
+ dokerberos = 1;
+ break;
+#endif
+ case 'C':
+ case 'i':
+#ifdef USE_QFA
+ case 'P':
+#endif
+ case 'R':
+ case 'r':
+ case 't':
+ case 'x':
+ if (command != '\0')
+ errx(1,
+ "%c and %c options are mutually exclusive",
+ ch, command);
+ command = ch;
+#ifdef USE_QFA
+ if (ch == 'P') {
+ gTapeposfile = optarg;
+ createtapeposflag = 1;
+ }
+#endif
+
+ break;
+ case 'l':
+ lflag = 1;
+ break;
+ case 'L':
+ Lflag = strtol(optarg, &p, 10);
+ if (*p)
+ errx(1, "illegal limit -- %s", optarg);
+ if (Lflag < 0)
+ errx(1, "limit must be greater than 0");
+ break;
+ case 'm':
+ mflag = 0;
+ break;
+ case 'M':
+ Mflag = 1;
+ break;
+ case 'N':
+ Nflag = 1;
+ break;
+ case 'o':
+ oflag = 1;
+ break;
+#ifdef USE_QFA
+ case 'Q':
+ gTapeposfile = optarg;
+ tapeposflag = 1;
+ aflag = 1;
+ break;
+#endif
+ case 's':
+ /* Dumpnum (skip to) for multifile dump tapes. */
+ dumpnum = strtol(optarg, &p, 10);
+ if (*p)
+ errx(1, "illegal dump number -- %s", optarg);
+ if (dumpnum <= 0)
+ errx(1, "dump number must be greater than 0");
+ break;
+ case 'u':
+ uflag = 1;
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ case 'V':
+ Vflag = 1;
+ break;
+ case 'X':
+ if( !strcmp(optarg,"-") ) {
+ use_stdin("-X");
+ filelist = stdin;
+ }
+ else
+ if ( !(filelist = fopen(optarg,"r")) )
+ errx(1, "can't open file for reading -- %s", optarg);
+ break;
+ case 'y':
+ yflag = 1;
+ break;
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (command == '\0')
+ errx(1, "none of C, i, R, r, t or x options specified");
+
+#ifdef USE_QFA
+ if (!mflag && tapeposflag)
+ errx(1, "m and Q options are mutually exclusive");
+
+ if (tapeposflag && command != 'i' && command != 'x' && command != 't')
+ errx(1, "Q option is not valid for %c command", command);
+#endif
+
+ if (Afile && command != 'i' && command != 'x' && command != 't')
+ errx(1, "A option is not valid for %c command", command);
+
+ if (signal(SIGINT, onintr) == SIG_IGN)
+ (void) signal(SIGINT, SIG_IGN);
+ if (signal(SIGTERM, onintr) == SIG_IGN)
+ (void) signal(SIGTERM, SIG_IGN);
+ setlinebuf(stderr);
+
+ atexit(cleanup);
+
+ if (command == 'C' && inputdev[0] != '/' && strcmp(inputdev, "-")
+#ifdef RRESTORE
+ && !strchr(inputdev, ':')
+#endif
+ ) {
+ /* since we chdir into the directory we are comparing
+ * to, we must retain the full tape path */
+ char wd[MAXPATHLEN], fullpathinput[MAXPATHLEN];
+ if (!getcwd(wd, MAXPATHLEN))
+ err(1, "can't get current directory");
+ snprintf(fullpathinput, MAXPATHLEN, "%s/%s", wd, inputdev);
+ fullpathinput[MAXPATHLEN - 1] = '\0';
+ setinput(fullpathinput);
+ }
+ else
+ setinput(inputdev);
+
+ if (argc == 0 && !filelist) {
+ argc = 1;
+ *--argv = ".";
+ }
+
+#ifdef USE_QFA
+ if (tapeposflag) {
+ msg("reading QFA positions from %s\n", gTapeposfile);
+ if ((gTapeposfp = fopen(gTapeposfile, "r")) == NULL)
+ errx(1, "can't open file for reading -- %s",
+ gTapeposfile);
+ /* start reading header info */
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ gTps[strlen(gTps) - 1] = 0; /* delete end of line */
+ if (strcmp(gTps, QFA_MAGIC) != 0)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ gTps[strlen(gTps) - 1] = 0;
+ if (strcmp(gTps, QFA_VERSION) != 0)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ /* read dumpdate */
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ gTps[strlen(gTps) - 1] = 0;
+ qfadumpdate = atol(gTps);
+ /* read empty line */
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ gTps[strlen(gTps) - 1] = 0;
+ /* read table header line */
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+ errx(1, "not requested format of -- %s", gTapeposfile);
+ gTps[strlen(gTps) - 1] = 0;
+ /* end reading header info */
+ /* tape position table starts here */
+ gSeekstart = ftell(gTapeposfp); /* remember for later use */
+#ifdef sunos
+ if (GetSCSIIDFromPath(inputdev, &scsiid)) {
+ errx(1, "can't get SCSI-ID for %s\n", inputdev);
+ }
+ if (scsiid < 0) {
+ errx(1, "can't get SCSI-ID for %s\n", inputdev);
+ }
+ sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+ if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+ errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno);
+ }
+#endif
+ }
+#endif /* USE_QFA */
+
+ switch (command) {
+ /*
+ * Compare contents of tape.
+ */
+ case 'C': {
+ struct STAT stbuf;
+
+ Vprintf(stdout, "Begin compare restore\n");
+ compare_ignore_not_found = 0;
+ compare_errors = 0;
+ setup();
+ printf("filesys = %s\n", filesys);
+ if (STAT(filesys, &stbuf) < 0)
+ err(1, "cannot stat directory %s", filesys);
+ if (chdir(filesys) < 0)
+ err(1, "cannot cd to %s", filesys);
+ compare_ignore_not_found = dumptime > 0;
+ initsymtable((char *)0);
+ extractdirs(0);
+ treescan(".", ROOTINO, nodeupdates);
+ compareleaves();
+ checkrestore();
+ if (compare_errors) {
+ printf("Some files were modified!\n");
+ exit(2);
+ }
+ break;
+ }
+
+ /*
+ * Interactive mode.
+ */
+ case 'i':
+ setup();
+ extractdirs(1);
+ initsymtable(NULL);
+ runcmdshell();
+ break;
+ /*
+ * Incremental restoration of a file system.
+ */
+ case 'r':
+ aflag = 1; /* in -r or -R mode, -a is default */
+ setup();
+ if (dumptime > 0) {
+ /*
+ * This is an incremental dump tape.
+ */
+ Vprintf(stdout, "Begin incremental restore\n");
+ initsymtable(symtbl);
+ extractdirs(1);
+ removeoldleaves();
+ Vprintf(stdout, "Calculate node updates.\n");
+ treescan(".", ROOTINO, nodeupdates);
+ findunreflinks();
+ removeoldnodes();
+ } else {
+ /*
+ * This is a level zero dump tape.
+ */
+ Vprintf(stdout, "Begin level 0 restore\n");
+ initsymtable((char *)0);
+ extractdirs(1);
+ Vprintf(stdout, "Calculate extraction list.\n");
+ treescan(".", ROOTINO, nodeupdates);
+ }
+ createleaves(symtbl);
+ createlinks();
+ setdirmodes(FORCE);
+ checkrestore();
+ if (dflag) {
+ Vprintf(stdout, "Verify the directory structure\n");
+ treescan(".", ROOTINO, verifyfile);
+ }
+ dumpsymtable(symtbl, (long)1);
+ break;
+ /*
+ * Resume an incremental file system restoration.
+ */
+ case 'R':
+ aflag = 1; /* in -r or -R mode, -a is default */
+ initsymtable(symtbl);
+ skipmaps();
+ skipdirs();
+ createleaves(symtbl);
+ createlinks();
+ setdirmodes(FORCE);
+ checkrestore();
+ dumpsymtable(symtbl, (long)1);
+ break;
+
+/* handle file names from either text file (-X) or the command line */
+#define NEXTFILE(p) \
+ p = NULL; \
+ if (argc) { \
+ --argc; \
+ p = *argv++; \
+ } \
+ else if (filelist) { \
+ if ((p = fgets(fname, MAXPATHLEN, filelist))) { \
+ if ( *p && *(p + strlen(p) - 1) == '\n' ) /* possible null string */ \
+ *(p + strlen(p) - 1) = '\0'; \
+ if ( !*p ) /* skip empty lines */ \
+ continue; \
+ } \
+ }
+
+ /*
+ * List contents of tape.
+ */
+ case 't':
+ setup();
+ extractdirs(0);
+ initsymtable((char *)0);
+ printvolinfo();
+ for (;;) {
+ NEXTFILE(p);
+ if (!p)
+ break;
+ canon(p, name, sizeof(name));
+ ino = dirlookup(name);
+ if (ino == 0)
+ continue;
+ treescan(name, ino, listfile);
+ }
+ break;
+ /*
+ * Batch extraction of tape contents.
+ */
+ case 'x':
+#ifdef DEBUG_QFA
+ tistart = time(NULL);
+#endif
+ setup();
+ extractdirs(1);
+ initsymtable((char *)0);
+ for (;;) {
+ NEXTFILE(p);
+ if (!p)
+ break;
+ canon(p, name, sizeof(name));
+ ino = dirlookup(name);
+ if (ino == 0)
+ continue;
+ if (mflag)
+ pathcheck(name);
+ treescan(name, ino, addfile);
+ }
+ createfiles();
+ createlinks();
+ setdirmodes(oflag ? FORCE : 0);
+ if (dflag)
+ checkrestore();
+#ifdef sunos
+ if (fdsmtc != -1) {
+ close(fdsmtc);
+ }
+#endif /* sunos */
+#ifdef DEBUG_QFA
+ tiend = time(NULL);
+ titaken = tiend - tistart;
+ msg("restore took %d:%02d:%02d\n", titaken / 3600,
+ (titaken % 3600) / 60, titaken % 60);
+#endif /* DEBUG_QFA */
+ break;
+#ifdef USE_QFA
+ case 'P':
+#ifdef DEBUG_QFA
+ tistart = time(NULL);
+#endif
+#ifdef sunos
+ if (GetSCSIIDFromPath(inputdev, &scsiid)) {
+ errx(1, "can't get SCSI-ID for %s\n", inputdev);
+ }
+ if (scsiid < 0) {
+ errx(1, "can't get SCSI-ID for %s\n", inputdev);
+ }
+ sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+ if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+ errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno);
+ }
+#endif /* sunos */
+ setup();
+ msg("writing QFA positions to %s\n", gTapeposfile);
+ (void) umask(orig_umask);
+ if ((gTapeposfd = open(gTapeposfile, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
+ |S_IROTH|S_IWOTH)) < 0)
+ errx(1, "can't create tapeposfile\n");
+ (void) umask(FORCED_UMASK);
+ /* print QFA-file header */
+ sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
+ errx(1, "can't write tapeposfile\n");
+ sprintf(gTps, "ino\ttapeno\ttapepos\n");
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
+ errx(1, "can't write tapeposfile\n");
+
+ extractdirs(1);
+ initsymtable((char *)0);
+ for (;;) {
+ NEXTFILE(p);
+ if (!p)
+ break;
+ canon(p, name, sizeof(name));
+ ino = dirlookup(name);
+ if (ino == 0)
+ continue;
+ if (mflag)
+ pathcheck(name);
+ treescan(name, ino, addfile);
+ }
+ createfiles();
+#ifdef sunos
+ if (fdsmtc != -1) {
+ close(fdsmtc);
+ }
+#endif /* sunos */
+#ifdef DEBUG_QFA
+ tiend = time(NULL);
+ titaken = tiend - tistart;
+ msg("writing QFA positions took %d:%02d:%02d\n", titaken / 3600,
+ (titaken % 3600) / 60, titaken % 60);
+#endif /* DEBUG_QFA */
+ break;
+#endif /* USE_QFA */
+ }
+ exit(0);
+ /* NOTREACHED */
+ return 0; /* gcc shut up */
+}
+
+static void
+usage(void)
+{
+ char white[MAXPATHLEN];
+ const char *ext2ver, *ext2date;
+
+ memset(white, ' ', MAXPATHLEN);
+ white[MIN(strlen(__progname), MAXPATHLEN - 1)] = '\0';
+
+#ifdef __linux__
+ ext2fs_get_library_version(&ext2ver, &ext2date);
+ (void)fprintf(stderr, "%s %s (using libext2fs %s of %s)\n",
+ __progname, _DUMP_VERSION, ext2ver, ext2date);
+#else
+ (void)fprintf(stderr, "%s %s\n", __progname, _DUMP_VERSION);
+#endif
+
+#ifdef KERBEROS
+#define kerbflag "k"
+#else
+#define kerbflag
+#endif
+
+#ifdef USE_QFA
+#define qfaflag "[-Q file] "
+#else
+#define qfaflag
+#endif
+
+ fprintf(stderr,
+ "usage:"
+ "\t%s -C [-cd" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n"
+ "\t%s [-F script] [-L limit] [-s fileno]\n"
+ "\t%s -i [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
+ "\t%s [-F script] " qfaflag "[-s fileno]\n"
+#ifdef USE_QFA
+ "\t%s -P file [-acdh" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n"
+ "\t%s [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n"
+#endif
+ "\t%s -r [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+ "\t%s [-s fileno] [-T directory]\n"
+ "\t%s -R [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+ "\t%s [-s fileno] [-T directory]\n"
+ "\t%s -t [-cdh" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n"
+ "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n"
+ "\t%s -x [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n"
+ "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
+ __progname, white,
+ __progname, white,
+#ifdef USE_QFA
+ __progname, white,
+#endif
+ __progname, white,
+ __progname, white,
+ __progname, white,
+ __progname, white);
+ exit(1);
+}
+
+/*
+ * obsolete --
+ * Change set of key letters and ordered arguments into something
+ * getopt(3) will like.
+ */
+static void
+obsolete(int *argcp, char **argvp[])
+{
+ int argc, flags;
+ char *ap, **argv, *flagsp = NULL, **nargv, *p = NULL;
+
+ /* Setup. */
+ argv = *argvp;
+ argc = *argcp;
+
+ /* Return if no arguments or first argument has leading dash. */
+ ap = argv[1];
+ if (argc == 1 || *ap == '-')
+ return;
+
+ /* Allocate space for new arguments. */
+ if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
+ (p = flagsp = malloc(strlen(ap) + 2)) == NULL)
+ err(1, "malloc args");
+
+ *nargv++ = *argv;
+ argv += 2, argc -= 2;
+
+ for (flags = 0; *ap; ++ap) {
+ switch (*ap) {
+ case 'A':
+ case 'b':
+ case 'D':
+ case 'f':
+ case 'F':
+ case 'L':
+ case 'Q':
+ case 's':
+ case 'T':
+ case 'X':
+ if (*argv == NULL) {
+ warnx("option requires an argument -- %c", *ap);
+ usage();
+ }
+ if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
+ err(1, "malloc arg");
+ nargv[0][0] = '-';
+ nargv[0][1] = *ap;
+ (void)strcpy(&nargv[0][2], *argv);
+ ++argv;
+ ++nargv;
+ break;
+ default:
+ if (!flags) {
+ *p++ = '-';
+ flags = 1;
+ }
+ *p++ = *ap;
+ break;
+ }
+ }
+
+ /* Terminate flags. */
+ if (flags) {
+ *p = '\0';
+ *nargv++ = flagsp;
+ }
+
+ /* Copy remaining arguments. */
+ while ((*nargv++ = *argv++));
+
+ /* Update argument count. */
+ *argcp = nargv - *argvp - 1;
+}
+
+/*
+ * use_stdin --
+ * reserve stdin for opt (avoid conflicts)
+ */
+void
+use_stdin(const char *opt)
+{
+ if (stdin_opt)
+ errx(1, "can't handle standard input for both %s and %s",
+ stdin_opt, opt);
+ stdin_opt = opt;
+}
--- /dev/null
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: restore.8.in,v 1.31 2003/06/11 13:01:36 stelian Exp $
+.\"
+.TH RESTORE 8 "version __VERSION__ of __DATE__" BSD "System management commands"
+.SH NAME
+restore \- restore files or file systems from backups made with dump
+.SH SYNOPSIS
+.B restore \-C
+[\fB\-cdklMvVy\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-D \fIfilesystem\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-L \fIlimit\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+.PP
+.B restore \-i
+[\fB\-acdhklmMNouvVy\fR]
+[\fB\-A \fIfile\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-Q \fIfile\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+.PP
+.B restore \-P
+.I file
+[\fB\-acdhklmMNuvVy\fR]
+[\fB\-A \fIfile\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+[\fB\-X \fIfilelist\fR]
+[ \fIfile ... \fR]
+.PP
+.B restore \-R
+[\fB\-cdklMNuvVy\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+.PP
+.B restore \-r
+[\fB\-cdklMNuvVy\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+.PP
+.B restore \-t
+[\fB\-cdhklMNuvVy\fR]
+[\fB\-A \fIfile\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-Q \fIfile\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+[\fB\-X \fIfilelist\fR]
+[ \fIfile ... \fR]
+.PP
+.B restore \-x
+[\fB\-adchklmMNouvVy\fR]
+[\fB\-A \fIfile\fR]
+[\fB\-b \fIblocksize\fR]
+[\fB\-f \fIfile\fR]
+[\fB\-F \fIscript\fR]
+[\fB\-Q \fIfile\fR]
+[\fB\-s \fIfileno\fR]
+[\fB\-T \fIdirectory\fR]
+[\fB\-X \fIfilelist\fR]
+[ \fIfile ... \fR]
+.PP
+(The 4.3BSD option syntax is implemented for backward compatibility but is not
+documented here.)
+.SH DESCRIPTION
+The
+.B restore
+command performs the inverse function of
+.BR dump (8).
+A full backup of a file system may be restored and subsequent incremental
+backups layered on top of it. Single files and directory subtrees may be
+restored from full or partial backups.
+.B Restore
+works across a network; to do this see the
+.B \-f
+flag described below. Other arguments to the command are file or directory
+names specifying the files that are to be restored. Unless the
+.B \-h
+flag is specified (see below), the appearance of a directory name refers to
+the files and (recursively) subdirectories of that directory.
+.PP
+Exactly one of the following flags is required:
+.TP
+.B \-C
+This mode allows comparison of files from a dump.
+.B Restore
+reads the backup and compares its contents with files present on the disk. It
+first changes its working directory to the root of the filesystem that was
+dumped and compares the tape with the files in its new current directory. See
+also the
+.B \-L
+flag described below.
+.TP
+.B \-i
+This mode allows interactive restoration of files from a dump. After reading in
+the directory information from the dump,
+.B restore
+provides a shell like interface that allows the user to move around the
+directory tree selecting files to be extracted. The available commands are
+given below; for those commands that require an argument, the default is the
+current directory.
+.RS
+.TP
+.B add \fR[\fIarg\fR]
+The current directory or specified argument is added to the list of files to be
+extracted. If a directory is specified, then it and all its descendents are
+added to the extraction list (unless the
+.B \-h
+flag is specified on the command line). Files that are on the extraction list
+are prepended with a \*(lq*\*(rq when they are listed by
+.BR ls .
+.TP
+.BI cd " arg"
+Change the current working directory to the specified argument.
+.TP
+.B delete \fR[\fIarg\fR]
+The current directory or specified argument is deleted from the list of files
+to be extracted. If a directory is specified, then it and all its descendents
+are deleted from the extraction list (unless the
+.B \-h
+flag is specified on the command line). The most expedient way to extract most
+of the files from a directory is to add the directory to the extraction list
+and then delete those files that are not needed.
+.TP
+.B extract
+All files on the extraction list are extracted from the dump.
+.B Restore
+will ask which volume the user wishes to mount. The fastest way to extract a f
+ew files is to start with the last volume and work towards the first volume.
+.TP
+.B help
+List a summary of the available commands.
+.TP
+.B ls \fR[\fIarg\fR]
+List the current or specified directory. Entries that are directories are
+appended with a \*(lq/\*(rq. Entries that have been marked for extraction are
+prepended with a \*(lq*\*(rq. If the verbose flag is set, the inode number of
+each entry is also listed.
+.TP
+.B pwd
+Print the full pathname of the current working directory.
+.TP
+.B quit
+.B Restore
+immediately exits, even if the extraction list is not empty.
+.TP
+.B setmodes
+All directories that have been added to the extraction list have their owner,
+modes, and times set; nothing is extracted from the dump. This is useful for
+cleaning up after a
+.B restore
+has been prematurely aborted.
+.TP
+.B verbose
+The sense of the
+.B \-v
+flag is toggled. When set, the verbose flag causes the
+.B ls
+command to list the inode numbers of all entries. It also causes
+.B restore
+to print out information about each file as it is extracted.
+.RE
+.TP
+.BI \-P " file"
+.B Restore
+creates a new Quick File Access file
+.I file
+from an existing dump file without restoring its contents.
+.TP
+.B \-R
+.B Restore
+requests a particular tape of a multi-volume set on which to restart a full
+restore (see the
+.B \-r
+flag below). This is useful if the restore has been interrupted.
+.TP
+.B \-r
+Restore (rebuild) a file system. The target file system should be made pristine
+with
+.BR mke2fs (8),
+mounted, and the user
+.BR cd 'd
+into the pristine file system before starting the restoration of the initial
+level 0 backup. If the level 0 restores successfully, the
+.B \-r
+flag may be used to restore any necessary incremental backups on top of the
+level 0. The
+.B \-r
+flag precludes an interactive file extraction and can be detrimental to one's
+health (not to mention the disk) if not used carefully. An example:
+.IP
+.RS 14
+.B mke2fs /dev/sda1
+.TP
+.B mount /dev/sda1 /mnt
+.TP
+.B cd /mnt
+.TP
+.B restore rf /dev/st0
+.RE
+.IP
+Note that
+.B restore
+leaves a file
+.I restoresymtable
+in the root directory to pass information between incremental restore passes.
+This file should be removed when the last incremental has been restored.
+.IP
+.BR Restore ,
+in conjunction with
+.BR mke2fs (8)
+and
+.BR dump (8),
+may be used to modify file system parameters such as size or block size.
+.TP
+.B \-t
+The names of the specified files are listed if they occur on the backup. If no
+file argument is given, the root directory is listed, which results in the
+entire content of the backup being listed, unless the
+.B \-h
+flag has been specified. Note that the
+.B \-t
+flag replaces the function of the old
+.BR dumpdir (8)
+program. See also the
+.B \-X
+option below.
+.TP
+.B \-x
+The named files are read from the given media. If a named file matches a
+directory whose contents are on the backup and the
+.B \-h
+flag is not specified, the directory is recursively extracted. The owner,
+modification time, and mode are restored (if possible). If no file argument is
+given, the root directory is extracted, which results in the entire content of
+the backup being extracted, unless the
+.B \-h
+flag has been specified. See also the
+.B \-X
+option below.
+.SH OPTIONS
+The following additional options may be specified:
+.TP
+.B \-a
+In
+.B \-i
+or
+.B \-x
+mode,
+.B restore
+does ask the user for the volume number on which the files to be extracted are
+supposed to be (in order to minimise the time by reading only the interesting
+volumes). The
+.B \-a
+option disables this behaviour and reads all the volumes starting with 1. This
+option is useful when the operator does not know on which volume the files to
+be extracted are and/or when he prefers the longer unattended mode rather than
+the shorter interactive mode.
+.TP
+.BI \-A " archive_file"
+Read the table of contents from
+.I archive_file
+instead of the media. This option can be used in combination with the
+.BR \-t ,
+.BR \-i ,
+or
+.B \-x
+options, making it possible to check whether files are on the media without
+having to mount the media.
+.TP
+.BI \-b " blocksize"
+The number of kilobytes per dump record. If the
+.B \-b
+option is not specified,
+.B restore
+tries to determine the media block size dynamically.
+.TP
+.B \-c
+Normally,
+.B restore
+will try to determine dynamically whether the dump was made from an old
+(pre-4.4) or new format file system. The
+.B \-c
+flag disables this check, and only allows reading a dump in the old format.
+.TP
+.B \-d
+The
+.B \-d
+(debug) flag causes
+.B restore
+to print debug information.
+.TP
+.BI \-D " filesystem"
+The
+.B \-D
+flag allows the user to specify the filesystem name when using
+.B restore
+with the
+.B \-C
+option to check the backup.
+.TP
+.BI \-f " file"
+Read the backup from
+.IR file ;
+.I file
+may be a special device file like
+.I /dev/st0
+(a tape drive),
+.I /dev/sda1
+(a disk drive), an ordinary file, or
+.I \-
+(the standard input). If the name of the file is of the form
+.I host:file
+or
+.IR user@host:file ,
+.B restore
+reads from the named file on the remote host using
+.BR rmt (8).
+.TP
+.BI \-F " script"
+Run script at the beginning of each tape. The device name and the current
+volume number are passed on the command line. The script must return 0 if
+.B restore
+should continue without asking the user to change the tape, 1 if
+.B restore
+should continue but ask the user to change the tape. Any other exit code will
+cause
+.B restore
+to abort. For security reasons,
+.B restore
+reverts back to the real user ID and the real group ID before running the
+script.
+.TP
+.B \-h
+Extract the actual directory, rather than the files that it references. This
+prevents hierarchical restoration of complete subtrees from the dump.
+.TP
+.B \-k
+Use Kerberos authentication when contacting the remote tape server. (Only
+available if this options was enabled when
+.B restore
+was compiled.)
+.TP
+.B \-l
+When doing remote restores, assume the remote file is a regular file (instead
+of a tape device). If you're restoring a remote compressed file, you will need
+to specify this option or
+.B restore
+will fail to access it correctly.
+.TP
+.BI \-L " limit"
+The
+.B \-L
+flag allows the user to specify a maximal number of miscompares when using
+.B restore
+with the
+.B \-C
+option to check the backup. If this limit is reached,
+.B restore
+will abort with an error message. A value of 0 (the default value) disables
+the check.
+.TP
+.B \-m
+Extract by inode numbers rather than by file name. This is useful if only a few
+files are being extracted, and one wants to avoid regenerating the complete
+pathname to the file.
+.TP
+.B \-M
+Enables the multi-volume feature (for reading dumps made using the
+.B \-M
+option of dump). The name specified with
+.B \-f
+is treated as a prefix and
+.B restore
+tries to read in sequence from
+.I <prefix>001, <prefix>002
+etc.
+.TP
+.B \-N
+The
+.B \-N
+flag causes
+.B restore
+to perform a full execution as requested by one of
+.BR \-i ,
+.BR \-R ,
+.BR \-r ,
+.B t
+or
+.B x
+command without actually writing any file on disk.
+.TP
+.B \-o
+The
+.B \-o
+flag causes
+.B restore
+to automatically restore the current directory permissions without asking the
+operator whether to do so in one of
+.B \-i
+or
+.B \-x
+modes.
+.TP
+.BI \-Q " file"
+Use the file
+.I file
+in order to read tape position as stored using the dump Quick File Access mode,
+in one of
+.BR \-i ,
+.B \-x
+or
+.B \-t
+mode.
+.IP
+It is recommended to set up the st driver to return logical tape positions
+rather than physical before calling
+.B dump/restore
+with parameter
+.BR \-Q .
+Since not all tape devices support physical tape positions those tape devices
+return an error during
+.B dump/restore
+when the st driver is set to the default physical setting. Please see the
+.BR st (4)
+man page, option
+.B MTSETDRVBUFFER
+, or the
+.BR mt(1)
+man page, on how to set the driver to return logical tape positions.
+.IP
+Before calling
+.B restore
+with parameter
+.BR \-Q ,
+always make sure the st driver is set to return the same type of tape position
+used during the call to
+.BR dump .
+Otherwise
+.B restore
+may be confused.
+.IP
+This option can be used when restoring from local or remote tapes (see above)
+or from local or remote files.
+.TP
+.BI \-s " fileno"
+Read from the specified
+.I fileno
+on a multi-file tape. File numbering starts at 1.
+.TP
+.BI \-T " directory"
+The
+.B \-T
+flag allows the user to specify a directory to use for the storage of temporary
+files. The default value is
+.IR /tmp .
+This flag is most useful when restoring files after having booted from a
+floppy. There might be little or no space on the floppy filesystem, but another
+source of space might exist.
+.TP
+.B \-u
+When creating certain types of files,
+.B restore
+may generate a warning diagnostic if they already exist in the target
+directory. To prevent this, the
+.B \-u
+(unlink) flag causes
+.B restore
+to remove old entries before attempting to create new ones.
+.TP
+.B \-v
+Normally
+.B restore
+does its work silently. The
+.B \-v
+(verbose) flag causes it to type the name of each file it treats preceded by
+its file type.
+.TP
+.B \-V
+Enables reading multi-volume non-tape mediums like CDROMs.
+.TP
+.BI \-X " filelist"
+Read list of files to be listed or extracted from the text file
+.I filelist
+in addition to those specified on the command line. This can be used in
+conjunction with the
+.B \-t
+or
+.B \-x
+commands. The file
+.I filelist
+should contain file names separated by newlines.
+.I filelist
+may be an ordinary file or
+.I -
+(the standard input).
+.TP
+.B \-y
+Do not ask the user whether to abort the restore in the event of an error.
+Always try to skip over the bad block(s) and continue.
+.SH DIAGNOSTICS
+Complains if it gets a read error. If
+.B y
+has been specified, or the user responds
+.BR y ,
+.B restore
+will attempt to continue the restore.
+.PP
+If a backup was made using more than one tape volume,
+.B restore
+will notify the user when it is time to mount the next volume. If the
+.B \-x
+or
+.B \-i
+flag has been specified,
+.B restore
+will also ask which volume the user wishes to mount. The fastest way to extract
+a few files is to start with the last volume, and work towards the first volume.
+.PP
+There are numerous consistency checks that can be listed by
+.BR restore .
+Most checks are self-explanatory or can \*(lqnever happen\*(rq. Common errors
+are given below:
+.TP
+.I Converting to new file system format
+A dump tape created from the old file system has been loaded. It is
+automatically converted to the new file system format.
+.TP
+.I <filename>: not found on tape
+The specified file name was listed in the tape directory, but was not found on
+the tape. This is caused by tape read errors while looking for the file, and
+from using a dump tape created on an active file system.
+.TP
+.I expected next file <inumber>, got <inumber>
+A file that was not listed in the directory showed up. This can occur when
+using a dump created on an active file system.
+.TP
+.I Incremental dump too low
+When doing an incremental restore, a dump that was written before the previous
+incremental dump, or that has too low an incremental level has been loaded.
+.TP
+.I Incremental dump too high
+When doing an incremental restore, a dump that does not begin its coverage
+where the previous incremental dump left off, or that has too high an
+incremental level has been loaded.
+.TP
+.I Tape read error while restoring <filename>
+.TP
+.I Tape read error while skipping over inode <inumber>
+.TP
+.I Tape read error while trying to resynchronize
+A tape (or other media) read error has occurred. If a file name is specified,
+its contents are probably partially wrong. If an inode is being skipped or the
+tape is trying to resynchronize, no extracted files have been corrupted, though
+files may not be found on the tape.
+.TP
+.I resync restore, skipped <num> blocks
+After a dump read error,
+.B restore
+may have to resynchronize itself. This message lists the number of blocks that
+were skipped over.
+.SH EXIT STATUS
+.B Restore
+exits with zero status on success. Tape errors are indicated with an exit code
+of 1.
+.PP
+When doing a comparison of files from a dump, an exit code of 2 indicates that
+some files were modified or deleted since the dump was made.
+.SH ENVIRONMENT
+If the following environment variable exists it will be utilized by
+.BR restore :
+.TP
+.B TAPE
+If no
+.B \-f
+option was specified,
+.B restore
+will use the device specified via
+.B TAPE
+as the dump device.
+.B TAPE
+may be of the form
+.IR tapename ,
+.I host:tapename
+or
+.IR user@host:tapename .
+.TP
+.B TMPDIR
+The directory given in
+.B TMPDIR
+will be used instead of
+.I /tmp
+to store temporary files.
+.TP
+.B RMT
+The environment variable
+.B RMT
+will be used to determine the pathname of the remote
+.BR rmt (8)
+program.
+.TP
+.B RSH
+.B Restore
+uses the contents of this variable to determine the name of the remote shell
+command to use when doing a network restore (rsh, ssh etc.). If this variable
+is not set,
+.BR rcmd (3)
+will be used, but only root will be able to do a network restore.
+.SH FILES
+.TP
+.I /dev/st0
+the default tape drive
+.TP
+.I /tmp/rstdir*
+file containing directories on the tape
+.TP
+.I /tmp/rstmode*
+owner, mode, and time stamps for directories
+.TP
+.I ./restoresymtable
+information passed between incremental restores
+.SH SEE ALSO
+.BR dump (8),
+.BR mount (8),
+.BR mke2fs (8),
+.BR rmt (8)
+.SH BUGS
+.B Restore
+can get confused when doing incremental restores from dumps that were made on
+active file systems.
+.PP
+A level 0 dump must be done after a full restore. Because
+.B restore
+runs in user code, it has no control over inode allocation; thus a full dump
+must be done to get a new set of directories reflecting the new inode
+numbering, even though the content of the files is unchanged.
+.PP
+The temporary files
+.I /tmp/rstdir*
+and
+.I /tmp/rstmode*
+are generated with a unique name based on the date of the dump and the process
+ID (see
+.BR mktemp (3) ),
+except when
+.B \-r
+or
+.B \-R
+is used. Because
+.B \-R
+allows you to restart a
+.B \-r
+operation that may have been interrupted, the temporary files should be the
+same across different processes. In all other cases, the files are unique
+because it is possible to have two different dumps started at the same time,
+and separate operations shouldn't conflict with each other.
+.PP
+To do a network restore, you have to run
+.B restore
+as root or use a remote shell replacement (see
+.B RSH
+variable). This is due to the previous security history of
+.B dump
+and
+.BR restore .
+(
+.B restore
+is written to be setuid root, but we are not certain all bugs are gone from the
+code - run setuid at your own risk.)
+.PP
+At the end of restores in
+.B \-i
+or
+.B \-x
+modes (unless
+.B \-o
+option is in use),
+.B restore
+will ask the operator whether to set the permissions on the current
+directory. If the operator confirms this action, the permissions
+on the directory from where
+.B restore
+was launched will be replaced by the permissions on the dumped root
+inode. Although this behaviour is not really a bug, it has proven itself
+to be confusing for many users, so it is recommended to answer 'no',
+unless you're performing a full restore and you do want to restore the
+permissions on '/'.
+.PP
+It should be underlined that because it runs in user code,
+.B restore
+, when run with the
+.B \-C
+option, sees the files as the kernel presents them, whereas
+.B dump
+sees all the files on a given filesystem. In particular, this
+can cause some confusion when comparing a dumped filesystem a part
+of which is hidden by a filesystem mounted on top of it.
+.SH AUTHOR
+The
+.B dump/restore
+backup suite was ported to Linux's Second Extended File System by Remy Card
+<card@Linux.EU.Org>. He maintained the initial versions of
+.B dump
+(up and including 0.4b4, released in january 1997).
+.PP
+Starting with 0.4b5, the new maintainer is Stelian Pop <stelian@popies.net>.
+.SH AVAILABILITY
+The
+.B dump/restore
+backup suite is available from <http://dump.sourceforge.net>
+.SH HISTORY
+The
+.B restore
+command appeared in 4.2BSD.
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: restore.c,v 1.33 2003/11/22 16:52:16 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <sys/types.h>
+
+#ifdef __linux__
+#include <sys/param.h>
+#include <sys/time.h>
+#include <time.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+#endif /* __linux__ */
+
+#include <protocols/dumprestore.h>
+
+#include <compaterr.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __linux__
+#include <ext2fs/ext2fs.h>
+#endif
+
+#include "restore.h"
+#include "extern.h"
+
+static char *keyval __P((int));
+
+/*
+ * This implements the 't' option.
+ * List entries on the tape.
+ */
+long
+listfile(char *name, dump_ino_t ino, int type)
+{
+ long descend = hflag ? GOOD : FAIL;
+#ifdef USE_QFA
+ long tnum;
+ long long tpos;
+#endif
+
+ if (TSTINO(ino, dumpmap) == 0)
+ return (descend);
+ Vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir ");
+#ifdef USE_QFA
+ if (tapeposflag) { /* add QFA positions to output */
+ (void)Inode2Tapepos(ino, &tnum, &tpos, 1);
+ fprintf(stdout, "%10lu\t%ld\t%lld\t%s\n", (unsigned long)ino,
+ tnum, tpos, name);
+ }
+ else
+#endif
+ fprintf(stdout, "%10lu\t%s\n", (unsigned long)ino, name);
+ return (descend);
+}
+
+/*
+ * This implements the 'x' option.
+ * Request that new entries be extracted.
+ */
+long
+addfile(char *name, dump_ino_t ino, int type)
+{
+ struct entry *ep, *np;
+ long descend = hflag ? GOOD : FAIL;
+ char buf[100];
+
+ if (TSTINO(ino, dumpmap) == 0) {
+ Dprintf(stdout, "%s: not on the tape\n", name);
+ return (descend);
+ }
+ if (ino == WINO && command == 'i' && !vflag)
+ return (descend);
+ if (!mflag) {
+ (void) snprintf(buf, sizeof(buf), "./%lu", (unsigned long)ino);
+ name = buf;
+ if (type == NODE) {
+ (void) genliteraldir(name, ino);
+ return (descend);
+ }
+ }
+ ep = lookupino(ino);
+ if (ep != NULL) {
+ if (strcmp(name, myname(ep)) == 0) {
+ ep->e_flags |= NEW;
+ return (descend);
+ }
+ type |= LINK;
+ for (np = ep->e_links; np; np = np->e_links)
+ if (strcmp(name, myname(np)) == 0) {
+ np->e_flags |= NEW;
+ return (descend);
+ }
+ }
+ ep = addentry(name, ino, type);
+#ifdef USE_QFA
+ if ((type == NODE) && (!createtapeposflag))
+#else
+ if (type == NODE)
+#endif
+ newnode(ep);
+ ep->e_flags |= NEW;
+ return (descend);
+}
+
+/*
+ * This is used by the 'i' option to undo previous requests made by addfile.
+ * Delete entries from the request queue.
+ */
+/* ARGSUSED */
+long
+deletefile(char *name, dump_ino_t ino, UNUSED(int type))
+{
+ long descend = hflag ? GOOD : FAIL;
+ struct entry *ep;
+
+ if (TSTINO(ino, dumpmap) == 0)
+ return (descend);
+ ep = lookupname(name);
+ if (ep != NULL) {
+ ep->e_flags &= ~NEW;
+ ep->e_flags |= REMOVED;
+ if (ep->e_type != NODE)
+ freeentry(ep);
+ }
+ return (descend);
+}
+
+/*
+ * The following four routines implement the incremental
+ * restore algorithm. The first removes old entries, the second
+ * does renames and calculates the extraction list, the third
+ * cleans up link names missed by the first two, and the final
+ * one deletes old directories.
+ *
+ * Directories cannot be immediately deleted, as they may have
+ * other files in them which need to be moved out first. As
+ * directories to be deleted are found, they are put on the
+ * following deletion list. After all deletions and renames
+ * are done, this list is actually deleted.
+ */
+static struct entry *removelist;
+
+/*
+ * Remove invalid whiteouts from the old tree.
+ * Remove unneeded leaves from the old tree.
+ * Remove directories from the lookup chains.
+ */
+void
+removeoldleaves(void)
+{
+ struct entry *ep, *nextep;
+ dump_ino_t i, mydirino;
+
+ Vprintf(stdout, "Mark entries to be removed.\n");
+ if ((ep = lookupino(WINO))) {
+ Vprintf(stdout, "Delete whiteouts\n");
+ for ( ; ep != NULL; ep = nextep) {
+ nextep = ep->e_links;
+ mydirino = ep->e_parent->e_ino;
+ /*
+ * We remove all whiteouts that are in directories
+ * that have been removed or that have been dumped.
+ */
+ if (TSTINO(mydirino, usedinomap) &&
+ !TSTINO(mydirino, dumpmap))
+ continue;
+#ifdef __linux__
+ (void)fprintf(stderr, "BUG! Should call delwhiteout\n");
+#else
+#ifdef sunos
+#else
+ delwhiteout(ep);
+#endif
+#endif
+ freeentry(ep);
+ }
+ }
+ for (i = ROOTINO + 1; i < maxino; i++) {
+ ep = lookupino(i);
+ if (ep == NULL)
+ continue;
+ if (TSTINO(i, usedinomap))
+ continue;
+ for ( ; ep != NULL; ep = ep->e_links) {
+ Dprintf(stdout, "%s: REMOVE\n", myname(ep));
+ if (ep->e_type == LEAF) {
+ removeleaf(ep);
+ freeentry(ep);
+ } else {
+ mktempname(ep);
+ deleteino(ep->e_ino);
+ ep->e_next = removelist;
+ removelist = ep;
+ }
+ }
+ }
+}
+
+/*
+ * For each directory entry on the incremental tape, determine which
+ * category it falls into as follows:
+ * KEEP - entries that are to be left alone.
+ * NEW - new entries to be added.
+ * EXTRACT - files that must be updated with new contents.
+ * LINK - new links to be added.
+ * Renames are done at the same time.
+ */
+long
+nodeupdates(char *name, dump_ino_t ino, int type)
+{
+ struct entry *ep, *np, *ip;
+ long descend = GOOD;
+ int lookuptype = 0;
+ int key = 0;
+ /* key values */
+# define ONTAPE 0x1 /* inode is on the tape */
+# define INOFND 0x2 /* inode already exists */
+# define NAMEFND 0x4 /* name already exists */
+# define MODECHG 0x8 /* mode of inode changed */
+
+ /*
+ * This routine is called once for each element in the
+ * directory hierarchy, with a full path name.
+ * The "type" value is incorrectly specified as LEAF for
+ * directories that are not on the dump tape.
+ *
+ * Check to see if the file is on the tape.
+ */
+ if (TSTINO(ino, dumpmap))
+ key |= ONTAPE;
+ /*
+ * Check to see if the name exists, and if the name is a link.
+ */
+ np = lookupname(name);
+ if (np != NULL) {
+ key |= NAMEFND;
+ ip = lookupino(np->e_ino);
+ if (ip == NULL)
+ panic("corrupted symbol table\n");
+ if (ip != np)
+ lookuptype = LINK;
+ }
+ /*
+ * Check to see if the inode exists, and if one of its links
+ * corresponds to the name (if one was found).
+ */
+ ip = lookupino(ino);
+ if (ip != NULL) {
+ key |= INOFND;
+ for (ep = ip->e_links; ep != NULL; ep = ep->e_links) {
+ if (ep == np) {
+ ip = ep;
+ break;
+ }
+ }
+ }
+ /*
+ * If both a name and an inode are found, but they do not
+ * correspond to the same file, then both the inode that has
+ * been found and the inode corresponding to the name that
+ * has been found need to be renamed. The current pathname
+ * is the new name for the inode that has been found. Since
+ * all files to be deleted have already been removed, the
+ * named file is either a now unneeded link, or it must live
+ * under a new name in this dump level. If it is a link, it
+ * can be removed. If it is not a link, it is given a
+ * temporary name in anticipation that it will be renamed
+ * when it is later found by inode number.
+ */
+ if (((key & (INOFND|NAMEFND)) == (INOFND|NAMEFND)) && ip != np) {
+ if (lookuptype == LINK) {
+ removeleaf(np);
+ freeentry(np);
+ } else {
+ Dprintf(stdout, "name/inode conflict, mktempname %s\n",
+ myname(np));
+ mktempname(np);
+ }
+ np = NULL;
+ key &= ~NAMEFND;
+ }
+ if ((key & ONTAPE) &&
+ (((key & INOFND) && ip->e_type != type) ||
+ ((key & NAMEFND) && np->e_type != type)))
+ key |= MODECHG;
+
+ /*
+ * Decide on the disposition of the file based on its flags.
+ * Note that we have already handled the case in which
+ * a name and inode are found that correspond to different files.
+ * Thus if both NAMEFND and INOFND are set then ip == np.
+ */
+ switch (key) {
+
+ /*
+ * A previously existing file has been found.
+ * Mark it as KEEP so that other links to the inode can be
+ * detected, and so that it will not be reclaimed by the search
+ * for unreferenced names.
+ */
+ case INOFND|NAMEFND:
+ ip->e_flags |= KEEP;
+ Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
+ flagvalues(ip));
+ break;
+
+ /*
+ * A file on the tape has a name which is the same as a name
+ * corresponding to a different file in the previous dump.
+ * Since all files to be deleted have already been removed,
+ * this file is either a now unneeded link, or it must live
+ * under a new name in this dump level. If it is a link, it
+ * can simply be removed. If it is not a link, it is given a
+ * temporary name in anticipation that it will be renamed
+ * when it is later found by inode number (see INOFND case
+ * below). The entry is then treated as a new file.
+ */
+ case ONTAPE|NAMEFND:
+ case ONTAPE|NAMEFND|MODECHG:
+ if (lookuptype == LINK) {
+ removeleaf(np);
+ freeentry(np);
+ } else {
+ mktempname(np);
+ }
+ /* fall through */
+
+ /*
+ * A previously non-existent file.
+ * Add it to the file system, and request its extraction.
+ * If it is a directory, create it immediately.
+ * (Since the name is unused there can be no conflict)
+ */
+ case ONTAPE:
+ ep = addentry(name, ino, type);
+ if (type == NODE)
+ newnode(ep);
+ ep->e_flags |= NEW|KEEP;
+ Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
+ flagvalues(ep));
+ break;
+
+ /*
+ * A file with the same inode number, but a different
+ * name has been found. If the other name has not already
+ * been found (indicated by the KEEP flag, see above) then
+ * this must be a new name for the file, and it is renamed.
+ * If the other name has been found then this must be a
+ * link to the file. Hard links to directories are not
+ * permitted, and are either deleted or converted to
+ * symbolic links. Finally, if the file is on the tape,
+ * a request is made to extract it.
+ */
+ case ONTAPE|INOFND:
+ if (type == LEAF && (ip->e_flags & KEEP) == 0)
+ ip->e_flags |= EXTRACT;
+ /* fall through */
+ case INOFND:
+ if ((ip->e_flags & KEEP) == 0) {
+ renameit(myname(ip), name);
+ moveentry(ip, name);
+ ip->e_flags |= KEEP;
+ Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
+ flagvalues(ip));
+ break;
+ }
+ if (ip->e_type == NODE) {
+ descend = FAIL;
+ fprintf(stderr,
+ "deleted hard link %s to directory %s\n",
+ name, myname(ip));
+ break;
+ }
+ ep = addentry(name, ino, type|LINK);
+ ep->e_flags |= NEW;
+ Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name,
+ flagvalues(ep));
+ break;
+
+ /*
+ * A previously known file which is to be updated. If it is a link,
+ * then all names referring to the previous file must be removed
+ * so that the subset of them that remain can be recreated.
+ */
+ case ONTAPE|INOFND|NAMEFND:
+ if (lookuptype == LINK) {
+ removeleaf(np);
+ freeentry(np);
+ ep = addentry(name, ino, type|LINK);
+ if (type == NODE)
+ newnode(ep);
+ ep->e_flags |= NEW|KEEP;
+ Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name,
+ flagvalues(ep));
+ break;
+ }
+ if (type == LEAF && lookuptype != LINK)
+ np->e_flags |= EXTRACT;
+ np->e_flags |= KEEP;
+ Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
+ flagvalues(np));
+ break;
+
+ /*
+ * An inode is being reused in a completely different way.
+ * Normally an extract can simply do an "unlink" followed
+ * by a "creat". Here we must do effectively the same
+ * thing. The complications arise because we cannot really
+ * delete a directory since it may still contain files
+ * that we need to rename, so we delete it from the symbol
+ * table, and put it on the list to be deleted eventually.
+ * Conversely if a directory is to be created, it must be
+ * done immediately, rather than waiting until the
+ * extraction phase.
+ */
+ case ONTAPE|INOFND|MODECHG:
+ case ONTAPE|INOFND|NAMEFND|MODECHG:
+ if (ip->e_flags & KEEP) {
+ badentry(ip, "cannot KEEP and change modes");
+ break;
+ }
+ if (ip->e_type == LEAF) {
+ /* changing from leaf to node */
+ for ( ; ip != NULL; ip = ip->e_links) {
+ if (ip->e_type != LEAF)
+ badentry(ip, "NODE and LEAF links to same inode");
+ removeleaf(ip);
+ freeentry(ip);
+ }
+ ip = addentry(name, ino, type);
+ newnode(ip);
+ } else {
+ /* changing from node to leaf */
+ if ((ip->e_flags & TMPNAME) == 0)
+ mktempname(ip);
+ deleteino(ip->e_ino);
+ ip->e_next = removelist;
+ removelist = ip;
+ ip = addentry(name, ino, type);
+ }
+ ip->e_flags |= NEW|KEEP;
+ Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
+ flagvalues(ip));
+ break;
+
+ /*
+ * A hard link to a directory that has been removed.
+ * Ignore it.
+ */
+ case NAMEFND:
+ Dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key),
+ name);
+ descend = FAIL;
+ break;
+
+ /*
+ * If we find a directory entry for a file that is not on
+ * the tape, then we must have found a file that was created
+ * while the dump was in progress. Since we have no contents
+ * for it, we discard the name knowing that it will be on the
+ * next incremental tape.
+ */
+ case 0:
+ if (compare_ignore_not_found) break;
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ name, (unsigned long)ino);
+ do_compare_error;
+ break;
+
+ /*
+ * If any of these arise, something is grievously wrong with
+ * the current state of the symbol table.
+ */
+ case INOFND|NAMEFND|MODECHG:
+ case NAMEFND|MODECHG:
+ case INOFND|MODECHG:
+ fprintf(stderr, "[%s] %s: inconsistent state\n", keyval(key),
+ name);
+ break;
+
+ /*
+ * These states "cannot" arise for any state of the symbol table.
+ */
+ case ONTAPE|MODECHG:
+ case MODECHG:
+ default:
+ panic("[%s] %s: impossible state\n", keyval(key), name);
+ break;
+ }
+ return (descend);
+}
+
+/*
+ * Calculate the active flags in a key.
+ */
+static char *
+keyval(int key)
+{
+ static char keybuf[32];
+
+ (void) strcpy(keybuf, "|NIL");
+ keybuf[0] = '\0';
+ if (key & ONTAPE)
+ (void) strcat(keybuf, "|ONTAPE");
+ if (key & INOFND)
+ (void) strcat(keybuf, "|INOFND");
+ if (key & NAMEFND)
+ (void) strcat(keybuf, "|NAMEFND");
+ if (key & MODECHG)
+ (void) strcat(keybuf, "|MODECHG");
+ return (&keybuf[1]);
+}
+
+/*
+ * Find unreferenced link names.
+ */
+void
+findunreflinks(void)
+{
+ struct entry *ep, *np;
+ dump_ino_t i;
+
+ Vprintf(stdout, "Find unreferenced names.\n");
+ for (i = ROOTINO; i < maxino; i++) {
+ ep = lookupino(i);
+ if (ep == NULL || ep->e_type == LEAF || TSTINO(i, dumpmap) == 0)
+ continue;
+ for (np = ep->e_entries; np != NULL; np = np->e_sibling) {
+ if (np->e_flags == 0) {
+ Dprintf(stdout,
+ "%s: remove unreferenced name\n",
+ myname(np));
+ removeleaf(np);
+ freeentry(np);
+ }
+ }
+ }
+ /*
+ * Any leaves remaining in removed directories is unreferenced.
+ */
+ for (ep = removelist; ep != NULL; ep = ep->e_next) {
+ for (np = ep->e_entries; np != NULL; np = np->e_sibling) {
+ if (np->e_type == LEAF) {
+ if (np->e_flags != 0)
+ badentry(np, "unreferenced with flags");
+ Dprintf(stdout,
+ "%s: remove unreferenced name\n",
+ myname(np));
+ removeleaf(np);
+ freeentry(np);
+ }
+ }
+ }
+}
+
+/*
+ * Remove old nodes (directories).
+ * Note that this routine runs in O(N*D) where:
+ * N is the number of directory entries to be removed.
+ * D is the maximum depth of the tree.
+ * If N == D this can be quite slow. If the list were
+ * topologically sorted, the deletion could be done in
+ * time O(N).
+ */
+void
+removeoldnodes(void)
+{
+ struct entry *ep, **prev;
+ long change;
+
+ Vprintf(stdout, "Remove old nodes (directories).\n");
+ do {
+ change = 0;
+ prev = &removelist;
+ for (ep = removelist; ep != NULL; ep = *prev) {
+ if (ep->e_entries != NULL) {
+ prev = &ep->e_next;
+ continue;
+ }
+ *prev = ep->e_next;
+ removenode(ep);
+ freeentry(ep);
+ change++;
+ }
+ } while (change);
+ for (ep = removelist; ep != NULL; ep = ep->e_next)
+ badentry(ep, "cannot remove, non-empty");
+}
+
+/* Compare the file specified in `ep' (which is on tape) to the */
+/* current copy of this file on disk. If do_compare is 0, then just */
+/* make our caller think we did it--this is used to handle hard links */
+/* to files and devices. */
+static void
+compare_entry(struct entry *ep, int do_compare)
+{
+ if ((ep->e_flags & (NEW|EXTRACT)) == 0) {
+ badentry(ep, "unexpected file on tape");
+ do_compare_error;
+ }
+ if (do_compare) (void) comparefile(myname(ep));
+ ep->e_flags &= ~(NEW|EXTRACT);
+}
+
+/*
+ * This is the routine used to compare files for the 'C' command.
+ */
+void
+compareleaves(void)
+{
+ struct entry *ep;
+ dump_ino_t first;
+ long curvol;
+
+ first = lowerbnd(ROOTINO);
+ curvol = volno;
+ while (curfile.ino < maxino) {
+ first = lowerbnd(first);
+ /*
+ * If the next available file is not the one which we
+ * expect then we have missed one or more files. Since
+ * we do not request files that were not on the tape,
+ * the lost files must have been due to a tape read error,
+ * or a file that was removed while the dump was in progress.
+ */
+ while (first < curfile.ino) {
+ ep = lookupino(first);
+ if (ep == NULL)
+ panic("%d: bad first\n", first);
+ fprintf(stderr, "%s: not found on tape\n", myname(ep));
+ do_compare_error;
+ ep->e_flags &= ~(NEW|EXTRACT);
+ first = lowerbnd(first);
+ }
+ /*
+ * If we find files on the tape that have no corresponding
+ * directory entries, then we must have found a file that
+ * was created while the dump was in progress. Since we have
+ * no name for it, we discard it knowing that it will be
+ * on the next incremental tape.
+ */
+ if (first != curfile.ino) {
+ fprintf(stderr, "expected next file %ld, got %lu\n",
+ (long)first, (unsigned long)curfile.ino);
+ do_compare_error;
+ skipfile();
+ goto next;
+ }
+ ep = lookupino(curfile.ino);
+ if (ep == NULL) {
+ panic("unknown file on tape\n");
+ do_compare_error;
+ }
+ compare_entry(ep, 1);
+ for (ep = ep->e_links; ep != NULL; ep = ep->e_links) {
+ compare_entry(ep, 0);
+ }
+
+ /*
+ * We checkpoint the restore after every tape reel, so
+ * as to simplify the amount of work re quired by the
+ * 'R' command.
+ */
+ next:
+ if (curvol != volno) {
+ skipmaps();
+ curvol = volno;
+ }
+ }
+ /*
+ * If we encounter the end of the tape and the next available
+ * file is not the one which we expect then we have missed one
+ * or more files. Since we do not request files that were not
+ * on the tape, the lost files must have been due to a tape
+ * read error, or a file that was removed while the dump was
+ * in progress.
+ */
+ first = lowerbnd(first);
+ while (first < curfile.ino) {
+ ep = lookupino(first);
+ if (ep == NULL)
+ panic("%d: bad first\n", first);
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)first);
+ do_compare_error;
+ ep->e_flags &= ~(NEW|EXTRACT);
+ first = lowerbnd(first);
+ }
+}
+
+/*
+ * This is the routine used to extract files for the 'r' command.
+ * Extract new leaves.
+ */
+void
+createleaves(char *symtabfile)
+{
+ struct entry *ep;
+ dump_ino_t first;
+ long curvol;
+ int doremove;
+
+ if (command == 'R') {
+ Vprintf(stdout, "Continue extraction of new leaves\n");
+ } else {
+ Vprintf(stdout, "Extract new leaves.\n");
+ dumpsymtable(symtabfile, volno);
+ }
+ first = lowerbnd(ROOTINO);
+ curvol = volno;
+ while (curfile.ino < maxino) {
+ first = lowerbnd(first);
+ /*
+ * If the next available file is not the one which we
+ * expect then we have missed one or more files. Since
+ * we do not request files that were not on the tape,
+ * the lost files must have been due to a tape read error,
+ * or a file that was removed while the dump was in progress.
+ */
+ while (first < curfile.ino) {
+ ep = lookupino(first);
+ if (ep == NULL)
+ panic("%d: bad first\n", first);
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)first);
+ ep->e_flags &= ~(NEW|EXTRACT);
+ first = lowerbnd(first);
+ }
+ /*
+ * If we find files on the tape that have no corresponding
+ * directory entries, then we must have found a file that
+ * was created while the dump was in progress. Since we have
+ * no name for it, we discard it knowing that it will be
+ * on the next incremental tape.
+ */
+ if (first != curfile.ino) {
+ fprintf(stderr, "expected next file %ld, got %lu\n",
+ (long)first, (unsigned long)curfile.ino);
+ skipfile();
+ goto next;
+ }
+ ep = lookupino(curfile.ino);
+ if (ep == NULL)
+ panic("unknown file on tape\n");
+ if ((ep->e_flags & (NEW|EXTRACT)) == 0)
+ badentry(ep, "unexpected file on tape");
+ /*
+ * If the file is to be extracted, then the old file must
+ * be removed since its type may change from one leaf type
+ * to another (e.g. "file" to "character special").
+ */
+ if ((ep->e_flags & EXTRACT) != 0)
+ doremove = 1;
+ else
+ doremove = 0;
+ (void) extractfile(ep, doremove);
+ ep->e_flags &= ~(NEW|EXTRACT);
+
+finderres:
+ if ((first == curfile.ino) && (spcl.c_flags & DR_EXTATTRIBUTES)) {
+ switch (spcl.c_extattributes) {
+ case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+ (void)extractfinderinfoufs(myname(ep));
+#else
+ msg("MacOSX not supported in this version, skipping\n");
+ skipfile();
+#endif
+ break;
+ case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+ (void)extractresourceufs(myname(ep));
+#else
+ msg("MacOSX not supported in this version, skipping\n");
+ skipfile();
+#endif
+ break;
+ case EXT_ACL:
+ msg("ACLs not supported in this version, skipping\n");
+ skipfile();
+ break;
+ default:
+ msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+ skipfile();
+ break;
+ }
+ goto finderres;
+ }
+
+ /*
+ * We checkpoint the restore after every tape reel, so
+ * as to simplify the amount of work required by the
+ * 'R' command.
+ */
+next:
+ if (curvol != volno) {
+ dumpsymtable(symtabfile, volno);
+ skipmaps();
+ curvol = volno;
+ }
+ }
+ /*
+ * If we encounter the end of the tape and the next available
+ * file is not the one which we expect then we have missed one
+ * or more files. Since we do not request files that were not
+ * on the tape, the lost files must have been due to a tape
+ * read error, or a file that was removed while the dump was
+ * in progress.
+ */
+ first = lowerbnd(first);
+ while (first < curfile.ino) {
+ ep = lookupino(first);
+ if (ep == NULL)
+ panic("%d: bad first\n", first);
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)first);
+ do_compare_error;
+ ep->e_flags &= ~(NEW|EXTRACT);
+ first = lowerbnd(first);
+ }
+}
+
+/*
+ * This is the routine used to extract files for the 'x' and 'i' commands.
+ * Efficiently extract a subset of the files on a tape.
+ */
+void
+createfiles(void)
+{
+ dump_ino_t first, next, last;
+ struct entry *ep;
+ long curvol;
+#ifdef USE_QFA
+ long tnum, tmpcnt;
+ long long tpos, curtpos = 0;
+ time_t tistart, tiend, titaken;
+ int volChg;
+#endif
+
+ Vprintf(stdout, "Extract requested files\n");
+ curfile.action = SKIP;
+#ifdef USE_QFA
+ if (tapeposflag)
+ curfile.ino = 0;
+ else
+#endif
+ if (volinfo[1] == ROOTINO)
+ curfile.ino = 0;
+ else
+ getvol((long)1);
+ skipmaps();
+ skipdirs();
+ first = lowerbnd(ROOTINO);
+ last = upperbnd(maxino - 1);
+ for (;;) {
+#ifdef USE_QFA
+ tmpcnt = 1;
+#endif
+ first = lowerbnd(first);
+ last = upperbnd(last);
+ /*
+ * Check to see if any files remain to be extracted
+ */
+ if (first > last)
+ return;
+ /*
+ * Reject any volumes with inodes greater
+ * than the last one needed
+ */
+ while (curfile.ino > last) {
+ curfile.action = SKIP;
+ if (!pipein)
+ getvol((long)0);
+ if (curfile.ino == maxino) {
+ next = lowerbnd(first);
+ while (next < curfile.ino) {
+ ep = lookupino(next);
+ if (ep == NULL)
+ panic("corrupted symbol table\n");
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)next);
+ ep->e_flags &= ~NEW;
+ next = lowerbnd(next);
+ }
+ return;
+ }
+ skipmaps();
+ skipdirs();
+ }
+ /*
+ * Decide on the next inode needed.
+ * Skip across the inodes until it is found
+ * or an out of order volume change is encountered
+ */
+ next = lowerbnd(curfile.ino);
+#ifdef USE_QFA
+ tistart = time(NULL);
+ if (tapeposflag) {
+ /* get tape position for inode */
+ (void)Inode2Tapepos(next, &tnum, &tpos, 0);
+ if (tpos != 0) {
+ if (tnum != volno) {
+ (void)RequestVol(tnum);
+ volChg = 1;
+ } else {
+ volChg = 0;
+ }
+ if (GetTapePos(&curtpos) == 0) {
+ /* curtpos +1000 ???, some drives
+ * might be too slow */
+ if (((tpos > (curtpos + 1000)) && (volChg == 0)) || ((tpos != curtpos) && (volChg == 1))) {
+ volChg = 0;
+#ifdef DEBUG_QFA
+ msg("positioning tape %ld from %lld to %lld for inode %lu ...\n", volno, curtpos, tpos, (unsigned long)next);
+#endif
+ if (GotoTapePos(tpos) == 0) {
+#ifdef DEBUG_QFA
+ if (GetTapePos(&curtpos) == 0) {
+ msg("before resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+ }
+#endif
+ ReReadInodeFromTape(next);
+#ifdef DEBUG_QFA
+ if (GetTapePos(&curtpos) == 0) {
+ msg("after resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+ }
+#endif
+ }
+ } else {
+#ifdef DEBUG_QFA
+ msg("already at tape %ld position %ld for inode %lu ...\n", volno, tpos, (unsigned long)next);
+#endif
+ }
+ }
+ }
+ }
+ else
+#endif /* USA_QFA */
+ if (volinfo[1] == ROOTINO) {
+ int i, goodvol = 1;
+
+ for (i = 1; i < (int)TP_NINOS && volinfo[i] != 0; ++i)
+ if (volinfo[i] < next)
+ goodvol = i;
+
+ if (goodvol != volno)
+ RequestVol(goodvol);
+ }
+
+ do {
+ curvol = volno;
+ while (next > curfile.ino && volno == curvol) {
+#ifdef USE_QFA
+ ++tmpcnt;
+#endif
+ skipfile();
+ }
+ skipmaps();
+ skipdirs();
+ } while (volno == curvol + 1);
+#ifdef USE_QFA
+ tiend = time(NULL);
+ titaken = tiend - tistart;
+#ifdef DEBUG_QFA
+ if (titaken / 60 > 0)
+ msg("%ld reads took %d:%02d:%02d\n",
+ tmpcnt, titaken / 3600,
+ (titaken % 3600) / 60, titaken % 60);
+#endif
+#endif /* USE_QFA */
+
+ /*
+ * If volume change out of order occurred the
+ * current state must be recalculated
+ */
+ if (volno != curvol)
+ continue;
+ /*
+ * If the current inode is greater than the one we were
+ * looking for then we missed the one we were looking for.
+ * Since we only attempt to extract files listed in the
+ * dump map, the lost files must have been due to a tape
+ * read error, or a file that was removed while the dump
+ * was in progress. Thus we report all requested files
+ * between the one we were looking for, and the one we
+ * found as missing, and delete their request flags.
+ */
+ while (next < curfile.ino) {
+ ep = lookupino(next);
+ if (ep == NULL)
+ panic("corrupted symbol table\n");
+#ifdef USE_QFA
+ if (!createtapeposflag)
+#endif
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)next);
+ ep->e_flags &= ~NEW;
+ next = lowerbnd(next);
+ }
+ /*
+ * The current inode is the one that we are looking for,
+ * so extract it per its requested name.
+ */
+ if (next == curfile.ino && next <= last) {
+ ep = lookupino(next);
+ if (ep == NULL)
+ panic("corrupted symbol table\n");
+#ifdef USE_QFA
+ if (createtapeposflag) {
+#ifdef DEBUG_QFA
+ msg("inode %ld at tapepos %ld\n", curfile.ino, curtapepos);
+#endif
+ sprintf(gTps, "%ld\t%ld\t%lld\n", (unsigned long)curfile.ino, volno, curtapepos);
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
+ warn("error writing tapepos file.\n");
+ skipfile();
+ } else {
+#endif /* USE_QFA */
+ (void) extractfile(ep, 0);
+
+finderres:
+ if ((next == curfile.ino) && (spcl.c_flags & DR_EXTATTRIBUTES)) {
+ switch (spcl.c_extattributes) {
+ case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+ (void)extractfinderinfoufs(myname(ep));
+#else
+ msg("MacOSX not supported in this version, skipping\n");
+ skipfile();
+#endif
+ break;
+ case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+ (void)extractresourceufs(myname(ep));
+#else
+ msg("MacOSX not supported in this version, skipping\n");
+ skipfile();
+#endif
+ break;
+ case EXT_ACL:
+ msg("ACLs not supported in this version, skipping\n");
+ skipfile();
+ break;
+ default:
+ msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+ skipfile();
+ break;
+ }
+ goto finderres;
+ }
+
+#ifdef USE_QFA
+ }
+#endif /* USE_QFA */
+ ep->e_flags &= ~NEW;
+ if (volno != curvol)
+ skipmaps();
+ }
+ }
+}
+
+/*
+ * Add links.
+ */
+void
+createlinks(void)
+{
+ struct entry *np, *ep;
+ dump_ino_t i;
+ char name[BUFSIZ];
+
+ if ((ep = lookupino(WINO))) {
+ Vprintf(stdout, "Add whiteouts\n");
+ for ( ; ep != NULL; ep = ep->e_links) {
+ if ((ep->e_flags & NEW) == 0)
+ continue;
+#ifdef __linux__
+ (void)fprintf(stderr, "BUG! Should call addwhiteout\n");
+#else
+#ifdef sunos
+#else
+ (void) addwhiteout(myname(ep));
+#endif
+#endif
+ ep->e_flags &= ~NEW;
+ }
+ }
+ Vprintf(stdout, "Add links\n");
+ for (i = ROOTINO; i < maxino; i++) {
+ ep = lookupino(i);
+ if (ep == NULL)
+ continue;
+ for (np = ep->e_links; np != NULL; np = np->e_links) {
+ if ((np->e_flags & NEW) == 0)
+ continue;
+ (void) strcpy(name, myname(ep));
+ if (ep->e_type == NODE) {
+ (void) linkit(name, myname(np), SYMLINK);
+ } else {
+ (void) linkit(name, myname(np), HARDLINK);
+ }
+ np->e_flags &= ~NEW;
+ }
+ }
+}
+
+/*
+ * Check the symbol table.
+ * We do this to insure that all the requested work was done, and
+ * that no temporary names remain.
+ */
+void
+checkrestore(void)
+{
+ struct entry *ep;
+ dump_ino_t i;
+
+ Vprintf(stdout, "Check the symbol table.\n");
+ for (i = WINO; i < maxino; i++) {
+ for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
+ ep->e_flags &= ~KEEP;
+ if (ep->e_type == NODE)
+ ep->e_flags &= ~(NEW|EXISTED);
+ if (ep->e_flags /* != NULL */)
+ badentry(ep, "incomplete operations");
+ }
+ }
+}
+
+/*
+ * Compare with the directory structure on the tape
+ * A paranoid check that things are as they should be.
+ */
+long
+verifyfile(char *name, dump_ino_t ino, int type)
+{
+ struct entry *np, *ep;
+ long descend = GOOD;
+
+ ep = lookupname(name);
+ if (ep == NULL) {
+ fprintf(stderr, "Warning: missing name %s\n", name);
+ return (FAIL);
+ }
+ np = lookupino(ino);
+ if (np != ep)
+ descend = FAIL;
+ for ( ; np != NULL; np = np->e_links)
+ if (np == ep)
+ break;
+ if (np == NULL)
+ panic("missing inumber %d\n", ino);
+ if (ep->e_type == LEAF && type != LEAF)
+ badentry(ep, "type should be LEAF");
+ return (descend);
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ *
+ * $Id: restore.h,v 1.29 2004/04/13 13:04:33 stelian Exp $
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <protocols/dumprestore.h>
+/*
+ * Flags
+ */
+extern int aflag; /* automatic volume increment */
+extern char *Afile; /* archive file */
+extern int cvtflag; /* convert from old to new tape format */
+extern int bflag; /* set input block size */
+extern int dflag; /* print out debugging info */
+extern int hflag; /* restore heirarchies */
+extern int lflag; /* assume remote filename is a regular file */
+extern int Lflag; /* compare errors limit */
+extern int mflag; /* restore by name instead of inode number */
+extern int Mflag; /* multi-volume restore */
+extern int oflag; /* do restore permissions without asking */
+extern int Vflag; /* multi-volume on a single device like CDROM */
+extern int Nflag; /* do not write the disk */
+extern int uflag; /* unlink symlink targets */
+extern int vflag; /* print out actions taken */
+extern int yflag; /* always try to recover from tape errors */
+extern int zflag; /* tape is in compressed format */
+extern int ufs2flag; /* tape is a FreeBSD UFS2 dump */
+extern char* bot_script; /* beginning of tape script */
+/*
+ * Global variables
+ */
+extern char *host; /* name of the remote host */
+extern char *dumpmap; /* map of inodes on this dump tape */
+extern char *usedinomap; /* map of inodes that are in use on this fs */
+extern dump_ino_t maxino; /* highest numbered inode in this file system */
+extern long dumpnum; /* location of the dump on this tape */
+extern long volno; /* current volume being read */
+extern long ntrec; /* number of TP_BSIZE records per tape block */
+extern time_t dumptime; /* time that this dump begins */
+extern time_t dumpdate; /* time that this dump was made */
+extern char command; /* opration being performed */
+extern FILE *terminal; /* file descriptor for the terminal input */
+extern int pipein; /* input is from a pipe */
+extern char *tmpdir; /* name of temp directory */
+extern int oldinofmt; /* reading tape with old format inodes */
+extern int Bcvt; /* need byte swapping on inodes and dirs */
+extern int compare_ignore_not_found;
+ /* used to compare incremental dumps, */
+ /* so messages about "not found" files */
+ /* isn't seen. */
+extern int compare_errors; /* did we encounter any compare errors? */
+extern char filesys[NAMELEN];/* name of dumped filesystem */
+extern dump_ino_t volinfo[]; /* which inode on which volume archive info */
+
+/*
+ * Each file in the file system is described by one of these entries
+ */
+struct entry {
+ char *e_name; /* the current name of this entry */
+ u_char e_namlen; /* length of this name */
+ char e_type; /* type of this entry, see below */
+ short e_flags; /* status flags, see below */
+ dump_ino_t e_ino; /* inode number in previous file sys */
+ long e_index; /* unique index (for dumpped table) */
+ struct entry *e_parent; /* pointer to parent directory (..) */
+ struct entry *e_sibling; /* next element in this directory (.) */
+ struct entry *e_links; /* hard links to this inode */
+ struct entry *e_entries; /* for directories, their entries */
+ struct entry *e_next; /* hash chain list */
+};
+/* types */
+#define LEAF 1 /* non-directory entry */
+#define NODE 2 /* directory entry */
+#define LINK 4 /* synthesized type, stripped by addentry */
+/* flags */
+#define EXTRACT 0x0001 /* entry is to be replaced from the tape */
+#define NEW 0x0002 /* a new entry to be extracted */
+#define KEEP 0x0004 /* entry is not to change */
+#define REMOVED 0x0010 /* entry has been removed */
+#define TMPNAME 0x0020 /* entry has been given a temporary name */
+#define EXISTED 0x0040 /* directory already existed during extract */
+
+/*
+ * Constants associated with entry structs
+ */
+#define HARDLINK 1
+#define SYMLINK 2
+#define TMPHDR "RSTTMP"
+
+/*
+ * The entry describes the next file available on the tape
+ */
+struct context {
+ char *name; /* name of file */
+ dump_ino_t ino; /* inumber of file */
+#if defined(__linux__) || defined(sunos)
+ struct new_bsd_inode *dip; /* pointer to inode */
+#else
+ struct dinode *dip; /* pointer to inode */
+#endif
+ char action; /* action being taken on this file */
+} curfile;
+/* actions */
+#define USING 1 /* extracting from the tape */
+#define SKIP 2 /* skipping */
+#define UNKNOWN 3 /* disposition or starting point is unknown */
+
+/*
+ * Definitions for library routines operating on directories.
+ */
+typedef struct rstdirdesc RST_DIR;
+
+/*
+ * Flags to setdirmodes.
+ */
+#define FORCE 0x0001
+
+/*
+ * Useful macros
+ */
+#define TSTINO(ino, map) \
+ (map[(u_int)((ino) - 1) / NBBY] & (1 << ((u_int)((ino) - 1) % NBBY)))
+#define SETINO(ino, map) \
+ map[(u_int)((ino) - 1) / NBBY] |= 1 << ((u_int)((ino) - 1) % NBBY)
+
+#define Dprintf if (dflag) fprintf
+#define Vprintf if (vflag) fprintf
+
+#define GOOD 1
+#define FAIL 0
+
+#ifdef USE_QFA
+#define QFA_MAGIC "495115637697"
+#define QFA_VERSION "1.0"
+extern FILE *gTapeposfp;
+extern char *gTapeposfile;
+extern char gTps[255];
+extern long gSeekstart;
+extern int tapeposflag;
+extern int gTapeposfd;
+extern int createtapeposflag;
+extern unsigned long qfadumpdate;
+extern long long curtapepos;
+#ifdef sunos
+int fdsmtc;
+long scsiid;
+char smtcpath[2048];
+#endif
+#endif /* USE_QFA */
+
+#define do_compare_error \
+ if (++compare_errors >= Lflag && Lflag) { \
+ printf("Compare errors limit reached, exiting...\n"); \
+ exit(2); \
+ }
+
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: symtab.c,v 1.22 2003/10/26 16:05:48 stelian Exp $";
+#endif /* not lint */
+
+/*
+ * These routines maintain the symbol table which tracks the state
+ * of the file system being restored. They provide lookup by either
+ * name or inode number. They also provide for creation, deletion,
+ * and renaming of entries. Because of the dynamic nature of pathnames,
+ * names should not be saved, but always constructed just before they
+ * are needed, by calling "myname".
+ */
+
+#include <config.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#include <sys/time.h>
+#include <time.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+#endif /* __linux__ */
+
+#include <errno.h>
+#include <compaterr.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __linux__
+#include <ext2fs/ext2fs.h>
+#endif
+
+#include "restore.h"
+#include "extern.h"
+
+/*
+ * The following variables define the inode symbol table.
+ * The primary hash table is dynamically allocated based on
+ * the number of inodes in the file system (maxino), scaled by
+ * HASHFACTOR. The variable "entry" points to the hash table;
+ * the variable "entrytblsize" indicates its size (in entries).
+ */
+#define HASHFACTOR 5
+static struct entry **entry;
+static long entrytblsize;
+
+static void addino __P((dump_ino_t, struct entry *));
+static struct entry *lookupparent __P((char *));
+static void removeentry __P((struct entry *));
+
+/*
+ * Look up an entry by inode number
+ */
+struct entry *
+lookupino(dump_ino_t inum)
+{
+ struct entry *ep;
+
+ if (inum < WINO || inum >= maxino)
+ return (NULL);
+ for (ep = entry[inum % entrytblsize]; ep != NULL; ep = ep->e_next)
+ if (ep->e_ino == inum)
+ return (ep);
+ return (NULL);
+}
+
+/*
+ * Add an entry into the entry table
+ */
+static void
+addino(dump_ino_t inum, struct entry *np)
+{
+ struct entry **epp;
+
+ if (inum < WINO || inum >= maxino)
+ panic("addino: out of range %d\n", inum);
+ epp = &entry[inum % entrytblsize];
+ np->e_ino = inum;
+ np->e_next = *epp;
+ *epp = np;
+ if (dflag)
+ for (np = np->e_next; np != NULL; np = np->e_next)
+ if (np->e_ino == inum)
+ badentry(np, "duplicate inum");
+}
+
+/*
+ * Delete an entry from the entry table
+ */
+void
+deleteino(dump_ino_t inum)
+{
+ struct entry *next;
+ struct entry **prev;
+
+ if (inum < WINO || inum >= maxino)
+ panic("deleteino: out of range %d\n", inum);
+ prev = &entry[inum % entrytblsize];
+ for (next = *prev; next != NULL; next = next->e_next) {
+ if (next->e_ino == inum) {
+ next->e_ino = 0;
+ *prev = next->e_next;
+ return;
+ }
+ prev = &next->e_next;
+ }
+ panic("deleteino: %d not found\n", inum);
+}
+
+/*
+ * Look up an entry by name
+ */
+struct entry *
+lookupname(char *name)
+{
+ struct entry *ep;
+ char *np, *cp;
+ char buf[MAXPATHLEN];
+
+ cp = name;
+ for (ep = lookupino(ROOTINO); ep != NULL; ep = ep->e_entries) {
+ for (np = buf; *cp != '/' && *cp != '\0' &&
+ np < &buf[sizeof(buf)]; )
+ *np++ = *cp++;
+ if (np == &buf[sizeof(buf)])
+ break;
+ *np = '\0';
+ for ( ; ep != NULL; ep = ep->e_sibling)
+ if (strcmp(ep->e_name, buf) == 0)
+ break;
+ if (ep == NULL)
+ break;
+ if (*cp++ == '\0')
+ return (ep);
+ }
+ return (NULL);
+}
+
+/*
+ * Look up the parent of a pathname
+ */
+static struct entry *
+lookupparent(char *name)
+{
+ struct entry *ep;
+ char *tailindex;
+
+ tailindex = strrchr(name, '/');
+ if (tailindex == NULL)
+ return (NULL);
+ *tailindex = '\0';
+ ep = lookupname(name);
+ *tailindex = '/';
+ if (ep == NULL)
+ return (NULL);
+ if (ep->e_type != NODE)
+ panic("%s is not a directory\n", name);
+ return (ep);
+}
+
+/*
+ * Determine the current pathname of a node or leaf
+ */
+char *
+myname(struct entry *ep)
+{
+ char *cp;
+ static char namebuf[MAXPATHLEN];
+
+ for (cp = &namebuf[MAXPATHLEN - 2]; cp > &namebuf[ep->e_namlen]; ) {
+ cp -= ep->e_namlen;
+ memmove(cp, ep->e_name, (size_t)ep->e_namlen);
+ if (ep == lookupino(ROOTINO))
+ return (cp);
+ *(--cp) = '/';
+ ep = ep->e_parent;
+ }
+ panic("%s: pathname too long\n", cp);
+ return(cp);
+}
+
+/*
+ * Unused symbol table entries are linked together on a free list
+ * headed by the following pointer.
+ */
+static struct entry *freelist = NULL;
+
+/*
+ * add an entry to the symbol table
+ */
+struct entry *
+addentry(char *name, dump_ino_t inum, int type)
+{
+ struct entry *np, *ep;
+
+ if (freelist != NULL) {
+ np = freelist;
+ freelist = np->e_next;
+ memset(np, 0, sizeof(struct entry));
+ } else {
+ np = (struct entry *)calloc(1, sizeof(struct entry));
+ if (np == NULL)
+ errx(1, "no memory to extend symbol table");
+ }
+ np->e_type = type & ~LINK;
+ ep = lookupparent(name);
+ if (ep == NULL) {
+ if (inum != ROOTINO || lookupino(ROOTINO) != NULL)
+ panic("bad name to addentry %s\n", name);
+ np->e_name = savename(name);
+ np->e_namlen = strlen(name);
+ np->e_parent = np;
+ addino(ROOTINO, np);
+ return (np);
+ }
+ np->e_name = savename(strrchr(name, '/') + 1);
+ np->e_namlen = strlen(np->e_name);
+ np->e_parent = ep;
+ np->e_sibling = ep->e_entries;
+ ep->e_entries = np;
+ if (type & LINK) {
+ ep = lookupino(inum);
+ if (ep == NULL)
+ panic("link to non-existent name\n");
+ np->e_ino = inum;
+ np->e_links = ep->e_links;
+ ep->e_links = np;
+ } else if (inum != 0) {
+ if (lookupino(inum) != NULL)
+ panic("duplicate entry\n");
+ addino(inum, np);
+ }
+ return (np);
+}
+
+/*
+ * delete an entry from the symbol table
+ */
+void
+freeentry(struct entry *ep)
+{
+ struct entry *np;
+ dump_ino_t inum;
+
+ if (ep->e_flags != REMOVED)
+ badentry(ep, "not marked REMOVED");
+ if (ep->e_type == NODE) {
+ if (ep->e_links != NULL)
+ badentry(ep, "freeing referenced directory");
+ if (ep->e_entries != NULL)
+ badentry(ep, "freeing non-empty directory");
+ }
+ if (ep->e_ino != 0) {
+ np = lookupino(ep->e_ino);
+ if (np == NULL)
+ badentry(ep, "lookupino failed");
+ if (np == ep) {
+ inum = ep->e_ino;
+ deleteino(inum);
+ if (ep->e_links != NULL)
+ addino(inum, ep->e_links);
+ } else {
+ for (; np != NULL; np = np->e_links) {
+ if (np->e_links == ep) {
+ np->e_links = ep->e_links;
+ break;
+ }
+ }
+ if (np == NULL)
+ badentry(ep, "link not found");
+ }
+ }
+ removeentry(ep);
+ freename(ep->e_name);
+ ep->e_next = freelist;
+ freelist = ep;
+}
+
+/*
+ * Relocate an entry in the tree structure
+ */
+void
+moveentry(struct entry *ep, char *newname)
+{
+ struct entry *np;
+ char *cp;
+
+ np = lookupparent(newname);
+ if (np == NULL)
+ badentry(ep, "cannot move ROOT");
+ if (np != ep->e_parent) {
+ removeentry(ep);
+ ep->e_parent = np;
+ ep->e_sibling = np->e_entries;
+ np->e_entries = ep;
+ }
+ cp = strrchr(newname, '/') + 1;
+ freename(ep->e_name);
+ ep->e_name = savename(cp);
+ ep->e_namlen = strlen(cp);
+ if (strcmp(gentempname(ep), ep->e_name) == 0)
+ ep->e_flags |= TMPNAME;
+ else
+ ep->e_flags &= ~TMPNAME;
+}
+
+/*
+ * Remove an entry in the tree structure
+ */
+static void
+removeentry(struct entry *ep)
+{
+ struct entry *np;
+
+ np = ep->e_parent;
+ if (np->e_entries == ep) {
+ np->e_entries = ep->e_sibling;
+ } else {
+ for (np = np->e_entries; np != NULL; np = np->e_sibling) {
+ if (np->e_sibling == ep) {
+ np->e_sibling = ep->e_sibling;
+ break;
+ }
+ }
+ if (np == NULL)
+ badentry(ep, "cannot find entry in parent list");
+ }
+}
+
+/*
+ * Table of unused string entries, sorted by length.
+ *
+ * Entries are allocated in STRTBLINCR sized pieces so that names
+ * of similar lengths can use the same entry. The value of STRTBLINCR
+ * is chosen so that every entry has at least enough space to hold
+ * a "struct strtbl" header. Thus every entry can be linked onto an
+ * appropriate free list.
+ *
+ * NB. The macro "allocsize" below assumes that "struct strhdr"
+ * has a size that is a power of two.
+ */
+struct strhdr {
+ struct strhdr *next;
+};
+
+#define STRTBLINCR (sizeof(struct strhdr))
+#define allocsize(size) (((size) + 1 + STRTBLINCR - 1) & ~(STRTBLINCR - 1))
+
+static struct strhdr strtblhdr[allocsize(MAXNAMLEN) / STRTBLINCR];
+
+/*
+ * Allocate space for a name. It first looks to see if it already
+ * has an appropriate sized entry, and if not allocates a new one.
+ */
+char *
+savename(char *name)
+{
+ struct strhdr *np;
+ long len;
+ char *cp;
+
+ if (name == NULL)
+ panic("bad name\n");
+ len = strlen(name);
+ np = strtblhdr[len / STRTBLINCR].next;
+ if (np != NULL) {
+ strtblhdr[len / STRTBLINCR].next = np->next;
+ cp = (char *)np;
+ } else {
+ cp = malloc((unsigned)allocsize(len));
+ if (cp == NULL)
+ errx(1, "no space for string table");
+ }
+ (void) strcpy(cp, name);
+ return (cp);
+}
+
+/*
+ * Free space for a name. The resulting entry is linked onto the
+ * appropriate free list.
+ */
+void
+freename(char *name)
+{
+ struct strhdr *tp, *np;
+
+ tp = &strtblhdr[strlen(name) / STRTBLINCR];
+ np = (struct strhdr *)name;
+ np->next = tp->next;
+ tp->next = np;
+}
+
+/*
+ * Useful quantities placed at the end of a dumped symbol table.
+ */
+struct symtableheader {
+ int32_t volno;
+ int32_t stringsize;
+ int32_t entrytblsize;
+ time_t dumptime;
+ time_t dumpdate;
+ dump_ino_t maxino;
+ int32_t ntrec;
+ int32_t zflag;
+};
+
+/*
+ * dump a snapshot of the symbol table
+ */
+void
+dumpsymtable(char *filename, long checkpt)
+{
+ struct entry *ep, *tep;
+ dump_ino_t i;
+ struct entry temp, *tentry;
+ long mynum = 1, stroff = 0;
+ FILE *fd;
+ struct symtableheader hdr;
+
+ Vprintf(stdout, "Check pointing the restore\n");
+ if (Nflag)
+ return;
+ if ((fd = fopen(filename, "w")) == NULL) {
+ warn("fopen");
+ panic("cannot create save file %s for symbol table\n",
+ filename);
+ }
+ clearerr(fd);
+ /*
+ * Assign indices to each entry
+ * Write out the string entries
+ */
+ for (i = WINO; i <= maxino; i++) {
+ for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
+ ep->e_index = mynum++;
+ (void) fwrite(ep->e_name, sizeof(char),
+ (int)allocsize(ep->e_namlen), fd);
+ }
+ }
+ /*
+ * Convert pointers to indexes, and output
+ */
+ tep = &temp;
+ stroff = 0;
+ for (i = WINO; i <= maxino; i++) {
+ for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
+ memmove(tep, ep, sizeof(struct entry));
+ tep->e_name = (char *)stroff;
+ stroff += allocsize(ep->e_namlen);
+ tep->e_parent = (struct entry *)ep->e_parent->e_index;
+ if (ep->e_links != NULL)
+ tep->e_links =
+ (struct entry *)ep->e_links->e_index;
+ if (ep->e_sibling != NULL)
+ tep->e_sibling =
+ (struct entry *)ep->e_sibling->e_index;
+ if (ep->e_entries != NULL)
+ tep->e_entries =
+ (struct entry *)ep->e_entries->e_index;
+ if (ep->e_next != NULL)
+ tep->e_next =
+ (struct entry *)ep->e_next->e_index;
+ (void) fwrite((char *)tep, sizeof(struct entry), 1, fd);
+ }
+ }
+ /*
+ * Convert entry pointers to indexes, and output
+ */
+ for (i = 0; (long)i < entrytblsize; i++) {
+ if (entry[i] == NULL)
+ tentry = NULL;
+ else
+ tentry = (struct entry *)entry[i]->e_index;
+ (void) fwrite((char *)&tentry, sizeof(struct entry *), 1, fd);
+ }
+ hdr.volno = checkpt;
+ hdr.maxino = maxino;
+ hdr.entrytblsize = entrytblsize;
+ hdr.stringsize = stroff;
+ hdr.dumptime = dumptime;
+ hdr.dumpdate = dumpdate;
+ hdr.ntrec = ntrec;
+ hdr.zflag = zflag;
+ (void) fwrite((char *)&hdr, sizeof(struct symtableheader), 1, fd);
+ if (ferror(fd)) {
+ warn("fwrite");
+ panic("output error to file %s writing symbol table\n",
+ filename);
+ }
+ (void) fclose(fd);
+}
+
+/*
+ * Initialize a symbol table from a file
+ */
+void
+initsymtable(char *filename)
+{
+ char *base;
+ long tblsize;
+ struct entry *ep;
+ struct entry *baseep, *lep;
+ struct symtableheader hdr;
+ struct stat stbuf;
+ long i;
+ int fd;
+
+ Vprintf(stdout, "Initialize symbol table.\n");
+ if (filename == NULL) {
+ entrytblsize = maxino / HASHFACTOR;
+ entry = (struct entry **)
+ calloc((unsigned)entrytblsize, sizeof(struct entry *));
+ if (entry == (struct entry **)NULL)
+ errx(1, "no memory for entry table");
+ ep = addentry(".", ROOTINO, NODE);
+ ep->e_flags |= NEW;
+ return;
+ }
+ if ((fd = open(filename, O_RDONLY, 0)) < 0) {
+ warn("open");
+ errx(1, "cannot open symbol table file %s", filename);
+ }
+ if (fstat(fd, &stbuf) < 0) {
+ warn("stat");
+ errx(1, "cannot stat symbol table file %s", filename);
+ }
+ tblsize = stbuf.st_size - sizeof(struct symtableheader);
+ base = calloc(sizeof(char), (unsigned)tblsize);
+ if (base == NULL)
+ errx(1, "cannot allocate space for symbol table");
+ if (read(fd, base, (int)tblsize) < 0 ||
+ read(fd, (char *)&hdr, sizeof(struct symtableheader)) < 0) {
+ warn("read");
+ errx(1, "cannot read symbol table file %s", filename);
+ }
+ switch (command) {
+ case 'r':
+ /*
+ * For normal continuation, insure that we are using
+ * the next incremental tape
+ */
+ if (hdr.dumpdate != dumptime)
+ errx(1, "Incremental tape too %s",
+ (hdr.dumpdate < dumptime) ? "low" : "high");
+ break;
+ case 'R':
+ /*
+ * For restart, insure that we are using the same tape
+ */
+ curfile.action = SKIP;
+ dumptime = hdr.dumptime;
+ dumpdate = hdr.dumpdate;
+ zflag = hdr.zflag;
+ if (!bflag)
+ newtapebuf(hdr.ntrec);
+ getvol(hdr.volno);
+ break;
+ default:
+ panic("initsymtable called from command %c\n", command);
+ break;
+ }
+ resizemaps(maxino, hdr.maxino);
+ maxino = hdr.maxino;
+ entrytblsize = hdr.entrytblsize;
+ entry = (struct entry **)
+ (base + tblsize - (entrytblsize * sizeof(struct entry *)));
+ baseep = (struct entry *)(base + hdr.stringsize - sizeof(struct entry));
+ lep = (struct entry *)entry;
+ for (i = 0; i < entrytblsize; i++) {
+ if (entry[i] == NULL)
+ continue;
+ entry[i] = &baseep[(long)entry[i]];
+ }
+ for (ep = &baseep[1]; ep < lep; ep++) {
+ ep->e_name = base + (long)ep->e_name;
+ ep->e_parent = &baseep[(long)ep->e_parent];
+ if (ep->e_sibling != NULL)
+ ep->e_sibling = &baseep[(long)ep->e_sibling];
+ if (ep->e_links != NULL)
+ ep->e_links = &baseep[(long)ep->e_links];
+ if (ep->e_entries != NULL)
+ ep->e_entries = &baseep[(long)ep->e_entries];
+ if (ep->e_next != NULL)
+ ep->e_next = &baseep[(long)ep->e_next];
+ }
+}
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: tape.c,v 1.81 2004/05/25 10:39:31 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <compaterr.h>
+#include <system.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/mtio.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#include <sys/time.h>
+#include <time.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#define quad_t int64_t
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#endif
+#endif /* __linux__ */
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
+#include <protocols/dumprestore.h>
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif /* HAVE_ZLIB */
+
+#ifdef HAVE_BZLIB
+#include <bzlib.h>
+#endif /* HAVE_BZLIB */
+
+#ifdef HAVE_LZO
+#include <minilzo.h>
+#endif /* HAVE_LZO */
+
+#include "restore.h"
+#include "extern.h"
+#include "pathnames.h"
+
+#ifdef USE_QFA
+int noresyncmesg = 0;
+#endif /* USE_QFA */
+static long fssize = MAXBSIZE;
+static int mt = -1;
+int pipein = 0;
+static int magtapein = 0; /* input is from magtape */
+static char magtape[MAXPATHLEN];
+static char magtapeprefix[MAXPATHLEN];
+static int blkcnt;
+static int numtrec;
+static char *tapebuf; /* input buffer for read */
+static int bufsize; /* buffer size without prefix */
+static char *tbufptr = NULL; /* active tape buffer */
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+static char *comprbuf; /* uncompress work buf */
+static size_t comprlen; /* size including prefix */
+#endif
+static union u_spcl endoftapemark;
+static long blksread; /* blocks read since last header */
+static long tpblksread = 0; /* TP_BSIZE blocks read */
+static long tapesread;
+static sigjmp_buf restart;
+static int gettingfile = 0; /* restart has a valid frame */
+char *host = NULL;
+
+static int ofile;
+static char *map;
+static char lnkbuf[MAXPATHLEN + 1];
+static int pathlen;
+
+int oldinofmt; /* old inode format conversion required */
+int Bcvt; /* Swap Bytes (for CCI or sun) */
+static int Qcvt; /* Swap quads (for sun) */
+
+#define FLUSHTAPEBUF() blkcnt = ntrec + 1
+
+static void accthdr __P((struct s_spcl *));
+static int checksum __P((int *));
+static void findinode __P((struct s_spcl *));
+static void findtapeblksize __P((void));
+static int gethead __P((struct s_spcl *));
+static int converthead __P((struct s_spcl *));
+static void converttapebuf __P((struct tapebuf *));
+static void readtape __P((char *));
+static void setdumpnum __P((void));
+#ifdef DUMP_MACOSX
+static void xtrfilefinderinfo __P((char *, size_t));
+#endif
+
+static u_int swabi __P((u_int));
+#if 0
+static u_long swabl __P((u_long));
+#endif
+static u_char *swab64 __P((u_char *, int));
+static u_char *swab32 __P((u_char *, int));
+static u_char *swab16 __P((u_char *, int));
+static void terminateinput __P((void));
+static void xtrfile __P((char *, size_t));
+static void xtrlnkfile __P((char *, size_t));
+static void xtrlnkskip __P((char *, size_t));
+static void xtrmap __P((char *, size_t));
+static void xtrmapskip __P((char *, size_t));
+static void xtrskip __P((char *, size_t));
+static void setmagtapein __P((void));
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+static void newcomprbuf __P((int));
+static void (*readtape_func) __P((char *));
+static void readtape_set __P((char *));
+static void readtape_uncompr __P((char *));
+static void readtape_comprfile __P((char *));
+static void readtape_comprtape __P((char *));
+static char *decompress_tapebuf __P((struct tapebuf *, int));
+static void msg_read_error __P((char *));
+#endif
+static int read_a_block __P((int, char *, size_t, long *));
+#define PREFIXSIZE sizeof(struct tapebuf)
+
+#define COMPARE_ONTHEFLY 1
+
+#if COMPARE_ONTHEFLY
+static int ifile; /* input file for compare */
+static int cmperror; /* compare error */
+static void xtrcmpfile __P((char *, size_t));
+static void xtrcmpskip __P((char *, size_t));
+#endif
+
+static int readmapflag;
+static int readingmaps; /* set to 1 while reading the maps */
+
+#ifdef DUMP_MACOSX
+static DumpFinderInfo gFndrInfo;
+#endif
+
+/*
+ * Set up an input source. This is called from main.c before setup() is.
+ */
+void
+setinput(char *source)
+{
+ int i;
+ char *n;
+
+ FLUSHTAPEBUF();
+ if (bflag)
+ newtapebuf(ntrec);
+ else
+ newtapebuf(NTREC > HIGHDENSITYTREC ? NTREC : HIGHDENSITYTREC);
+ terminal = stdin;
+
+#ifdef RRESTORE
+ if ((n = strchr(source, ':'))) {
+ for (i = 0; i < (n - source); i++) {
+ if (source[i] == '/')
+ break;
+ }
+ if (source[i] != '/') {
+ host = source;
+ source = strchr(host, ':');
+ *source++ = '\0';
+ if (rmthost(host) == 0)
+ exit(1);
+ }
+ } else
+#endif
+ if (strcmp(source, "-") == 0) {
+ /*
+ * Since input is coming from a pipe we must establish
+ * our own connection to the terminal.
+ */
+ terminal = fopen(_PATH_TTY, "r");
+ if (terminal == NULL) {
+ warn("cannot open %s", _PATH_TTY);
+ terminal = fopen(_PATH_DEVNULL, "r");
+ if (terminal == NULL)
+ err(1, "cannot open %s", _PATH_DEVNULL);
+ }
+ pipein++;
+ }
+ setuid(getuid()); /* no longer need or want root privileges */
+ if (Mflag) {
+ strncpy(magtapeprefix, source, MAXPATHLEN);
+ magtapeprefix[MAXPATHLEN-1] = '\0';
+ snprintf(magtape, MAXPATHLEN, "%s%03d", source, 1);
+ }
+ else
+ strncpy(magtape, source, MAXPATHLEN);
+ magtape[MAXPATHLEN - 1] = '\0';
+}
+
+void
+newtapebuf(long size)
+{
+ static int tapebufsize = -1;
+
+ ntrec = size;
+ bufsize = ntrec * TP_BSIZE;
+ if (size <= tapebufsize)
+ return;
+ if (tapebuf != NULL)
+ free(tapebuf);
+ tapebuf = malloc(size * TP_BSIZE + sizeof(struct tapebuf));
+ if (tapebuf == NULL)
+ errx(1, "Cannot allocate space for tape buffer");
+ tapebufsize = size;
+}
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+static void
+newcomprbuf(int size)
+{
+ size_t buf_size = (size+1) * TP_BSIZE + sizeof(struct tapebuf);
+ if (buf_size <= comprlen)
+ return;
+ comprlen = buf_size;
+ if (comprbuf != NULL)
+ free(comprbuf);
+ comprbuf = malloc(comprlen);
+ if (comprbuf == NULL)
+ errx(1, "Cannot allocate space for decompress buffer");
+}
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+
+/*
+ * Verify that the tape drive can be accessed and
+ * that it actually is a dump tape.
+ */
+void
+setup(void)
+{
+ int i, j, *ip, bot_code;
+ struct STAT stbuf;
+ char *temptape;
+
+ Vprintf(stdout, "Verify tape and initialize maps\n");
+ if (Afile == NULL && bot_script) {
+ msg("Launching %s\n", bot_script);
+ bot_code = system_command(bot_script, magtape, 1);
+ if (bot_code != 0 && bot_code != 1) {
+ msg("Restore aborted by the beginning of tape script\n");
+ exit(1);
+ }
+ }
+
+ if (Afile)
+ temptape = Afile;
+ else
+ temptape = magtape;
+
+#ifdef RRESTORE
+ if (!Afile && host)
+ mt = rmtopen(temptape, O_RDONLY);
+ else
+#endif
+ if (pipein)
+ mt = 0;
+ else
+ mt = OPEN(temptape, O_RDONLY, 0);
+ if (mt < 0)
+ err(1, "%s", temptape);
+ if (!Afile) {
+ volno = 1;
+ setmagtapein();
+ setdumpnum();
+ }
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+ readtape_func = readtape_set;
+#if defined(HAVE_LZO)
+ if (lzo_init() != LZO_E_OK) {
+ msg("internal error - lzo_init failed \n");
+ exit(1);
+ }
+#endif
+#endif
+ FLUSHTAPEBUF();
+ findtapeblksize();
+ if (gethead(&spcl) == FAIL) {
+ blkcnt--; /* push back this block */
+ blksread--;
+ tpblksread--;
+ cvtflag++;
+ if (gethead(&spcl) == FAIL)
+ errx(1, "Tape is not a dump tape");
+ fprintf(stderr, "Converting to new file system format.\n");
+ }
+
+ if (zflag) {
+ fprintf(stderr, "Dump tape is compressed.\n");
+#if !defined(HAVE_ZLIB) && !defined(HAVE_BZLIB) && !defined(HAVE_LZO)
+ errx(1,"This restore version doesn't support decompression");
+#endif /* !HAVE_ZLIB && !HAVE_BZLIB */
+ }
+ if (pipein) {
+ endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
+ endoftapemark.s_spcl.c_type = TS_END;
+ ip = (int *)&endoftapemark;
+ j = sizeof(union u_spcl) / sizeof(int);
+ i = 0;
+ do
+ i += *ip++;
+ while (--j);
+ endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
+ }
+ if (vflag || command == 't' || command == 'C')
+ printdumpinfo();
+#ifdef USE_QFA
+ if (tapeposflag && (unsigned long)spcl.c_date != qfadumpdate)
+ errx(1, "different QFA/dumpdates detected\n");
+#endif
+ if (filesys[0] == '\0') {
+ char *dirptr;
+ strncpy(filesys, spcl.c_filesys, NAMELEN);
+ filesys[NAMELEN - 1] = '\0';
+ dirptr = strstr(filesys, " (dir");
+ if (dirptr != NULL)
+ *dirptr = '\0';
+ }
+ dumptime = spcl.c_ddate;
+ dumpdate = spcl.c_date;
+ if (STAT(".", &stbuf) < 0)
+ err(1, "cannot stat .");
+ if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE )
+ fssize = TP_BSIZE;
+ if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE)
+ fssize = stbuf.st_blksize;
+ if (((fssize - 1) & fssize) != 0)
+ errx(1, "bad block size %ld", fssize);
+ if (spcl.c_volume != 1)
+ errx(1, "Tape is not volume 1 of the dump");
+ if (gethead(&spcl) == FAIL) {
+ Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread);
+ panic("no header after volume mark!\n");
+ }
+ readingmaps = 1;
+ findinode(&spcl);
+ if (spcl.c_type != TS_CLRI)
+ errx(1, "Cannot find file removal list");
+ maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
+ map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
+ if (map == NULL)
+ errx(1, "no memory for active inode map");
+ usedinomap = map;
+ curfile.action = USING;
+ getfile(xtrmap, xtrmapskip);
+ while (spcl.c_type == TS_ADDR) {
+ /* Recompute maxino and the map */
+ dump_ino_t oldmaxino = maxino;
+ maxino += (spcl.c_count * TP_BSIZE * NBBY) + 1;
+ resizemaps(oldmaxino, maxino);
+ map = usedinomap;
+
+ spcl.c_dinode.di_size = spcl.c_count * TP_BSIZE;
+ getfile(xtrmap, xtrmapskip);
+ }
+ Dprintf(stdout, "maxino = %lu\n", (unsigned long)maxino);
+ if (spcl.c_type != TS_BITS) {
+ if (spcl.c_type == TS_END) {
+ msg("Cannot find file dump list, assuming empty tape\n");
+ exit(0);
+ }
+ errx(1, "Cannot find file dump list");
+ }
+ map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
+ if (map == (char *)NULL)
+ errx(1, "no memory for file dump list");
+ dumpmap = map;
+ curfile.action = USING;
+ getfile(xtrmap, xtrmapskip);
+ while (spcl.c_type == TS_ADDR) {
+ spcl.c_dinode.di_size = spcl.c_count * TP_BSIZE;
+ getfile(xtrmap, xtrmapskip);
+ }
+ /*
+ * If there may be whiteout entries on the tape, pretend that the
+ * whiteout inode exists, so that the whiteout entries can be
+ * extracted.
+ */
+ if (oldinofmt == 0)
+ SETINO(WINO, dumpmap);
+ readingmaps = 0;
+ findinode(&spcl);
+}
+
+/*
+ * Prompt user to load a new dump volume.
+ * "Nextvol" is the next suggested volume to use.
+ * This suggested volume is enforced when doing full
+ * or incremental restores, but can be overridden by
+ * the user when only extracting a subset of the files.
+ */
+void
+getvol(long nextvol)
+{
+ long newvol = 0, wantnext = 0, i;
+ long saved_blksread = 0, saved_tpblksread = 0;
+ union u_spcl tmpspcl;
+# define tmpbuf tmpspcl.s_spcl
+ char buf[TP_BSIZE];
+ int haderror = 0, bot_code = 1;
+
+ if (nextvol == 1) {
+ tapesread = 0;
+ gettingfile = 0;
+ tpblksread = 0;
+ blksread = 0;
+ }
+ if (pipein) {
+ if (nextvol != 1)
+ panic("Changing volumes on pipe input?\n");
+ if (volno == 1)
+ return;
+ goto gethdr;
+ }
+ saved_blksread = blksread;
+ saved_tpblksread = tpblksread;
+#if defined(USE_QFA) && defined(sunos)
+ if (createtapeposflag || tapeposflag)
+ close(fdsmtc);
+#endif
+again:
+ if (pipein)
+ exit(1); /* pipes do not get a second chance */
+ if (aflag || curfile.action != SKIP) {
+ newvol = nextvol;
+ wantnext = 1;
+ } else {
+ newvol = 0;
+ wantnext = 0;
+ }
+ while (newvol <= 0) {
+ if (tapesread == 0) {
+ fprintf(stderr, "%s%s%s%s%s",
+ "You have not read any volumes yet.\n",
+ "Unless you know which volume your",
+ " file(s) are on you should start\n",
+ "with the last volume and work",
+ " towards the first.\n");
+ } else {
+ fprintf(stderr, "You have read volumes");
+ strcpy(buf, ": ");
+ for (i = 1; i < 32; i++)
+ if (tapesread & (1 << i)) {
+ fprintf(stderr, "%s%ld", buf, (long)i);
+ strcpy(buf, ", ");
+ }
+ fprintf(stderr, "\n");
+ }
+ do {
+ fprintf(stderr, "Specify next volume # (none if no more volumes): ");
+ (void) fflush(stderr);
+ (void) fgets(buf, TP_BSIZE, terminal);
+ } while (!feof(terminal) && buf[0] == '\n');
+ if (feof(terminal))
+ exit(1);
+ if (!strcmp(buf, "none\n")) {
+ terminateinput();
+ return;
+ }
+ newvol = atoi(buf);
+ if (newvol <= 0) {
+ fprintf(stderr,
+ "Volume numbers are positive numerics\n");
+ }
+ }
+ if (newvol == volno) {
+ tapesread |= 1 << volno;
+#if defined(USE_QFA) && defined(sunos)
+ if (createtapeposflag || tapeposflag) {
+ if (OpenSMTCmt(magtape) < 0) {
+ volno = -1;
+ haderror = 1;
+ goto again;
+ }
+ }
+#endif /* USE_QFA */
+ return;
+ }
+ closemt();
+
+ /*
+ * if using an archive file, reset its name so readtape()
+ * could properly use remote access.
+ */
+ Afile = NULL;
+
+ if (Mflag) {
+ snprintf(magtape, MAXPATHLEN, "%s%03ld", magtapeprefix, newvol);
+ magtape[MAXPATHLEN - 1] = '\0';
+ }
+ if (bot_script && !haderror) {
+ msg("Launching %s\n", bot_script);
+ bot_code = system_command(bot_script, magtape, newvol);
+ if (bot_code != 0 && bot_code != 1) {
+ msg("Restore aborted by the beginning of tape script\n");
+ exit(1);
+ }
+ }
+ if (haderror || (bot_code && !Mflag)) {
+ haderror = 0;
+#ifdef sunos
+ fprintf(stderr, "Mount volume %ld\n", (long)newvol);
+#else
+ fprintf(stderr, "Mount tape volume %ld\n", (long)newvol);
+#endif
+ fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
+#ifdef sunos
+ fprintf(stderr, "then enter volume name (default: %s) ", magtape);
+#else
+ fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
+#endif
+ (void) fflush(stderr);
+ (void) fgets(buf, TP_BSIZE, terminal);
+ if (feof(terminal))
+ exit(1);
+ if (!strcmp(buf, "none\n")) {
+ terminateinput();
+ return;
+ }
+ if (buf[0] != '\n') {
+ char *pos;
+ (void) strncpy(magtape, buf, sizeof(magtape));
+ magtape[sizeof(magtape) - 1] = '\0';
+ if ((pos = strchr(magtape, '\n')))
+ magtape[pos - magtape] = '\0';
+ }
+ }
+#if defined(USE_QFA) && defined(sunos)
+ if (createtapeposflag || tapeposflag) {
+ if (OpenSMTCmt(magtape) < 0) {
+ volno = -1;
+ haderror = 1;
+ goto again;
+ }
+ }
+#endif /* USE_QFA */
+#ifdef RRESTORE
+ if (host)
+ mt = rmtopen(magtape, O_RDONLY);
+ else
+#endif
+ mt = OPEN(magtape, O_RDONLY, 0);
+
+ if (mt == -1) {
+ fprintf(stderr, "Cannot open %s\n", magtape);
+ volno = -1;
+ haderror = 1;
+ goto again;
+ }
+gethdr:
+ setmagtapein();
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+ readtape_func = readtape_set;
+#endif
+ volno = newvol;
+ setdumpnum();
+ FLUSHTAPEBUF();
+ findtapeblksize();
+ if (gethead(&tmpbuf) == FAIL) {
+ Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread);
+ fprintf(stderr, "tape is not dump tape\n");
+ volno = 0;
+ haderror = 1;
+ blksread = saved_blksread;
+ tpblksread = saved_tpblksread;
+ goto again;
+ }
+ if (tmpbuf.c_volume != volno) {
+ fprintf(stderr, "Wrong volume (%d)\n", tmpbuf.c_volume);
+ volno = 0;
+ haderror = 1;
+ blksread = saved_blksread;
+ tpblksread = saved_tpblksread;
+ goto again;
+ }
+ if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
+ fprintf(stderr, "Wrong dump date\n\tgot: %s",
+#ifdef sunos
+ ctime(&tmpbuf.c_date));
+#else
+ ctime4(&tmpbuf.c_date));
+#endif
+ fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
+ volno = 0;
+ haderror = 1;
+ blksread = saved_blksread;
+ tpblksread = saved_tpblksread;
+ goto again;
+ }
+ tapesread |= 1 << volno;
+ /*
+ * If continuing from the previous volume, skip over any
+ * blocks read already at the end of the previous volume.
+ *
+ * If coming to this volume at random, skip to the beginning
+ * of the next record.
+ */
+ if (zflag) {
+ fprintf(stderr, "Dump tape is compressed.\n");
+#if !defined(HAVE_ZLIB) && !defined(HAVE_BZLIB) && !defined(HAVE_LZO)
+ errx(1,"This restore version doesn't support decompression");
+#endif /* !HAVE_ZLIB && !HAVE_BZLIB */
+ }
+ Dprintf(stdout, "read %ld recs, tape starts with %ld\n",
+ tpblksread - 1, (long)tmpbuf.c_firstrec);
+ if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
+ if (!wantnext) {
+ tpblksread = tmpbuf.c_firstrec + 1;
+ for (i = tmpbuf.c_count; i > 0; i--)
+ readtape(buf);
+ } else if (tmpbuf.c_firstrec > 0 &&
+ tmpbuf.c_firstrec < tpblksread - 1) {
+ /*
+ * -1 since we've read the volume header
+ */
+ i = tpblksread - tmpbuf.c_firstrec - 1;
+ Dprintf(stderr, "Skipping %ld duplicate record%s.\n",
+ (long)i, i > 1 ? "s" : "");
+ while (--i >= 0)
+ readtape(buf);
+ }
+ }
+ if (curfile.action == USING) {
+ if (volno == 1)
+ panic("active file into volume 1\n");
+ return;
+ }
+ /*
+ * Skip up to the beginning of the next record
+ */
+ if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER))
+ for (i = tmpbuf.c_count; i > 0; i--)
+ readtape(buf);
+ (void) gethead(&spcl);
+ findinode(&spcl);
+ if (gettingfile) {
+ gettingfile = 0;
+ siglongjmp(restart, 1);
+ }
+}
+
+/*
+ * Handle unexpected EOF.
+ */
+static void
+terminateinput(void)
+{
+
+ if (gettingfile && curfile.action == USING) {
+ printf("Warning: %s %s\n",
+ "End-of-input encountered while extracting", curfile.name);
+ }
+ curfile.name = "<name unknown>";
+ curfile.action = UNKNOWN;
+ curfile.dip = NULL;
+ curfile.ino = maxino;
+ if (gettingfile) {
+ gettingfile = 0;
+ siglongjmp(restart, 1);
+ }
+}
+
+/*
+ * handle multiple dumps per tape by skipping forward to the
+ * appropriate one.
+ */
+static void
+setdumpnum(void)
+{
+ struct mtop tcom;
+
+ if (dumpnum == 1 || volno != 1)
+ return;
+ if (pipein)
+ errx(1, "Cannot have multiple dumps on pipe input");
+ tcom.mt_op = MTFSF;
+ tcom.mt_count = dumpnum - 1;
+#ifdef RRESTORE
+ if (host) {
+ if (rmtioctl(MTFSF, dumpnum - 1) < 0) {
+ fprintf(stderr, "rmtioctl MTFSF: %s\n", strerror(errno));
+ exit(1);
+ }
+ } else
+#endif
+ if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) {
+ fprintf(stderr, "rmtioctl MTFSF: %s\n", strerror(errno));
+ exit(1);
+ /* warn("ioctl MTFSF"); */
+ }
+}
+
+void
+printdumpinfo(void)
+{
+#ifdef sunos
+ Vprintf(stdout, "Dump date: %s", ctime(&spcl.c_date));
+ Vprintf(stdout, "Dumped from: %s",
+ (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate));
+ if (spcl.c_host[0] == '\0')
+ return;
+ Vprintf(stdout, "Level %d dump of %s on %s:%s\n",
+ spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
+ Vprintf(stdout, "Label: %s\n", spcl.c_label);
+#else
+ fprintf(stdout, "Dump date: %s", ctime4(&spcl.c_date));
+ fprintf(stdout, "Dumped from: %s",
+ (spcl.c_ddate == 0) ? "the epoch\n" : ctime4(&spcl.c_ddate));
+ if (spcl.c_host[0] == '\0')
+ return;
+ fprintf(stdout, "Level %d dump of %s on %s:%s\n",
+ spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
+ fprintf(stdout, "Label: %s\n", spcl.c_label);
+#endif
+}
+
+void
+printvolinfo(void)
+{
+ int i;
+
+ if (volinfo[1] == ROOTINO) {
+ printf("Starting inode numbers by volume:\n");
+ for (i = 1; i < (int)TP_NINOS && volinfo[i] != 0; ++i)
+ printf("\tVolume %d: %lu\n", i, (unsigned long)volinfo[i]);
+ }
+}
+
+
+int
+extractfile(struct entry *ep, int doremove)
+{
+ unsigned int flags;
+ mode_t mode;
+ struct timeval timep[2];
+ char *name = myname(ep);
+
+ /* If removal is requested (-r mode) do remove it unless
+ * we are extracting a metadata only inode */
+ if (spcl.c_flags & DR_METAONLY) {
+ Vprintf(stdout, "file %s is metadata only\n", name);
+ }
+ else {
+ if (doremove) {
+ removeleaf(ep);
+ ep->e_flags &= ~REMOVED;
+ }
+ }
+
+ curfile.name = name;
+ curfile.action = USING;
+#if defined(__linux__) || defined(sunos)
+ timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
+ timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
+ timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
+ timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
+#else /* __linux__ || sunos */
+ timep[0].tv_sec = curfile.dip->di_atime;
+ timep[0].tv_usec = curfile.dip->di_atimensec / 1000;
+ timep[1].tv_sec = curfile.dip->di_mtime;
+ timep[1].tv_usec = curfile.dip->di_mtimensec / 1000;
+#endif /* __linux__ */
+ mode = curfile.dip->di_mode;
+ flags = curfile.dip->di_flags;
+ switch (mode & IFMT) {
+
+ default:
+ fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode);
+ skipfile();
+ return (FAIL);
+
+ case IFSOCK:
+ Vprintf(stdout, "skipped socket %s\n", name);
+ skipfile();
+ return (GOOD);
+
+ case IFDIR:
+ if (mflag) {
+ if (ep == NULL || ep->e_flags & EXTRACT)
+ panic("unextracted directory %s\n", name);
+ skipfile();
+ return (GOOD);
+ }
+ Vprintf(stdout, "extract file %s\n", name);
+ return (genliteraldir(name, curfile.ino));
+
+ case IFLNK:
+ {
+#ifdef HAVE_LCHOWN
+ uid_t luid = curfile.dip->di_uid;
+ gid_t lgid = curfile.dip->di_gid;
+#endif
+ if (! (spcl.c_flags & DR_METAONLY)) {
+ lnkbuf[0] = '\0';
+ pathlen = 0;
+ getfile(xtrlnkfile, xtrlnkskip);
+ if (pathlen == 0) {
+ Vprintf(stdout,
+ "%s: zero length symbolic link (ignored)\n", name);
+ return (GOOD);
+ }
+ if (linkit(lnkbuf, name, SYMLINK) == FAIL)
+ return (FAIL);
+ }
+ else
+ skipfile();
+
+#ifdef HAVE_LCHOWN
+ (void) lchown(name, luid, lgid);
+#endif
+ return (GOOD);
+ }
+
+ case IFIFO:
+ Vprintf(stdout, "extract fifo %s\n", name);
+ if (Nflag) {
+ skipfile();
+ return (GOOD);
+ }
+ if (! (spcl.c_flags & DR_METAONLY)) {
+ if (uflag && !Nflag)
+ (void)unlink(name);
+ if (mkfifo(name, mode) < 0) {
+ warn("%s: cannot create fifo", name);
+ skipfile();
+ return (FAIL);
+ }
+ }
+ (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void) chmod(name, mode);
+ if (flags)
+#ifdef __linux__
+ (void) fsetflags(name, flags);
+#else
+#ifdef sunos
+ {
+ warn("%s: cannot call chflags", name);
+ /* (void) chflags(name, flags); */
+ }
+#else
+ (void) chflags(name, flags);
+#endif
+#endif
+ skipfile();
+ utimes(name, timep);
+ return (GOOD);
+
+ case IFCHR:
+ case IFBLK:
+ Vprintf(stdout, "extract special file %s\n", name);
+ if (Nflag) {
+ skipfile();
+ return (GOOD);
+ }
+ if (! (spcl.c_flags & DR_METAONLY)) {
+ if (uflag)
+ (void)unlink(name);
+ if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
+ warn("%s: cannot create special file", name);
+ skipfile();
+ return (FAIL);
+ }
+ }
+ (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void) chmod(name, mode);
+ if (flags)
+#ifdef __linux__
+ {
+ warn("%s: fsetflags called on a special file", name);
+ (void) fsetflags(name, flags);
+ }
+#else
+#ifdef sunos
+ {
+ warn("%s: cannot call chflags on a special file", name);
+ /* (void) chflags(name, flags); */
+ }
+#else
+ {
+ warn("%s: chflags called on a special file", name);
+ (void) chflags(name, flags);
+ }
+#endif
+#endif
+ skipfile();
+ utimes(name, timep);
+ return (GOOD);
+
+ case IFREG:
+ {
+ uid_t luid = curfile.dip->di_uid;
+ gid_t lgid = curfile.dip->di_gid;
+
+ Vprintf(stdout, "extract file %s\n", name);
+ if (Nflag) {
+ skipfile();
+ return (GOOD);
+ }
+ if (! (spcl.c_flags & DR_METAONLY)) {
+ if (uflag)
+ (void)unlink(name);
+ if ((ofile = OPEN(name, O_WRONLY | O_CREAT | O_TRUNC,
+ 0666)) < 0) {
+ warn("%s: cannot create file", name);
+ skipfile();
+ return (FAIL);
+ }
+ getfile(xtrfile, xtrskip);
+ (void) close(ofile);
+ }
+ else
+ skipfile();
+ (void) chown(name, luid, lgid);
+ (void) chmod(name, mode);
+ if (flags)
+#ifdef __linux__
+ (void) fsetflags(name, flags);
+#else
+#ifdef sunos
+ {
+ warn("%s: cannot call chflags", name);
+ /* (void) chflags(name, flags); */
+ }
+#else
+ (void) chflags(name, flags);
+#endif
+#endif
+ utimes(name, timep);
+ return (GOOD);
+ }
+ }
+ /* NOTREACHED */
+}
+
+#ifdef DUMP_MACOSX
+int
+extractfinderinfoufs(char *name)
+{
+ int err;
+ char oFileRsrc[MAXPATHLEN];
+ int flags;
+ mode_t mode;
+ struct timeval timep[2];
+ u_int32_t uid;
+ u_int32_t gid;
+ char path[MAXPATHLEN], fname[MAXPATHLEN];
+ int toto;
+
+ curfile.name = name;
+ curfile.action = USING;
+ timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
+ timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
+ timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
+ timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
+ mode = curfile.dip->di_mode;
+ flags = curfile.dip->di_flags;
+ uid = curfile.dip->di_uid;
+ gid = curfile.dip->di_gid;
+
+ switch (mode & IFMT) {
+
+ default:
+ fprintf(stderr, "%s: (extr. finfoufs) unknown file mode 0%o\n", name, mode);
+ skipfile();
+ return (FAIL);
+
+ case IFDIR:
+ fprintf(stderr, "%s: (extr. finfoufs[IFDIR]) unknown file mode 0%o\n", name, mode);
+ skipfile();
+ return (FAIL);
+
+ case IFLNK:
+ skipfile();
+ return (GOOD);
+
+ case IFREG:
+ Vprintf(stdout, "extract finderinfo file %s\n", name);
+ if (Nflag) {
+ skipfile();
+ return (GOOD);
+ }
+ getfile(xtrfilefinderinfo, xtrskip);
+
+ GetPathFile(name, path, fname);
+ strcpy(oFileRsrc, path);
+ strcat(oFileRsrc, "._");
+ strcat(oFileRsrc, fname);
+
+ if ((err = CreateAppleDoubleFileRes(oFileRsrc, &gFndrInfo.fndrinfo,
+ mode, flags, timep, uid, gid)) != 0) {
+ fprintf(stderr, "%s: cannot create finderinfo: %s\n",
+ name, strerror(errno));
+ skipfile();
+ return (FAIL);
+ }
+ return (GOOD);
+ }
+ /* NOTREACHED */
+}
+
+
+int
+extractresourceufs(char *name)
+{
+ char oFileRsrc[MAXPATHLEN];
+ int flags;
+ mode_t mode;
+ struct timeval timep[2];
+ char path[MAXPATHLEN], fname[MAXPATHLEN];
+ ASDHeaderPtr hp;
+ ASDEntryPtr ep;
+ u_long loff;
+ u_int32_t uid;
+ u_int32_t gid;
+ u_int64_t di_size;
+ char *p;
+ char buf[1024];
+
+ curfile.name = name;
+ curfile.action = USING;
+ timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
+ timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
+ timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
+ timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
+ mode = curfile.dip->di_mode;
+ flags = curfile.dip->di_flags;
+ uid = curfile.dip->di_uid;
+ gid = curfile.dip->di_gid;
+ di_size = curfile.dip->di_size;
+
+ switch (mode & IFMT) {
+
+ default:
+ fprintf(stderr, "%s: (extr. resufs) unknown file mode 0%o\n", name, mode);
+ skipfile();
+ return (FAIL);
+
+ case IFDIR:
+ fprintf(stderr, "%s: (extr. resufs [IFDIR]) unknown file mode 0%o\n", name, mode);
+ skipfile();
+ return (FAIL);
+
+ case IFLNK:
+ skipfile();
+ return (GOOD);
+
+ case IFREG:
+ Vprintf(stdout, "extract resource file %s\n", name);
+ if (Nflag) {
+ skipfile();
+ return (GOOD);
+ }
+
+ GetPathFile(name, path, fname);
+ strcpy(oFileRsrc, path);
+ strcat(oFileRsrc, "._");
+ strcat(oFileRsrc, fname);
+
+ if ((ofile = open(oFileRsrc, O_RDONLY, 0)) < 0) {
+ fprintf(stderr, "%s: cannot read finderinfo: %s\n",
+ name, strerror(errno));
+ skipfile();
+ return (FAIL);
+ }
+ read(ofile, buf, 70);
+ (void) close(ofile);
+ p = buf;
+ hp = (ASDHeaderPtr)p;
+ /* the header */
+ hp->entries++;
+ p += sizeof(ASDHeader) - CORRECT;
+ ep = (ASDEntryPtr)p;
+ /* the finderinfo entry */
+ ep->offset += sizeof(ASDEntry);
+ loff = ep->offset;
+
+ p += sizeof(ASDEntry);
+ /* the finderinfo data */
+ bcopy(p, p + sizeof(ASDEntry), INFOLEN);
+ ep = (ASDEntryPtr)p;
+ /* the new resourcefork entry */
+ ep->entryID = EntryRSRCFork;
+ ep->offset = loff + INFOLEN;
+ ep->len = di_size;
+ /* write the new appledouble entries to the file */
+ if ((ofile = open(oFileRsrc, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+ fprintf(stderr, "%s: cannot create resource file: %s\n",
+ name, strerror(errno));
+ skipfile();
+ return (FAIL);
+ }
+ write(ofile, buf, 70 + sizeof(ASDEntry));
+ /* and add the resource data from tape */
+ getfile(xtrfile, xtrskip);
+
+ (void) fchown(ofile, uid, gid);
+ (void) fchmod(ofile, mode);
+ (void) close(ofile);
+ (void) fsetflags(oFileRsrc, flags);
+ utimes(oFileRsrc, timep);
+ return (GOOD);
+ }
+ /* NOTREACHED */
+}
+#endif /* DUMP_MACOSX */
+
+/*
+ * skip over bit maps on the tape
+ */
+void
+skipmaps(void)
+{
+
+ while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI)
+ skipfile();
+}
+
+/*
+ * skip over a file on the tape
+ */
+void
+skipfile(void)
+{
+
+ curfile.action = SKIP;
+ getfile(xtrnull, xtrnull);
+}
+
+/*
+ * Extract a file from the tape.
+ * When an allocated block is found it is passed to the fill function;
+ * when an unallocated block (hole) is found, a zeroed buffer is passed
+ * to the skip function.
+ */
+void
+getfile(void (*fill) __P((char *, size_t)), void (*skip) __P((char *, size_t)))
+{
+ int i;
+ volatile int curblk = 0;
+ volatile quad_t size = spcl.c_dinode.di_size;
+ volatile int last_write_was_hole = 0;
+ quad_t origsize = size;
+ static char clearedbuf[MAXBSIZE];
+ char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
+ char junk[TP_BSIZE];
+
+ if (spcl.c_type == TS_END)
+ panic("ran off end of tape\n");
+ if (spcl.c_magic != NFS_MAGIC)
+ panic("not at beginning of a file\n");
+ if (!gettingfile && setjmp(restart) != 0)
+ return;
+ gettingfile++;
+loop:
+ for (i = 0; i < spcl.c_count; i++) {
+ if (readmapflag || spcl.c_addr[i]) {
+ readtape(&buf[curblk++][0]);
+ if (curblk == fssize / TP_BSIZE) {
+ (*fill)((char *)buf, (size_t)(size > TP_BSIZE ?
+ fssize : (curblk - 1) * TP_BSIZE + size));
+ curblk = 0;
+ last_write_was_hole = 0;
+ }
+ } else {
+ if (curblk > 0) {
+ (*fill)((char *)buf, (size_t)(size > TP_BSIZE ?
+ curblk * TP_BSIZE :
+ (curblk - 1) * TP_BSIZE + size));
+ curblk = 0;
+ }
+ (*skip)(clearedbuf, (long)(size > TP_BSIZE ?
+ TP_BSIZE : size));
+ last_write_was_hole = 1;
+ }
+ if ((size -= TP_BSIZE) <= 0) {
+ for (i++; i < spcl.c_count; i++)
+ if (readmapflag || spcl.c_addr[i])
+ readtape(junk);
+ break;
+ }
+ }
+ if (gethead(&spcl) == GOOD && size > 0) {
+ if (spcl.c_type == TS_ADDR)
+ goto loop;
+ Dprintf(stdout,
+ "Missing address (header) block for %s at %ld blocks\n",
+ curfile.name, (long)blksread);
+ }
+ if (curblk > 0) {
+ (*fill)((char *)buf, (size_t)((curblk * TP_BSIZE) + size));
+ last_write_was_hole = 0;
+ }
+ if (size > 0) {
+ fprintf(stderr, "Missing blocks at the end of %s, assuming hole\n", curfile.name);
+ while (size > 0) {
+ size_t skp = size > TP_BSIZE ? TP_BSIZE : size;
+ (*skip)(clearedbuf, skp);
+ size -= skp;
+ }
+ last_write_was_hole = 1;
+ }
+ if (last_write_was_hole) {
+ FTRUNCATE(ofile, origsize);
+ }
+ if (!readingmaps)
+ findinode(&spcl);
+ gettingfile = 0;
+}
+
+/*
+ * Write out the next block of a file.
+ */
+static void
+xtrfile(char *buf, size_t size)
+{
+
+ if (Nflag)
+ return;
+ if (write(ofile, buf, (int) size) == -1)
+ err(1, "write error extracting inode %lu, name %s\nwrite",
+ (unsigned long)curfile.ino, curfile.name);
+}
+
+#ifdef DUMP_MACOSX
+static void
+xtrfilefinderinfo(char *buf, size_t size)
+{
+ if (Nflag)
+ return;
+ bcopy(buf, &gFndrInfo, size);
+}
+#endif /* DUMP_MACOSX */
+
+/*
+ * Skip over a hole in a file.
+ */
+/* ARGSUSED */
+static void
+xtrskip(UNUSED(char *buf), size_t size)
+{
+
+ if (LSEEK(ofile, (OFF_T)size, SEEK_CUR) == -1)
+ err(1, "seek error extracting inode %lu, name %s\nlseek",
+ (unsigned long)curfile.ino, curfile.name);
+}
+
+/*
+ * Collect the next block of a symbolic link.
+ */
+static void
+xtrlnkfile(char *buf, size_t size)
+{
+
+ pathlen += size;
+ if (pathlen > MAXPATHLEN)
+ errx(1, "symbolic link name: %s->%s%s; too long %d",
+ curfile.name, lnkbuf, buf, pathlen);
+ (void) strcat(lnkbuf, buf);
+}
+
+/*
+ * Skip over a hole in a symbolic link (should never happen).
+ */
+/* ARGSUSED */
+static void
+xtrlnkskip(UNUSED(char *buf), UNUSED(size_t size))
+{
+
+ errx(1, "unallocated block in symbolic link %s", curfile.name);
+}
+
+/*
+ * Collect the next block of a bit map.
+ */
+static void
+xtrmap(char *buf, size_t size)
+{
+
+ memmove(map, buf, size);
+ map += size;
+}
+
+/*
+ * Skip over a hole in a bit map (should never happen).
+ */
+/* ARGSUSED */
+static void
+xtrmapskip(UNUSED(char *buf), size_t size)
+{
+
+ panic("hole in map\n");
+ map += size;
+}
+
+/*
+ * Noop, when an extraction function is not needed.
+ */
+/* ARGSUSED */
+void
+xtrnull(UNUSED(char *buf), UNUSED(size_t size))
+{
+
+ return;
+}
+
+#if COMPARE_ONTHEFLY
+/*
+ * Compare the next block of a file.
+ */
+static void
+xtrcmpfile(char *buf, size_t size)
+{
+ static char cmpbuf[MAXBSIZE];
+
+ if (cmperror)
+ return;
+
+ if (read(ifile, cmpbuf, size) != (ssize_t)size) {
+ fprintf(stderr, "%s: size has changed.\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+
+ if (memcmp(buf, cmpbuf, size) != 0) {
+ fprintf(stderr, "%s: tape and disk copies are different\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+}
+
+/*
+ * Skip over a hole in a file.
+ */
+static void
+xtrcmpskip(UNUSED(char *buf), size_t size)
+{
+ static char cmpbuf[MAXBSIZE];
+ int i;
+
+ if (cmperror)
+ return;
+
+ if (read(ifile, cmpbuf, size) != (ssize_t)size) {
+ fprintf(stderr, "%s: size has changed.\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+
+ for (i = 0; i < (int)size; ++i)
+ if (cmpbuf[i] != '\0') {
+ fprintf(stderr, "%s: tape and disk copies are different\n",
+ curfile.name);
+ cmperror = 1;
+ return;
+ }
+}
+#endif /* COMPARE_ONTHEFLY */
+
+#if !COMPARE_ONTHEFLY
+static int
+do_cmpfiles(int fd_tape, int fd_disk, long size)
+{
+ static char buf_tape[BUFSIZ];
+ static char buf_disk[BUFSIZ];
+ ssize_t n_tape;
+ ssize_t n_disk;
+
+ while (size > 0) {
+ if ((n_tape = read(fd_tape, buf_tape, sizeof(buf_tape))) < 1) {
+ close(fd_tape), close(fd_disk);
+ panic("do_cmpfiles: unexpected EOF[1]");
+ }
+ if ((n_disk = read(fd_disk, buf_disk, sizeof(buf_tape))) < 1) {
+ close(fd_tape), close(fd_disk);
+ panic("do_cmpfiles: unexpected EOF[2]");
+ }
+ if (n_tape != n_disk) {
+ close(fd_tape), close(fd_disk);
+ panic("do_cmpfiles: sizes different!");
+ }
+ if (memcmp(buf_tape, buf_disk, (size_t)n_tape) != 0) return (1);
+ size -= n_tape;
+ }
+ return (0);
+}
+
+/* for debugging compare problems */
+#undef COMPARE_FAIL_KEEP_FILE
+
+static
+#ifdef COMPARE_FAIL_KEEP_FILE
+/* return true if tapefile should be unlinked after compare */
+int
+#else
+void
+#endif
+cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
+{
+ struct STAT sbuf_tape;
+ int fd_tape, fd_disk;
+
+ if (STAT(tapefile, &sbuf_tape) != 0) {
+ panic("Can't lstat tmp file %s: %s\n", tapefile,
+ strerror(errno));
+ do_compare_error;
+ }
+
+ if (sbuf_disk->st_size != sbuf_tape.st_size) {
+ fprintf(stderr,
+ "%s: size changed from %ld to %ld.\n",
+ diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
+ do_compare_error;
+#ifdef COMPARE_FAIL_KEEP_FILE
+ return (0);
+#else
+ return;
+#endif
+ }
+
+ if ((fd_tape = OPEN(tapefile, O_RDONLY)) < 0) {
+ panic("Can't open %s: %s\n", tapefile, strerror(errno));
+ do_compare_error;
+ }
+ if ((fd_disk = OPEN(diskfile, O_RDONLY)) < 0) {
+ close(fd_tape);
+ panic("Can't open %s: %s\n", diskfile, strerror(errno));
+ do_compare_error;
+ }
+
+ if (do_cmpfiles(fd_tape, fd_disk, sbuf_tape.st_size)) {
+ fprintf(stderr, "%s: tape and disk copies are different\n",
+ diskfile);
+ close(fd_tape);
+ close(fd_disk);
+ do_compare_error;
+#ifdef COMPARE_FAIL_KEEP_FILE
+ /* rename the file to live in /tmp */
+ /* rename `tapefile' to /tmp/<basename of diskfile> */
+ {
+ char *p = strrchr(diskfile, '/');
+ char newname[MAXPATHLEN];
+ if (!p) {
+ panic("can't find / in %s\n", diskfile);
+ }
+ snprintf(newname, sizeof(newname), "%s/debug/%s", tmpdir, p + 1);
+ if (rename(tapefile, newname)) {
+ panic("rename from %s to %s failed: %s\n",
+ tapefile, newname,
+ strerror(errno));
+ } else {
+ fprintf(stderr, "*** %s saved to %s\n",
+ tapefile, newname);
+ }
+ }
+
+ /* don't unlink the file (it's not there anymore */
+ /* anyway) */
+ return (0);
+#else
+ return;
+#endif
+ }
+ close(fd_tape);
+ close(fd_disk);
+#ifdef COMPARE_FAIL_KEEP_FILE
+ return (1);
+#endif
+}
+#endif /* !COMPARE_ONTHEFLY */
+
+#if !COMPARE_ONTHEFLY
+static char tmpfilename[MAXPATHLEN];
+#endif
+
+void
+comparefile(char *name)
+{
+ unsigned int mode;
+ struct STAT sb;
+ int r;
+#if !COMPARE_ONTHEFLY
+ static char *tmpfile = NULL;
+ struct STAT stemp;
+#endif
+
+ curfile.name = name;
+ curfile.action = USING;
+ mode = curfile.dip->di_mode;
+
+ if ((mode & IFMT) == IFSOCK) {
+ Vprintf(stdout, "skipped socket %s\n", name);
+ skipfile();
+ return;
+ }
+
+ if ((r = LSTAT(name, &sb)) != 0) {
+ warn("%s: does not exist (%d)", name, r);
+ do_compare_error;
+ skipfile();
+ return;
+ }
+
+ Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name,
+ (long)sb.st_size, mode);
+
+ if (sb.st_mode != mode) {
+ fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
+ name, mode & 07777, sb.st_mode & 07777);
+ do_compare_error;
+ }
+ if (spcl.c_flags & DR_METAONLY) {
+ skipfile();
+ return;
+ }
+ switch (mode & IFMT) {
+ default:
+ skipfile();
+ return;
+
+ case IFSOCK:
+ skipfile();
+ return;
+
+ case IFDIR:
+ skipfile();
+ return;
+
+ case IFLNK: {
+ char lbuf[MAXPATHLEN + 1];
+ int lsize;
+
+ if (!(sb.st_mode & S_IFLNK)) {
+ fprintf(stderr, "%s: is no longer a symbolic link\n",
+ name);
+ do_compare_error;
+ return;
+ }
+ lnkbuf[0] = '\0';
+ pathlen = 0;
+ getfile(xtrlnkfile, xtrlnkskip);
+ if (pathlen == 0) {
+ fprintf(stderr,
+ "%s: zero length symbolic link (ignored)\n",
+ name);
+ do_compare_error;
+ return;
+ }
+ if ((lsize = readlink(name, lbuf, MAXPATHLEN)) < 0) {
+ panic("readlink of %s failed: %s", name,
+ strerror(errno));
+ do_compare_error;
+ }
+ lbuf[lsize] = 0;
+ if (strcmp(lbuf, lnkbuf) != 0) {
+ fprintf(stderr,
+ "%s: symbolic link changed from %s to %s.\n",
+ name, lnkbuf, lbuf);
+ do_compare_error;
+ return;
+ }
+ return;
+ }
+
+ case IFCHR:
+ case IFBLK:
+ if (!(sb.st_mode & (S_IFCHR|S_IFBLK))) {
+ fprintf(stderr, "%s: no longer a special file\n",
+ name);
+ do_compare_error;
+ skipfile();
+ return;
+ }
+
+ if (sb.st_rdev != (dev_t)curfile.dip->di_rdev) {
+ fprintf(stderr,
+ "%s: device changed from %d,%d to %d,%d.\n",
+ name,
+ major(curfile.dip->di_rdev),
+ minor(curfile.dip->di_rdev),
+ major(sb.st_rdev),
+ minor(sb.st_rdev));
+ do_compare_error;
+ }
+ skipfile();
+ return;
+
+ case IFREG:
+#if COMPARE_ONTHEFLY
+ if ((ifile = OPEN(name, O_RDONLY)) < 0) {
+ panic("Can't open %s: %s\n", name, strerror(errno));
+ skipfile();
+ do_compare_error;
+ }
+ else {
+ cmperror = 0;
+ getfile(xtrcmpfile, xtrcmpskip);
+ if (!cmperror) {
+ char c;
+ if (read(ifile, &c, 1) != 0) {
+ fprintf(stderr, "%s: size has changed.\n",
+ name);
+ cmperror = 1;
+ }
+ }
+ if (cmperror)
+ do_compare_error;
+ close(ifile);
+ }
+#else
+ if (tmpfile == NULL) {
+ /* argument to mktemp() must not be in RO space: */
+ snprintf(tmpfilename, sizeof(tmpfilename), "%s/restoreCXXXXXX", tmpdir);
+ tmpfile = mktemp(&tmpfilename[0]);
+ }
+ if ((STAT(tmpfile, &stemp) == 0) && (unlink(tmpfile) != 0)) {
+ panic("cannot delete tmp file %s: %s\n",
+ tmpfile, strerror(errno));
+ }
+ if ((ofile = OPEN(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
+ panic("cannot create file temp file %s: %s\n",
+ name, strerror(errno));
+ }
+ getfile(xtrfile, xtrskip);
+ (void) close(ofile);
+#ifdef COMPARE_FAIL_KEEP_FILE
+ if (cmpfiles(tmpfile, name, &sb))
+ unlink(tmpfile);
+#else
+ cmpfiles(tmpfile, name, &sb);
+ unlink(tmpfile);
+#endif
+#endif /* COMPARE_ONTHEFLY */
+ return;
+ }
+ /* NOTREACHED */
+}
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+static void (*readtape_func)(char *) = readtape_set;
+
+/*
+ * Read TP_BSIZE blocks from the input.
+ * Handle read errors, and end of media.
+ * Decompress compressed blocks.
+ */
+static void
+readtape(char *buf)
+{
+ (*readtape_func)(buf); /* call the actual processing routine */
+}
+
+/*
+ * Set function pointer for readtape() routine. zflag and magtapein must
+ * be correctly set before the first call to readtape().
+ */
+static void
+readtape_set(char *buf)
+{
+ if (!zflag)
+ readtape_func = readtape_uncompr;
+ else {
+ newcomprbuf(ntrec);
+ if (magtapein)
+ readtape_func = readtape_comprtape;
+ else
+ readtape_func = readtape_comprfile;
+ }
+ readtape(buf);
+}
+
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+
+/*
+ * This is the original readtape(), it's used for reading uncompressed input.
+ * Read TP_BSIZE blocks from the input.
+ * Handle read errors, and end of media.
+ */
+static void
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+readtape_uncompr(char *buf)
+#else
+readtape(char *buf)
+#endif
+{
+ ssize_t rd, newvol, i;
+ int cnt, seek_failed;
+
+ if (blkcnt < numtrec) {
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+ return;
+ }
+ tbufptr = tapebuf;
+ for (i = 0; i < ntrec; i++)
+ ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
+ if (numtrec == 0)
+ numtrec = ntrec;
+ cnt = ntrec * TP_BSIZE;
+ rd = 0;
+#ifdef USE_QFA
+ if (createtapeposflag)
+ (void)GetTapePos(&curtapepos);
+#endif
+getmore:
+#ifdef RRESTORE
+ if (!Afile && host)
+ i = rmtread(&tapebuf[rd], cnt);
+ else
+#endif
+ i = read(mt, &tapebuf[rd], cnt);
+
+ /*
+ * Check for mid-tape short read error.
+ * If found, skip rest of buffer and start with the next.
+ */
+ if (!pipein && numtrec < ntrec && i > 0) {
+ Dprintf(stdout, "mid-media short read error.\n");
+ numtrec = ntrec;
+ }
+ /*
+ * Handle partial block read.
+ */
+ if (pipein && i == 0 && rd > 0)
+ i = rd;
+ else if (i > 0 && i != ntrec * TP_BSIZE) {
+ if (pipein) {
+ rd += i;
+ cnt -= i;
+ if (cnt > 0)
+ goto getmore;
+ i = rd;
+ } else {
+ /*
+ * Short read. Process the blocks read.
+ */
+ if (i % TP_BSIZE != 0)
+ Vprintf(stdout,
+ "partial block read: %ld should be %ld\n",
+ (long)i, ntrec * TP_BSIZE);
+ numtrec = i / TP_BSIZE;
+ }
+ }
+ /*
+ * Handle read error.
+ */
+ if (i < 0) {
+ fprintf(stderr, "Tape read error while ");
+ switch (curfile.action) {
+ default:
+ fprintf(stderr, "trying to set up tape\n");
+ break;
+ case UNKNOWN:
+ fprintf(stderr, "trying to resynchronize\n");
+ break;
+ case USING:
+ fprintf(stderr, "restoring %s\n", curfile.name);
+ break;
+ case SKIP:
+ fprintf(stderr, "skipping over inode %lu\n",
+ (unsigned long)curfile.ino);
+ break;
+ }
+ if (!yflag && !reply("continue"))
+ exit(1);
+ i = ntrec * TP_BSIZE;
+ memset(tapebuf, 0, (size_t)i);
+#ifdef RRESTORE
+ if (!Afile && host)
+ seek_failed = (rmtseek(i, 1) < 0);
+ else
+#endif
+ seek_failed = (LSEEK(mt, i, SEEK_CUR) == (OFF_T)-1);
+
+ if (seek_failed) {
+ warn("continuation failed");
+ if (!yflag && !reply("assume end-of-tape and continue"))
+ exit(1);
+ i = 0;
+ }
+ }
+ /*
+ * Handle end of tape.
+ */
+ if (i == 0) {
+ Vprintf(stdout, "End-of-tape encountered\n");
+ if (!pipein) {
+ newvol = volno + 1;
+ volno = 0;
+ numtrec = 0;
+ getvol(newvol);
+ readtape(buf);
+ return;
+ }
+ if (rd % TP_BSIZE != 0)
+ panic("partial block read: %d should be %d\n",
+ rd, ntrec * TP_BSIZE);
+ terminateinput();
+ memmove(&tapebuf[rd], &endoftapemark, TP_BSIZE);
+ }
+ blkcnt = 0;
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+}
+
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+
+/*
+ * Read a compressed format block from a file or pipe and uncompress it.
+ * Attempt to handle read errors, and end of file.
+ */
+static void
+readtape_comprfile(char *buf)
+{
+ long rl, size, i, ret;
+ int newvol;
+ struct tapebuf *tpb;
+
+ if (blkcnt < numtrec) {
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+ return;
+ }
+ /* need to read the next block */
+ tbufptr = tapebuf;
+ for (i = 0; i < ntrec; i++)
+ ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
+ numtrec = ntrec;
+ tpb = (struct tapebuf *) tapebuf;
+
+ /* read the block prefix */
+ ret = read_a_block(mt, tapebuf, PREFIXSIZE, &rl);
+ converttapebuf(tpb);
+
+ if (Vflag && (ret == 0 || rl < (int)PREFIXSIZE || tpb->length == 0))
+ ret = 0;
+ if (ret <= 0)
+ goto readerr;
+
+ /* read the data */
+ size = tpb->length;
+ if (size > bufsize) {
+ /* something's wrong */
+ Vprintf(stdout, "Prefix size error, max size %d, got %ld\n",
+ bufsize, size);
+ size = bufsize;
+ tpb->length = bufsize;
+ }
+ ret = read_a_block(mt, tpb->buf, size, &rl);
+ if (ret <= 0)
+ goto readerr;
+
+ tbufptr = decompress_tapebuf(tpb, rl + PREFIXSIZE);
+ if (tbufptr == NULL) {
+ msg_read_error("File decompression error while");
+ if (!yflag && !reply("continue"))
+ exit(1);
+ memset(tapebuf, 0, bufsize);
+ tbufptr = tapebuf;
+ }
+
+ blkcnt = 0;
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+ return;
+
+readerr:
+ /* Errors while reading from a file or pipe are catastrophic. Since
+ * there are no block boundaries, it's impossible to bypass the
+ * block in error and find the start of the next block.
+ */
+ if (ret == 0) {
+ /* It's possible to have multiple input files using -M
+ * and -f file1,file2...
+ */
+ Vprintf(stdout, "End-of-File encountered\n");
+ if (!pipein) {
+ newvol = volno + 1;
+ volno = 0;
+ numtrec = 0;
+ getvol(newvol);
+ readtape(buf);
+ return;
+ }
+ }
+ msg_read_error("Read error while");
+ /* if (!yflag && !reply("continue")) */
+ exit(1);
+}
+
+/*
+ * Read compressed data from a tape and uncompress it.
+ * Handle read errors, and end of media.
+ * Since a tape consists of separate physical blocks, we try
+ * to recover from errors by repositioning the tape to the next
+ * block.
+ */
+static void
+readtape_comprtape(char *buf)
+{
+ long rl, size, i;
+ int ret, newvol;
+ struct tapebuf *tpb;
+ struct mtop tcom;
+
+ if (blkcnt < numtrec) {
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+ return;
+ }
+ /* need to read the next block */
+ tbufptr = tapebuf;
+ for (i = 0; i < ntrec; i++)
+ ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
+ numtrec = ntrec;
+ tpb = (struct tapebuf *) tapebuf;
+
+ /* read the block */
+ size = bufsize + PREFIXSIZE;
+ ret = read_a_block(mt, tapebuf, size, &rl);
+ if (ret <= 0)
+ goto readerr;
+
+ converttapebuf(tpb);
+ tbufptr = decompress_tapebuf(tpb, rl);
+ if (tbufptr == NULL) {
+ msg_read_error("Tape decompression error while");
+ if (!yflag && !reply("continue"))
+ exit(1);
+ memset(tapebuf, 0, PREFIXSIZE + bufsize);
+ tbufptr = tapebuf;
+ }
+ goto moverecord;
+
+readerr:
+ /* Handle errors: EOT switches to the next volume, other errors
+ * attempt to position the tape to the next block.
+ */
+ if (ret == 0) {
+ Vprintf(stdout, "End-of-tape encountered\n");
+ newvol = volno + 1;
+ volno = 0;
+ numtrec = 0;
+ getvol(newvol);
+ readtape(buf);
+ return;
+ }
+
+ msg_read_error("Tape read error while");
+ if (!yflag && !reply("continue"))
+ exit(1);
+ memset(tapebuf, 0, PREFIXSIZE + bufsize);
+ tbufptr = tapebuf;
+
+#ifdef RRESTORE
+ if (host)
+ rl = rmtioctl(MTFSR, 1);
+ else
+#endif
+ {
+ tcom.mt_op = MTFSR;
+ tcom.mt_count = 1;
+ rl = ioctl(mt, MTIOCTOP, &tcom);
+ }
+
+ if (rl < 0) {
+ warn("continuation failed");
+ if (!yflag && !reply("assume end-of-tape and continue"))
+ exit(1);
+ ret = 0; /* end of tape */
+ goto readerr;
+ }
+
+moverecord:
+ blkcnt = 0;
+ memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+ blksread++;
+ tpblksread++;
+}
+
+/*
+ * Decompress a struct tapebuf into a buffer. readsize is the size read
+ * from the tape/file and is used for error messages. Returns a pointer
+ * to the location of the uncompressed buffer or NULL on errors.
+ * Adjust numtrec and complain for a short block.
+ */
+static char *
+decompress_tapebuf(struct tapebuf *tpbin, int readsize)
+{
+ /* If zflag is on, all blocks have a struct tapebuf prefix */
+ /* zflag gets set in setup() from the dump header */
+ int cresult, blocklen;
+ unsigned long worklen;
+ char *output = NULL,*reason = NULL, *lengtherr = NULL;
+
+ /* build a length error message */
+ blocklen = tpbin->length;
+ if (readsize < blocklen + (int)PREFIXSIZE)
+ lengtherr = "short";
+ else
+ if (readsize > blocklen + (int)PREFIXSIZE)
+ lengtherr = "long";
+
+ worklen = comprlen;
+ cresult = 1;
+ if (tpbin->compressed) {
+ /* uncompress whatever we read, if it fails, complain later */
+ if (tpbin->flags == COMPRESS_ZLIB) {
+#ifndef HAVE_ZLIB
+ errx(1,"This restore version doesn't support zlib decompression");
+#else
+ cresult = uncompress(comprbuf, &worklen,
+ tpbin->buf, blocklen);
+ output = comprbuf;
+ switch (cresult) {
+ case Z_OK:
+ break;
+ case Z_MEM_ERROR:
+ reason = "not enough memory";
+ break;
+ case Z_BUF_ERROR:
+ reason = "buffer too small";
+ break;
+ case Z_DATA_ERROR:
+ reason = "data error";
+ break;
+ default:
+ reason = "unknown";
+ }
+ if (cresult == Z_OK)
+ cresult = 1;
+ else
+ cresult = 0;
+#endif /* HAVE_ZLIB */
+ }
+ if (tpbin->flags == COMPRESS_BZLIB) {
+#ifndef HAVE_BZLIB
+ errx(1,"This restore version doesn't support bzlib decompression");
+#else
+ unsigned int worklen2 = worklen;
+ cresult = BZ2_bzBuffToBuffDecompress(
+ comprbuf, &worklen2,
+ tpbin->buf, blocklen, 0, 0);
+ worklen = worklen2;
+ output = comprbuf;
+ switch (cresult) {
+ case BZ_OK:
+ break;
+ case BZ_MEM_ERROR:
+ reason = "not enough memory";
+ break;
+ case BZ_OUTBUFF_FULL:
+ reason = "buffer too small";
+ break;
+ case BZ_DATA_ERROR:
+ case BZ_DATA_ERROR_MAGIC:
+ case BZ_UNEXPECTED_EOF:
+ reason = "data error";
+ break;
+ default:
+ reason = "unknown";
+ }
+ if (cresult == BZ_OK)
+ cresult = 1;
+ else
+ cresult = 0;
+#endif /* HAVE_BZLIB */
+ }
+ if (tpbin->flags == COMPRESS_LZO) {
+#ifndef HAVE_LZO
+ errx(1,"This restore version doesn't support lzo decompression");
+#else
+ lzo_uint worklen2 = worklen;
+ cresult = lzo1x_decompress(tpbin->buf, blocklen,
+ comprbuf, &worklen2, NULL);
+ worklen = worklen2;
+ output = comprbuf;
+ switch (cresult) {
+ case LZO_E_OK:
+ break;
+ case LZO_E_ERROR:
+ case LZO_E_EOF_NOT_FOUND:
+ reason = "data error";
+ break;
+ default:
+ reason = "unknown";
+ }
+ if (cresult == LZO_E_OK)
+ cresult = 1;
+ else
+ cresult = 0;
+#endif /* HAVE_LZO */
+ }
+ }
+ else {
+ output = tpbin->buf;
+ worklen = blocklen;
+ }
+ if (cresult) {
+ numtrec = worklen / TP_BSIZE;
+ if (worklen % TP_BSIZE != 0)
+ reason = "length mismatch";
+ }
+ if (reason) {
+ if (lengtherr)
+ fprintf(stderr, "%s compressed block: %d expected: %u\n",
+ lengtherr, readsize, tpbin->length + PREFIXSIZE);
+ fprintf(stderr, "decompression error, block %ld: %s\n",
+ tpblksread+1, reason);
+ if (!cresult)
+ output = NULL;
+ }
+ return output;
+}
+
+/*
+ * Print an error message for a read error.
+ * This was exteracted from the original readtape().
+ */
+static void
+msg_read_error(char *m)
+{
+ switch (curfile.action) {
+ default:
+ fprintf(stderr, "%s trying to set up tape\n", m);
+ break;
+ case UNKNOWN:
+ fprintf(stderr, "%s trying to resynchronize\n", m);
+ break;
+ case USING:
+ fprintf(stderr, "%s restoring %s\n", m, curfile.name);
+ break;
+ case SKIP:
+ fprintf(stderr, "%s skipping over inode %lu\n", m,
+ (unsigned long)curfile.ino);
+ break;
+ }
+}
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
+
+/*
+ * Read the first block and get the blocksize from it. Test
+ * for a compressed dump tape/file. setup() will make the final
+ * determination by checking the compressed flag if gethead()
+ * finds a valid header. The test here is necessary to offset the buffer
+ * by the size of the compressed prefix. zflag is set here so that
+ * readtape_set can set the correct function pointer for readtape().
+ * Note that the first block of each tape/file is not compressed
+ * and does not have a prefix.
+ */
+static void
+findtapeblksize(void)
+{
+ long i;
+ size_t len;
+ struct tapebuf *tpb = (struct tapebuf *) tapebuf;
+ struct s_spcl spclpt;
+
+ for (i = 0; i < ntrec; i++)
+ ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
+ blkcnt = 0;
+ tbufptr = tapebuf;
+ /*
+ * For a pipe or file, read in the first record. For a tape, read
+ * the first block.
+ */
+ len = magtapein ? ntrec * TP_BSIZE : TP_BSIZE;
+
+ if (read_a_block(mt, tapebuf, len, &i) <= 0)
+ errx(1, "Tape read error on first record");
+
+ memcpy(&spclpt, tapebuf, TP_BSIZE);
+ if (converthead(&spclpt) == FAIL) {
+ cvtflag++;
+ if (converthead(&spclpt) == FAIL) {
+ /* Special case for old compressed tapes with prefix */
+ if (magtapein && (i % TP_BSIZE != 0))
+ goto oldformat;
+ errx(1, "Tape is not a dump tape");
+ }
+ fprintf(stderr, "Converting to new file system format.\n");
+ }
+ /*
+ * If the input is from a file or a pipe, we read TP_BSIZE
+ * bytes looking for a dump header. If the dump is compressed
+ * we need to read in the rest of the block, as determined
+ * by c_ntrec in the dump header. The first block of the
+ * dump is not compressed and does not have a prefix.
+ */
+ if (!magtapein) {
+ if (spclpt.c_type == TS_TAPE
+ && spclpt.c_flags & DR_COMPRESSED) {
+ /* It's a compressed dump file, read in the */
+ /* rest of the block based on spclpt.c_ntrec. */
+ if (spclpt.c_ntrec > ntrec)
+ errx(1, "Tape blocksize is too large, use "
+ "\'-b %d\' ", spclpt.c_ntrec);
+ ntrec = spclpt.c_ntrec;
+ len = (ntrec - 1) * TP_BSIZE;
+ zflag = 1;
+ }
+ else {
+ /* read in the rest of the block based on bufsize */
+ len = bufsize - TP_BSIZE;
+ }
+ if (read_a_block(mt, tapebuf+TP_BSIZE, len, &i) < 0
+ || (i != (long)len && i % TP_BSIZE != 0))
+ errx(1,"Error reading dump file header");
+ tbufptr = tapebuf;
+ numtrec = ntrec;
+ Vprintf(stdout, "Input block size is %ld\n", ntrec);
+ return;
+ } /* if (!magtapein) */
+
+ /*
+ * If the input is a tape, we tried to read ntrec * TP_BSIZE bytes.
+ * If the value of ntrec is too large, we read less than
+ * what we asked for; adjust the value of ntrec and test for
+ * a compressed dump tape.
+ */
+ if (i % TP_BSIZE != 0) {
+oldformat:
+ /* may be old format compressed dump tape with a prefix */
+ memcpy(&spclpt, tpb->buf, TP_BSIZE);
+ cvtflag = 0;
+ if (converthead(&spclpt) == FAIL) {
+ cvtflag++;
+ if (converthead(&spclpt) == FAIL)
+ errx(1, "Tape is not a dump tape");
+ fprintf(stderr, "Converting to new file system format.\n");
+ }
+ if (i % TP_BSIZE == PREFIXSIZE
+ && tpb->compressed == 0
+ && spclpt.c_type == TS_TAPE
+ && spclpt.c_flags & DR_COMPRESSED) {
+ zflag = 1;
+ tbufptr = tpb->buf;
+ if (tpb->length > bufsize)
+ errx(1, "Tape blocksize is too large, use "
+ "\'-b %d\' ", tpb->length / TP_BSIZE);
+ }
+ else
+ errx(1, "Tape block size (%ld) is not a multiple of dump block size (%d)",
+ i, TP_BSIZE);
+ }
+ ntrec = i / TP_BSIZE;
+ if (spclpt.c_type == TS_TAPE) {
+ if (spclpt.c_flags & DR_COMPRESSED)
+ zflag = 1;
+ if (spclpt.c_ntrec > ntrec)
+ errx(1, "Tape blocksize is too large, use "
+ "\'-b %d\' ", spclpt.c_ntrec);
+ }
+ numtrec = ntrec;
+ Vprintf(stdout, "Tape block size is %ld\n", ntrec);
+}
+
+/*
+ * Read a block of data handling all of the messy details.
+ */
+static int read_a_block(int fd, char *buf, size_t len, long *lengthread)
+{
+ long i = 1, size;
+
+ size = len;
+ while (size > 0) {
+#ifdef RRESTORE
+ if (!Afile && host)
+ i = rmtread(buf, size);
+ else
+#endif
+ i = read(fd, buf, size);
+
+ if (i <= 0)
+ break; /* EOD or error */
+ size -= i;
+ if (magtapein)
+ break; /* block at a time for mt */
+ buf += i;
+ }
+ *lengthread = len - size;
+ return i;
+}
+
+void
+closemt(void)
+{
+
+ if (mt < 0)
+ return;
+#ifdef RRESTORE
+ if (!Afile && host)
+ rmtclose();
+ else
+#endif
+ (void) close(mt);
+}
+
+static void
+setmagtapein(void) {
+ struct mtget mt_stat;
+ static int done = 0;
+ if (done)
+ return;
+ done = 1;
+ if (!pipein) {
+ /* need to know if input is really from a tape */
+#ifdef RRESTORE
+ if (host)
+ magtapein = !lflag;
+ else
+#endif
+ magtapein = ioctl(mt, MTIOCGET, (char *)&mt_stat) == 0;
+ }
+
+ Vprintf(stdout,"Input is from a %s %s\n",
+ host ? "remote" : "local",
+ magtapein ? "tape" :
+ Vflag ? "multi-volume (no tape)" : "file/pipe");
+}
+
+/*
+ * Read the next block from the tape.
+ * Check to see if it is one of several vintage headers.
+ * If it is an old style header, convert it to a new style header.
+ * If it is not any valid header, return an error.
+ */
+static int
+gethead(struct s_spcl *buf)
+{
+ readtape((char *)buf);
+ return converthead(buf);
+}
+
+static int
+converthead(struct s_spcl *buf)
+{
+ int32_t i;
+ union {
+ quad_t qval;
+ int32_t val[2];
+ } qcvt;
+ union u_ospcl {
+ char dummy[TP_BSIZE];
+ struct s_ospcl {
+ int32_t c_type;
+ int32_t c_date;
+ int32_t c_ddate;
+ int32_t c_volume;
+ int32_t c_tapea;
+ u_int16_t c_inumber;
+ int32_t c_magic;
+ int32_t c_checksum;
+ struct odinode {
+ u_int16_t odi_mode;
+ u_int16_t odi_nlink;
+ u_int16_t odi_uid;
+ u_int16_t odi_gid;
+ int32_t odi_size;
+ int32_t odi_rdev;
+ char odi_addr[36];
+ int32_t odi_atime;
+ int32_t odi_mtime;
+ int32_t odi_ctime;
+ } c_dinode;
+ int32_t c_count;
+ char c_fill[256];
+ } s_ospcl;
+ } u_ospcl;
+
+ if (!cvtflag) {
+ if (buf->c_magic != NFS_MAGIC) {
+ if (swabi(buf->c_magic) != NFS_MAGIC)
+ return (FAIL);
+ if (!Bcvt) {
+ Vprintf(stdout, "Note: Doing Byte swapping\n");
+ Bcvt = 1;
+ }
+ }
+ if (checksum((int *)buf) == FAIL)
+ return (FAIL);
+ if (Bcvt)
+ swabst((u_char *)"8i4s31i528bi192b3i", (u_char *)buf);
+ goto good;
+ }
+ memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE);
+ if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+ return(FAIL);
+ if (u_ospcl.s_ospcl.c_magic == OFS_MAGIC) {
+ memset((char *)buf, 0, (long)TP_BSIZE);
+ buf->c_type = u_ospcl.s_ospcl.c_type;
+ buf->c_date = u_ospcl.s_ospcl.c_date;
+ buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
+ buf->c_volume = u_ospcl.s_ospcl.c_volume;
+ buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
+ buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
+ buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
+ buf->c_magic = u_ospcl.s_ospcl.c_magic;
+ buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
+ buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
+ buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
+ buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
+ buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
+ buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
+#if defined(__linux__) || defined(sunos)
+ buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
+ buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+ buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+#else /* __linux__ || sunos */
+ buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
+ buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+ buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+#endif /* __linux__ || sunos */
+ buf->c_count = u_ospcl.s_ospcl.c_count;
+ memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
+ }
+ else if (u_ospcl.s_ospcl.c_magic == FS_UFS2_MAGIC) {
+ buf->c_date = (int32_t)(*(int64_t *)&u_ospcl.dummy[896]);
+ buf->c_ddate = (int32_t)(*(int64_t *)&u_ospcl.dummy[904]);
+ buf->c_tapea = (int32_t)(*(int64_t *)&u_ospcl.dummy[912]);
+ buf->c_firstrec = (int32_t)(*(int64_t *)&u_ospcl.dummy[920]);
+ buf->c_ntrec = 0;
+ buf->c_extattributes = 0;
+ buf->c_flags |= DR_NEWINODEFMT;
+ ufs2flag = 1;
+ }
+ else
+ return(FAIL);
+ buf->c_magic = NFS_MAGIC;
+
+good:
+ if ((buf->c_dinode.di_size == 0 || buf->c_dinode.di_size > 0xfffffff) &&
+ (buf->c_dinode.di_mode & IFMT) == IFDIR && Qcvt == 0) {
+ qcvt.qval = buf->c_dinode.di_size;
+ if (qcvt.val[0] || qcvt.val[1]) {
+ Vprintf(stdout, "Note: Doing Quad swapping\n");
+ Qcvt = 1;
+ }
+ }
+ if (Qcvt) {
+ qcvt.qval = buf->c_dinode.di_size;
+ i = qcvt.val[1];
+ qcvt.val[1] = qcvt.val[0];
+ qcvt.val[0] = i;
+ buf->c_dinode.di_size = qcvt.qval;
+ }
+ readmapflag = 0;
+
+ switch (buf->c_type) {
+
+ case TS_CLRI:
+ case TS_BITS:
+ /*
+ * Have to patch up missing information in bit map headers
+ */
+ buf->c_inumber = 0;
+ buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
+ if (buf->c_count > TP_NINDIR)
+ readmapflag = 1;
+ else
+ for (i = 0; i < buf->c_count; i++)
+ buf->c_addr[i]++;
+ break;
+
+ case TS_TAPE:
+ if ((buf->c_flags & DR_NEWINODEFMT) == 0)
+ oldinofmt = 1;
+ /* fall through */
+ case TS_END:
+ buf->c_inumber = 0;
+ if (buf->c_flags & DR_INODEINFO) {
+ memcpy(volinfo, buf->c_inos, TP_NINOS * sizeof(dump_ino_t));
+ if (Bcvt)
+ swabst((u_char *)"128i", (u_char *)volinfo);
+ }
+ break;
+
+ case TS_INODE:
+ case TS_ADDR:
+ break;
+
+ default:
+ panic("gethead: unknown inode type %d\n", buf->c_type);
+ break;
+ }
+ /*
+ * If we are restoring a filesystem with old format inodes,
+ * copy the uid/gid to the new location.
+ */
+ if (oldinofmt) {
+ buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
+ buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
+ }
+ if (dflag)
+ accthdr(buf);
+ return(GOOD);
+}
+
+static void
+converttapebuf(struct tapebuf *tpb)
+{
+ if (Bcvt) {
+ struct tb {
+ unsigned int length:28;
+ unsigned int flags:3;
+ unsigned int compressed:1;
+ } tb;
+ swabst((u_char *)"i", (u_char *)tpb);
+ memcpy(&tb, tpb, 4);
+ tpb->length = tb.length;
+ tpb->flags = tb.flags;
+ tpb->compressed = tb.compressed;
+ }
+}
+
+/*
+ * Check that a header is where it belongs and predict the next header
+ */
+static void
+accthdr(struct s_spcl *header)
+{
+ static dump_ino_t previno = 0x7fffffff;
+ static int prevtype;
+ static long predict;
+ long blks, i;
+
+ if (header->c_type == TS_TAPE) {
+ fprintf(stderr, "Volume header (%s inode format) ",
+ oldinofmt ? "old" : "new");
+ if (header->c_firstrec)
+ fprintf(stderr, "begins with record %d",
+ header->c_firstrec);
+ fprintf(stderr, "\n");
+ previno = 0x7fffffff;
+ return;
+ }
+ if (previno == 0x7fffffff)
+ goto newcalc;
+ switch (prevtype) {
+ case TS_BITS:
+ fprintf(stderr, "Dumped inodes map header");
+ break;
+ case TS_CLRI:
+ fprintf(stderr, "Used inodes map header");
+ break;
+ case TS_INODE:
+ fprintf(stderr, "File header, ino %lu", (unsigned long)previno);
+ break;
+ case TS_ADDR:
+ fprintf(stderr, "File continuation header, ino %ld", (long)previno);
+ break;
+ case TS_END:
+ fprintf(stderr, "End of tape header");
+ break;
+ }
+ if (predict != blksread - 1)
+ fprintf(stderr, "; predicted %ld blocks, got %ld blocks",
+ predict, blksread - 1);
+ fprintf(stderr, "\n");
+newcalc:
+ blks = 0;
+ if (header->c_type != TS_END)
+ for (i = 0; i < header->c_count; i++)
+ if (readmapflag || header->c_addr[i] != 0)
+ blks++;
+ predict = blks;
+ blksread = 0;
+ prevtype = header->c_type;
+ previno = header->c_inumber;
+}
+
+/*
+ * Find an inode header.
+ * Complain if had to skip, and complain is set.
+ */
+static void
+findinode(struct s_spcl *header)
+{
+ static long skipcnt = 0;
+ long i;
+ char buf[TP_BSIZE];
+
+ curfile.name = "<name unknown>";
+ curfile.action = UNKNOWN;
+ curfile.dip = NULL;
+ curfile.ino = 0;
+ do {
+ if (header->c_magic != NFS_MAGIC) {
+ skipcnt++;
+ while (gethead(header) == FAIL ||
+ header->c_date != dumpdate)
+ skipcnt++;
+ }
+ switch (header->c_type) {
+
+ case TS_ADDR:
+ /*
+ * Skip up to the beginning of the next record
+ */
+ for (i = 0; i < header->c_count; i++)
+ if (header->c_addr[i])
+ readtape(buf);
+ while (gethead(header) == FAIL ||
+ header->c_date != dumpdate)
+ skipcnt++;
+ break;
+
+ case TS_INODE:
+ curfile.dip = &header->c_dinode;
+ curfile.ino = header->c_inumber;
+ break;
+
+ case TS_END:
+ curfile.ino = maxino;
+ break;
+
+ case TS_CLRI:
+ curfile.name = "<file removal list>";
+ break;
+
+ case TS_BITS:
+ curfile.name = "<file dump list>";
+ break;
+
+ case TS_TAPE:
+ panic("unexpected tape header\n");
+ /* NOTREACHED */
+
+ default:
+ panic("unknown tape header type %d\n", spcl.c_type);
+ /* NOTREACHED */
+
+ }
+ } while (header->c_type == TS_ADDR);
+ if (skipcnt > 0)
+#ifdef USE_QFA
+ if (!noresyncmesg)
+#endif
+ fprintf(stderr, "resync restore, skipped %ld blocks\n",
+ skipcnt);
+ skipcnt = 0;
+}
+
+static int
+checksum(int *buf)
+{
+ int i, j;
+
+ j = sizeof(union u_spcl) / sizeof(int);
+ i = 0;
+ if(!Bcvt) {
+ do
+ i += *buf++;
+ while (--j);
+ } else {
+ /* What happens if we want to read restore tapes
+ for a 16bit int machine??? */
+ do
+ i += swabi(*buf++);
+ while (--j);
+ }
+
+ if (i != CHECKSUM) {
+ fprintf(stderr, "Checksum error %o, inode %lu file %s\n", i,
+ (unsigned long)curfile.ino, curfile.name);
+ return(FAIL);
+ }
+ return(GOOD);
+}
+
+#ifdef RRESTORE
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#ifdef __STDC__
+msg(const char *fmt, ...)
+#else
+msg(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+#endif /* RRESTORE */
+
+static u_char *
+swab16(u_char *sp, int n)
+{
+ char c;
+
+ while (--n >= 0) {
+ c = sp[0]; sp[0] = sp[1]; sp[1] = c;
+ sp += 2;
+ }
+ return (sp);
+}
+
+static u_char *
+swab32(u_char *sp, int n)
+{
+ char c;
+
+ while (--n >= 0) {
+ c = sp[0]; sp[0] = sp[3]; sp[3] = c;
+ c = sp[1]; sp[1] = sp[2]; sp[2] = c;
+ sp += 4;
+ }
+ return (sp);
+}
+
+static u_char *
+swab64(u_char *sp, int n)
+{
+ char c;
+
+ while (--n >= 0) {
+ c = sp[0]; sp[0] = sp[7]; sp[7] = c;
+ c = sp[1]; sp[1] = sp[6]; sp[6] = c;
+ c = sp[2]; sp[2] = sp[5]; sp[5] = c;
+ c = sp[3]; sp[3] = sp[4]; sp[4] = c;
+ sp += 8;
+ }
+ return (sp);
+}
+
+void
+swabst(u_char *cp, u_char *sp)
+{
+ int n = 0;
+
+ while (*cp) {
+ switch (*cp) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = (n * 10) + (*cp++ - '0');
+ continue;
+
+ case 's': case 'w': case 'h':
+ if (n == 0)
+ n = 1;
+ sp = swab16(sp, n);
+ break;
+
+ case 'i':
+ if (n == 0)
+ n = 1;
+ sp = swab32(sp, n);
+ break;
+
+ case 'l':
+ if (n == 0)
+ n = 1;
+ sp = swab64(sp, n);
+ break;
+
+ default: /* Any other character, like 'b' counts as byte. */
+ if (n == 0)
+ n = 1;
+ sp += n;
+ break;
+ }
+ cp++;
+ n = 0;
+ }
+}
+
+static u_int
+swabi(u_int x)
+{
+ swabst((u_char *)"i", (u_char *)&x);
+ return (x);
+}
+
+#if 0
+static u_long
+swabl(u_long x)
+{
+ swabst((u_char *)"l", (u_char *)&x);
+ return (x);
+}
+#endif
+
+void
+RequestVol(long tnum)
+{
+ FLUSHTAPEBUF();
+ getvol(tnum);
+}
+
+#ifdef USE_QFA
+#ifdef sunos
+extern int fdsmtc;
+
+struct uscsi_cmd {
+ int uscsi_flags; /* read, write, etc. see below */
+ short uscsi_status; /* resulting status */
+ short uscsi_timeout; /* Command Timeout */
+ caddr_t uscsi_cdb; /* cdb to send to target */
+ caddr_t uscsi_bufaddr; /* i/o source/destination */
+ u_int uscsi_buflen; /* size of i/o to take place */
+ u_int uscsi_resid; /* resid from i/o operation */
+ u_char uscsi_cdblen; /* # of valid cdb bytes */
+ u_char uscsi_rqlen; /* size of uscsi_rqbuf */
+ u_char uscsi_rqstatus; /* status of request sense cmd */
+ u_char uscsi_rqresid; /* resid of request sense cmd */
+ caddr_t uscsi_rqbuf; /* request sense buffer */
+ void *uscsi_reserved_5; /* Reserved for Future Use */
+};
+
+#define CDB_GROUP0 6 /* 6-byte cdb's */
+#define CDB_GROUP1 10 /* 10-byte cdb's */
+#define CDB_GROUP2 10 /* 10-byte cdb's */
+#define CDB_GROUP3 0 /* reserved */
+#define CDB_GROUP4 16 /* 16-byte cdb's */
+#define CDB_GROUP5 12 /* 12-byte cdb's */
+#define CDB_GROUP6 0 /* reserved */
+#define CDB_GROUP7 0 /* reserved */
+
+#define USCSI_WRITE 0x00000 /* send data to device */
+#define USCSI_SILENT 0x00001 /* no error messages */
+#define USCSI_DIAGNOSE 0x00002 /* fail if any error occurs */
+#define USCSI_ISOLATE 0x00004 /* isolate from normal commands */
+#define USCSI_READ 0x00008 /* get data from device */
+#define USCSI_RESET 0x04000 /* Reset target */
+#define USCSI_RESET_ALL 0x08000 /* Reset all targets */
+#define USCSI_RQENABLE 0x10000 /* Enable Request Sense extensions */
+
+#define USCSIIOC (0x04 << 8)
+#define USCSICMD (USCSIIOC|201) /* user scsi command */
+
+#define USCSI_TIMEOUT 30
+#define USCSI_SHORT_TIMEOUT 900
+#define USCSI_LONG_TIMEOUT 14000
+
+#define B(s,i) ((unsigned char)((s) >> i))
+#define B1(s) ((unsigned char)(s))
+
+#define MSB4(s,v) *(s)=B(v,24),(s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
+
+
+int
+GetTapePos(long long *pos)
+{
+ int err = 0;
+ struct uscsi_cmd scmd;
+ char buf[512];
+ char parm[512 * 8];
+ long lpos;
+
+ (void)memset((void *)buf, 0, sizeof(buf));
+ (void)memset((void *)&scmd, 0, sizeof(scmd));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_timeout = USCSI_TIMEOUT;
+ scmd.uscsi_cdb = buf;
+ scmd.uscsi_cdblen = CDB_GROUP1;
+ buf[0] = 0x34; /* read position */
+ buf[1] = 0;
+ (void)memset((void *)parm, 0, 512);
+ scmd.uscsi_bufaddr = parm;
+ scmd.uscsi_buflen = 56;
+ if (ioctl(fdsmtc, USCSICMD, &scmd) == -1) {
+ err = errno;
+ return err;
+ }
+ (void)memcpy(&lpos, &parm[4], sizeof(long));
+ *pos = lpos;
+ return err;
+}
+
+int
+GotoTapePos(long long pos)
+{
+ int err = 0;
+ struct uscsi_cmd scmd;
+ char buf[512];
+ char parm[512 * 8];
+ long lpos = (long)pos;
+
+ (void)memset((void *)buf, 0, sizeof(buf));
+ (void)memset((void *)&scmd, 0, sizeof(scmd));
+ scmd.uscsi_flags = USCSI_WRITE|USCSI_SILENT;
+ scmd.uscsi_timeout = 360; /* 5 Minutes */
+ scmd.uscsi_cdb = buf;
+ scmd.uscsi_cdblen = CDB_GROUP1;
+ buf[0] = 0x2b; /* locate */
+ buf[1] = 0;
+ MSB4(&buf[3], lpos);
+ (void)memset((void *)parm, 0, 512);
+ scmd.uscsi_bufaddr = NULL;
+ scmd.uscsi_buflen = 0;
+ if (ioctl(fdsmtc, USCSICMD, &scmd) == -1) {
+ err = errno;
+ return err;
+ }
+ return err;
+}
+#endif
+
+#define LSEEK_GET_TAPEPOS 10
+#define LSEEK_GO2_TAPEPOS 11
+
+#ifdef __linux__
+typedef struct mt_pos {
+ short mt_op;
+ int mt_count;
+} MTPosRec, *MTPosPtr;
+
+
+/*
+ * get the current position of the tape
+ */
+int
+GetTapePos(long long *pos)
+{
+ int err = 0;
+
+#ifdef RDUMP
+ if (host) {
+ *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS);
+ err = *pos < 0;
+ }
+ else
+#endif
+ {
+ if (magtapein) {
+ long mtpos;
+ *pos = 0;
+ err = (ioctl(mt, MTIOCPOS, &mtpos) < 0);
+ *pos = (long long)mtpos;
+ }
+ else {
+ *pos = LSEEK(mt, 0, SEEK_CUR);
+ err = (*pos < 0);
+ }
+ }
+ if (err) {
+ err = errno;
+ fprintf(stdout, "[%ld] error: %d (getting tapepos: %lld)\n",
+ (unsigned long)getpid(), err, *pos);
+ return err;
+ }
+ return err;
+}
+
+/*
+ * go to specified position on tape
+ */
+int
+GotoTapePos(long long pos)
+{
+ int err = 0;
+
+#ifdef RDUMP
+ if (host)
+ err = (rmtseek((OFF_T)pos, (int)LSEEK_GO2_TAPEPOS) < 0);
+ else
+#endif
+ {
+ if (magtapein) {
+ struct mt_pos buf;
+ buf.mt_op = MTSEEK;
+ buf.mt_count = (int) pos;
+ err = (ioctl(mt, MTIOCTOP, &buf) < 0);
+ }
+ else {
+ pos = LSEEK(mt, pos, SEEK_SET);
+ err = (pos < 0);
+ }
+ }
+ if (err) {
+ err = errno;
+ fprintf(stdout, "[%ld] error: %d (setting tapepos: %lld)\n",
+ (unsigned long)getpid(), err, pos);
+ return err;
+ }
+ return err;
+}
+#endif /* __linux__ */
+
+/*
+ * read next data from tape to re-sync
+ */
+void
+ReReadFromTape(void)
+{
+ FLUSHTAPEBUF();
+ noresyncmesg = 1;
+ if (gethead(&spcl) == FAIL) {
+#ifdef DEBUG_QFA
+ fprintf(stdout, "DEBUG 1 gethead failed\n");
+#endif
+ }
+ findinode(&spcl);
+ noresyncmesg = 0;
+}
+
+void
+ReReadInodeFromTape(dump_ino_t theino)
+{
+ long cntloop = 0;
+
+ FLUSHTAPEBUF();
+ noresyncmesg = 1;
+ do {
+ cntloop++;
+ gethead(&spcl);
+ } while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate));
+#ifdef DEBUG_QFA
+ fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
+ fprintf(stderr, "DEBUG: bufsize %ld\n", bufsize);
+ fprintf(stderr, "DEBUG: ntrec %ld\n", ntrec);
+ fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
+#endif
+ findinode(&spcl);
+ noresyncmesg = 0;
+}
+
+#ifdef sunos
+int
+OpenSMTCmt(char *themagtape)
+{
+ if (GetSCSIIDFromPath(themagtape, &scsiid)) {
+ fprintf(stderr, "can't get SCSI-ID for %s\n", themagtape);
+ return -1;
+ }
+ if (scsiid < 0) {
+ fprintf(stderr, "can't get SCSI-ID for %s\n", themagtape);
+ return -1;
+ }
+ sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+ if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+ fprintf(stderr, "can't open smtc device: %s, %d\n", smtcpath, errno);
+ return -1;
+ }
+ return 0;
+}
+#endif /* sunos */
+#endif /* USE_QFA */
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: utilities.c,v 1.24 2003/11/22 16:52:16 stelian Exp $";
+#endif /* not lint */
+
+#include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <compaterr.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#ifdef __linux__
+#include <sys/time.h>
+#include <time.h>
+#include <fcntl.h>
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
+#include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
+#include <bsdcompat.h>
+#else /* __linux__ */
+#ifdef sunos
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#endif
+#endif /* __linux__ */
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
+#include "restore.h"
+#include "extern.h"
+
+/*
+ * Insure that all the components of a pathname exist.
+ */
+void
+pathcheck(char *name)
+{
+ char *cp;
+ struct entry *ep;
+ char *start;
+
+ start = strchr(name, '/');
+ if (start == 0)
+ return;
+ for (cp = start; *cp != '\0'; cp++) {
+ if (*cp != '/')
+ continue;
+ *cp = '\0';
+ ep = lookupname(name);
+ if (ep == NULL) {
+ /* Safe; we know the pathname exists in the dump. */
+ ep = addentry(name, pathsearch(name)->d_ino, NODE);
+ newnode(ep);
+ }
+ ep->e_flags |= NEW|KEEP;
+ *cp = '/';
+ }
+}
+
+/*
+ * Change a name to a unique temporary name.
+ */
+void
+mktempname(struct entry *ep)
+{
+ char oldname[MAXPATHLEN];
+
+ if (ep->e_flags & TMPNAME)
+ badentry(ep, "mktempname: called with TMPNAME");
+ ep->e_flags |= TMPNAME;
+ (void) strcpy(oldname, myname(ep));
+ freename(ep->e_name);
+ ep->e_name = savename(gentempname(ep));
+ ep->e_namlen = strlen(ep->e_name);
+ renameit(oldname, myname(ep));
+}
+
+/*
+ * Generate a temporary name for an entry.
+ */
+char *
+gentempname(struct entry *ep)
+{
+ static char name[MAXPATHLEN];
+ struct entry *np;
+ long i = 0;
+
+ for (np = lookupino(ep->e_ino);
+ np != NULL && np != ep; np = np->e_links)
+ i++;
+ if (np == NULL)
+ badentry(ep, "not on ino list");
+ (void) snprintf(name, sizeof(name), "%s%ld%lu", TMPHDR, i, (unsigned long)ep->e_ino);
+ return (name);
+}
+
+/*
+ * Rename a file or directory.
+ */
+void
+renameit(char *from, char *to)
+{
+ if (!Nflag && rename(from, to) < 0) {
+ warn("cannot rename %s to %s", from, to);
+ return;
+ }
+ Vprintf(stdout, "rename %s to %s\n", from, to);
+}
+
+/*
+ * Create a new node (directory).
+ */
+void
+newnode(struct entry *np)
+{
+ char *cp;
+ if (np->e_type != NODE)
+ badentry(np, "newnode: not a node");
+ cp = myname(np);
+ if (command == 'C') return;
+
+ if (!Nflag && mkdir(cp, 0777) < 0 && !uflag) {
+ np->e_flags |= EXISTED;
+ warn("%s", cp);
+ return;
+ }
+ Vprintf(stdout, "Make node %s\n", cp);
+}
+
+/*
+ * Remove an old node (directory).
+ */
+void
+removenode(struct entry *ep)
+{
+ char *cp;
+
+ if (ep->e_type != NODE)
+ badentry(ep, "removenode: not a node");
+ if (ep->e_entries != NULL)
+ badentry(ep, "removenode: non-empty directory");
+ ep->e_flags |= REMOVED;
+ ep->e_flags &= ~TMPNAME;
+ cp = myname(ep);
+ if (!Nflag && rmdir(cp) < 0) {
+ warn("%s", cp);
+ return;
+ }
+ Vprintf(stdout, "Remove node %s\n", cp);
+}
+
+/*
+ * Remove a leaf.
+ */
+void
+removeleaf(struct entry *ep)
+{
+ char *cp;
+
+ if (command == 'C') return;
+
+ if (ep->e_type != LEAF)
+ badentry(ep, "removeleaf: not a leaf");
+ ep->e_flags |= REMOVED;
+ ep->e_flags &= ~TMPNAME;
+ cp = myname(ep);
+ if (!Nflag && unlink(cp) < 0) {
+ warn("%s", cp);
+ return;
+ }
+ Vprintf(stdout, "Remove leaf %s\n", cp);
+}
+
+/*
+ * Create a link.
+ */
+int
+linkit(char *existing, char *new, int type)
+{
+
+ /* if we want to unlink first, do it now so *link() won't fail */
+ if (uflag && !Nflag)
+ (void)unlink(new);
+
+ if (type == SYMLINK) {
+ if (!Nflag && symlink(existing, new) < 0) {
+ warn("cannot create symbolic link %s->%s",
+ new, existing);
+ return (FAIL);
+ }
+ } else if (type == HARDLINK) {
+ int ret;
+
+ if (!Nflag && (ret = link(existing, new)) < 0) {
+
+#if !defined(__linux__) && !defined(sunos)
+ struct stat s;
+
+ /*
+ * Most likely, the schg flag is set. Clear the
+ * flags and try again.
+ */
+ if (stat(existing, &s) == 0 && s.st_flags != 0 &&
+ chflags(existing, 0) == 0) {
+ ret = link(existing, new);
+ chflags(existing, s.st_flags);
+ }
+#else
+ unsigned long s;
+
+ /*
+ * Most likely, the immutable or append-only attribute
+ * is set. Clear the attributes and try again.
+ */
+#ifdef sunos
+#else
+ if (fgetflags (existing, &s) != -1 &&
+ fsetflags (existing, 0) != -1) {
+ ret = link(existing, new);
+ fsetflags(existing, s);
+ }
+#endif
+#endif
+ if (ret < 0) {
+ warn("warning: cannot create hard link %s->%s",
+ new, existing);
+ return (FAIL);
+ }
+ }
+ } else {
+ panic("linkit: unknown type %d\n", type);
+ return (FAIL);
+ }
+ Vprintf(stdout, "Create %s link %s->%s\n",
+ type == SYMLINK ? "symbolic" : "hard", new, existing);
+ return (GOOD);
+}
+
+#if !defined(__linux__) && !defined(sunos)
+/*
+ * Create a whiteout.
+ */
+int
+addwhiteout(char *name)
+{
+
+ if (!Nflag && mknod(name, S_IFWHT, 0) < 0) {
+ warn("cannot create whiteout %s", name);
+ return (FAIL);
+ }
+ Vprintf(stdout, "Create whiteout %s\n", name);
+ return (GOOD);
+}
+
+/*
+ * Delete a whiteout.
+ */
+void
+delwhiteout(struct entry *ep)
+{
+ char *name;
+
+ if (ep->e_type != LEAF)
+ badentry(ep, "delwhiteout: not a leaf");
+ ep->e_flags |= REMOVED;
+ ep->e_flags &= ~TMPNAME;
+ name = myname(ep);
+ if (!Nflag && undelete(name) < 0) {
+ warn("cannot delete whiteout %s", name);
+ return;
+ }
+ Vprintf(stdout, "Delete whiteout %s\n", name);
+}
+#endif
+
+/*
+ * find lowest number file (above "start") that needs to be extracted
+ */
+dump_ino_t
+lowerbnd(dump_ino_t start)
+{
+ struct entry *ep;
+
+ for ( ; start < maxino; start++) {
+ ep = lookupino(start);
+ if (ep == NULL || ep->e_type == NODE)
+ continue;
+ if (ep->e_flags & (NEW|EXTRACT))
+ return (start);
+ }
+ return (start);
+}
+
+/*
+ * find highest number file (below "start") that needs to be extracted
+ */
+dump_ino_t
+upperbnd(dump_ino_t start)
+{
+ struct entry *ep;
+
+ for ( ; start > ROOTINO; start--) {
+ ep = lookupino(start);
+ if (ep == NULL || ep->e_type == NODE)
+ continue;
+ if (ep->e_flags & (NEW|EXTRACT))
+ return (start);
+ }
+ return (start);
+}
+
+/*
+ * report on a badly formed entry
+ */
+void
+badentry(struct entry *ep, const char *msg)
+{
+
+ fprintf(stderr, "bad entry: %s\n", msg);
+ fprintf(stderr, "name: %s\n", myname(ep));
+ fprintf(stderr, "parent name %s\n", myname(ep->e_parent));
+ if (ep->e_sibling != NULL)
+ fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling));
+ if (ep->e_entries != NULL)
+ fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries));
+ if (ep->e_links != NULL)
+ fprintf(stderr, "next link name: %s\n", myname(ep->e_links));
+ if (ep->e_next != NULL)
+ fprintf(stderr,
+ "next hashchain name: %s\n", myname(ep->e_next));
+ fprintf(stderr, "entry type: %s\n",
+ ep->e_type == NODE ? "NODE" : "LEAF");
+ fprintf(stderr, "inode number: %lu\n", (unsigned long)ep->e_ino);
+ panic("flags: %s\n", flagvalues(ep));
+}
+
+/*
+ * Construct a string indicating the active flag bits of an entry.
+ */
+char *
+flagvalues(struct entry *ep)
+{
+ static char flagbuf[BUFSIZ];
+
+ (void) strcpy(flagbuf, "|NIL");
+ flagbuf[0] = '\0';
+ if (ep->e_flags & REMOVED)
+ (void) strcat(flagbuf, "|REMOVED");
+ if (ep->e_flags & TMPNAME)
+ (void) strcat(flagbuf, "|TMPNAME");
+ if (ep->e_flags & EXTRACT)
+ (void) strcat(flagbuf, "|EXTRACT");
+ if (ep->e_flags & NEW)
+ (void) strcat(flagbuf, "|NEW");
+ if (ep->e_flags & KEEP)
+ (void) strcat(flagbuf, "|KEEP");
+ if (ep->e_flags & EXISTED)
+ (void) strcat(flagbuf, "|EXISTED");
+ return (&flagbuf[1]);
+}
+
+/*
+ * Check to see if a name is on a dump tape.
+ */
+dump_ino_t
+dirlookup(const char *name)
+{
+ struct direct *dp;
+ dump_ino_t ino;
+
+ ino = ((dp = pathsearch(name)) == NULL) ? 0 : dp->d_ino;
+
+ if (ino == 0 || TSTINO(ino, dumpmap) == 0)
+ fprintf(stderr, "%s is not on the tape\n", name);
+ return (ino);
+}
+
+/*
+ * Elicit a reply.
+ */
+int
+reply(const char *question)
+{
+ char c;
+
+ do {
+ fprintf(stderr, "%s? [yn] ", question);
+ (void) fflush(stderr);
+ c = getc(terminal);
+ while (c != '\n' && getc(terminal) != '\n')
+ if (feof(terminal))
+ return (FAIL);
+ } while (c != 'y' && c != 'n');
+ if (c == 'y')
+ return (GOOD);
+ return (FAIL);
+}
+
+/*
+ * handle unexpected inconsistencies
+ */
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#ifdef __STDC__
+panic(const char *fmt, ...)
+#else
+panic(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ vfprintf(stderr, fmt, ap);
+ if (yflag)
+ return;
+ if (reply("abort") == GOOD) {
+ if (reply("dump core") == GOOD)
+ abort();
+ exit(1);
+ }
+}
+
+void resizemaps(dump_ino_t oldmax, dump_ino_t newmax)
+{
+ char *map;
+
+ if (usedinomap) {
+ map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
+ if (map == NULL)
+ errx(1, "no memory for active inode map");
+ memcpy(map, usedinomap, howmany(oldmax, NBBY));
+ free(usedinomap);
+ usedinomap = map;
+ }
+ if (dumpmap) {
+ map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
+ if (map == NULL)
+ errx(1, "no memory for file dump list");
+ memcpy(map, dumpmap, howmany(oldmax, NBBY));
+ free(dumpmap);
+ dumpmap = map;
+ }
+}
+
+void
+GetPathFile(char *source, char *path, char *fname)
+{
+ char *p, *s;
+
+ *path = 0;
+ *fname = 0;
+ p = s = source;
+ while (*s) {
+ if (*s == '/') {
+ p = s + 1;
+ }
+ s++;
+ }
+ if (p == source) {
+ *path = 0;
+ } else {
+ strncpy(path, source, p - source);
+ path[p - source] = 0;
+ }
+ strcpy(fname, p);
+}
+
+#ifdef USE_QFA
+/*
+ * search for ino in QFA file
+ *
+ * if exactmatch:
+ * if ino found return tape number and tape position
+ * if ino not found return tnum=0 and tpos=0
+ *
+ * if not exactmatch:
+ * if ino found return tape number and tape position
+ * if ino not found return tape number and tape position of last smaller ino
+ * if no smaller inode found return tnum=0 and tpos=0
+ */
+int
+Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch)
+{
+ char *p, *pp;
+ char numbuff[32];
+ unsigned long tmpino;
+ long tmptnum;
+ long long tmptpos;
+
+ *tpos = 0;
+ *tnum = 0;
+ if (fseek(gTapeposfp, gSeekstart, SEEK_SET) == -1)
+ return errno;
+ while (1) {
+ gSeekstart = ftell(gTapeposfp); /* remember for later use */
+ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) {
+ return 0;
+ }
+ gTps[strlen(gTps) - 1] = 0; /* delete end of line */
+ p = gTps;
+ bzero(numbuff, sizeof(numbuff));
+ pp = numbuff;
+ /* read inode */
+ while ((*p != 0) && (*p != '\t'))
+ *pp++ = *p++;
+ tmpino = atol(numbuff);
+ if (*p == 0)
+ return 1; /* may NOT happen */
+ p++;
+ bzero(numbuff, sizeof(numbuff));
+ pp = numbuff;
+ /* read tapenum */
+ while ((*p != 0) && (*p != '\t'))
+ *pp++ = *p++;
+ if (*p == 0)
+ return 1; /* may NOT happen */
+ tmptnum = atol(numbuff);
+ p++;
+ bzero(numbuff, sizeof(numbuff));
+ pp = numbuff;
+ /* read tapepos */
+ while ((*p != 0) && (*p != '\t'))
+ *pp++ = *p++;
+ tmptpos = atoll(numbuff);
+
+ if (exactmatch) {
+ if (tmpino == ino) {
+ *tnum = tmptnum;
+ *tpos = tmptpos;
+ return 0;
+ }
+ } else {
+ if (tmpino > ino) {
+ return 0;
+ } else {
+ *tnum = tmptnum;
+ *tpos = tmptpos;
+ }
+ }
+ }
+ return 0;
+}
+
+#ifdef sunos
+int
+GetSCSIIDFromPath(char *devPath, long *id)
+{
+ int len;
+ char fbuff[2048];
+ char path[2048];
+ char fname[2048];
+ char *fpn = fname;
+ char idstr[32];
+ char *ip = idstr;
+
+ bzero(fbuff, sizeof(fbuff));
+ if ((len = readlink(devPath, fbuff, 2048)) == -1) {
+ return errno;
+ }
+ fbuff[len] = 0;
+ GetPathFile(fbuff, path, fname);
+ (void)memset(idstr, 0, sizeof(idstr));
+ while (*fpn && (*fpn != ',')) {
+ if (*fpn <= '9' && *fpn >= '0') {
+ *ip = *fpn;
+ ip++;
+ }
+ fpn++;
+ }
+ if (*idstr) {
+ *id = atol(idstr);
+ } else {
+ *id = -1;
+ }
+ return 0;
+}
+#endif
+#endif /* USE_QFA */
+
+#ifdef DUMP_MACOSX
+int
+CreateAppleDoubleFileRes(char *oFile, FndrFileInfo *finderinfo, mode_t mode, int flags,
+ struct timeval *timep, u_int32_t uid, u_int32_t gid)
+{
+ int err = 0;
+ int fdout;
+ char *p;
+ char *pp;
+ ASDHeaderPtr hp;
+ ASDEntryPtr ep;
+ long thesize;
+ long n;
+
+
+ n = 1; /* number of entries in double file ._ only finderinfo */
+ /*
+ no data fork
+ n++;
+ currently no resource fork
+ n++;
+ */
+
+ thesize = sizeof(ASDHeader) + (n * sizeof(ASDEntry)) + INFOLEN;
+ if ((pp = p = (char *)malloc(thesize)) == NULL) {
+ err = errno;
+ return err;
+ }
+
+ hp = (ASDHeaderPtr)p;
+ p += sizeof(ASDHeader);
+ ep = (ASDEntryPtr)p;
+ p += sizeof(ASDEntry) * n;
+
+ hp->magic = ADOUBLE_MAGIC;
+ hp->version = ASD_VERSION2;
+
+ bzero(&hp->filler, sizeof(hp->filler));
+ hp->entries = (short)n;
+
+ ep->entryID = EntryFinderInfo;
+ ep->offset = p - pp - CORRECT;
+ ep->len = INFOLEN; /* sizeof(MacFInfo) + sizeof(FXInfo); */
+ bzero(p, ep->len);
+ bcopy(finderinfo, p, sizeof(FndrFileInfo));
+ p += ep->len;
+ ep++;
+
+ if ((fdout = open(oFile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+ err = errno;
+ free(pp);
+ return err;
+ }
+
+ /* write the ASDHeader */
+ if (write(fdout, pp, sizeof(ASDHeader) - CORRECT) == -1) {
+ err = errno;
+ close(fdout);
+ free(pp);
+ unlink(oFile);
+ return err;
+ }
+ /* write the ASDEntries */
+ if (write(fdout, pp + sizeof(ASDHeader), thesize - sizeof(ASDHeader)) == -1) {
+ err = errno;
+ close(fdout);
+ free(pp);
+ unlink(oFile);
+ return err;
+ }
+
+ (void)fchown(fdout, uid, gid);
+ (void)fchmod(fdout, mode);
+ close(fdout);
+ (void)fsetflags(oFile, flags);
+ utimes(oFile, timep);
+ free(pp);
+ return err;
+}
+#endif /* DUMP_MACOSX */
--- /dev/null
+# $Id: Makefile.in,v 1.10 2003/05/08 21:11:39 stelian Exp $
+
+top_srcdir= @top_srcdir@
+srcdir= @srcdir@
+top_builddir= ..
+
+@MCONFIG@
+
+ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS)
+ALL_LDFLAGS= @LDFLAGS@ @LDOPTS@ @STATIC@
+LIBS= $(GLIBS)
+DEPLIBS= ../compat/lib/libcompat.a
+
+PROG= rmt
+SRCS= rmt.c
+OBJS= rmt.o
+MAN8= rmt.8
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: $(PROG) @ERMT@ $(MAN8)
+
+$(PROG): $(OBJS) $(DEPLIBS)
+ $(LD) $(ALL_LDFLAGS) -o $(PROG) $(OBJS) $(LIBS)
+
+ermt: ermt.o cipher.o $(DEPLIBS)
+ $(LD) $(ALL_LDFLAGS) -o ermt ermt.o cipher.o $(LIBS) @CRYPTO@
+
+ermt.o: rmt.c
+ $(CC) -c $(ALL_CFLAGS) -DERMT -o ermt.o rmt.c
+
+$(MAN8): rmt.8.in
+ sed -e "s|__DATE__|$(DATE)|g" \
+ -e "s|__VERSION__|$(VERSION)|g" $< > $@
+
+install:: all
+ $(INSTALL) -d $(SBINDIR) $(MANDIR)
+ $(INSTALLBIN) $(PROG) $(SBINDIR)
+ $(INSTALLMAN) $(srcdir)/$(MAN8) $(MANDIR)
+
+clean::
+ rm -f $(PROG) @ERMT@ \#* *.s *.o *.a *~ core rmt.8
+
+distclean:: clean
+ rm -f Makefile Makefile.old .depend
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+
--- /dev/null
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <strings.h>
+#include <errno.h>
+#include <openssl/evp.h>
+
+/*
+ * Encrypt or decrypt buf, returning a pointer to the transformed data,
+ * or NULL on error.
+ * The returned data is the same size as the input data,
+ * which means we must turn off cipher padding, and require that buflen
+ * be a multiple of the cipher block size (8 for Blowfish).
+ * To keep things simple, the return value is a malloc'd
+ * buffer that is overwritten on each call.
+ *
+ * Ken Lalonde <ken@globalremit.com>, 2003
+ */
+char *
+cipher(char *buf, int buflen, int do_encrypt)
+{
+ static EVP_CIPHER_CTX ctx;
+ static char *out = NULL; /* return value, grown as necessary */
+ static int outlen = 0;
+ static int init = 0, which, blocksize;
+ int n;
+
+ if (!init) {
+ static const EVP_CIPHER *cipher;
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+ // Read key from $HOME/.ermt.key
+ char *keyfile = ".ermt.key";
+ unsigned char buf[128];
+ FILE *fp;
+ int i;
+
+ openlog("ermt", LOG_PID, LOG_DAEMON);
+ // Not needed: OpenSSL_add_all_algorithms();
+ // Not needed: ERR_load_crypto_strings();
+ cipher = EVP_bf_cbc(); // or: EVP_aes_{128,192,256}_cbc()
+ // We want the ability to decrypt the output
+ // using "openssl enc -d -kfile K -nopad -nosalt", which
+ // means we must read the key file the same way
+ // openssl does. But be careful: if the key contains
+ // \0 or \r or \n, the effective size will be reduced.
+ if ((fp = fopen(keyfile, "r")) == NULL) {
+ syslog(LOG_ERR, "Can't open key file %s: %m", keyfile);
+ return NULL;
+ }
+ buf[0] = '\0';
+ fgets(buf, sizeof buf, fp);
+ fclose(fp);
+ i = strlen(buf);
+ if ((i > 0) &&
+ ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+ buf[--i]='\0';
+ if ((i > 0) &&
+ ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
+ buf[--i]='\0';
+ if (i < 1) {
+ syslog(LOG_ERR, "zero length key");
+ errno = EINVAL;
+ return NULL;
+ }
+ EVP_BytesToKey(cipher, EVP_md5(), NULL,
+ buf, strlen(buf), 1, key, iv);
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, do_encrypt);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0); // -nopad
+ OPENSSL_cleanse(buf, sizeof buf);
+ OPENSSL_cleanse(key, sizeof key);
+ OPENSSL_cleanse(iv, sizeof iv);
+ blocksize = EVP_CIPHER_CTX_block_size(&ctx);
+ which = do_encrypt;
+ init = 1;
+ }
+ if (which != do_encrypt) {
+ syslog(LOG_ERR, "Cannot switch modes");
+ errno = EINVAL;
+ return NULL;
+ }
+ if ((buflen % blocksize) != 0) {
+ syslog(LOG_ERR, "Buffer size is not a multiple of cipher block size");
+ errno = EINVAL;
+ return NULL;
+ }
+ if (outlen < buflen+blocksize) {
+ outlen = (buflen+blocksize) * 2;
+ out = realloc(out, outlen);
+ }
+ if (!EVP_CipherUpdate(&ctx, out, &n, buf, buflen)) {
+ syslog(LOG_ERR, "EVP_CipherUpdate failed");
+ errno = EINVAL;
+ return NULL;
+ }
+ if (n != buflen) {
+ syslog(LOG_ERR, "EVP_CipherUpdate: %d != %d", n, buflen);
+ errno = EINVAL;
+ return NULL;
+ }
+ // assert(ctx->buf_len == 0);
+ return out;
+}
+
+/* Decrypt stdin to stdout, and exit */
+int
+decrypt()
+{
+ char buf[8*1024], *cp;
+ int n;
+
+ while ((n = fread(buf, 1, sizeof buf, stdin)) > 0) {
+ if ((cp = cipher(buf, n, 0)) == NULL) {
+ fprintf(stderr, "ermt: Error decoding input; see daemon.err syslog\n");
+ exit(1);
+ }
+ fwrite(cp, 1, n, stdout);
+ }
+ if (ferror(stdin)) {
+ perror("ermt: stdin: read");
+ exit(1);
+ }
+ if (fflush(stdout)) {
+ perror("ermt: stdout: write");
+ exit(1);
+ }
+ exit(0);
+}
--- /dev/null
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: rmt.8.in,v 1.10 2003/03/30 15:40:40 stelian Exp $
+.\"
+.TH RMT 8 "version __VERSION__ of __DATE__" BSD "System management commands"
+.SH NAME
+rmt \- remote magtape protocol module
+.SH SYNOPSIS
+.B rmt
+.SH DESCRIPTION
+.B Rmt
+is a program used by the remote
+.BR dump (8),
+.BR restore (8)
+or
+.BR tar (1)
+programs in manipulating a magnetic tape drive through an interprocess
+communication connection.
+.B Rmt
+is normally started up with an
+.BR rexec (3)
+or
+.BR rcmd (3)
+call.
+.PP
+The
+.B rmt
+program accepts requests specific to the manipulation of magnetic tapes,
+performs the commands, then responds with a status indication. All responses
+are in
+.B ASCII
+and in one of the following two forms.
+.PP
+Successful commands have responses of:
+.RS
+.B A\fInumber\fR\en
+.RE
+.PP
+where
+.I number
+is an
+.B ASCII
+representation of a decimal number.
+.PP
+Unsuccessful commands are responded to with:
+.RS
+.B E\fIerror-number\fR\en\fIerror-message\fR\en
+.RE
+.PP
+where
+.I error-number
+is one of the possible error numbers described in
+.BR intro (2)
+and
+.I error-message
+is the corresponding error string as printed from a call to
+.BR perror (3).
+.PP
+The protocol is comprised of the following commands, which are sent as
+indicated - no spaces are supplied between the command and its arguments, or
+between its arguments, and \en indicates that a newline should be supplied:
+.TP
+.B O\fIdevice\fR\en\fImode\fR\en
+Open the specified
+.I device
+using the indicated
+.IR mode .
+.I Device
+is a full pathname and
+.I mode
+is an
+.B ASCII
+representation of a decimal number suitable for passing to
+.BR open (2).
+If a device had already been opened, it is closed before a new open is
+performed.
+.TP
+.B C\fIdevice\fR\en
+Close the currently open device. The
+.I device
+specified is ignored.
+.TP
+.B L\fIwhence\fR\en\fIoffset\fR\en
+Perform an
+.BR lseek (2)
+operation using the specified parameters. The response value is that returned
+from the
+.B lseek
+call.
+.TP
+.B W\fIcount\fR\en
+Write data onto the open device.
+.B Rmt
+reads
+.I count
+bytes from the connection, aborting if a premature end-of-file is encountered.
+The response value is that returned from the
+.BR write (2)
+call.
+.TP
+.B R\fIcount\fR\en
+Read
+.I count
+bytes of data from the open device. If
+.I count
+exceeds the size of the data buffer (10 kilobytes), it is truncated to the
+data buffer size.
+.B Rmt
+then performs the requested
+.BR read (2)
+and responds with
+.B A\fIcount-read\fR\en
+if the read was successful; otherwise an error in the standard format is
+returned. If the read was successful, the data read is then sent.
+.TP
+.B I\fIoperation\fR\en\fIcount\fR\en
+Perform a
+.B MTIOCOP
+.BR ioctl (2)
+command using the specified parameters. The parameters are interpreted as the
+.B ASCII
+representations of the decimal values to place in the
+.B mt_op
+and
+.B mt_count
+fields of the structure used in the
+.B ioctl
+call. The return value is the
+.I count
+parameter when the operation is successful.
+.IP
+By issuing the
+.B I-1\en0\en
+command, a client will specify that he is using the VERSION 1 protocol.
+.IP
+For a VERSION 0 client, the
+.I operation
+parameter is the platform
+.B mt_op
+value (could be different if the client and the
+.B rmt
+server are on two different platforms). For a VERSION 1 client, the
+.I operation
+parameter is standardized as below:
+.RS
+.TP
+.B 0
+Issue a
+.B MTWEOF
+command (write
+.I count
+end-of-file records).
+.TP
+.B 1
+Issue a
+.B MTFSF
+command (forward space over
+.I count
+file marks).
+.TP
+.B 2
+Issue a
+.B MTBSF
+command (backward space over
+.I count
+file marks).
+.TP
+.B 3
+Issue a
+.B MTFSR
+command (forward space
+.I count
+inter-record gaps).
+.TP
+.B 4
+Issue a
+.B MTBSR
+command (backward space
+.I count
+inter-record gaps).
+.TP
+.B 5
+Issue a
+.B MTREW
+command (rewind).
+.TP
+.B 6
+Issue a
+.B MTOFFL
+command (rewind and put the drive offline).
+.TP
+.B 7
+Issue a
+.B MTNOP
+command (no operation, set status only).
+.RE
+.TP
+.B i\fIoperation\fR\en\fIcount\fR\en
+Perform an extended
+.B MTIOCOP
+.BR ioctl (2)
+command using the specified parameters. The parameters are interpreted as the
+.B ASCII
+representations of the decimal values to place in the
+.B mt_op
+and
+.B mt_count
+fields of the structure used in the
+.B ioctl
+call. The return value is the
+.I count
+parameter when the operation is successful. The possible operations are:
+.RS
+.TP
+.B 0
+Issue a
+.B MTCACHE
+command (switch cache on).
+.TP
+.B 1
+Issue a
+.B MTNOCACHE
+command (switch cache off).
+.TP
+.B 2
+Issue a
+.B MTRETEN
+command (retension the tape).
+.TP
+.B 3
+Issue a
+.B MTERASE
+command (erase the entire tape).
+.TP
+.B 4
+Issue a
+.B MTEOM
+command (position to end of media).
+.TP
+.B 5
+Issue a
+.B MTNBSF
+command (backward space count files to BOF).
+.RE
+.TP
+.B S
+Return the status of the open device, as obtained with a
+.B MTIOCGET
+.B ioctl
+call. If the operation was successful, an \*(lqack\*(rq is sent with the size
+of the status buffer, then the status buffer is sent (in binary, which is
+non-portable between different platforms).
+.TP
+.BI s sub-command
+This is a replacement for the previous
+.B S
+command, portable across different platforms. If the open device is a magnetic
+tape, return members of the magnetic tape status structure, as obtained with a
+.B MTIOCGET
+ioctl call. If the open device is not a magnetic tape, an error is returned. If
+the
+.B MTIOCGET
+operation was successful, the numerical value of the structure member is
+returned in decimal. The following sub commands are supported:
+.RS
+.TP
+.B T
+return the content of the structure member
+.B mt_type
+which contains the type of the magnetic tape device.
+.TP
+.B D
+return the content of the structure member
+.B mt_dsreg
+which contains the "drive status register".
+.TP
+.B E
+return the content of the structure member
+.B mt_erreg
+which contains the "error register". This structure member must be retrieved
+first because it is cleared after each
+.B MTIOCGET
+ioctl call.
+.TP
+.B R
+return the content of the structure member
+.B mt_resid
+which contains the residual count of the last I/O.
+.TP
+.B F
+return the content of the structure member
+.B mt_fileno
+which contains the file number of the current tape position.
+.TP
+.B B
+return the content of the structure member
+.B mt_blkno
+which contains the block number of the current tape position.
+.TP
+.B f
+return the content of the structure member
+.B mt_flags
+which contains MTF_ flags from the driver.
+.TP
+.B b
+return the content of the structure member
+.B mt_bf
+which contains the optimum blocking factor.
+.RE
+.PP
+Any other command causes
+.B rmt
+to exit.
+.SH DIAGNOSTICS
+All responses are of the form described above.
+.SH SEE ALSO
+.BR rcmd (3),
+.BR rexec (3),
+.I /usr/include/sys/mtio.h,
+.BR rdump (8),
+.BR rrestore (8)
+.SH BUGS
+People should be discouraged from using this for a remote file access protocol.
+.SH AUTHOR
+The
+.B dump/restore
+backup suit was ported to Linux's Second Extended File System by Remy Card
+<card@Linux.EU.Org>. He maintained the initial versions of
+.B dump
+(up and including 0.4b4, released in january 1997).
+.PP
+Starting with 0.4b5, the new maintainer is Stelian Pop <stelian@popies.net>.
+.SH AVAILABILITY
+The
+.B dump/restore
+backup suit is available from <http://dump.sourceforge.net>
+.SH HISTORY
+The
+.B rmt
+command appeared in 4.2BSD.
--- /dev/null
+/*
+ * Ported to Linux's Second Extended File System as part of the
+ * dump and restore backup suit
+ * Remy Card <card@Linux.EU.Org>, 1994-1997
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id: rmt.c,v 1.28 2003/11/22 16:52:16 stelian Exp $";
+#endif /* not linux */
+
+/*
+ * rmt
+ */
+#include <config.h>
+#include <compatlfs.h>
+#include <rmtflags.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/mtio.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifndef __linux__
+#include <sgtty.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int tape = -1;
+
+static char *record;
+static int maxrecsize = -1;
+
+#define SSIZE 64
+static char device[SSIZE];
+static char count[SSIZE], filemode[SSIZE], pos[SSIZE], op[SSIZE];
+
+static char resp[BUFSIZ];
+
+static FILE *debug;
+#define DEBUG(f) if (debug) fprintf(debug, f)
+#define DEBUG1(f,a) if (debug) fprintf(debug, f, a)
+#define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
+
+/*
+ * Support for Sun's extended RMT protocol
+ * code originally written by Jörg Schilling <schilling@fokus.gmd.de>
+ * and relicensed by his permission from GPL to BSD for use in dump.
+ *
+ * rmt_version is 0 for regular clients (Linux included)
+ * rmt_version is 1 for extended clients (Sun especially). In this case
+ * we support some extended commands (see below) and we remap
+ * the ioctl commands to the UNIX "standard", as per:
+ * ftp://ftp.fokus.gmd.de/pub/unix/star/README.mtio
+ *
+ * In order to use rmt version 1, a client must send "I-1\n0\n"
+ * before issuing the other I commands.
+ */
+static int rmt_version = 0;
+#define RMTI_VERSION -1
+#define RMT_VERSION 1
+
+/* Extended 'i' commands */
+#define RMTI_CACHE 0
+#define RMTI_NOCACHE 1
+#define RMTI_RETEN 2
+#define RMTI_ERASE 3
+#define RMTI_EOM 4
+#define RMTI_NBSF 5
+
+/* Extended 's' comands */
+#define MTS_TYPE 'T'
+#define MTS_DSREG 'D'
+#define MTS_ERREG 'E'
+#define MTS_RESID 'R'
+#define MTS_FILENO 'F'
+#define MTS_BLKNO 'B'
+#define MTS_FLAGS 'f'
+#define MTS_BF 'b'
+
+static char *checkbuf __P((char *, int));
+static void error __P((int));
+static void getstring __P((char *));
+static unsigned long swaplong __P((unsigned long inv));
+#ifdef ERMT
+char *cipher __P((char *, int, int));
+void decrypt __P((void));
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ OFF_T rval = 0;
+ char c;
+ int n, i, cc, oflags;
+ unsigned long block = 0;
+ char *cp;
+
+ int magtape = 0;
+
+#ifdef ERMT
+ if (argc > 1 && strcmp(argv[1], "-d") == 0)
+ decrypt(); /* decrypt stdin to stdout, and exit() */
+#endif
+ /* Skip "-c /etc/rmt", which appears when rmt is used as a shell */
+ if (argc > 2 && strcmp(argv[1], "-c") == 0)
+ argc -= 2, argv += 2;
+ argc--, argv++;
+ if (argc > 0) {
+ debug = fopen(*argv, "w");
+ if (debug == 0)
+ exit(1);
+ (void)setbuf(debug, (char *)0);
+ }
+top:
+ errno = 0;
+ rval = 0;
+ if (read(0, &c, 1) != 1)
+ exit(0);
+ switch (c) {
+
+ case 'O':
+ if (tape >= 0)
+ (void) close(tape);
+ getstring(device);
+ getstring(filemode);
+ DEBUG2("rmtd: O %s %s\n", device, filemode);
+ /*
+ * Translate extended GNU syntax into its numeric platform equivalent
+ */
+ oflags = rmtflags_toint(filemode);
+#ifdef O_TEXT
+ /*
+ * Default to O_BINARY the client may not know that we need it.
+ */
+ if ((oflags & O_TEXT) == 0)
+ oflags |= O_BINARY;
+#endif
+ DEBUG2("rmtd: O %s %d\n", device, oflags);
+ /*
+ * XXX the rmt protocol does not provide a means to
+ * specify the permission bits; allow rw for everyone,
+ * as modified by the users umask
+ */
+ tape = OPEN(device, oflags, 0666);
+ if (tape < 0)
+ goto ioerror;
+ block = 0;
+ {
+ struct mtget mt_stat;
+ magtape = ioctl(tape, MTIOCGET, (char *)&mt_stat) == 0;
+ }
+ goto respond;
+
+ case 'C':
+ DEBUG1("rmtd: C (%lu blocks)\n", block);
+ getstring(device); /* discard */
+ if (close(tape) < 0)
+ goto ioerror;
+ tape = -1;
+ block = 0;
+ goto respond;
+
+#ifdef USE_QFA
+#define LSEEK_GET_TAPEPOS 10
+#define LSEEK_GO2_TAPEPOS 11
+#endif
+
+ case 'L':
+ getstring(count);
+ getstring(pos);
+ DEBUG2("rmtd: L %s %s\n", count, pos);
+ if (!magtape) { /* traditional */
+ switch (atoi(pos)) {
+ case SEEK_SET:
+ case SEEK_CUR:
+ case SEEK_END:
+ rval = LSEEK(tape, (OFF_T)atoll(count), atoi(pos));
+ break;
+#ifdef USE_QFA
+ case LSEEK_GET_TAPEPOS:
+ rval = LSEEK(tape, (OFF_T)0, SEEK_CUR);
+ break;
+ case LSEEK_GO2_TAPEPOS:
+ rval = LSEEK(tape, (OFF_T)atoll(count), SEEK_SET);
+ break;
+#endif /* USE_QFA */
+ default:
+ errno = EINVAL;
+ goto ioerror;
+ break;
+ }
+ }
+ else {
+ switch (atoi(pos)) {
+ case SEEK_SET:
+ case SEEK_CUR:
+ case SEEK_END:
+ rval = LSEEK(tape, (OFF_T)atoll(count), atoi(pos));
+ break;
+#ifdef USE_QFA
+ case LSEEK_GET_TAPEPOS: /* QFA */
+ case LSEEK_GO2_TAPEPOS:
+ {
+ struct mtop buf;
+ long mtpos;
+
+ buf.mt_op = MTSETDRVBUFFER;
+ buf.mt_count = MT_ST_BOOLEANS | MT_ST_SCSI2LOGICAL;
+ if (ioctl(tape, MTIOCTOP, &buf) < 0) {
+ goto ioerror;
+ }
+
+ if (atoi(pos) == LSEEK_GET_TAPEPOS) { /* get tapepos */
+ if (ioctl(tape, MTIOCPOS, &mtpos) < 0) {
+ goto ioerror;
+ }
+ rval = (OFF_T)mtpos;
+ } else {
+ buf.mt_op = MTSEEK;
+ buf.mt_count = atoi(count);
+ if (ioctl(tape, MTIOCTOP, &buf) < 0) {
+ goto ioerror;
+ }
+ rval = (OFF_T)buf.mt_count;
+ }
+ }
+ break;
+#endif /* USE_QFA */
+ default:
+ errno = EINVAL;
+ goto ioerror;
+ }
+ }
+ if (rval < 0)
+ goto ioerror;
+ goto respond;
+
+ case 'W':
+ getstring(count);
+ n = atoi(count);
+ if (n < 1)
+ exit(2);
+ DEBUG2("rmtd: W %s (block = %lu)\n", count, block);
+ record = checkbuf(record, n);
+ for (i = 0; i < n; i += cc) {
+ cc = read(0, &record[i], n - i);
+ if (cc <= 0) {
+ DEBUG("rmtd: premature eof\n");
+ exit(2);
+ }
+ }
+#ifdef ERMT
+ if ((cp = cipher(record, n, 1)) == NULL)
+ goto ioerror;
+#else
+ cp = record;
+#endif
+ rval = write(tape, cp, n);
+ if (rval < 0)
+ goto ioerror;
+ block += n >> 10;
+ goto respond;
+
+ case 'R':
+ getstring(count);
+ DEBUG2("rmtd: R %s (block %lu)\n", count, block);
+ n = atoi(count);
+ record = checkbuf(record, n);
+ rval = read(tape, record, n);
+ if (rval < 0)
+ goto ioerror;
+#ifdef ERMT
+ if ((cp = cipher(record, rval, 0)) == NULL)
+ goto ioerror;
+#else
+ cp = record;
+#endif
+ (void)sprintf(resp, "A%lld\n", (long long)rval);
+ (void)write(1, resp, strlen(resp));
+ (void)write(1, cp, rval);
+ block += n >> 10;
+ goto top;
+
+ case 'I':
+ getstring(op);
+ getstring(count);
+ DEBUG2("rmtd: I %s %s\n", op, count);
+ if (atoi(op) == RMTI_VERSION) {
+ rval = RMT_VERSION;
+ rmt_version = 1;
+ }
+ else {
+ struct mtop mtop;
+ mtop.mt_op = -1;
+ if (rmt_version) {
+ /* rmt version 1, assume UNIX/Solaris/Mac OS X client */
+ switch (atoi(op)) {
+#ifdef MTWEOF
+ case 0:
+ mtop.mt_op = MTWEOF;
+ break;
+#endif
+#ifdef MTFSF
+ case 1:
+ mtop.mt_op = MTFSF;
+ break;
+#endif
+#ifdef MTBSF
+ case 2:
+ mtop.mt_op = MTBSF;
+ break;
+#endif
+#ifdef MTFSR
+ case 3:
+ mtop.mt_op = MTFSR;
+ break;
+#endif
+#ifdef MTBSR
+ case 4:
+ mtop.mt_op = MTBSR;
+ break;
+#endif
+#ifdef MTREW
+ case 5:
+ mtop.mt_op = MTREW;
+ break;
+#endif
+#ifdef MTOFFL
+ case 6:
+ mtop.mt_op = MTOFFL;
+ break;
+#endif
+#ifdef MTNOP
+ case 7:
+ mtop.mt_op = MTNOP;
+ break;
+#endif
+#ifdef MTRETEN
+ case 8:
+ mtop.mt_op = MTRETEN;
+ break;
+#endif
+#ifdef MTERASE
+ case 9:
+ mtop.mt_op = MTERASE;
+ break;
+#endif
+#ifdef MTEOM
+ case 10:
+ mtop.mt_op = MTEOM;
+ break;
+#endif
+ }
+ if (mtop.mt_op == -1) {
+ errno = EINVAL;
+ goto ioerror;
+ }
+ }
+ else {
+ /* rmt version 0, assume linux client */
+ mtop.mt_op = atoi(op);
+ }
+ mtop.mt_count = atoi(count);
+ if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) {
+ goto ioerror;
+ }
+ rval = mtop.mt_count;
+ }
+ goto respond;
+
+ case 'i':
+ { struct mtop mtop;
+
+ getstring (op);
+ getstring (count);
+ DEBUG2 ("rmtd: i %s %s\n", op, count);
+ switch (atoi(op)) {
+#ifdef MTCACHE
+ case RMTI_CACHE:
+ mtop.mt_op = MTCACHE;
+ break;
+#endif
+#ifdef MTNOCACHE
+ case RMTI_NOCACHE:
+ mtop.mt_op = MTNOCACHE;
+ break;
+#endif
+#ifdef MTRETEN
+ case RMTI_RETEN:
+ mtop.mt_op = MTRETEN;
+ break;
+#endif
+#ifdef MTERASE
+ case RMTI_ERASE:
+ mtop.mt_op = MTERASE;
+ break;
+#endif
+#ifdef MTEOM
+ case RMTI_EOM:
+ mtop.mt_op = MTEOM;
+ break;
+#endif
+#ifdef MTNBSF
+ case RMTI_NBSF:
+ mtop.mt_op = MTNBSF;
+ break;
+#endif
+ default:
+ errno = EINVAL;
+ goto ioerror;
+ }
+ mtop.mt_count = atoi (count);
+ if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0) {
+ goto ioerror;
+ }
+
+ rval = mtop.mt_count;
+
+ goto respond;
+ }
+
+ case 'S': /* status */
+ DEBUG("rmtd: S\n");
+ { struct mtget mtget;
+
+ if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) {
+ goto ioerror;
+ }
+
+ if (rmt_version) {
+ rval = sizeof(mtget);
+ /* assume byte order:
+ Linux on Intel (little), Solaris on SPARC (big), Mac OS X on PPC (big)
+ thus need byte swapping from little to big
+ */
+ mtget.mt_type = swaplong(mtget.mt_type);
+ mtget.mt_resid = swaplong(mtget.mt_resid);
+ mtget.mt_dsreg = swaplong(mtget.mt_dsreg);
+ mtget.mt_gstat = swaplong(mtget.mt_gstat);
+ mtget.mt_erreg = swaplong(mtget.mt_erreg);
+ mtget.mt_fileno = swaplong(mtget.mt_fileno);
+ mtget.mt_blkno = swaplong(mtget.mt_blkno);
+ (void)sprintf(resp, "A%lld\n", (long long)rval);
+ (void)write(1, resp, strlen(resp));
+ (void)write(1, (char *)&mtget, sizeof (mtget));
+ } else {
+ rval = sizeof (mtget);
+ (void)sprintf(resp, "A%lld\n", (long long)rval);
+ (void)write(1, resp, strlen(resp));
+ (void)write(1, (char *)&mtget, sizeof (mtget));
+ }
+ goto top;
+ }
+
+ case 's':
+ { char s;
+ struct mtget mtget;
+
+ DEBUG ("rmtd: s\n");
+
+ if (read (0, &s, 1) != 1)
+ goto top;
+ DEBUG1 ("rmtd: s %d\n", s);
+
+ if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0) {
+ goto ioerror;
+ }
+
+ switch (s) {
+ case MTS_TYPE:
+ rval = mtget.mt_type;
+ break;
+ case MTS_DSREG:
+ rval = mtget.mt_dsreg;
+ break;
+ case MTS_ERREG:
+ rval = mtget.mt_erreg;
+ break;
+ case MTS_RESID:
+ rval = mtget.mt_resid;
+ break;
+ case MTS_FILENO:
+ rval = mtget.mt_fileno;
+ break;
+ case MTS_BLKNO:
+ rval = mtget.mt_blkno;
+ break;
+ case MTS_FLAGS:
+ rval = mtget.mt_gstat;
+ break;
+ case MTS_BF:
+ rval = 0;
+ break;
+ default:
+ errno = EINVAL;
+ goto ioerror;
+ }
+
+ goto respond;
+ }
+
+ case 'V': /* version */
+ getstring(op);
+ DEBUG1("rmtd: V %s\n", op);
+ rval = 2;
+ goto respond;
+
+ default:
+ DEBUG1("rmtd: garbage command %c\n", c);
+ exit(3);
+ }
+respond:
+ DEBUG1("rmtd: A %lld\n", (long long)rval);
+ (void)sprintf(resp, "A%lld\n", (long long)rval);
+ (void)write(1, resp, strlen(resp));
+ goto top;
+ioerror:
+ error(errno);
+ goto top;
+}
+
+static void getstring(char *bp)
+{
+ int i;
+ char *cp = bp;
+
+ for (i = 0; i < SSIZE - 1; i++) {
+ if (read(0, cp+i, 1) != 1)
+ exit(0);
+ if (cp[i] == '\n')
+ break;
+ }
+ cp[i] = '\0';
+}
+
+static char *
+checkbuf(char *record, int size)
+{
+
+ if (size <= maxrecsize)
+ return (record);
+ if (record != 0)
+ free(record);
+ record = malloc(size);
+ if (record == 0) {
+ DEBUG("rmtd: cannot allocate buffer space\n");
+ exit(4);
+ }
+ maxrecsize = size;
+ while (size > 1024 &&
+ setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
+ size -= 1024;
+ return (record);
+}
+
+static void
+error(int num)
+{
+
+ DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));
+ (void)snprintf(resp, sizeof(resp), "E%d\n%s\n", num, strerror(num));
+ (void)write(1, resp, strlen(resp));
+}
+
+static unsigned long
+swaplong(unsigned long inv)
+{
+ union lconv {
+ unsigned long ul;
+ unsigned char uc[4];
+ } *inp, outv;
+
+ inp = (union lconv *)&inv;
+
+ outv.uc[0] = inp->uc[3];
+ outv.uc[1] = inp->uc[2];
+ outv.uc[2] = inp->uc[1];
+ outv.uc[3] = inp->uc[0];
+
+ return (outv.ul);
+}