dump-0.4b44/0000755000175000017500000000000011574405662012526 5ustar steliansteliandump-0.4b44/COPYRIGHT0000644000175000017500000000350707641607757014037 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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. */ dump-0.4b44/TODO0000644000175000017500000000224510235441364013211 0ustar stelianstelian$Id: TODO,v 1.25 2005/05/02 15:10:44 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. Better readline completition in restore (escape spaces etc). dump-0.4b44/dump.lsm0000644000175000017500000000121311574405523014201 0ustar stelianstelianBegin3 Title: dump and restore for Ext2fs Version: 0.4b44 Entered-date: 10JUN11 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.4b43.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 dump-0.4b44/KNOWNBUGS0000644000175000017500000000121407015635010014007 0ustar stelianstelian$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. dump-0.4b44/depfix.sed0000644000175000017500000000070707000363230014465 0ustar stelianstelian# $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\ dump-0.4b44/examples/0000755000175000017500000000000011574405661014343 5ustar steliansteliandump-0.4b44/examples/encrypted_rmt/0000755000175000017500000000000011574405661017222 5ustar steliansteliandump-0.4b44/examples/encrypted_rmt/README0000644000175000017500000000552707644624204020112 0ustar stelianstelianThis 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 dump-0.4b44/examples/dump_on_cd_3/0000755000175000017500000000000011574405661016674 5ustar steliansteliandump-0.4b44/examples/dump_on_cd_3/README0000644000175000017500000000117610171462774017561 0ustar stelianstelianI took the dump_on_cd_2/EN/* scripts and merged the pair of scripts into one script, which checks it's arguments to tell whether or not it is called from dump and acts accordingly. The script commandline takes dump arguments except -f (output file/device), -F (script to run after each volume is finished) and -B (volume size) which are overridden. You can use the script to backup to CD with cdrtecord from cdrtools or to DVD with either cdrtools with DVD support or growisofs from dvd+rw-tools. You must configure the burning process by adjusting the variables at the top of the script. Andrew Basterfield bob@cemetery.homeunix.org dump-0.4b44/examples/dump_on_cd_3/dump_disk0000755000175000017500000000533410171463004020571 0ustar stelianstelian#!/bin/sh # This script dumps the specified Filesystem via dump on a CD/DVD # DISK_CAPACITY defines the capacity in MB per disk. # The script's own name $0 is passed via the -F option of dump # When using cdrecord/dvdrecord and 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. # Set this to 4300 for DVD and 650 or 700 for CD #DISK_CAPACITY=10 # testing #DISK_CAPACITY=650 DISK_CAPACITY=4300 BSIZE="$(echo "$DISK_CAPACITY*1024" | bc -l )" TSIZE="$(echo "$DISK_CAPACITY*1024*1024" | bc -l )" # This is used for testing #RECORD_BIN="dd of=/dev/null bs=1k if=" # This is for writing to CD with cdrtools, this uses track-at-once mode # in case cdrtools does not support disk-at-once with your burner #RECORD_BIN="/usr/bin/cdrecord dev=0,0,0 fs=64M speed=2 -eject -tao -pad -tsize=$TSIZE -data " # This is for writing to DVD with cdrtools with DVD support, this has to # use disk-at-once mode. #RECORD_BIN="/usr/bin/cdrecord dev=0,0,0 fs=64M speed=2 -eject -dao -pad -tsize=$TSIZE -data " # This is for writing to DVD with growisofs RECORD_BIN="/usr/bin/growisofs -Z /dev/dvd=" FIFO="/tmp/dump.$$.fifo" DUMP="/sbin/dump" cleanup() { rm -f $FIFO } error_exit() { retcode=$? echo >&2 "Error $retcode: exiting" exit $retcode } trap error_exit ERR write_output() { # supplied info from "dump -F": # $1 = filename # $2 = sequence number echo "Please insert disk No. $(($2+1))" ANSWER="" while [ "$ANSWER" != "y" ] ; do echo -n "Is the disk ready? (y/n) " read &2 "Usage: $0 " echo >&2 "See 'man dump' for dump options" echo >&2 "the dump options -F -f -B are not required and are overridden" exit 1 fi set -m # We need proper job control if [ "$#" = "2" ] && [ -p "$1" ]; then write_output "$@" || (kill $$ >/dev/null 2>&1; exit 1) exit 0 else mkfifo $FIFO trap cleanup EXIT if write_output "$FIFO" "0"; then if $DUMP "$@" -F "$0" -f "$FIFO" -B$BSIZE; then echo "Waiting for background writing process to complete" wait % # Wait for the background writing process else kill % >/dev/null 2>&1 # or kill it exit 1 fi exit 0 else kill % >/dev/null 2>&1 # Kill the background writing process exit 1 fi fi dump-0.4b44/examples/dump_on_cd_2/0000755000175000017500000000000011574405661016673 5ustar steliansteliandump-0.4b44/examples/dump_on_cd_2/EN/0000755000175000017500000000000011574405661017175 5ustar steliansteliandump-0.4b44/examples/dump_on_cd_2/EN/dump_userexit_CD0000644000175000017500000000103107510260446022351 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/EN/backup_DVD0000644000175000017500000000270507510260446021061 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/EN/backup_CD0000644000175000017500000000205707510260446020732 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/EN/dump_userexit_DVD0000644000175000017500000000116107510260446022504 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/README0000644000175000017500000000045307510041627017546 0ustar stelianstelian[...] 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 dump-0.4b44/examples/dump_on_cd_2/DE/0000755000175000017500000000000011574405661017163 5ustar steliansteliandump-0.4b44/examples/dump_on_cd_2/DE/dump_userexit_CD0000644000175000017500000000111307510260446022340 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/DE/backup_DVD0000644000175000017500000000270207510260446021044 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/DE/backup_CD0000644000175000017500000000213207510041630020702 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd_2/DE/dump_userexit_DVD0000644000175000017500000000116207510260446022473 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd/0000755000175000017500000000000011574405661016452 5ustar steliansteliandump-0.4b44/examples/dump_on_cd/README0000644000175000017500000000413707347633475017350 0ustar stelianstelian 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. dump-0.4b44/examples/dump_on_cd/verify_dump.sh0000755000175000017500000000020707347633475021352 0ustar stelianstelian#!/bin/bash if [ `id -u` != 0 ]; then echo "root priviledges are required" exit 1 fi cd / /sbin/restore -V -b64 -C -f /dev/cdrom dump-0.4b44/examples/dump_on_cd/start_dump.sh0000755000175000017500000000071507347633475021207 0ustar stelianstelian#!/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 dump-0.4b44/examples/dump_on_cd/dump_userinfo.sh0000755000175000017500000000043507347633475021703 0ustar stelianstelian#!/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 & dump-0.4b44/examples/howto/0000755000175000017500000000000011574405661015503 5ustar steliansteliandump-0.4b44/examples/howto/ultra-mini-howto0000644000175000017500000002451307362540514020647 0ustar stelianstelianDump/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 - dump-0.4b44/examples/cron_dump_to_disk/0000755000175000017500000000000011574405661020045 5ustar steliansteliandump-0.4b44/examples/cron_dump_to_disk/backup_rotate0000755000175000017500000000756711013761761022627 0ustar stelianstelian#!/bin/bash ### # Copyright (C) 2001 Eugenio Diaz # # 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. # ## # # This script will redirect the backup directory to implement desired # backup schedules. # # We will use just a seven day format where 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=${BACKUPPART:-"/backup"} BACKUPDIR=${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 ###" ## end of script dump-0.4b44/examples/cron_dump_to_disk/README0000644000175000017500000000302307401655630020720 0ustar stelianstelianHere 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 dump-0.4b44/examples/cron_dump_to_disk/crontab_entries.txt0000644000175000017500000000037207401655630023766 0ustar stelianstelian# 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 dump-0.4b44/examples/cron_dump_to_disk/backupskel.tar.gz0000644000175000017500000000045107401655630023315 0ustar stelianstelian‹BKõ;íÖÁjÄ P?%_ OŸOÿ »®Zè:̦Ð&àÄEÿ¾Æ¡›.¦Šv ÷lˆ‹„ë}QÕ‘§(R®Õ÷ëå>rçÅ×u1²¨AÚ¿šRù¼ŽiTZ–õÚºŸžÿSÚ<.óqüh¹ nËß EÏ$N‘µVù÷ Í!§4Í-¿¬+Ž·õŸi[/dÕà.[³á›)äožò}ôŸ™·ô9Ôþ‡€þ÷ ÍsžÎm7À®ùêügùßEéÿ¸æÔtìÊßñ–¿XFþ=hó2ç¶`_ÿëüb‘eþŸrjûØ•?ÇÚ‘Ú<¤×»8ÿ}åOõüǘÿ]hó¾ÌëéíïÏeæ/D²åï-úð+Ÿ4ï#Š(dump-0.4b44/examples/cron_dump_to_disk/backup0000755000175000017500000002011711013761761021233 0ustar stelianstelian#!/bin/bash ### # Copyright (C) 2001 Eugenio Diaz # # 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. # ## # # This script will make a simple backup of the most critical # partitions, using the "dump" facility, into the backup partition. # # Run the following to make a complete backup: # # $ su -c "backup full" # # Run the following to make an incremental backup: # # $ su -c "backup inc" # # Add "nodumpdate" to run a backup but not effect the backup state # recorded in the file /var/lib/dumpdates and reported by dump -W: # # $ su -c "backup full nodumpdate" # ## if [ "$2" = "nodumpdate" ]; then UPDATEDDATE="" else UPDATEDDATE="-u" fi if [ "$1" = "full" ]; then DLEVEL="0" BTYPE="full" BACKUP="Full" elif [ "$1" = "inc" ]; then DLEVEL="1" BTYPE="inc" BACKUP="Incremental" else echo "Usage: $0 full|inc [nodumpdate]" exit 1 fi # # Configuration Parameters # BACKUPPART=${BACKUPPART:-"/backup"} BACKUPDIR=${BACKUPDIR:-"current"} DUMPLOGARCH="$BACKUPPART/backup.dump.log.gz" FSTODUMP=${FSTODUMP:-/ /var /home /mnt/hdb1 /usr} DUMPFILESMODE="0644" DUMPFILESOWN="root.root" # # Start # echo echo "############################################################" echo "Starting ${BACKUP} backup" echo "############################################################" echo # # Make system backup # echo "### ${BACKUP} System Dump Backup ###" echo "Using backup partition: $BACKUPPART" echo "Filesystems to dump: $FSTODUMP" echo -n "Remounting backup partition read-write ... " if ( mount $BACKUPPART -o remount,rw &> /dev/null ) then echo "done." elif ( mount $BACKUPPART -o rw &> /dev/null ) then echo "done." else echo "failure!" echo "There were problems remounting $BACKUPPART in read-write mode!" echo "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" exit 1 fi echo -n "Checking directory structure on backup partition ... " if [ -d $BACKUPPART/$BACKUPDIR -a -w $BACKUPPART/$BACKUPDIR ]; then echo "done." echo -n "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 -Fe $BACKUPPART | awk '{printf "%6.0f\n", $4}') SAVAILDEL=$(du -s --block-size=1048576 $BACKUPPART/$BACKUPDIR/. | awk '{printf "%6.0f\n", $1}') SAVAIL=$(( $SAVAILFREE + $SAVAILDEL )) if [ "$(( $SAVAIL - $SREQ ))" -gt "0" ]; then echo "done." echo "Available: $SAVAIL MB Required: $SREQ MB." else echo "not enough space!" echo "There is not enough space left in $BACKUPPART for the backup!" echo "Available: $SAVAIL MB Required: $SREQ MB." echo -n "Remounting backup partition read-only ... " if ( mount $BACKUPPART -o remount,ro &> /dev/null ) then echo "done." elif ( mount $BACKUPPART -o ro &> /dev/null ) then echo "done." else echo "failure!" echo "There were problems remounting $BACKUPPART in read-only mode!" echo "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" exit 1 fi echo "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" exit 1 fi echo -n "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 "Dumping filesystems ... " for FS in $FSTODUMP do if [ "$FS" = "/" ]; then FSNAME="root" else FSNAME="$(echo $FS | tr / _ | cut -b 2-)" fi sync TODAY="$(date +%a%Y%m%d)" echo -n "Starting dump of $FSNAME ( $FS ) ... " if ( dump -$DLEVEL $UPDATEDDATE -z -M -s 27306 -f $BACKUPPART/$BACKUPDIR/$FSNAME.$BTYPE. -Q $BACKUPPART/$BACKUPDIR/$FSNAME.$BTYPE.qfa -L ${TODAY}file $FS &> $BACKUPPART/$BACKUPDIR/$FSNAME.log ) then echo "done." else echo "problems!" echo "There were problems with the dump of $FSNAME ( $FS )." echo "Check log file at $BACKUPPART/$BACKUPDIR/$FSNAME.log.gz" echo "Also check log archive file $DUMPLOGARCH." fi echo -n "Verifying dump of $FSNAME ( $FS ) ... " echo "------------------------------------------------------------" >> $BACKUPPART/$BACKUPDIR/$FSNAME.log echo "Result of dump for $FSNAME ( $FS ):" >> $BACKUPPART/$BACKUPDIR/$FSNAME.log if ( restore -C -M -f $BACKUPPART/$BACKUPDIR/$FSNAME.$BTYPE. >> $BACKUPPART/$BACKUPDIR/$FSNAME.log 2>&1 ) then echo "done." else echo "problems!" echo "There were problems verifying the dump of $FSNAME ( $FS )." echo "Check log file $BACKUPPART/$BACKUPDIR/$FSNAME.log.gz for more info" fi gzip < $BACKUPPART/$BACKUPDIR/$FSNAME.log >> $DUMPLOGARCH echo "------------------------------------------------------------" | gzip >> $DUMPLOGARCH done echo -n "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 "Compressing dump log files ... " gzip $BACKUPPART/$BACKUPDIR/*.log &> /dev/null echo "done." sync else echo "problems!" echo "There are problems with the directory structure." echo "Check directory: $BACKUPPART/$BACKUPDIR" 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 "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" exit 1 fi echo "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" 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 "Aborting ${BACKUP} System Dump Backup." echo "Aborted." echo "------------------------------------------------------------" exit 1 fi echo "### End of ${BACKUP} System Dump Backup ###" echo "Done." echo "------------------------------------------------------------" ## end of script dump-0.4b44/examples/dump_on_remote_cd/0000755000175000017500000000000011574405661020025 5ustar steliansteliandump-0.4b44/examples/dump_on_remote_cd/get-dumpdata-to-cdrecord0000755000175000017500000000360707471135404024534 0ustar stelianstelian#!/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 -f " 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: dump-0.4b44/examples/dump_on_remote_cd/README0000644000175000017500000000247007471135404020704 0ustar stelianstelian> 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 ] [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 ------------------------------------------------------------------------ dump-0.4b44/examples/dump_on_remote_cd/dump-to-remote-cd0000755000175000017500000000513207471135404023212 0ustar stelianstelian#!/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 ] [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 ] [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 dump-0.4b44/examples/remote_backup_ssh/0000755000175000017500000000000011574405661020040 5ustar steliansteliandump-0.4b44/examples/remote_backup_ssh/backitup0000644000175000017500000000305507373337227021574 0ustar stelianstelian#!/bin/sh # # This script will backup local drives to a remote tape drive over ssh. # written by David B. Peterson # # 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 dump-0.4b44/configure0000755000175000017500000056634311574405662014456 0ustar stelianstelian#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.67. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 IFS=$as_save_IFS ;; 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="dump/dump.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS top_builddir CRYPTO BZLIB ZLIB READLINE BLKID EXT2FS_LIBS EXT2FS_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG DUMPDATESPATH MANMODE MANGRP MANOWNER BINMODE BINGRP BINOWNER LDOPTS CCOPTS LD CCTRANSSELINUX LTRANSSELINUX OPTDEFS ERMT RMTDIR STATIC RESTOREDEBUG DUMPDEBUG EGREP GREP CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC PATCH RANLIB AR RM MV CP LN_S SET_MAKE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='MCONFIG' ac_user_opts=' enable_option_checking enable_debug enable_static enable_staticz enable_rmt enable_ermt enable_kerberos enable_readline enable_oldstylefscript enable_largefile enable_qfa enable_qfadebug enable_macosx enable_transselinux with_cc with_linker with_ccopts with_ldopts with_binowner with_bingrp with_binmode with_manowner with_mangrp with_manmode with_dumpdatespath ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR EXT2FS_CFLAGS EXT2FS_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # 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. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= 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 case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -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) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$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 ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$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 ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) 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 ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=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 ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_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'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" 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 $as_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 ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # 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 the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | 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 test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # 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 \`..'] 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] --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] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --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) --enable-transselinux restore can translate SELinux EAs (default is YES) 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 if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path EXT2FS_CFLAGS C compiler flags for EXT2FS, overriding pkg-config EXT2FS_LIBS linker flags for EXT2FS, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested 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 else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.67 Copyright (C) 2010 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 fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_check_header_preproc LINENO HEADER VAR # ---------------------------------------------- # Tests whether HEADER is present, setting the cache variable VAR accordingly. ac_fn_c_check_header_preproc () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f conftest.err conftest.i conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_preproc # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* 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_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type cat >config.log <<_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.67. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { 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` /usr/bin/hostinfo = `(/usr/bin/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=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&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_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append 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 as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset 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: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > 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 cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5 ; } 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. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_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 $ac_precious_vars; 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,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_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 # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_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. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## 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" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_CP+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CP" && ac_cv_path_CP="cp" ;; esac fi CP=$ac_cv_path_CP if test -n "$CP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 $as_echo "$CP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MV+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MV" && ac_cv_path_MV="mv" ;; esac fi MV=$ac_cv_path_MV if test -n "$MV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MV" >&5 $as_echo "$MV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_RM+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_RM" && ac_cv_path_RM="rm" ;; esac fi RM=$ac_cv_path_RM if test -n "$RM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 $as_echo "$RM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="ar" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_PATCH+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_PATCH="${ac_tool_prefix}patch" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PATCH=$ac_cv_prog_PATCH if test -n "$PATCH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5 $as_echo "$PATCH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_PATCH+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_PATCH="patch" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_PATCH=$ac_cv_prog_ac_ct_PATCH if test -n "$ac_ct_PATCH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PATCH" >&5 $as_echo "$ac_ct_PATCH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_PATCH" = x; then PATCH=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PATCH=$ac_ct_PATCH fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* 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 -std 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 -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 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 for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : 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 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 as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # 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. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir 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. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&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 : $as_echo_n "(cached) " >&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 to if __STDC__ is defined, since # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$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 to if __STDC__ is defined, since # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5 ; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #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)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h 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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TYPES_H 1 _ACEOF fi done CPPFLAGS="-D_BSD_SOURCE -D_USE_BSD_SIGNAL ${CPPFLAGS}" # Check whether --enable-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 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 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 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 was given. if test "${enable_ermt+set}" = set; then : enableval=$enable_ermt; if test "$enableval" = "no" then ERMT="" echo "Not compiling ermt" else if test "$RMTDIR" = "" then as_fn_error $? "ermt requires --enable-rmt" "$LINENO" 5 fi ERMT="ermt" echo "Compiling ermt" fi else ERMT="" echo "Not compiling ermt by default" fi # Check whether --enable-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 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="yes" $as_echo "#define HAVE_READLINE 1" >>confdefs.h echo "Including readline support" fi else READLINE="yes" $as_echo "#define HAVE_READLINE 1" >>confdefs.h echo "Including readline support by default" fi # Check whether --enable-oldstylefscript was given. if test "${enable_oldstylefscript+set}" = set; then : enableval=$enable_oldstylefscript; if test "$enableval" = "yes" then $as_echo "#define OLD_STYLE_FSCRIPT 1" >>confdefs.h 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 was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; if test "$enableval" = "yes" then $as_echo "#define USE_LFS 1" >>confdefs.h echo "Enabling Large File System support" else echo "Not enabling Large File System support" fi else $as_echo "#define USE_LFS 1" >>confdefs.h echo "Enabling Large File System support by default" fi # Check whether --enable-qfa was given. if test "${enable_qfa+set}" = set; then : enableval=$enable_qfa; if test "$enableval" = "yes" then $as_echo "#define USE_QFA 1" >>confdefs.h echo "Enabling Quick File Access support" else echo "Not enabling Quick File Access support" fi else $as_echo "#define USE_QFA 1" >>confdefs.h echo "Enabling Quick File Access support by default" fi # Check whether --enable-qfadebug was given. if test "${enable_qfadebug+set}" = set; then : enableval=$enable_qfadebug; if test "$enableval" = "yes" then $as_echo "#define DEBUG_QFA 1" >>confdefs.h 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 was given. if test "${enable_macosx+set}" = set; then : enableval=$enable_macosx; if test "$enableval" = "yes" then $as_echo "#define DUMP_MACOSX 1" >>confdefs.h 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 --enable-transselinux was given. if test "${enable_transselinux+set}" = set; then : enableval=$enable_transselinux; if test "$enableval" = "yes" then LTRANSSELINUX="-lselinux" CCTRANSSELINUX="-DTRANSSELINUX" echo "restore can translate SELinux EAs" else LTRANSSELINUX="" CCTRANSSELINUX="" echo "restore can not translate SELinux EAs" fi else LTRANSSELINUX="-lselinux" CCTRANSSELINUX="-DTRANSSELINUX" echo "restore can translate SELinux EAs by default" fi # Check whether --with-cc was given. if test "${with_cc+set}" = set; then : withval=$with_cc; { $as_echo "$as_me:${as_lineno-$LINENO}: result: CC=$withval" >&5 $as_echo "CC=$withval" >&6; } CC=$withval else if test -z "$CC" ; then CC=cc; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: CC defaults to $CC" >&5 $as_echo "CC defaults to $CC" >&6; } fi export CC # Check whether --with-linker was given. if test "${with_linker+set}" = set; then : withval=$with_linker; { $as_echo "$as_me:${as_lineno-$LINENO}: result: LD=$withval" >&5 $as_echo "LD=$withval" >&6; } LD=$withval else if test -z "$LD" ; then LD=$CC; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: LD defaults to $LD" >&5 $as_echo "LD defaults to $LD" >&6; } fi export LD # Check whether --with-ccopts was given. if test "${with_ccopts+set}" = set; then : withval=$with_ccopts; { $as_echo "$as_me:${as_lineno-$LINENO}: result: CCOPTS is $withval" >&5 $as_echo "CCOPTS is $withval" >&6; } CCOPTS=$withval CFLAGS="$CFLAGS $withval" else CCOPTS= fi # Check whether --with-ldopts was given. if test "${with_ldopts+set}" = set; then : withval=$with_ldopts; { $as_echo "$as_me:${as_lineno-$LINENO}: result: LDFLAGS is $withval" >&5 $as_echo "LDFLAGS is $withval" >&6; } LDOPTS=$withval LDFLAGS="$LDFLAGS $withval" else LDOPTS= fi # Check whether --with-binowner was given. if test "${with_binowner+set}" = set; then : withval=$with_binowner; { $as_echo "$as_me:${as_lineno-$LINENO}: result: BINOWNER is $withval" >&5 $as_echo "BINOWNER is $withval" >&6; } BINOWNER=$withval else BINOWNER=root echo "BINOWNER defaults to $BINOWNER" fi # Check whether --with-bingrp was given. if test "${with_bingrp+set}" = set; then : withval=$with_bingrp; { $as_echo "$as_me:${as_lineno-$LINENO}: result: BINGRP is $withval" >&5 $as_echo "BINGRP is $withval" >&6; } BINGRP=$withval else BINGRP=tty echo "BINGRP defaults to $BINGRP" fi # Check whether --with-binmode was given. if test "${with_binmode+set}" = set; then : withval=$with_binmode; { $as_echo "$as_me:${as_lineno-$LINENO}: result: BINMODE is $withval" >&5 $as_echo "BINMODE is $withval" >&6; } BINMODE=$withval else BINMODE=0755 echo "BINMODE defaults to $BINMODE" fi # Check whether --with-manowner was given. if test "${with_manowner+set}" = set; then : withval=$with_manowner; { $as_echo "$as_me:${as_lineno-$LINENO}: result: MANOWNER is $withval" >&5 $as_echo "MANOWNER is $withval" >&6; } MANOWNER=$withval else MANOWNER=man echo "MANOWNER defaults to $MANOWNER" fi # Check whether --with-mangrp was given. if test "${with_mangrp+set}" = set; then : withval=$with_mangrp; { $as_echo "$as_me:${as_lineno-$LINENO}: result: MANGRP is $withval" >&5 $as_echo "MANGRP is $withval" >&6; } MANGRP=$withval else MANGRP=tty echo "MANGRP defaults to $MANGRP" fi # Check whether --with-manmode was given. if test "${with_manmode+set}" = set; then : withval=$with_manmode; { $as_echo "$as_me:${as_lineno-$LINENO}: result: MANMODE is $withval" >&5 $as_echo "MANMODE is $withval" >&6; } MANMODE=$withval else MANMODE=0644 echo "MANMODE defaults to $MANMODE" fi # Check whether --with-dumpdatespath was given. if test "${with_dumpdatespath+set}" = set; then : withval=$with_dumpdatespath; { $as_echo "$as_me:${as_lineno-$LINENO}: result: DUMPDATESPATH is $withval" >&5 $as_echo "DUMPDATESPATH is $withval" >&6; } DUMPDATESPATH=$withval else DUMPDATESPATH="${sysconfdir}/dumpdates" echo "DUMPDATESPATH defaults to $DUMPDATESPATH" fi ac_fn_c_check_header_preproc "$LINENO" "ext2fs/ext2fs.h" "ac_cv_header_ext2fs_ext2fs_h" if test "x$ac_cv_header_ext2fs_ext2fs_h" = x""yes; then : ext2fs_h=yes else ext2fs_h=no fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXT2FS" >&5 $as_echo_n "checking for EXT2FS... " >&6; } if test -n "$EXT2FS_CFLAGS"; then pkg_cv_EXT2FS_CFLAGS="$EXT2FS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs\""; } >&5 ($PKG_CONFIG --exists --print-errors "ext2fs") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_EXT2FS_CFLAGS=`$PKG_CONFIG --cflags "ext2fs" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$EXT2FS_LIBS"; then pkg_cv_EXT2FS_LIBS="$EXT2FS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs\""; } >&5 ($PKG_CONFIG --exists --print-errors "ext2fs") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_EXT2FS_LIBS=`$PKG_CONFIG --libs "ext2fs" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then EXT2FS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "ext2fs" 2>&1` else EXT2FS_PKG_ERRORS=`$PKG_CONFIG --print-errors "ext2fs" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$EXT2FS_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (ext2fs) were not met: $EXT2FS_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables EXT2FS_CFLAGS and EXT2FS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables EXT2FS_CFLAGS and EXT2FS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5 ; } else EXT2FS_CFLAGS=$pkg_cv_EXT2FS_CFLAGS EXT2FS_LIBS=$pkg_cv_EXT2FS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi if test -n "$STATIC" ; then EXT2FS_LIBS=`$PKG_CONFIG --libs --static ext2fs` fi if test "$ext2fs_h" = no -o "x$EXT2FS_LIBS" = "x"; then as_fn_error $? "You need to install the Ext2fs libraries from the E2fsprogs distribution first - hint: make install-libs" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext2fs_read_inode_full in -lext2fs" >&5 $as_echo_n "checking for ext2fs_read_inode_full in -lext2fs... " >&6; } if test "${ac_cv_lib_ext2fs_ext2fs_read_inode_full+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lext2fs -lcom_err $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ext2fs_read_inode_full (); int main () { return ext2fs_read_inode_full (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ext2fs_ext2fs_read_inode_full=yes else ac_cv_lib_ext2fs_ext2fs_read_inode_full=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ext2fs_ext2fs_read_inode_full" >&5 $as_echo "$ac_cv_lib_ext2fs_ext2fs_read_inode_full" >&6; } if test "x$ac_cv_lib_ext2fs_ext2fs_read_inode_full" = x""yes; then : rif=yes else rif=no fi if test "$rif" = yes; then $as_echo "#define HAVE_EXT2FS_READ_INODE_FULL 1" >>confdefs.h fi for ac_header in ext2fs/ext2_fs.h do : ac_fn_c_check_header_preproc "$LINENO" "ext2fs/ext2_fs.h" "ac_cv_header_ext2fs_ext2_fs_h" if test "x$ac_cv_header_ext2fs_ext2_fs_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_EXT2FS_EXT2_FS_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext2_ino_t type in libext2fs headers" >&5 $as_echo_n "checking for ext2_ino_t type in libext2fs headers... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include int main () { ext2_ino_t ino = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_EXT2_INO_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for s_journal_inum field in ext2_super_block struct" >&5 $as_echo_n "checking for s_journal_inum field in ext2_super_block struct... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include int main () { struct ext2_super_block es; es.s_journal_inum = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_EXT2_JOURNAL_INUM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_header_preproc "$LINENO" "blkid/blkid.h" "ac_cv_header_blkid_blkid_h" if test "x$ac_cv_header_blkid_blkid_h" = x""yes; then : blkid_h=yes else blkid_h=no fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid\""; } >&5 ($PKG_CONFIG --exists --print-errors "blkid") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test -n $STATIC ; then BLKID=`$PKG_CONFIG --libs --static blkid` else BLKID=`$PKG_CONFIG --libs blkid` fi if test "$blkid_h" = yes ; then $as_echo "#define HAVE_BLKID 1" >>confdefs.h fi else BLKID="" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 $as_echo_n "checking for tgetent in -lncurses... " >&6; } if test "${ac_cv_lib_ncurses_tgetent+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ncurses_tgetent=yes else ac_cv_lib_ncurses_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 $as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } if test "x$ac_cv_lib_ncurses_tgetent" = x""yes; then : ncurses_lib=yes else ncurses_lib=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 $as_echo_n "checking for tgetent in -ltermcap... " >&6; } if test "${ac_cv_lib_termcap_tgetent+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_termcap_tgetent=yes else ac_cv_lib_termcap_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 $as_echo "$ac_cv_lib_termcap_tgetent" >&6; } if test "x$ac_cv_lib_termcap_tgetent" = x""yes; then : termcap_lib=yes else termcap_lib=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 $as_echo_n "checking for tgetent in -ltinfo... " >&6; } if test "${ac_cv_lib_tinfo_tgetent+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltinfo $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tinfo_tgetent=yes else ac_cv_lib_tinfo_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 $as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } if test "x$ac_cv_lib_tinfo_tgetent" = x""yes; then : tinfo_lib=yes else tinfo_lib=no fi if test "$ncurses_lib" = no -a "$termcap_lib" = no -a "$tinfo_lib" = no; then if test "$READLINE" = "yes"; then as_fn_error $? "You need to install the ncurses or termcap library or configure without --enable-readline" "$LINENO" 5 fi fi if test "$tinfo_lib" = yes; then rdllib="-ltinfo" elif test "$ncurses_lib" = yes; then rdllib="-lncurses" elif test "$termcap_lib" = yes; then rdllib="-ltermcap" fi ac_fn_c_check_header_preproc "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" if test "x$ac_cv_header_readline_readline_h" = x""yes; then : readline_h=yes else readline_h=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $rdllib $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = x""yes; then : readline_lib=yes else readline_lib=no fi if test "$readline_h" = no -o "$readline_lib" = no; then if test "$READLINE" = "yes"; then as_fn_error $? "You need to install the GNU readline library or configure without --enable-readline" "$LINENO" 5 fi fi if test "$READLINE" = yes; then READLINE="-lreadline $rdllib" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -lreadline" >&5 $as_echo_n "checking for rl_completion_matches in -lreadline... " >&6; } if test "${ac_cv_lib_readline_rl_completion_matches+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline "-ltermcap" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rl_completion_matches (); int main () { return rl_completion_matches (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_rl_completion_matches=yes else ac_cv_lib_readline_rl_completion_matches=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_completion_matches" >&5 $as_echo "$ac_cv_lib_readline_rl_completion_matches" >&6; } if test "x$ac_cv_lib_readline_rl_completion_matches" = x""yes; then : rlcm=yes else rlcm=no fi if test "$rlcm" = yes; then $as_echo "#define HAVE_READLINE_RLCM 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_append_character in -lreadline" >&5 $as_echo_n "checking for rl_completion_append_character in -lreadline... " >&6; } if test "${ac_cv_lib_readline_rl_completion_append_character+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline "-ltermcap" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rl_completion_append_character (); int main () { return rl_completion_append_character (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_rl_completion_append_character=yes else ac_cv_lib_readline_rl_completion_append_character=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_completion_append_character" >&5 $as_echo "$ac_cv_lib_readline_rl_completion_append_character" >&6; } if test "x$ac_cv_lib_readline_rl_completion_append_character" = x""yes; then : rcac=yes else rcac=no fi if test "$rcac" = yes; then $as_echo "#define HAVE_READLINE_CAC 1" >>confdefs.h fi ac_fn_c_check_header_preproc "$LINENO" "zlib.h" "ac_cv_header_zlib_h" if test "x$ac_cv_header_zlib_h" = x""yes; then : zlib_h=yes else zlib_h=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zlibVersion in -lz" >&5 $as_echo_n "checking for zlibVersion in -lz... " >&6; } if test "${ac_cv_lib_z_zlibVersion+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char zlibVersion (); int main () { return zlibVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_zlibVersion=yes else ac_cv_lib_z_zlibVersion=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_zlibVersion" >&5 $as_echo "$ac_cv_lib_z_zlibVersion" >&6; } if test "x$ac_cv_lib_z_zlibVersion" = x""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 $as_echo "#define HAVE_ZLIB 1" >>confdefs.h else ZLIB="" fi ac_fn_c_check_header_preproc "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" if test "x$ac_cv_header_bzlib_h" = x""yes; then : bzlib_h=yes else bzlib_h=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzBuffToBuffCompress in -lbz2" >&5 $as_echo_n "checking for BZ2_bzBuffToBuffCompress in -lbz2... " >&6; } if test "${ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbz2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char BZ2_bzBuffToBuffCompress (); int main () { return BZ2_bzBuffToBuffCompress (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=yes else ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&5 $as_echo "$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&6; } if test "x$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" = x""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 $as_echo "#define HAVE_BZLIB 1" >>confdefs.h else BZLIB="" fi for ac_func in err errx verr verrx vwarn vwarnx warn warnx realpath lchown do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "glob" "ac_cv_func_glob" if test "x$ac_cv_func_glob" = x""yes; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extended glob routines" >&5 $as_echo_n "checking for extended glob routines... " >&6; } if test "$ac_cv_func_glob" = "yes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # include # ifdef GLOB_ALTDIRFUNC yes # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : $as_echo "#define HAVE_GLOB 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } echo "Your system does not support extended glob, will use the internal routines" fi rm -f conftest* fi if test "$ERMT" != ""; then ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_evp_h" = x""yes; then : evp_h=yes else evp_h=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_set_padding in -lcrypto" >&5 $as_echo_n "checking for EVP_CIPHER_CTX_set_padding in -lcrypto... " >&6; } if test "${ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char EVP_CIPHER_CTX_set_padding (); int main () { return EVP_CIPHER_CTX_set_padding (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=yes else ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&5 $as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&6; } if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" = x""yes; then : crypto_lib=yes else crypto_lib=no fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcrypto") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test -n $STATIC ; then CRYPTO=`$PKG_CONFIG --libs --static libcrypto` else CRYPTO=`$PKG_CONFIG --libs libcrypto` fi else CRYPTO="" fi if test "$evp_h" = no -o "x$CRYPTO" = "x"; then as_fn_error or configure without --enable-ermt "You need to install the OpenSSL library (version 0.9.7a or later)" "$LINENO" 5 fi fi ac_fn_c_check_type "$LINENO" "quad_t" "ac_cv_type_quad_t" "$ac_includes_default" if test "x$ac_cv_type_quad_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define quad_t int64_t _ACEOF fi ac_fn_c_check_type "$LINENO" "u_quad_t" "ac_cv_type_u_quad_t" "$ac_includes_default" if test "x$ac_cv_type_u_quad_t" = x""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, we kill variables containing newlines. # 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. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}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 "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end 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" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} 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}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $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} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 IFS=$as_save_IFS ;; 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent 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 the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. 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=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; 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 || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "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" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; 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 against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then if $AWK 'BEGIN { getline <"/dev/null" }' /dev/null; then ac_cs_awk_getline=: ac_cs_awk_pipe_init= ac_cs_awk_read_file=' while ((getline aline < (F[key])) > 0) print(aline) close(F[key])' ac_cs_awk_pipe_fini= else ac_cs_awk_getline=false ac_cs_awk_pipe_init="print \"cat <<'|#_!!_#|' &&\"" ac_cs_awk_read_file=' print "|#_!!_#|" print "cat " F[key] " &&" '$ac_cs_awk_pipe_init # The final `:' finishes the AND list. ac_cs_awk_pipe_fini='END { print "|#_!!_#|"; print ":" }' fi ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF # Create commands to substitute file output variables. { echo "cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1" && echo 'cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&' && echo "$ac_subst_files" | sed 's/.*/F["&"]="$&"/' && echo "_ACAWK" && echo "_ACEOF" } >conf$$files.sh && . ./conf$$files.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 rm -f conf$$files.sh { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" \$ac_cs_awk_pipe_init } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } if (nfields == 3 && !substed) { key = field[2] if (F[key] != "" && line ~ /^[ ]*@.*@[ ]*$/) { \$ac_cs_awk_read_file next } } print line } \$ac_cs_awk_pipe_fini _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #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. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # 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. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;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&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | if $ac_cs_awk_getline; then $AWK -f "$tmp/subs.awk" else $AWK -f "$tmp/subs.awk" | $SHELL fi >$tmp/out \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # 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 || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi dump-0.4b44/Makefile.in0000644000175000017500000000075507614216430014573 0ustar steliansteliansrcdir= @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 # dump-0.4b44/config.guess0000755000175000017500000011544307614216430015047 0ustar stelianstelian#! /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 . # Please send patches to . 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 ." 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 <$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 /* 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 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 #include 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 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 #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 #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' /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 echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # 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 < # include #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 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 # 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 < 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: dump-0.4b44/compat/0000755000175000017500000000000011574405661014010 5ustar steliansteliandump-0.4b44/compat/lib/0000755000175000017500000000000011574405661014556 5ustar steliansteliandump-0.4b44/compat/lib/minilzo.c0000644000175000017500000020525607642006774016420 0ustar stelianstelian/* 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 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 #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 #endif #include #ifndef __LZO_CONF_H #define __LZO_CONF_H #if !defined(__LZO_IN_MINILZO) # ifndef __LZOCONF_H # include # endif #endif #if defined(__BOUNDS_CHECKING_ON) # include #else # define BOUNDS_CHECKING_OFF_DURING(stmt) stmt # define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) #endif #if !defined(LZO_HAVE_CONFIG_H) # include # include # if !defined(NO_STDLIB_H) # include # endif # define HAVE_MEMCMP # define HAVE_MEMCPY # define HAVE_MEMMOVE # define HAVE_MEMSET #else # include # if defined(HAVE_STDDEF_H) # include # endif # if defined(STDC_HEADERS) # include # include # 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 # endif #endif #include #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 # if 1 && defined(__WATCOMC__) # include __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" "\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 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 #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 *****/ dump-0.4b44/compat/lib/Makefile.in0000644000175000017500000000140007656544013016617 0ustar stelianstelian# $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 # dump-0.4b44/compat/lib/compaterr.c0000644000175000017500000001234607746770332016732 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #include #include #include #include #include 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 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 dump-0.4b44/compat/lib/bylabel.c0000644000175000017500000001303610072266614016332 0ustar stelianstelian/* * mount_by_label.c - aeb * * 1999-02-22 Arkadiusz Mi¶kiewicz * - added Native Language Support * 2000-01-20 James Antill * - Added error message if /proc/partitions cannot be opened * 2000-05-09 Erik Troan * - Added cache for UUID and disk labels * Wed Aug 16 2000 Erik Troan * - Ported to dump/restore */ #include #include #include #include #include #include #include #include #include #include #include #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 */ dump-0.4b44/compat/lib/README.LZO0000644000175000017500000001015707642006774016110 0ustar stelianstelian-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 ============================================================================ miniLZO -- mini subset of the LZO real-time data compression library ============================================================================ Author : Markus Franz Xaver Johannes Oberhumer 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----- dump-0.4b44/compat/lib/system.c0000644000175000017500000000605107641607763016257 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #include #include #include #include #include #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); } dump-0.4b44/compat/lib/README2.LZO0000644000175000017500000000077707642006774016201 0ustar stelianstelianThe 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, , http://www.oberhumer.com/ dump-0.4b44/compat/lib/compatglob.c0000644000175000017500000004625707746770332017075 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #ifndef HAVE_GLOB #include #include #include #include #include #include #include #include #include #include #include #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 */ dump-0.4b44/compat/lib/rmtflags.c0000644000175000017500000001102307641607763016545 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #include #include #include #include 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; } dump-0.4b44/compat/include/0000755000175000017500000000000011574405661015433 5ustar steliansteliandump-0.4b44/compat/include/bylabel.h0000644000175000017500000000206410072266614017213 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * 1999-02-22 Arkadiusz Mi¶kiewicz * - added Native Language Support * 2000-01-20 James Antill * - Added error message if /proc/partitions cannot be opened * 2000-05-09 Erik Troan * - Added cache for UUID and disk labels * Wed Aug 16 2000 Erik Troan * - Ported to dump/restore * Stelian Pop - Alcôve , 2000-2002 * * $Id: bylabel.h,v 1.6 2004/07/05 15:02:36 stelian Exp $ */ #ifndef _BYLABEL_H_ #define _BYLABEL_H_ #include #ifdef HAVE_BLKID #include 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_ */ dump-0.4b44/compat/include/lzoconf.h0000644000175000017500000003540607642006773017270 0ustar stelianstelian/* 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 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 #endif #include #ifdef __cplusplus extern "C" { #endif /*********************************************************************** // LZO requires a conforming ************************************************************************/ #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 # 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 */ dump-0.4b44/compat/include/compaterr.h0000644000175000017500000000566007641607762017615 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #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 #endif #include #include #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_ */ dump-0.4b44/compat/include/Makefile.in0000644000175000017500000000056207614216434017501 0ustar stelianstelian# $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 # dump-0.4b44/compat/include/bsdcompat.h0000644000175000017500000001410010235441365017546 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * * $Id: bsdcompat.h,v 1.24 2005/05/02 15:10:45 stelian Exp $ */ #include #include #include #include #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; __u16 di_extraisize; __u16 di_pad2; }; #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 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 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] dump-0.4b44/compat/include/rmtflags.h0000644000175000017500000000400107641607762017424 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 dump-0.4b44/compat/include/system.h0000644000175000017500000000400207641607762017132 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 dump-0.4b44/compat/include/compatglob.h0000644000175000017500000000761307641607762017750 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #ifdef HAVE_GLOB #include #else #include 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_ */ dump-0.4b44/compat/include/darwin.h0000644000175000017500000000666107746770373017114 0ustar stelianstelian/* * */ #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 dump-0.4b44/compat/include/pathnames.h0000644000175000017500000000435207746770332017576 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #ifdef __linux__ #include /* 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 */ dump-0.4b44/compat/include/minilzo.h0000644000175000017500000000607107642006774017274 0ustar stelianstelian/* 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 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 */ dump-0.4b44/compat/include/compatlfs.h0000644000175000017500000000460610263166024017571 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Stelian Pop - Alcôve , 2000-2002 * * $Id: compatlfs.h,v 1.6 2005/07/07 08:47:16 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 #ifdef USE_LFS #define _LARGEFILE64_SOURCE #define OPEN open64 #define FOPEN fopen64 #define LSEEK lseek64 #define STAT stat64 #define FSTAT fstat64 #define LSTAT lstat64 #define FTRUNCATE ftruncate64 #define OFF_T __off64_t #define MKSTEMP mkstemp64 #define FTELL ftello64 #else #define OPEN open #define FOPEN fopen #define LSEEK lseek #define STAT stat #define FSTAT fstat #define LSTAT lstat #define FTRUNCATE ftruncate #define OFF_T off_t #define MKSTEMP mkstemp #define FTELL ftell #endif /* USE_LFS */ #endif /* !_COMPATLFS_H_ */ dump-0.4b44/compat/include/protocols/0000755000175000017500000000000011574405661017457 5ustar steliansteliandump-0.4b44/compat/include/protocols/dumprestore.h0000644000175000017500000001405510235441366022201 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * * $Id: dumprestore.h,v 1.24 2005/05/02 15:10:46 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 /* * 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_XATTR 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 }; /* used for EA on tape */ #define EXT2_GOOD_OLD_INODE_SIZE 128 #define EXT2_XATTR_MAGIC 0xEA020000 /* block EA */ #define EXT2_XATTR_MAGIC2 0xEA020001 /* in inode EA */ #endif /* !_DUMPRESTORE_H_ */ dump-0.4b44/configure.in0000644000175000017500000003605311566415627015051 0ustar stelianstelianAC_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="" echo "Not compiling ermt" else if test "$RMTDIR" = "" then AC_MSG_ERROR(ermt requires --enable-rmt) fi ERMT="ermt" echo "Compiling ermt" fi , ERMT="" echo "Not compiling ermt by default" ) AC_SUBST(ERMT) 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="yes" AC_DEFINE([HAVE_READLINE],1,[Define if you want to include readline support.]) echo "Including readline support" fi , READLINE="yes" AC_DEFINE([HAVE_READLINE],1,[Define if you want to include readline support.]) echo "Including readline support by default" ) 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 Handle --enable-transselinux dnl AC_ARG_ENABLE([transselinux], [ --enable-transselinux restore can translate SELinux EAs (default is YES)], if test "$enableval" = "yes" then LTRANSSELINUX="-lselinux" CCTRANSSELINUX="-DTRANSSELINUX" echo "restore can translate SELinux EAs" else LTRANSSELINUX="" CCTRANSSELINUX="" echo "restore can not translate SELinux EAs" fi , LTRANSSELINUX="-lselinux" CCTRANSSELINUX="-DTRANSSELINUX" echo "restore can translate SELinux EAs by default" ) AC_SUBST(LTRANSSELINUX) AC_SUBST(CCTRANSSELINUX) 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], [-]) PKG_CHECK_MODULES(EXT2FS, [ext2fs]) if test -n "$STATIC" ; then EXT2FS_LIBS=`$PKG_CONFIG --libs --static ext2fs` fi if test "$ext2fs_h" = no -o "x$EXT2FS_LIBS" = "x"; then AC_MSG_ERROR(You need to install the Ext2fs libraries from the E2fsprogs distribution first - hint: make install-libs) fi dnl dnl Check for ext2fs_read_inode_full dnl AC_CHECK_LIB(ext2fs, ext2fs_read_inode_full, [rif=yes], [rif=no], [-lcom_err]) if test "$rif" = yes; then AC_DEFINE([HAVE_EXT2FS_READ_INODE_FULL],1,[Define this if your ext2fs libs have the ext2fs_read_inode_full function.]) 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 #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include ], [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 #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include ], [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], [-]) PKG_CHECK_EXISTS([blkid], [ if test -n $STATIC ; then BLKID=`$PKG_CONFIG --libs --static blkid` else BLKID=`$PKG_CONFIG --libs blkid` fi if test "$blkid_h" = yes ; then AC_DEFINE([HAVE_BLKID],1,[Define this if you have the blkid library.]) fi ],[BLKID=""]) AC_SUBST(BLKID) dnl dnl Check for ncurses or termcap libraries dnl AC_CHECK_LIB(ncurses, tgetent, [ncurses_lib=yes], [ncurses_lib=no]) AC_CHECK_LIB(termcap, tgetent, [termcap_lib=yes], [termcap_lib=no]) AC_CHECK_LIB(tinfo, tgetent, [tinfo_lib=yes], [tinfo_lib=no]) if test "$ncurses_lib" = no -a "$termcap_lib" = no -a "$tinfo_lib" = no; then if test "$READLINE" = "yes"; then AC_MSG_ERROR(You need to install the ncurses or termcap library or configure without --enable-readline) fi fi if test "$tinfo_lib" = yes; then rdllib="-ltinfo" elif test "$ncurses_lib" = yes; then rdllib="-lncurses" elif test "$termcap_lib" = yes; then rdllib="-ltermcap" 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], $rdllib) if test "$readline_h" = no -o "$readline_lib" = no; then if test "$READLINE" = "yes"; then AC_MSG_ERROR(You need to install the GNU readline library or configure without --enable-readline) fi fi if test "$READLINE" = yes; then READLINE="-lreadline $rdllib" fi AC_SUBST(READLINE) 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, zlibVersion, [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 # 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]) PKG_CHECK_EXISTS([libcrypto], [ if test -n $STATIC ; then CRYPTO=`$PKG_CONFIG --libs --static libcrypto` else CRYPTO=`$PKG_CONFIG --libs libcrypto` fi ],[CRYPTO=""]) if test "$evp_h" = no -o "x$CRYPTO" = "x"; then AC_MSG_ERROR(You need to install the OpenSSL library (version 0.9.7a or later), or configure without --enable-ermt) fi fi AC_SUBST(CRYPTO) 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) dump-0.4b44/REPORTING-BUGS0000644000175000017500000000470207421244236014555 0ustar stelianstelianCongratulations! 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 dump-0.4b44/testing/0000755000175000017500000000000011574405662014203 5ustar steliansteliandump-0.4b44/testing/scripts/0000755000175000017500000000000011574405662015672 5ustar steliansteliandump-0.4b44/testing/scripts/quick-regression.sh0000644000175000017500000002131611574405341021515 0ustar stelianstelian#!/bin/bash # # 5-second regression test for dump/verify/restore. It's not intended to be # an exhaustive regression test, just a quick way to verify that you haven't # introduced any errors when changing code. # # N.B., this only verifies that THIS build of dump(8) and THIS build of # restore(8) will play well together. It does not guarantee that these systems # are compatible with released versions of the software! For that we need # to keep images of known-good partitions and dump files. # # Author: Bear Giles (bgiles@coyotesong.com) # License granted to dump project under non-advertising BSD license. # # # Create 10 MB virtual partition. # # mkvirtpart(filename, loop device) # mkvirtpart() { FILENAME=$1 LOOPDEV=$2 if [ "$#" -ne "2" ]; then /bin/echo "usage: mkvrtpart FILENAME LOOPDEV" return 1 fi # create 10M sparse file /usr/bin/truncate -s 10M $FILENAME if [ "$?" -ne "0" ]; then /bin/echo "unable to create partition image." return 1 fi # mount and format it /sbin/losetup $LOOPDEV $FILENAME if [ "$?" -ne "0" ]; then /bin/echo "setting up loop device failed." return 1 fi /sbin/mkfs -text4 $LOOPDEV if [ "$?" -ne "0" ]; then /bin/echo "formating test partition failed." /sbin/losetup -d $LOOPDEV return 1 fi /sbin/losetup -d $LOOPDEV if [ "$?" -ne "0" ]; then /bin/echo "tearing down loop device failed." return 1 fi } # # Populate test filesystem # # mktestfs(root) mktestfs() { ROOT=$1 if [ "$#" -ne "1" ]; then /bin/echo "usage: mktestfs ROOT" return 1 fi if [ "$ROOT" == "" -o "$ROOT" == "/" ]; then /bin/echo "cowardly refusing to stomp on root." return 1 fi /usr/bin/install -d $ROOT # create typical file /usr/bin/touch $ROOT/perm644 /bin/chmod 0644 $ROOT/perm644 # create typical executable /usr/bin/touch $ROOT/perm755 /bin/chmod 0755 $ROOT/perm755 # create multiple symlinks /usr/bin/touch $ROOT/symlink /bin/ln $ROOT/symlink $ROOT/symlink1 /bin/ln $ROOT/symlink $ROOT/symlink2 # create hard links /usr/bin/touch $ROOT/hardlink /bin/ln $ROOT/hardlink $ROOT/hardlink1 /bin/ln $ROOT/hardlink $ROOT/hardlink2 # create block device /bin/mknod $ROOT/block b 10 20 # create character device /bin/mknod $ROOT/char c 11 21 # create FIFO /bin/mknod $ROOT/pipe p # make sparse device #/usr/bin/truncate -s 500k $ROOT/sparse # populate some files /bin/mkdir $ROOT/man1 /bin/cp -rp /usr/share/man/man1/* $ROOT/man1 } # # Single test cycle # dump_verify_restore() { if [ "$#" -lt "5" ]; then /bin/echo "usage: dump_verify_restore SRC_LOOPDEV SRC_MOUNTPOINT DEST_LOOPDEV DEST_MOUNTPOINT DUMPFILE ..." return 1 fi SRC_LOOPDEV=$1 SRC_MOUNTPOINT=$2 DEST_LOOPDEV=$3 DEST_MOUNTPOINT=$4 DUMPFILE=$5 shift; shift; shift; shift; shift /sbin/losetup $SRC_LOOPDEV $SRC_FILENAME if [ "$?" -ne "0" ]; then /bin/echo "setting up loop device failed." return 1 fi # we have to mount partition for verify to work even if we dump the # underlying partition. /bin/mount $SRC_LOOPDEV $SRC_MOUNTPOINT if [ "$?" -ne "0" ]; then /bin/echo "mounting source partition failed." /sbin/losetup -d $SRC_LOOPDEV return 1; fi # dump the test partition ../dump/dump -0 $@ -f $DUMPFILE $SRC_LOOPDEV if [ "$?" -ne "0" ]; then echo "dump failed, error code $?" /bin/rm $DUMPFILE /bin/umount $SRC_MOUNTPOINT /sbin/losetup -d $SRC_LOOPDEV return 1 fi # verify ../restore/restore -C -f $DUMPFILE if [ "$?" -ne "0" ]; then echo "verification failed, error code $?" /bin/rm $DUMPFILE /bin/umount $SRC_MOUNTPOINT /sbin/losetup -d $SRC_LOOPDEV return 1 fi # restore fs, compare to orginal one # I can't do that yet since restore will only restore to the current directory. # this makes sense for a number of reasons it difficult to test our newly # compiled code. # ../../restore/restore -r ... # tear everything down /bin/umount $SRC_MOUNTPOINT if [ "$?" -ne "0" ]; then /bin/echo "unmounting test partition failed." return 1 fi /sbin/losetup -d $SRC_LOOPDEV if [ "$?" -ne "0" ]; then /bin/echo "tearing down loop device failed." return 1 fi } # # set up source partition. # setup_src_partition() { SRC_FILENAME=$1 SRC_LOOPDEV=$2 SRC_MOUNTPOINT=$3 if [ "$#" -ne "3" ]; then /bin/echo "usage: setup_src_partition SRC_FILENAME SRC_LOOPDEV SRC_MOUNTPOINT" return 1 fi mkvirtpart $SRC_FILENAME $SRC_LOOPDEV if [ $? -ne 0 ]; then /bin/echo "creating source test partition failed." return 1 fi # mount it /sbin/losetup $SRC_LOOPDEV $SRC_FILENAME if [ "$?" -ne "0" ]; then /bin/echo "setting up loop device failed." return 1 fi /bin/mount $SRC_LOOPDEV $SRC_MOUNTPOINT if [ "$?" -ne "0" ]; then /bin/echo "mounting test partition failed." return 1 fi mktestfs $SRC_MOUNTPOINT if [ "$?" -ne "0" ]; then return 1 fi /bin/umount $SRC_LOOPDEV if [ "$?" -ne "0" ]; then /bin/echo "unmounting test partition failed." return 1 fi /sbin/losetup -d $SRC_LOOPDEV if [ "$?" -ne "0" ]; then /bin/echo "tearing down loop device failed." return 1 fi return 0 } # # clean up temporary files. We want to be extremely careful here that # we don't accidently do a 'rm -rf' on / # cleanup() { if [ "$#" -ne "6" ]; then /bin/echo "usage: cleanup SRC_FILENAME SRC_MOUNTPOINT DEST_FILENAME DEST_MOUNTPOINT BASEDIR DUMPFILE" return 1 fi SRC_FILENAME=$1 SRC_MOUNTPOINT=$2 DEST_FILENAME=$3 DEST_MOUNTPOINT=$4 BASEDIR=$5 DUMPFILE=$6 if [ "$BASEDIR" == "" -o "$BASEDIR" == "/" ]; then /bin/echo "cowardly refusing to delete root." return 1 fi # we don't do rm -r since we don't want to delete # anything we didn't create. /bin/rm -f $SRC_FILENAME /bin/rmdir $SRC_MOUNTPOINT /bin/rm -f $DEST_FILENAME /bin/rmdir $DEST_MOUNTPOINT /bin/rm -f $DUMPFILE /bin/rmdir $BASEDIR return 0 } ############################################### # # the actual script # BASEDIR=`/bin/mktemp -d` SRC_FILENAME=$BASEDIR/dump-test-src.img SRC_LOOPDEV=/dev/loop6 SRC_MOUNTPOINT=$BASEDIR/src DEST_FILENAME=$BASEDIR/dump-test-dst.img DEST_LOOPDEV=/dev/loop7 DEST_MOUNTPOINT=$BASEDIR/dest DUMPFILE=$BASEDIR/dump-test.dump /bin/echo BASEDIR = $BASEDIR /usr/bin/install -d $BASEDIR /usr/bin/install -d $SRC_MOUNTPOINT /usr/bin/install -d $DEST_MOUNTPOINT # Setup source partition setup_src_partition $SRC_FILENAME $SRC_LOOPDEV $SRC_MOUNTPOINT if [ $? -ne 0 ]; then /bin/echo "creating source test partition failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi # create dest partition (for restores) mkvirtpart $DEST_FILENAME $DEST_LOOPDEV if [ $? -ne 0 ]; then /bin/echo "creating destination test partition failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi echo echo "testing basic dump/restore" dump_verify_restore $SRC_LOOPDEV $SRC_MOUNTPOINT $DEST_LOOPDEV $DEST_MOUNTPOINT $DUMPFILE if [ $? -ne 0 ]; then /bin/echo "dump cycle failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi echo echo "testing compressed dump/restore (lzo)..." dump_verify_restore $SRC_LOOPDEV $SRC_MOUNTPOINT $DEST_LOOPDEV $DEST_MOUNTPOINT $DUMPFILE -y if [ $? -ne 0 ]; then /bin/echo "dump cycle failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi echo echo "testing compressed dump/restore (zlib)..." dump_verify_restore $SRC_LOOPDEV $SRC_MOUNTPOINT $DEST_LOOPDEV $DEST_MOUNTPOINT $DUMPFILE -z2 if [ $? -ne 0 ]; then /bin/echo "dump cycle failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi echo echo "testing compressed dump/restore (bzlib)..." dump_verify_restore $SRC_LOOPDEV $SRC_MOUNTPOINT $DEST_LOOPDEV $DEST_MOUNTPOINT $DUMPFILE -j2 if [ $? -ne 0 ]; then /bin/echo "dump cycle failed." cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE exit 1 fi cleanup $SRC_FILENAME $SRC_MOUNTPOINT $DEST_FILENAME $DEST_MOUNTPOINT $BASEDIR $DUMPFILE /bin/echo "#" /bin/echo "# success!" /bin/echo "#" exit 0 dump-0.4b44/README0000644000175000017500000000054107000363230013365 0ustar stelianstelian$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. dump-0.4b44/common/0000755000175000017500000000000011574405661014015 5ustar steliansteliandump-0.4b44/common/dumprmt.c0000644000175000017500000002724711404415665015662 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.30 2010/06/11 11:19:17 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #ifdef __linux__ #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #elif defined sunos #include #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __STDC__ #include #include #include #endif #ifdef __linux__ #include #endif #include #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(stderr, "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); if (write(tormtape, line, strlen(line)) != strlen(line)) return -1; if (write(tormtape, buf, count) != count) return -1; 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; } dump-0.4b44/common/Makefile.in0000644000175000017500000000115407656544013016064 0ustar stelianstelian# $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 # dump-0.4b44/restore/0000755000175000017500000000000011574405662014211 5ustar steliansteliandump-0.4b44/restore/utilities.c0000644000175000017500000003736511404415665016402 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.30 2010/06/11 11:19:17 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include #include #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #else /* __linux__ */ #ifdef sunos #include #include #include #else #include #include #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) { int i; for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != 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 (lgetflags (existing, &s) != -1 && lsetflags (existing, 0) != -1) { ret = link(existing, new); lsetflags(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) { int i; for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) { fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries[i])); break; } } } 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 #else #include #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) { if (fchdir(wdfd) < 0) warn("fchdir"); 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)lsetflags(oFile, flags); utimes(oFile, timep); free(pp); return err; } #endif /* DUMP_MACOSX */ int lgetflags(const char *path, unsigned long *flags) { int err; struct STAT sb; err = LSTAT(path, &sb); if (err < 0) return err; if (S_ISLNK(sb.st_mode) || S_ISFIFO(sb.st_mode)) { // no way to get/set flags on a symlink *flags = 0; return 0; } else return fgetflags(path, flags); } int lsetflags(const char *path, unsigned long flags) { int err; struct STAT sb; err = LSTAT(path, &sb); if (err < 0) return err; if (S_ISLNK(sb.st_mode) || S_ISFIFO(sb.st_mode)) { // no way to get/set flags on a symlink return 0; } else return fsetflags(path, flags); } dump-0.4b44/restore/interactive.c0000644000175000017500000005676407746770334016723 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #else /* __linux__ */ #ifdef sunos #include #include #else #include #include #endif #endif /* __linux__ */ #include #include #include #include #include #include #include #include #ifdef __linux__ #include #endif #if defined(__linux__) || defined(sunos) extern char * __progname; #endif #include "restore.h" #include "extern.h" #if HAVE_READLINE #include #include 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 #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 */ dump-0.4b44/restore/dirs.c0000644000175000017500000005631011404415665015317 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.36 2010/06/11 11:19:17 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #else /* __linux__ */ #ifdef sunos #include #include #else #include #include #endif #endif /* __linux__ */ #include #include #include #include #include #include #include #ifdef __linux__ #include #else #ifdef sunos #include #else #include #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; char xattr; }; /* * 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, OFF_T)); static void savemodeinfo __P((dump_ino_t, struct new_bsd_inode *, char *)); #else static struct inotab *allocinotab __P((dump_ino_t, OFF_T)); static void savemodeinfo __P((dump_ino_t, struct dinode *, char *)); #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; char xattr[XATTR_MAXSIZE]; int xattr_found = 0; dump_ino_t ino; 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 = ""; curfile.action = USING; ino = curfile.ino; if (curfile.dip == NULL || (curfile.dip->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; } memcpy(&ip, curfile.dip, sizeof(ip)); itp = allocinotab(ino, seekpt); getfile(putdir, xtrnull); xattr_found = 0; while (spcl.c_flags & DR_EXTATTRIBUTES) { switch (spcl.c_extattributes) { case EXT_MACOSFNDRINFO: msg("MacOSX attributes not supported, skipping\n"); skipfile(); break; case EXT_MACOSRESFORK: msg("MacOSX attributes not supported, skipping\n"); skipfile(); break; case EXT_XATTR: if (readxattr(xattr) == GOOD) xattr_found = 1; break; } } if (xattr_found) savemodeinfo(ino, &ip, xattr); else savemodeinfo(ino, &ip, NULL); 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, DIRBLKSIZ, 1, df) != 1 ) 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 (;;) { char xattr[XATTR_MAXSIZE]; if (fread((char *)&node, sizeof(struct modeinfo), 1, mf) != 1) { if (feof(mf)) break; err(1, "fread"); } if (node.xattr) { if (fread(xattr, XATTR_MAXSIZE, 1, mf) != 1) { if (feof(mf)) break; err(1, "fread"); } } 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); if (chown(cp, node.uid, node.gid) < 0) warn("chown"); (void) chmod(cp, node.mode); utimes(cp, node.timep); if (node.xattr) xattr_extract(cp, xattr); ep->e_flags &= ~NEW; if (node.flags) #ifdef __linux__ (void) lsetflags(cp, node.flags); #else #ifdef sunos #else (void) chflags(cp, node.flags); #endif #endif } } if (ferror(mf)) panic("error setting directory modes\n"); (void) fclose(mf); } /* * In restore -C mode, tests the attributes for all directories */ void comparedirmodes(void) { FILE *mf; struct modeinfo node; struct entry *ep; char *cp; Vprintf(stdout, "Compare directories modes, owner, attributes.\n"); 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 (;;) { char xattr[XATTR_MAXSIZE]; if (fread((char *)&node, sizeof(struct modeinfo), 1, mf) != 1) { if (feof(mf)) break; err(1, "fread"); } if (node.xattr) { if (fread(xattr, XATTR_MAXSIZE, 1, mf) != 1) { if (feof(mf)) break; err(1, "fread"); } } ep = lookupino(node.ino); if (ep == NULL) { panic("cannot find directory inode %d\n", node.ino); } else { struct STAT sb; unsigned long newflags; cp = myname(ep); if (LSTAT(cp, &sb) < 0) { warn("unable to stat %s", cp); do_compare_error; continue; } Vprintf(stdout, "comparing directory %s\n", cp); if (sb.st_mode != node.mode) { fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n", cp, node.mode & 07777, sb.st_mode & 07777); do_compare_error; } if (sb.st_uid != node.uid) { fprintf(stderr, "%s: uid changed from %d to %d.\n", cp, node.uid, sb.st_uid); do_compare_error; } if (sb.st_gid != node.gid) { fprintf(stderr, "%s: gid changed from %d to %d.\n", cp, node.gid, sb.st_gid); do_compare_error; } #ifdef __linux__ if (lgetflags(cp, &newflags) < 0) { if (node.flags != 0) { warn("%s: lgetflags failed", cp); do_compare_error; } } else { if (newflags != node.flags) { fprintf(stderr, "%s: flags changed from 0x%08x to 0x%08lx.\n", cp, node.flags, newflags); do_compare_error; } } #endif if (node.xattr) { if (xattr_compare(cp, xattr) == FAIL) do_compare_error; } else { if (xattr_compare(cp, NULL) == FAIL) do_compare_error; } 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, OFF_T seekpt) #else allocinotab(dump_ino_t ino, OFF_T seekpt) #endif { struct inotab *itp; 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; return itp; } static void #if defined(__linux__) || defined(sunos) savemodeinfo(dump_ino_t ino, struct new_bsd_inode *dip, char *xattr) { #else savemodeinfo(dump_ino_t ino, struct dinode *dip, char *xattr) { #endif struct modeinfo node; if (mf == NULL) return; 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; node.xattr = xattr ? 1 : 0; if ( fwrite((char *)&node, sizeof(struct modeinfo), 1, mf) != 1 ) err(1,"cannot write to file %s", modefile); if (xattr) if ( fwrite(xattr, XATTR_MAXSIZE, 1, mf) != 1 ) err(1,"cannot write to file %s", modefile); } /* * 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); } dump-0.4b44/restore/Makefile.in0000644000175000017500000000265410567374502016264 0ustar stelianstelian# $Id: Makefile.in,v 1.14 2007/02/22 20:12:50 stelian Exp $ top_srcdir= @top_srcdir@ srcdir= @srcdir@ top_builddir= .. @MCONFIG@ INC= -I$(top_srcdir)/restore ALL_CFLAGS= @CPPFLAGS@ @CFLAGS@ @CCOPTS@ @CCTRANSSELINUX@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @RESTOREDEBUG@ ALL_LDFLAGS= @LDFLAGS@ @LDOPTS@ @STATIC@ LIBS= $(GLIBS) -le2p @READLINE@ @ZLIB@ @BZLIB@ @LTRANSSELINUX@ 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 xattr.c OBJS= dirs.o interactive.o main.o restore.o symtab.o tape.o \ utilities.o xattr.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 # dump-0.4b44/restore/symtab.c0000644000175000017500000004405011404415665015653 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.28 2010/06/11 11:19:17 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 #include #include #include #ifdef __linux__ #include #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #else /* __linux__ */ #ifdef sunos #include #include #else #include #endif #endif /* __linux__ */ #include #include #include #include #include #include #include #ifdef __linux__ #include #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 *)); static int dir_hash __P((char *)); /* * Returns a hash given a file name */ static int dir_hash(char *name) { unsigned long hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; int len = strlen(name); while (len--) { unsigned long hash = hash1 + (hash0 ^ (*name++ * 7152373)); if (hash & 0x80000000) hash -= 0x7fffffff; hash1 = hash0; hash0 = hash; } return hash0 % dirhash_size; } /* * 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, *oldep; char *np, *cp; char buf[MAXPATHLEN]; ep = lookupino(ROOTINO); cp = name; if (*cp == '.') ++cp; if (*cp == '/') ++cp; if (*cp == '\0') return ep; while (ep != NULL) { for (np = buf; *cp != '/' && *cp != '\0' && np < &buf[sizeof(buf)]; ) *np++ = *cp++; if (np == &buf[sizeof(buf)]) break; *np = '\0'; oldep = ep; if (ep->e_entries != NULL) { ep = ep->e_entries[dir_hash(buf)]; for ( ; ep != NULL; ep = ep->e_sibling) if (strcmp(ep->e_name, buf) == 0) break; /* search all hash lists for renamed inodes */ if (ep == NULL) { int j; for (j = 0; j < dirhash_size; j++) { ep = oldep->e_entries[j]; for ( ; ep != NULL; ep = ep->e_sibling) if (strcmp(ep->e_name, buf) == 0) break; if (ep != NULL) 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; if (type & NODE) { np->e_entries = calloc(1, dirhash_size * sizeof(struct entry *)); if (np->e_entries == NULL) panic("unable to allocate directory entries\n"); } 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[dir_hash(np->e_name)]; ep->e_entries[dir_hash(np->e_name)] = 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) { int i; for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != 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[dir_hash(ep->e_name)]; np->e_entries[dir_hash(ep->e_name)] = 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 = ep->e_parent; struct entry *entry = np->e_entries[dir_hash(ep->e_name)]; if (entry == ep) { np->e_entries[dir_hash(ep->e_name)] = ep->e_sibling; } else { for (np = entry; np != NULL; np = np->e_sibling) { if (np->e_sibling == ep) { np->e_sibling = ep->e_sibling; break; } } if (np == NULL) { /* search all hash lists for renamed inodes */ int j; for (j = 0; j < dirhash_size; j++) { np = ep->e_parent; entry = np->e_entries[j]; if (entry == ep) { np->e_entries[j] = ep->e_sibling; return; } else { for (np = entry; np != NULL; np = np->e_sibling) { if (np->e_sibling == ep) { np->e_sibling = ep->e_sibling; return; } } } } 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 hashsize; 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, hashoff = 0; FILE *fd; struct symtableheader hdr; struct entry **temphash; 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, (int)allocsize(ep->e_namlen), sizeof(char), fd); } } /* * Write out e_entries tables */ temphash = calloc(1, dirhash_size * sizeof(struct entry *)); if (temphash == NULL) errx(1, "no memory for saving hashtable"); for (i = WINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { if (ep->e_entries != NULL) { int j; memcpy(temphash, ep->e_entries, dirhash_size * sizeof(struct entry *)); for (j = 0; j < dirhash_size; j++) { if (temphash[j]) temphash[j] = (struct entry *)ep->e_entries[j]->e_index; } fwrite(temphash, sizeof(struct entry *), dirhash_size, fd); } } } free(temphash); /* * Convert pointers to indexes, and output */ tep = &temp; stroff = 0; hashoff = 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 **)hashoff; hashoff += dirhash_size * sizeof(struct entry *); } 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.hashsize = hashoff; 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; } if (hdr.maxino > maxino) { 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 + hdr.hashsize - 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_type == NODE) { int i; ep->e_entries = (struct entry **)(base + hdr.stringsize + (long)ep->e_entries); for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i]) ep->e_entries[i] = &baseep[(long)ep->e_entries[i]]; } } else ep->e_entries = NULL; if (ep->e_next != NULL) ep->e_next = &baseep[(long)ep->e_next]; } } dump-0.4b44/restore/restore.h0000644000175000017500000001713510567374502016053 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * * $Id: restore.h,v 1.34 2007/02/22 20:12:50 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 #include /* * 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 */ extern int wdfd; /* original working directory */ extern int dirhash_size; /* size of the directory hash table */ /* * 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 */ #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ extern int transselinuxflag; extern char *transselinuxarg; #endif #define do_compare_error \ if (++compare_errors >= Lflag && Lflag) { \ printf("Compare errors limit reached, exiting...\n"); \ exit(2); \ } #define XATTR_MAXSIZE 4096 dump-0.4b44/restore/restore.8.in0000644000175000017500000005316611216405764016401 0ustar stelianstelian.\" 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.35 2009/06/18 09:42:12 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\-cdHklMvVy\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\-acdhHklmMNouvVy\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\-acdhHklmMNuvVy\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\-cdHklMNuvVy\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\-cdHklMNuvVy\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\-cdhHklMNuvVy\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\-adchHklmMNouvVy\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] .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 .BI \-H " hash_size" Use a hashtable having the specified number of entries for storing the directories entries instead of a linked list. This hashtable will considerably speed up inode lookups (visible especially in interactive mode when adding/removing files from the restore list), but at the price of much more memory usage. The default value is 1, meaning no hashtable is used. .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 001, 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. .PP (The 4.3BSD option syntax is implemented for backward compatibility but is not documented here.) .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 : 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 , got 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 .TP .I Tape read error while skipping over inode .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 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 . 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 . .SH AVAILABILITY The .B dump/restore backup suite is available from .SH HISTORY The .B restore command appeared in 4.2BSD. dump-0.4b44/restore/xattr.c0000644000175000017500000004345611404415665015527 0ustar stelianstelian/* * Copyright (c) 1999-2004 * Stelian Pop , 1999-2004 * * 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: xattr.c,v 1.7 2010/06/11 11:19:17 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ # include #endif #include "restore.h" #include "extern.h" #include "pathnames.h" /* * Data structures below taken from the kernel */ /* Maximum number of references to one attribute block */ #define EXT2_XATTR_REFCOUNT_MAX 1024 /* Name indexes */ #define EXT2_XATTR_INDEX_MAX 10 #define EXT2_XATTR_INDEX_USER 1 #define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS 2 #define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT 3 #define EXT2_XATTR_INDEX_TRUSTED 4 #define EXT2_XATTR_INDEX_LUSTRE 5 #define EXT2_XATTR_INDEX_SECURITY 6 struct ext2_xattr_header { u_int32_t h_magic; /* magic number for identification */ u_int32_t h_refcount; /* reference count */ u_int32_t h_blocks; /* number of disk blocks used */ u_int32_t h_hash; /* hash value of all attributes */ u_int32_t h_reserved[4]; /* zero right now */ }; struct ext3_xattr_ibody_header { u_int32_t h_magic; /* magic number for identification */ }; struct ext2_xattr_entry { u_char e_name_len; /* length of name */ u_char e_name_index; /* attribute name index */ u_int16_t e_value_offs; /* offset in disk block of value */ u_int32_t e_value_block; /* disk block attribute is stored on (n/i) */ u_int32_t e_value_size; /* size of attribute value */ u_int32_t e_hash; /* hash value of name and value */ char e_name[0]; /* attribute name */ }; #define EXT2_XATTR_PAD_BITS 2 #define EXT2_XATTR_PAD (1<e_name_len)) ) #define EXT3_XATTR_SIZE(size) \ (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND) #define HDR(buffer) ((struct ext2_xattr_header *)(buffer)) #define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr)) #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) #define BFIRST(buffer) ENTRY(HDR(buffer)+1) #define IFIRST(buffer) ENTRY(((struct ext3_xattr_ibody_header *)(buffer))+1) #define FIRST_ENTRY(buffer) \ ((HDR(buffer)->h_magic == EXT2_XATTR_MAGIC2) ? \ IFIRST(buffer) : \ BFIRST(buffer)) /* * On-block xattr value offsets start at the beginning of the block, but * on-inode xattr value offsets start after the initial header * (ext3_xattr_ibody_header). */ #define VALUE_OFFSET(buffer, entry) \ (((HDR(buffer)->h_magic == EXT2_XATTR_MAGIC2) ? \ (entry)->e_value_offs + sizeof(struct ext3_xattr_ibody_header) : \ (entry)->e_value_offs)) /* * xattr syscalls do not exist yet in libc, get our own copy here, * taken from libattr. */ #if defined (__i386__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 227 # define __NR_lgetxattr 230 # define __NR_llistxattr 233 #elif defined (__sparc__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 170 # define __NR_lgetxattr 173 # define __NR_llistxattr 179 #elif defined (__ia64__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 1218 # define __NR_lgetxattr 1221 # define __NR_llistxattr 1224 #elif defined (__powerpc__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 210 # define __NR_lgetxattr 213 # define __NR_llistxattr 216 #elif defined (__x86_64__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 189 # define __NR_lgetxattr 192 # define __NR_llistxattr 195 #elif defined (__s390__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 225 # define __NR_lgetxattr 228 # define __NR_llistxattr 231 #elif defined (__arm__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_SYSCALL_BASE 0x900000 # define __NR_lsetxattr (__NR_SYSCALL_BASE+227) # define __NR_lgetxattr (__NR_SYSCALL_BASE+230) # define __NR_llistxattr (__NR_SYSCALL_BASE+233) #elif defined (__mips64__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_Linux 5000 # define __NR_lsetxattr (__NR_Linux + 218) # define __NR_lgetxattr (__NR_Linux + 221) # define __NR_llistxattr (__NR_Linux + 224) #elif defined (__mips__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_Linux 4000 # define __NR_lsetxattr (__NR_Linux + 225) # define __NR_lgetxattr (__NR_Linux + 228) # define __NR_llistxattr (__NR_Linux + 231) #elif defined (__alpha__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 383 # define __NR_lgetxattr 386 # define __NR_llistxattr 389 #elif defined (__mc68000__) # define HAVE_XATTR_SYSCALLS 1 # define __NR_lsetxattr 224 # define __NR_lgetxattr 227 # define __NR_llistxattr 230 #else # warning "Extended attribute syscalls undefined for this architecture" # define HAVE_XATTR_SYSCALLS 0 #endif #if HAVE_XATTR_SYSCALLS # define SYSCALL(args...) syscall(args) #else # define SYSCALL(args...) ( errno = ENOSYS, -1 ) #endif static int lsetxattr __P((const char *, const char *, void *, size_t, int)); static ssize_t lgetxattr __P((const char *, const char *, void *, size_t)); static ssize_t llistxattr __P((const char *, char *, size_t)); static int xattr_cb_list __P((char *, char *, int, int, void *)); static int xattr_cb_set __P((char *, char *, int, int, void *)); static int xattr_cb_compare __P((char *, char *, int, int, void *)); static int xattr_verify __P((char *)); static int xattr_count __P((char *, int *)); static int xattr_walk __P((char *, int (*)(char *, char *, int, int, void *), void *)); static int lsetxattr(const char *path, const char *name, void *value, size_t size, int flags) { return SYSCALL(__NR_lsetxattr, path, name, value, size, flags); } static ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size) { return SYSCALL(__NR_lgetxattr, path, name, value, size); } static ssize_t llistxattr(const char *path, char *list, size_t size) { return SYSCALL(__NR_llistxattr, path, list, size); } #define POSIX_ACL_XATTR_VERSION 0x0002 #define ACL_UNDEFINED_ID (-1) #define ACL_USER_OBJ (0x01) #define ACL_USER (0x02) #define ACL_GROUP_OBJ (0x04) #define ACL_GROUP (0x08) #define ACL_MASK (0x10) #define ACL_OTHER (0x20) typedef struct { u_int16_t e_tag; u_int16_t e_perm; u_int32_t e_id; } posix_acl_xattr_entry; typedef struct { u_int32_t a_version; posix_acl_xattr_entry a_entries[0]; } posix_acl_xattr_header; static inline size_t posix_acl_xattr_size(int count) { return (sizeof(posix_acl_xattr_header) + (count * sizeof(posix_acl_xattr_entry))); } struct posix_acl_entry { short e_tag; unsigned short e_perm; unsigned int e_id; }; struct posix_acl { unsigned int a_count; struct posix_acl_entry a_entries[0]; }; #define EXT3_ACL_VERSION 0x0001 typedef struct { u_int16_t e_tag; u_int16_t e_perm; u_int32_t e_id; } ext3_acl_entry; typedef struct { u_int16_t e_tag; u_int16_t e_perm; } ext3_acl_entry_short; typedef struct { u_int32_t a_version; } ext3_acl_header; static inline int ext3_acl_count(size_t size) { ssize_t s; size -= sizeof(ext3_acl_header); s = size - 4 * sizeof(ext3_acl_entry_short); if (s < 0) { if (size % sizeof(ext3_acl_entry_short)) return -1; return size / sizeof(ext3_acl_entry_short); } else { if (s % sizeof(ext3_acl_entry)) return -1; return s / sizeof(ext3_acl_entry) + 4; } } int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size) { posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer; posix_acl_xattr_entry *ext_entry = ext_acl->a_entries; int real_size, n; real_size = posix_acl_xattr_size(acl->a_count); if (!buffer) return real_size; if (real_size > size) { fprintf(stderr, "ACL: not enough space to convert (%d %d)\n", real_size, (int)size); return -1; } ext_acl->a_version = POSIX_ACL_XATTR_VERSION; #if BYTE_ORDER == BIG_ENDIAN swabst("1i", (u_char *)ext_acl); #endif for (n=0; n < acl->a_count; n++, ext_entry++) { ext_entry->e_tag = acl->a_entries[n].e_tag; ext_entry->e_perm = acl->a_entries[n].e_perm; ext_entry->e_id = acl->a_entries[n].e_id; #if BYTE_ORDER == BIG_ENDIAN swabst("2s1i", (u_char *)ext_entry); #endif } return real_size; } static struct posix_acl * ext3_acl_from_disk(const void *value, size_t size) { const char *end = (char *)value + size; int n, count; struct posix_acl *acl; if (!value) return NULL; if (size < sizeof(ext3_acl_header)) { fprintf(stderr, "ACL size too little\n"); return NULL; } #if BYTE_ORDER == BIG_ENDIAN swabst("1i", (u_char *)value); #endif if (((ext3_acl_header *)value)->a_version != EXT3_ACL_VERSION) { fprintf(stderr, "ACL version unknown\n"); return NULL; } value = (char *)value + sizeof(ext3_acl_header); count = ext3_acl_count(size); if (count < 0) { fprintf(stderr, "ACL bad count\n"); return NULL; } if (count == 0) return NULL; acl = malloc(sizeof(struct posix_acl) + count * sizeof(struct posix_acl_entry)); if (!acl) { fprintf(stderr, "ACL malloc failed\n"); return NULL; } acl->a_count = count; for (n=0; n < count; n++) { ext3_acl_entry *entry = (ext3_acl_entry *)value; #if BYTE_ORDER == BIG_ENDIAN swabst("2s", (u_char *)entry); #endif if ((char *)value + sizeof(ext3_acl_entry_short) > end) goto fail; acl->a_entries[n].e_tag = entry->e_tag; acl->a_entries[n].e_perm = entry->e_perm; switch(acl->a_entries[n].e_tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER: value = (char *)value + sizeof(ext3_acl_entry_short); acl->a_entries[n].e_id = ACL_UNDEFINED_ID; break; case ACL_USER: case ACL_GROUP: #if BYTE_ORDER == BIG_ENDIAN swabst("4b1i", (u_char *)entry); #endif value = (char *)value + sizeof(ext3_acl_entry); if ((char *)value > end) goto fail; acl->a_entries[n].e_id = entry->e_id; break; default: goto fail; } } if (value != end) goto fail; return acl; fail: fprintf(stderr, "ACL bad entry\n"); free(acl); return NULL; } /* * Dump code starts here :) */ static int xattr_cb_list(char *name, char *value, int valuelen, int isSELinux, void *private) { isSELinux; value[valuelen] = '\0'; printf("EA: %s:%s\n", name, value); return GOOD; } static int xattr_cb_set(char *name, char *value, int valuelen, int isSELinux, void *private) { char *path = (char *)private; int err; if (Nflag) return GOOD; isSELinux; #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ if (isSELinux) err = lsetfilecon(path, value); else #endif err = lsetxattr(path, name, value, valuelen, 0); if (err) { warn("%s: EA set %s:%s failed", path, name, value); return FAIL; } return GOOD; } static int xattr_cb_compare(char *name, char *value, int valuelen, int isSELinux, void *private) { char *path = (char *)private; char valuef[XATTR_MAXSIZE]; int valuesz; isSELinux; #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ if (isSELinux) { security_context_t con = NULL; if (lgetfilecon(path, &con) < 0) { warn("%s: EA compare lgetfilecon failed\n", path); return FAIL; } valuesz = strlen(con) + 1; valuef[0] = 0; strncat(valuef, con, sizeof(valuef) - 1); freecon(con); } else { #endif valuesz = lgetxattr(path, name, valuef, XATTR_MAXSIZE); if (valuesz < 0) { warn("%s: EA compare lgetxattr failed\n", path); return FAIL; } #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ } #endif if (valuesz != valuelen || memcmp(value, valuef, valuelen)) { /* GAN24May06: show name and new value for user to compare */ fprintf(stderr, "%s: EA %s:%s value changed to %s\n", path, name, value, valuef); return FAIL; } return GOOD; } static int xattr_verify(char *buffer) { struct ext2_xattr_entry *entry; char *end; end = buffer + XATTR_MAXSIZE; #if BYTE_ORDER == BIG_ENDIAN swabst("4i", (u_char *)buffer); #endif if (HDR(buffer)->h_magic != EXT2_XATTR_MAGIC && HDR(buffer)->h_magic != EXT2_XATTR_MAGIC2) { fprintf(stderr, "error in EA block 1\n"); fprintf(stderr, "magic = %x\n", HDR(buffer)->h_magic); return FAIL; } /* check the on-disk data structure */ entry = FIRST_ENTRY(buffer); #if BYTE_ORDER == BIG_ENDIAN swabst("2b1s3i", (u_char *)entry); #endif while (!IS_LAST_ENTRY(entry)) { struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(entry); if ((char *)next >= end) { fprintf(stderr, "error in EA block\n"); return FAIL; } entry = next; #if BYTE_ORDER == BIG_ENDIAN swabst("2b1s3i", (u_char *)entry); #endif } return GOOD; } static int xattr_count(char *buffer, int *count) { struct ext2_xattr_entry *entry; int result = 0; /* list the attribute names */ for (entry = FIRST_ENTRY(buffer); !IS_LAST_ENTRY(entry); entry = EXT2_XATTR_NEXT(entry)) result++; *count = result; return GOOD; } static int xattr_walk(char *buffer, int (*xattr_cb)(char *, char *, int, int, void *), void *private) { struct ext2_xattr_entry *entry; /* list the attribute names */ for (entry = FIRST_ENTRY(buffer); !IS_LAST_ENTRY(entry); entry = EXT2_XATTR_NEXT(entry)) { char name[XATTR_MAXSIZE], value[XATTR_MAXSIZE]; int size; int off; int convertacl = 0; int convertcon = 0; switch (entry->e_name_index) { case EXT2_XATTR_INDEX_USER: strcpy(name, "user."); break; case EXT2_XATTR_INDEX_POSIX_ACL_ACCESS: strcpy(name, "system.posix_acl_access"); convertacl = 1; break; case EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT: strcpy(name, "system.posix_acl_default"); convertacl = 1; break; case EXT2_XATTR_INDEX_TRUSTED: strcpy(name, "trusted."); break; case EXT2_XATTR_INDEX_LUSTRE: strcpy(name, "lustre."); break; case EXT2_XATTR_INDEX_SECURITY: strcpy(name, "security."); #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ convertcon = transselinuxflag; #endif break; default: fprintf(stderr, "Unknown EA index\n"); return FAIL; } off = strlen(name); memcpy(name + off, entry->e_name, entry->e_name_len); name[off + entry->e_name_len] = '\0'; size = entry->e_value_size; memcpy(value, buffer + VALUE_OFFSET(buffer, entry), size); if (convertacl) { struct posix_acl *acl; acl = ext3_acl_from_disk(value, size); if (!acl) return FAIL; size = posix_acl_to_xattr(acl, value, XATTR_MAXSIZE); if (size < 0) return FAIL; free(acl); } #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ if (convertcon && strcmp(name, "security.selinux")) convertcon = 0; /*GAN24May06 only for selinux */ if (convertcon) { security_context_t con = NULL; int err; if (!transselinuxarg) err = security_canonicalize_context(value, &con); else { strncat(value, transselinuxarg, sizeof(value) - 1); err = security_canonicalize_context_raw(value, &con); } if (err < 0) { warn("%s: EA canonicalize failed\n", value); return FAIL; } size = strlen(con) + 1; value[0] = 0; strncat(value, con, sizeof(value) - 1); freecon(con); } #endif if (xattr_cb(name, value, size, convertcon, private) != GOOD) return FAIL; } return GOOD; } int xattr_compare(char *path, char *buffer) { int countf, countt; char *names = NULL, *end_names, *name; countf = llistxattr(path, NULL, 0); if (countf < 0) { warn("%s: llistxattr failed", path); return FAIL; } names = malloc(countf + 1); if (!names) { warn("%s: llistxattr failed", path); return FAIL; } countf = llistxattr(path, names, countf); if (countf < 0) { warn("%s: llistxattr failed", path); free(names); return FAIL; } names[countf] = '\0'; end_names = names + countf; countf = 0; for (name = names; name != end_names; name = strchr(name, '\0') + 1) { if (!*name) continue; countf++; } free(names); if (buffer) { if (xattr_verify(buffer) == FAIL) return FAIL; if (xattr_count(buffer, &countt) == FAIL) return FAIL; } else countt = 0; if (countf != countt) { fprintf(stderr, "%s: EA count changed from %d to %d\n", path, countt, countf); return FAIL; } if (!buffer) return GOOD; return xattr_walk(buffer, xattr_cb_compare, path); } int xattr_extract(char *path, char *buffer) { if (dflag) { fprintf(stderr, "xattr_extract(%s)\n", path); xattr_walk(buffer, xattr_cb_list, NULL); } if (xattr_verify(buffer) == FAIL) return FAIL; return xattr_walk(buffer, xattr_cb_set, path); } dump-0.4b44/restore/restore.c0000644000175000017500000007527511477171252016055 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.40 2010/12/06 14:26:50 stelian Exp $"; #endif /* not lint */ #include #include #ifdef __linux__ #include #include #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #else /* __linux__ */ #ifdef sunos #include #include #else #include #endif #endif /* __linux__ */ #include #include #include #include #include #ifdef __linux__ #include #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. * * This also takes care of directories which were missed by removeoldleaves(), * because their inode has been reused, but excluded from the dump. */ void findunreflinks(void) { struct entry *ep, *np; dump_ino_t i; int j; 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; if (ep->e_entries == NULL) continue; for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { if ((np->e_flags & ~TMPNAME) == 0) { Dprintf(stdout, "%s: remove unreferenced name\n", myname(np)); if (np->e_type == LEAF) { removeleaf(np); freeentry(np); } else { np->e_flags |= TMPNAME; deleteino(np->e_ino); np->e_next = removelist; removelist = np; } } } } } /* * Any leaves remaining in removed directories is unreferenced. */ for (ep = removelist; ep != NULL; ep = ep->e_next) { if (ep->e_entries == NULL) continue; for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; 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); } else { if ((np->e_flags & ~TMPNAME) != 0) badentry(np, "unreferenced with flags"); if (np->e_flags == 0) { Dprintf(stdout, "%s: remove unreferenced name\n", myname(np)); np->e_next = ep->e_next; ep->e_next = 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) { int docont = 0; if (ep->e_entries != NULL) { int i; for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) { prev = &ep->e_next; docont = 1; break; } } } if (docont) 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)); skipxattr(); } 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); 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); skipxattr(); ep->e_flags &= ~(NEW|EXTRACT); /* * 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) { #endif if (volinfo[1] == ROOTINO) curfile.ino = 0; else getvol((long)1); #ifdef USE_QFA } #endif 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); skipxattr(); #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); } dump-0.4b44/restore/extern.h0000644000175000017500000001400410235441366015660 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * * $Id: extern.h,v 1.25 2005/05/02 15:10:46 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 #include #ifndef __P #include #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 comparedirmodes __P((void)); 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)); int lsetflags __P((const char *, unsigned long)); int lgetflags __P((const char *, 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 void skipxattr __P((void)); int readxattr __P((char *)); int xattr_compare __P((char *, char *)); int xattr_extract __P((char *, char *)); dump-0.4b44/restore/main.c0000644000175000017500000004764111216405764015311 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.53 2009/06/18 09:42:12 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #ifdef __linux__ #include #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #else /* __linux__ */ #ifdef sunos #include #include #include #include #include #else #include #endif #endif /* __linux__ */ #include #include #include #include #include #ifdef __linux__ #include #include #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]; int wdfd; int dirhash_size = 1; #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 */ #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ int transselinuxflag = 0; char *transselinuxarg = NULL; #endif 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 */ #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ char transselinuxopt; #endif /* 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:" #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ "eE:" #endif "f:F:hH:i" #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; #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ case 'e': transselinuxflag = 1; transselinuxopt = ch; break; case 'E': transselinuxflag = 1; transselinuxarg = optarg; transselinuxopt = ch; break; #endif 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; case 'H': dirhash_size = strtol(optarg, &p, 10); if (*p) errx(1, "illegal hash size -- %s", optarg); if (dirhash_size < 1) errx(1, "hash size must be greater than 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); #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ if (transselinuxflag && !strchr("CirRx", command)) errx(1, "%c option is not valid for %c command", transselinuxopt, command); #endif 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); wdfd = open(".", O_RDONLY); if (wdfd < 0) err(1, "can't get current directory"); 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; Nflag = 1; aflag = 1; 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(1); treescan(".", ROOTINO, nodeupdates); compareleaves(); comparedirmodes(); checkrestore(); if (compare_errors) { printf("Some files were modified! %d compare errors\n", compare_errors); 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 #ifdef TRANSSELINUX /*GAN6May06 SELinux MLS */ # define tseflag "e" # define tsEflag "[-E mls] " #else # define tseflag # define tsEflag #endif fprintf(stderr, "usage:" "\t%s -C [-cd" tseflag "H" kerbflag "lMvVy] [-b blocksize] [-D filesystem] " tsEflag"\n" "\t%s [-f file] [-F script] [-L limit] [-s fileno]\n" "\t%s -i [-acd" tseflag "hH" kerbflag "lmMouvVy] [-A file] [-b blocksize] " tsEflag"\n" "\t%s [-f file] [-F script] " qfaflag "[-s fileno]\n" #ifdef USE_QFA "\t%s -P file [-acdhH" kerbflag "lmMuvVy] [-b blocksize]\n" "\t%s [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n" #endif "\t%s -r [-cd" tseflag "H" kerbflag "lMuvVy] [-b blocksize] " tsEflag"\n" "\t%s [-f file] [-F script] [-s fileno] [-T directory]\n" "\t%s -R [-cd" tseflag "H" kerbflag "lMuvVy] [-b blocksize] " tsEflag"\n" "\t%s [-f file] [-F script] [-s fileno] [-T directory]\n" "\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize]\n" "\t%s [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n" "\t%s -x [-acd" tseflag "hH" kerbflag "lmMouvVy] [-A file] [-b blocksize] " tsEflag"\n" "\t%s [-f file] [-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 'H': 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; } dump-0.4b44/restore/tape.c0000644000175000017500000023232411573714005015305 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.102 2011/06/08 15:40:53 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #else /* __linux__ */ #ifdef sunos #define quad_t int64_t #include #include #include #else #include #endif #endif /* __linux__ */ #ifdef DUMP_MACOSX #include "darwin.h" #endif #include #ifdef HAVE_ZLIB #include #endif /* HAVE_ZLIB */ #ifdef HAVE_BZLIB #include #endif /* HAVE_BZLIB */ #ifdef HAVE_LZO #include #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 xtrxattr __P((char *, size_t)); static void setmagtapein __P((void)); static int extractattr __P((char *)); static void compareattr __P((char *)); #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 */ static char xattrbuf[XATTR_MAXSIZE]; static int xattrlen; #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(); cvtflag = 0; 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; 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); if (!fgets(buf, TP_BSIZE, terminal)) break; } 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; if (compare_errors) fprintf(stderr, "%d compare errors so far\n", compare_errors); #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); if (!fgets(buf, TP_BSIZE, terminal)) exit(1); 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 = ""; 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: { uid_t luid = curfile.dip->di_uid; gid_t lgid = curfile.dip->di_gid; Vprintf(stdout, "extract socket %s\n", name); skipfile(); if (Nflag) return (GOOD); if (! (spcl.c_flags & DR_METAONLY)) { int sk; struct sockaddr_un addr; if (uflag) (void)unlink(name); if ((sk = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { warn("%s: cannot create socket", name); return (FAIL); } addr.sun_family = AF_UNIX; strcpy(addr.sun_path, name); if (bind(sk, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { warn("%s: cannot create socket", name); return (FAIL); } close(sk); } if (chown(name, luid, lgid) < 0) warn("%s: chown", name); if (chmod(name, mode) < 0) warn("%s: chmod", name); extractattr(name); utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); #else #ifdef sunos { warn("%s: cannot call chflags", name); /* (void) chflags(name, flags); */ } #else (void) chflags(name, flags); #endif #endif return (GOOD); } case IFDIR: { int ret; if (mflag) { if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); } Vprintf(stdout, "extract dir %s\n", name); ret = genliteraldir(name, curfile.ino); extractattr(name); return ret; } 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 if (lchown(name, luid, lgid) < 0) warn("%s: lchown", name); #endif extractattr(name); return (GOOD); } case IFIFO: { uid_t luid = curfile.dip->di_uid; gid_t lgid = curfile.dip->di_gid; Vprintf(stdout, "extract fifo %s\n", name); skipfile(); if (Nflag) 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); return (FAIL); } } if (chown(name, luid, lgid) < 0) warn("%s: chown", name); if (chmod(name, mode) < 0) warn("%s: chmod", name); extractattr(name); utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); #else #ifdef sunos { warn("%s: cannot call chflags", name); /* (void) chflags(name, flags); */ } #else (void) chflags(name, flags); #endif #endif return (GOOD); } case IFCHR: case IFBLK: { uid_t luid = curfile.dip->di_uid; gid_t lgid = curfile.dip->di_gid; int lrdev = (int)curfile.dip->di_rdev; Vprintf(stdout, "extract special file %s\n", name); skipfile(); if (Nflag) return (GOOD); if (! (spcl.c_flags & DR_METAONLY)) { if (uflag) (void)unlink(name); if (mknod(name, mode, lrdev) < 0) { warn("%s: cannot create special file", name); return (FAIL); } } if (chown(name, luid, lgid) < 0) warn("%s: chown", name); if (chmod(name, mode) < 0) warn("%s: chmod", name); extractattr(name); utimes(name, timep); if (flags) #ifdef __linux__ { warn("%s: lsetflags called on a special file", name); (void) lsetflags(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 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(); if (chown(name, luid, lgid) < 0) warn("%s: chown", name); if (chmod(name, mode) < 0) warn("%s: chmod", name); extractattr(name); utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); #else #ifdef sunos { warn("%s: cannot call chflags", name); /* (void) chflags(name, flags); */ } #else (void) chflags(name, flags); #endif #endif return (GOOD); } } /* NOTREACHED */ } static int extractattr(char *path) { while (spcl.c_flags & DR_EXTATTRIBUTES) { switch (spcl.c_extattributes) { case EXT_MACOSFNDRINFO: #ifdef DUMP_MACOSX (void)extractfinderinfoufs(path); #else msg("MacOSX not supported in this version, skipping\n"); skipfile(); #endif break; case EXT_MACOSRESFORK: #ifdef DUMP_MACOSX (void)extractresourceufs(path); #else msg("MacOSX not supported in this version, skipping\n"); skipfile(); #endif break; case EXT_XATTR: { char xattr[XATTR_MAXSIZE]; if (readxattr(xattr) == GOOD) { xattr_extract(path, xattr); break; } } default: msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes); skipfile(); break; } } return GOOD; } #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]; 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); if (fchown(ofile, uid, gid) < 0) warn("%s: fchown", name); if (fchmod(ofile, mode) < 0) warn("%s: fchmod", name); (void) close(ofile); utimes(oFileRsrc, timep); (void) lsetflags(oFileRsrc, flags); return (GOOD); } /* NOTREACHED */ } #endif /* DUMP_MACOSX */ int readxattr(char *buffer) { if (dflag) msg("reading EA data for inode %lu\n", curfile.ino); curfile.name = "EA block"; if (curfile.dip->di_size > XATTR_MAXSIZE) { fprintf(stderr, "EA size too big (%ld)", (long)curfile.dip->di_size); skipfile(); return (FAIL); } memset(xattrbuf, 0, XATTR_MAXSIZE); xattrlen = 0; /* * ugly hack: cope with invalid spcl.c_addr[] records written by * old versions of dump. */ readmapflag = 1; getfile(xtrxattr, xtrnull); readmapflag = 0; memcpy(buffer, xattrbuf, XATTR_MAXSIZE); return (GOOD); } /* * 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); } /* * skip over any extended attributes. */ void skipxattr(void) { while (spcl.c_flags & DR_EXTATTRIBUTES) skipfile(); } /* * 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; } } while (gethead(&spcl) != GOOD) { fprintf(stderr, "Incorrect block for %s at %ld blocks\n", curfile.name, (long)blksread); } if (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) { if (FTRUNCATE(ofile, origsize) < 0) warn("%s: ftruncate", curfile.name); } 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) { 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) { buf[size - 1] = '\0'; errx(1, "symbolic link name: %s->%s%s; too long %d", curfile.name, lnkbuf, buf, pathlen); } (void) strcat(lnkbuf, buf); lnkbuf[pathlen] = '\0'; } /* * 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 */ static void xtrxattr(char *buf, size_t size) { if (xattrlen + size > XATTR_MAXSIZE) { fprintf(stderr, "EA size too big (%ld)", (long)xattrlen + size); return; } memcpy(xattrbuf + xattrlen, buf, size); xattrlen += size; } #if !COMPARE_ONTHEFLY static int do_cmpfiles(int fd_tape, int fd_disk, OFF_T 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 %lld to %lld.\n", diskfile, (long long)sbuf_tape.st_size, (long 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/ */ { 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 */ static void compareattr(char *name) { int xattr_done = 0; while (spcl.c_flags & DR_EXTATTRIBUTES) { switch (spcl.c_extattributes) { case EXT_MACOSFNDRINFO: msg("MacOSX not supported for comparision in this version, skipping\n"); skipfile(); break; case EXT_MACOSRESFORK: msg("MacOSX not supported for comparision in this version, skipping\n"); skipfile(); break; case EXT_XATTR: { char xattr[XATTR_MAXSIZE]; if (readxattr(xattr) == GOOD) { if (xattr_compare(name, xattr) == FAIL) do_compare_error; xattr_done = 1; } else do_compare_error; break; } default: msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes); skipfile(); break; } } if (!xattr_done && xattr_compare(name, NULL) == FAIL) do_compare_error; } #if !COMPARE_ONTHEFLY static char tmpfilename[MAXPATHLEN]; #endif void comparefile(char *name) { mode_t mode; uid_t uid; uid_t gid; unsigned int flags; unsigned long newflags; 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; flags = curfile.dip->di_flags; uid = curfile.dip->di_uid; gid = curfile.dip->di_gid; if ((mode & IFMT) == IFSOCK) { Vprintf(stdout, "skipped socket %s\n", name); skipfile(); return; } if ((r = LSTAT(name, &sb)) != 0) { warn("unable to stat %s", name); do_compare_error; skipfile(); return; } Vprintf(stdout, "comparing %s (size: %lld, mode: 0%o)\n", name, (long 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 (sb.st_uid != uid) { fprintf(stderr, "%s: uid changed from %d to %d.\n", name, uid, sb.st_uid); do_compare_error; } if (sb.st_gid != gid) { fprintf(stderr, "%s: gid changed from %d to %d.\n", name, gid, sb.st_gid); do_compare_error; } #ifdef __linux__ if (lgetflags(name, &newflags) < 0) { if (flags != 0) { warn("%s: lgetflags failed", name); do_compare_error; } } else { if (newflags != flags) { fprintf(stderr, "%s: flags changed from 0x%08x to 0x%08lx.\n", name, flags, newflags); do_compare_error; } } #endif if (spcl.c_flags & DR_METAONLY) { skipfile(); return; } switch (mode & IFMT) { default: skipfile(); return; case IFSOCK: skipfile(); return; case IFDIR: skipfile(); compareattr(name); 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\n", 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; } compareattr(name); 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(); compareattr(name); return; case IFREG: #if COMPARE_ONTHEFLY if ((ifile = OPEN(name, O_RDONLY)) < 0) { warn("can't open %s", name); 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 */ compareattr(name); 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; #ifdef USE_QFA if (createtapeposflag) (void)GetTapePos(&curtapepos); #endif /* 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; #ifdef USE_QFA if (createtapeposflag) (void)GetTapePos(&curtapepos); #endif /* 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: %lu\n", lengtherr, readsize, (unsigned long)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); cvtflag = 0; 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 *)"8i4s1l29i528bi192b4i", (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 = ""; 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 = ""; break; case TS_BITS: curfile.name = ""; 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 #else #include #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)); tpblksread = spcl.c_tapea + spcl.c_volume; #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: tapea %d\n", spcl.c_tapea); fprintf(stderr, "DEBUG: tpblksread %ld\n", tpblksread); #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 */ dump-0.4b44/install-sh0000755000175000017500000001270107614216432014526 0ustar stelianstelian#!/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 dump-0.4b44/rmt/0000755000175000017500000000000011574405662013330 5ustar steliansteliandump-0.4b44/rmt/rmt.c0000644000175000017500000003324711404415666014304 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.29 2010/06/11 11:19:18 stelian Exp $"; #endif /* not linux */ /* * rmt */ #include #include #include #include #include #include #include #include #ifndef __linux__ #include #endif #include #include #include #include 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 * 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); if (write(1, resp, strlen(resp)) != strlen(resp)) goto ioerror; if (write(1, cp, rval) != rval) goto ioerror; 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); if (write(1, resp, strlen(resp)) != strlen(resp)) goto ioerror; if (write(1, (char *)&mtget, sizeof (mtget)) != sizeof(mtget)) goto ioerror; } else { rval = sizeof (mtget); (void)sprintf(resp, "A%lld\n", (long long)rval); if (write(1, resp, strlen(resp)) != strlen(resp)) goto ioerror; if (write(1, (char *)&mtget, sizeof (mtget)) != sizeof(mtget)) goto ioerror; } 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); if (write(1, resp, strlen(resp)) != strlen(resp)) goto ioerror; 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)); if (write(1, resp, strlen(resp)) != strlen(resp)) DEBUG("rmtd: write error\n"); } 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); } dump-0.4b44/rmt/Makefile.in0000644000175000017500000000215507656544013015400 0ustar stelianstelian# $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 # dump-0.4b44/rmt/cipher.c0000644000175000017500000000703411404415666014747 0ustar stelianstelian#include #include #include #include #include #include #include #include #include #include /* * 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 , 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'; if (!fgets(buf, sizeof buf, fp)) { syslog(LOG_ERR, "Error reading key file %s: %m", keyfile); return NULL; } 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); } dump-0.4b44/rmt/rmt.8.in0000644000175000017500000002117207641607770014637 0ustar stelianstelian.\" 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 . 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 . .SH AVAILABILITY The .B dump/restore backup suit is available from .SH HISTORY The .B rmt command appeared in 4.2BSD. dump-0.4b44/THANKS0000644000175000017500000001217310157571674013450 0ustar stelianstelian$Id: THANKS,v 1.89 2004/12/14 14:07:56 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 , by using the Ext2fs library, written by Theodore Ts'o . Kevin Layer added the comparison code in restore. Doug Paul helped me to make dump able to backup 2GB+ filesystems. David Frey (the old Debian dump maintainer), Bdale Garbee (the new Debian dump maintainer) and the people from Red Hat Software provided lots of patches. Stelian Pop 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 Kevin B. Haines K.B.Haines@rl.ac.uk 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@thyrsus.com Graham Reed greed@users.sourceforge.net Gunther Reiszig gunther@mit.edu Brian Ristuccia bristuccia@starentnetworks.com 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 Kyle Wilson kyle.wilson@amd.com Kim Yong-jun loveyou@hackerslab.org John Yu jky@it.bu.edu Ian Zimmerman itz@speakeasy.org Florian Zumbiehl florz@gmx.de dump-0.4b44/config.sub0000755000175000017500000007145307614216431014515 0ustar stelianstelian#! /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 . 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 ." 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: dump-0.4b44/CHANGES0000644000175000017500000021043611574405523013523 0ustar stelianstelian$Id: CHANGES,v 1.327 2011/06/10 12:17:23 stelian Exp $ Changes between versions 0.4b43 and 0.4b44 (released June 10, 2011) =================================================================== 1. Recognize ext4 partitions in dump -w commands (Sourceforge bug #3125587, RedHat bug #658890). Thanks to Jan Görig for reporting the bug and submitting the patch. 2. Fix an issue with multi volume backups, which breaks restoring of files which are splitted on two or more volumes and are starting on 2nd tape or later (RedHat bug #507948). 3. Fix a bug in dump when dumping files with holes. This bug was introduced in 0.4b42 while adding ext4 support. (Sourceforge bug #3133762). 4. Fix a bug in restore -P where useless index files for compressed dumps were created (Debian bug #583093). Thanks to Mark Wooding for the patch. 5. Fix SYS_clone invocation on s390 architectures (Sourceforge bug #3303235). Thanks to Adam Tkac for reporting the bug. 6. Fix static builds. Thanks to Peter Volkov for the patches. 7. Fix false negatives in configure zlib test. Thanks to Bear Giles for the patch. 8. Add quick regression script from Bear Giles . 9. Fix a bug introduced in 0.4b43 causing restore to crash when asking for a new volume when doing multi-volume restores. Thanks to Patrik Schindler for reporting the bug. Changes between versions 0.4b42 and 0.4b43 (released June 11, 2010) =================================================================== 1. Fix a bug in dump making impossible to handle large toc files (> 2 GB). Thanks to X DUGi for reporting the bug (Sourceforge bug #2820629) 2. Fix 'restore -x' in multi-volume mode, which caused files being spanned on the first and second volumes to be incorrectly extracted. Thanks to Adam Tkac for reporting the bug. (there may be several bug reports about this issue, including Sourceforge bug #2117008, RedHat bugs #232415 and #444958). 3. Remove -lselinux -lsepol from the standard libraries list, they shouldn't be needed if selinux is not enabled in dump (this also fixes a build failure when selinux libraries are not installed). 4. Fix restoration of extended attributes of fifos and device nodes. Thanks to Igor Zhbanov for the bug report. 5. Don't attempt to set extended attributes on files that were not extracted in 'restore -N' mode. Thanks to Jan Görig for the patch. 6. Make the dump man page explicit about ext4 support. 7. Fix a bug in dump which caused EA entries to be unrecognizable by restore in some corner cases. Add a workaround to restore making it able to properly deal with those corrupted EA entries. Thanks to John Austin for reporting the bug. 8. Fix some issues when restoring a dump which was generated using exclusion patterns (either via -e or via the nodump attribute) (see the Debian bug #574667 for details. Thanks to Frédéric Brière for the bug report and the associated patch. 9. Fix progress/estimated blocks display in dump when doing really huge backups. Thanks to Steve Bonds for the bug report and tests. (Sourceforge bug #2987758) 10. Improve level 1 dump speed by rearanging the "mapdirs" code. Thanks to Andreas Kies for finding the bottleneck and sending a patch (Sourceforge bug #2998119). 11. Use only ctime in order to compare newness instead of both ctime and mtime. This should both speed up dumping time and correct some side-effect bugs (like dumping files with an mtime in the future in every incremental backup). Thanks to Kieran Clancy for reporting the bug (Sourceforge bug #2999207). 12. Extract dumped UNIX sockets instead of ignoring them. (Sourceforge bug #3007216). 13. Compiler warning fixes (mainly warn_unused_result ones). Changes between versions 0.4b41 and 0.4b42 (released June 18, 2009) =================================================================== 1. Fix printout of the 'Connection to' message in dump/restore. Thanks to Dale Wiles for the bug report and its fix. 2. Fix dump -w/-W output for filesystems having the last backup level equal to 0. Thanks to Pascal Bouchareine for reporting the bug. 3. Enable restore to handle restoring onto a different SELinux policy from the dump. Thanks to Tony Nelson for the patch. (see http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=189845 for details) 4. Fix EA set failures when restoring immutable files. Thanks to Andrew Kroeger for the patch. 5. Fix "mode file too large" errors when restoring huge backups. Thanks to Kenneth Porter for the bug report. 6. Add the ability to link against libtinfo library if present, instead of libtermcap or libncurses libraries. Thanks to Adam Tkac for the patch. 7. When comparing a backup, do not consider to be an error the fact that we encounter files created while dump was in progress. Thanks to Kenneth Porter for the bug report. 8. Force '-a' to be the default value when running 'restore -C'. Thanks to Kenneth Porter for the bug report. 9. Many improvements to the 'cron_dump_to_disk' example. Thanks to Aaron S. Hawley for the patch. 10. Fix the QFA generation when extended attributes are backuped along with the inodes. Prior to this fix, the entries for some inodes may get corrupted (duplicated entries or incorrect ones), making the QFA file unusable for repositionning in restore. Many thanks to Kenneth Porter for the bug report and the testing of the fix. 11. Fix EA restoration in debug mode (Sourceforge bug #1986216). 12. Stefan Auracher noticed that the Tower of Hanoi backup strategy documented in the man page wasn't actually based on the Tower of Hanoi algorithm. The man page was updated accordingly. 13. Fix missing level information from dump output when using the default level (RedHat bug #493635). Thanks to Adam Tkac for the patch. 14. Fix the dump man page to reflect the fact that the default dump level is 0 not 9 (RedHat bug #356121). Thanks to Adam Tkac for the patch. 15. Fixed a few spelling errors in the man pages (RedHat bug #489853). Thanks to Adam Tkac for the patch. 16. Fixed restore man page and program usage which incorrectly stated that -P and -A were both allowed in the same invocation (RedHat bug #490627). Thanks to Adam Tkac for the patch. 17. Use sys_clone under Linux to share I/O contexts between dump processes, thus drastically increasing the performance of dump under CFQ (which is the default I/O scheduler used in a number of distributions). Thanks to Jeff Moyer for the patch. 18. Add (preliminary) ext4 support - thanks to libext2fs which does all the job for us. Thanks to Gertjan van Wingerde for the patch. Changes between versions 0.4b40 and 0.4b41 (released January 2, 2006) ===================================================================== 1. Fix restore of dumped Access Control Lists. The previous code for EA works fine, but ACLs needed conversion from the ext2/3 disk format to posix_acl format before restoring. 2. Fix some issues with restoration of EA on big endian platforms. 3. Fix restore when the symtab is over 2GB in size. 4. Made the directory hash indexing an optional feature, accessible by the '-H' option of restore, and disable it by default. 5. Fixed dump to not include extended attributes information in the toc (archive) file which confused restore -t. Changes between versions 0.4b39 and 0.4b40 (released May 2, 2005) ================================================================= 1. Changed restore to emit warnings (instead of emitting a fatal error) if a file (or a directory) is unavailable for a comparision (if the user doesn't have the necessary permissions to access it for example). Thanks to Kenneth Porter for the bug report. 2. Re-done the 'do not save directory entries to non-dumped inodes (excluded from dump)' feature. The previous implementation worked well for excluded directories but not for regular files. Thanks to Kenneth Porter for the bug report. 3. Fixed a bug in dump where the tape size was miscalculated when the user used -d/-s to specify the tape characteristics. Thanks to Philip Goisman for reporting the bug. 4. Fixed another bug introduced in restore with the hashtree implementation. This one caused restore to stop saying "removenode: non-empty directory" in some cases. 5. Added support for dumping and restoring ext2/3 extended attributes (EA), like the access control lists (ACL) or the security labels used by SELinux. Changes between versions 0.4b38 and 0.4b39 (released January 21, 2005) ====================================================================== 1. The newly added dump_on_cd_3 example was buggy, replace it with an updated version from Andrew Basterfield . 2. Made restore to chdir() back into the initial directory when dumping core while aborting a comparision operation. The previous behaviour was to write the corefile at the root of the directory being compared, which could very well be read only and preventing the corefile generation. Thanks to Kenneth Porter for the bug report. 3. Silenced the failure to call fgetflags() when comparing an entry which has no ext2 attributes (as in lsattr()). 4. Fix a brown paper bug in restore -C which broke restore and caused modifications on the filesystem being compared (directories containing a file with the same name as the directory get renamed to RSTTMP...). Thanks to Kenneth Porter for finding the bug and helping me reproduce it. 5. Made restore -C force the -N flag (no writing allowed on the disk) in order to prevent more bugs like the above one. Changes between versions 0.4b37 and 0.4b38 (released January 7, 2005) ===================================================================== 1. Fix a couple of troff syntax bugs in the man pages. Thanks to Eric Raymond for the patch. 2. Made restore use either libncurses or libtermcap, depending on which one is available at configure time. 3. Fixed restore negative size display bug when comparing a dump containing files over 2GB. Thanks to Steve Bonds for the bug report. 4. Do not save directory entries to non-dumped inodes (excluded from dump). This will eliminate the 'missing file' warnings when doing 'restore -C'. 5. Fix dump crash when backuping a huge (2TB) filesystem, due to a bogus calculation on the inode map size. Thanks to Kevin B. Haines for submitting the bug and testing the fix. 6. Fix a problem in restore where the final \0 in the symbolic link names could have been lost, generating corrupt filenames. Thanks to Kyle Wilson for reporting the bug. 7. Implemented a hash list for the directory names in restore. The linear list used before caused problems in interactive restores when dealing with directories having thousands of entries. Thanks to Brian Ristuccia for reporting the bug. 8. Improved restore -C, this time including the directory attributes into the comparision. 9. Made restore understand tapes containing EA/ACLs (which will be dumped by the next version of dump). In this version extended attributes on the tape are ignored, for full EA/ACL support wait for the next version or try the experimental EA patch. 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 for the suggestion. 2. Fix compilation on (at least the Linux Debian port to) AMD64. ( defines some types (__s64 and __u64) that are also defined by () 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 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 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 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 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 . 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 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 for reporting this, debugging the issue and making the patch. 10. Made restore understand FreeBSD UFS2 tapes. Thanks to David 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 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 for the patch. 2. Fixed configure to correctly understand CPPFLAGS, CFLAGS, LDFLAGS environment variables. Thanks to Arcady Genkin 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 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 for reporting this bug. 5. Made restore build on Solaris, making possible to restore Linux's "enhanced" tapes. Thanks to Uwe Gohlke for the patch. 6. Made an extension in the dump tape format capable of saving MacOSX specific inode extensions. Uwe Gohlke 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 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 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 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 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 for reporting the bug. 5. Fixed (again) handling of long (largefile) seeks in rmt. Thanks to Fabrice Bellet 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 for reporting the bug. 7. Fixed a bug preventing dump to access a filesystem having a label exactly 16 bytes in length. Thanks to 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 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 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 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 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 for the patch. 13. Fixed the 'S' command handling in the rmt client part. Thanks to Philippe Troin 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 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 for the patch and to Markus Oberhumer 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 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 for the patch. 19. Made dump work with 2.5 kernel end of tape early warning semantics. Thanks to Kai Makisara 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 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 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 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 , Elliott Mitchell , Greg Edwards , Brian Hoy . (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 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 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 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 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 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 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 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 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 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 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 . 3. Fixed the tape length calculation when using large tapes and compression. Thanks to Georg Lippold 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 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 for reporting the bug. 6. Fixed a lot of warnings in the code shown when compiling with 'gcc -W'. Thanks to Matthias Andree for reporting this. 7. Fixed a small markup bug in the dump man page. Thanks to Eric S. Raymond 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 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 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 in the FreeBSD version of dump: http://www.FreeBSD.org/cgi/query-pr.cgi?pr=32414 Thanks to Ted Grzesik for reporting the bug and help testing the patch. 4. Added some example scripts from Gerd Bavendiek 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 and Peter Samuel . 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 . 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 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 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 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 for reporting the bug. 6. Added the appropriate error message when dump fails to open the output file for writing. Thanks to Amith Varghese 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 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 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 for reporting this bug. 9. Added the -P option to restore to create a Quick File Access file from an already made dump. Patch contributed by Uwe Gohlke . 10. Made restore compile and run on Solaris, making it a possible replacement for the standard ufsrestore. Port was contributed by Uwe Gohlke . Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002) ===================================================================== 1. Added a set of backup scripts from Eugenio Diaz 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 for reporting the bug. 3. Fixed several restore bugs occuring when trying to restore some missing files on the tape. Thanks to Chris Siebenmann for reporting the bug. 4. Fixed --with-ldopts configure argument passing, installing from a separate object directory, makefile cleanups contributed by . 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 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 for reporting the bugs. 3. Added a script from David B. Peterson to the examples section. It features dumping several filesystems to a remote tape drive upon ssh. 4. Added a patch provided by Richard Jones 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 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 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 and to Theodore T'so 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 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 . 3. Check for the e2fsprogs header instead of the linux kernel header. This ensures that dump always has the latest version of this file. Patch submitted by Andreas Dilger . 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 . 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 . 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 , 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 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 for reporting the bug and providing a patch. 3. Added a compression option to dump, contributed by Jerry Peters . 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 for the patch and to Bdale Garbee 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 . 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 . 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 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 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 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 and bgjenero for reporting the bug. 5. Added the throughput information in dump's progression messages. Thanks to Andreas Dilger 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 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 for submitting the patch, and to Theodore T'so 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 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 for reporting the bug and to Dave Platt 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 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 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 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 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 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 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 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 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 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 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 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 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 for reporting the bug. 2. Fixed a readline-related bug which prevented 'cat DUMPFILE | restore -i -f -' from working. Thanks to Charles Karney 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 for reporting the bug. 2. Removed the requirement to build the RPM as root from the spec file. Thanks to Christian Weisgerber 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 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 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 for submitting the patch. 2. Fix for the exit code when using the size estimate option of dump. Thanks to Matti Taskinen 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 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 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 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 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 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 . 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 001, 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 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 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 for reporting the bug and to Theodore Y. Ts'o 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 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 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 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 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 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 ). 4. Made possible to dump a file system not mentioned in /etc/fstab. (Debian bug #11904, patch provided by Eirik Fuller ). 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 ). 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 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. dump-0.4b44/MAINTAINERS0000644000175000017500000000102607421244236014214 0ustar stelianstelian$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 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 . dump-0.4b44/dump.spec0000644000175000017500000002416011574405523014346 0ustar stelianstelian%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.4b44 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, ncurses-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 * Mon Jun 10 2011 Stelian Pop - dump 0.4b44 released, first packaging. * Mon Jun 11 2010 Stelian Pop - dump 0.4b43 released, first packaging. * Mon Jun 18 2009 Stelian Pop - dump 0.4b42 released, first packaging. * Mon Jan 2 2006 Stelian Pop - dump 0.4b41 released, first packaging. * Fri Jan 21 2005 Stelian Pop - dump 0.4b39 released, first packaging. * Fri Jan 7 2005 Stelian Pop - dump 0.4b38 released, first packaging. * Wed Jul 7 2004 Stelian Pop - dump 0.4b37 released, first packaging. * Wed Apr 21 2004 Stelian Pop - dump 0.4b36 released, first packaging. * Sun Dec 21 2003 Stelian Pop - dump 0.4b35 released, first packaging. * Fri Apr 18 2003 Stelian Pop - dump 0.4b34 released, first packaging. * Mon Feb 10 2003 Stelian Pop - dump 0.4b33 released, first packaging. * Fri Nov 15 2002 Stelian Pop - dump 0.4b32 released, first packaging. * Tue Jul 30 2002 Stelian Pop - dump 0.4b31 released, first packaging. * Thu Jul 25 2002 Stelian Pop - dump 0.4b30 released, first packaging. * Sat Jun 8 2002 Stelian Pop - dump 0.4b29 released, first packaging. * Fri Apr 12 2002 Stelian Pop - dump 0.4b28 released, first packaging. * Fri Feb 15 2002 Stelian Pop - dump 0.4b27 released, first packaging. * Mon Jan 7 2002 Stelian Pop - dump 0.4b26 released, first packaging. * Sat Nov 17 2001 Stelian Pop - dump 0.4b25 released, first packaging. * Wed Sep 12 2001 Stelian Pop - dump 0.4b24 released, first packaging. * Fri Jul 20 2001 Stelian Pop - dump 0.4b23 released, first packaging. * Sat May 12 2001 Stelian Pop - dump 0.4b22 released, first packaging. * Sat Jan 30 2001 Stelian Pop - dump 0.4b21 released, first packaging. * Fri Nov 10 2000 Stelian Pop - dump 0.4b20 released, first packaging. * Sun Aug 20 2000 Stelian Pop - dump 0.4b19 released, first packaging. * Thu Jun 30 2000 Stelian Pop - dump 0.4b18 released, first packaging. * Thu Jun 1 2000 Stelian Pop - dump 0.4b17 released, first packaging. * Sat Mar 11 2000 Stelian Pop - dump 0.4b16 released, first packaging. * Thu Mar 2 2000 Stelian Pop - dump 0.4b15 released, first packaging. * Thu Feb 10 2000 Stelian Pop - dump 0.4b14 released, first packaging. * Fri Jan 21 2000 Stelian Pop - dump 0.4b13 released, first packaging. * Fri Jan 8 2000 Stelian Pop - dump 0.4b12 released, first packaging. * Sun Dec 5 1999 Stelian Pop - dump 0.4b11 released, first packaging. * Sun Nov 21 1999 Stelian Pop - dump 0.4b10 released, first packaging. * Thu Nov 11 1999 Stelian Pop - make static versions also for rescue purposes. * Wed Nov 5 1999 Stelian Pop - dump 0.4b9 released, first packaging. * Wed Nov 3 1999 Stelian Pop - dump 0.4b8 released, first packaging. * Thu Oct 8 1999 Stelian Pop - dump 0.4b7 released, first packaging. * Thu Sep 30 1999 Stelian Pop - dump 0.4b6 released, first packaging. * Fri Sep 10 1999 Jeff Johnson - recompile with e2fsprogs = 1.15 (#4962). * Sat Jul 31 1999 Jeff Johnson - 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 - remove setuid/setgid bits from /sbin/rmt (dump/restore are OK). * Sun Mar 21 1999 Cristian Gafton - auto rebuild in the new build environment (release 6) * Fri Mar 19 1999 Jeff Johnson - strip binaries. * Thu Mar 18 1999 Jeff Johnson - Fix dangling symlinks (#1551). * Wed Mar 17 1999 Michael Maher - Top O' the morning, build root's fixed for man pages. * Fri Feb 19 1999 Preston Brown - upgraded to dump 0.4b4, massaged patches. * Tue Feb 02 1999 Ian A Cameron - added patch from Derrick J Brashear for traverse.c to stop bread errors * Wed Jan 20 1999 Jeff Johnson - restore original 6755 root.tty to dump/restore, defattr did tty->root (#684). - mark /etc/dumpdates as noreplace. * Tue Jul 14 1998 Jeff Johnson - add build root. * Tue May 05 1998 Prospector System - translations modified for de, fr, tr * Thu Apr 30 1998 Cristian Gafton - added a patch for resolving linux/types.h and sys/types.h conflicts * Wed Dec 31 1997 Erik Troan - added prototype of llseek() so dump would work on large partitions * Thu Oct 30 1997 Donnie Barnes - made all symlinks relative instead of absolute * Thu Jul 10 1997 Erik Troan - built against glibc * Thu Mar 06 1997 Michael K. Johnson - Moved rmt to its own package. * Tue Feb 11 1997 Michael Fulbright - Added endian cleanups for SPARC * Fri Feb 07 1997 Michael K. Johnson - Made /etc/dumpdates writeable by group disk. dump-0.4b44/linux-1.2.x.patch0000644000175000017500000000061707000353003015432 0ustar stelianstelian--- 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; } dump-0.4b44/INSTALL0000644000175000017500000000142607622135405013554 0ustar stelianstelian$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. dump-0.4b44/dump/0000755000175000017500000000000011574405661013472 5ustar steliansteliandump-0.4b44/dump/traverse.c0000644000175000017500000011105611530440077015465 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.72 2011/02/21 10:36:47 stelian Exp $"; #endif /* not lint */ #include #include #include #include #ifdef __STDC__ #include #include #endif #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #include #elif defined sunos #include #include #include #include #else #include #include #include #endif /* __linux__ */ #include #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 long *tapesize, int *dirskipped)); static void dump_xattr __P((dump_ino_t ino, struct dinode *dp)); #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) /* 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 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 (NODUMP_FLAG(dp)) do_exclude_ino(ino, "nodump attribute"); 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 (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 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 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 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 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 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 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 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. */ if ((isdir & 1) == 0) continue; nodump = (TSTINO(ino, usedinomap) == 0); if (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 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; 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 static void dump_xattr(dump_ino_t ino, struct dinode *dp) { if (dp->di_extraisize != 0) { #ifdef HAVE_EXT2FS_READ_INODE_FULL char inode[EXT2_INODE_SIZE(fs->super)]; errcode_t err; u_int32_t *magic; memset(inode, 0, EXT2_INODE_SIZE(fs->super)); err = ext2fs_read_inode_full(fs, (ext2_ino_t)ino, (struct ext2_inode *) inode, EXT2_INODE_SIZE(fs->super)); if (err) { com_err(disk, err, "while reading inode #%ld\n", (long)ino); exit(X_ABORT); } magic = (void *)inode + EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize; if (*magic == EXT2_XATTR_MAGIC) { char xattr[EXT2_INODE_SIZE(fs->super)]; int i; char *cp; if (vflag) msg("dumping EA (inode) in inode #%ld\n", (long)ino); memset(xattr, 0, EXT2_INODE_SIZE(fs->super)); memcpy(xattr, (void *)magic, EXT2_INODE_SIZE(fs->super) - (EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize)); magic = (u_int32_t *)xattr; *magic = EXT2_XATTR_MAGIC2; spcl.c_type = TS_INODE; spcl.c_dinode.di_size = EXT2_INODE_SIZE(fs->super); spcl.c_flags |= DR_EXTATTRIBUTES; spcl.c_extattributes = EXT_XATTR; spcl.c_count = howmany(EXT2_INODE_SIZE(fs->super), TP_BSIZE); for (i = 0; i < spcl.c_count; i++) spcl.c_addr[i] = 1; writeheader(ino); for (i = 0, cp = xattr; i < spcl.c_count; i++, cp += TP_BSIZE) writerec(cp, 0); spcl.c_flags &= ~DR_EXTATTRIBUTES; spcl.c_extattributes = 0; } #endif } if (dp->di_file_acl) { if (vflag) msg("dumping EA (block) in inode #%ld\n", (long)ino); spcl.c_type = TS_INODE; spcl.c_dinode.di_size = sblock->fs_bsize; spcl.c_flags |= DR_EXTATTRIBUTES; spcl.c_extattributes = EXT_XATTR; blksout(&dp->di_file_acl, EXT2_FRAGS_PER_BLOCK(fs->super), ino); spcl.c_flags &= ~DR_EXTATTRIBUTES; spcl.c_extattributes = 0; } } /* * 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; 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; dump_xattr(ino, dp); 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); dump_xattr(ino, dp); 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); dump_xattr(ino, dp); return; default: msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT); 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 = 0; ext2fs_block_iterate2(fs, (ext2_ino_t)ino, BLOCK_FLAG_DATA_ONLY, 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); dump_xattr(ino, dp); #else if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize) cnt = NDADDR * sblock->fs_frag; 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) { dump_xattr(ino, dp); return; } 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; /* do not save entries to excluded inodes */ if (exclude_ino(dirent->inode)) return 0; 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; 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); dump_xattr(ino, dp); } #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); spcl.c_dinode.di_size = mapsize; 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; #ifdef HAVE_EXT2FS_READ_INODE_FULL err = ext2fs_read_inode_full(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode, sizeof(struct dinode)); #else err = ext2fs_read_inode(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode); #endif 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); } } dump-0.4b44/dump/dump.8.in0000644000175000017500000005424311345154024015133 0ustar stelianstelian.\" 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.63 2010/03/08 10:57:24 stelian Exp $ .\" .TH DUMP 8 "version __VERSION__ of __DATE__" BSD "System management commands" .SH NAME dump \- ext2/3/4 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] .SH DESCRIPTION .B Dump examines files on an ext2/3/4 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, specified by .B \-0 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 0. 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 If you use this option, be aware that many programs that unpack files from archives (e.g. tar, rpm, unzip, dpkg) may set files' mtimes to dates in the past. Files installed in this way may not be dumped correctly using "dump -m" if the modified mtime is earlier than the previous level dump. .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 001, 002 etc. This can be useful when dumping to files on an ext2/3/4 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 recognized 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, 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. .PP Another backup strategy is the Tower of Hanoi sequence, which reuses older tapes in a way that for newer dates the available restore points are more frequent, then for older dates (see http://en.wikipedia.org/wiki/Backup_rotation_scheme for additional information). .PP (The 4.3BSD option syntax is implemented for backward compatibility but is not documented here.) .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 occurrence). .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/4 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/4 logical block number. It doesn't print out the corresponding 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 . 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 . .SH AVAILABILITY The .B dump/restore backup suite is available from .SH HISTORY A .B dump command appeared in .B Version 6 AT&T UNIX. dump-0.4b44/dump/dump.h0000644000175000017500000002401311366000016014570 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * * $Id: dump.h,v 1.50 2010/04/28 09:29:50 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 #include #include #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 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 #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 long *tapesize)); #ifdef __linux__ int mapfilesfromdir __P((dump_ino_t maxino, long long *tapesize, char *directory)); int maponefile __P((dump_ino_t maxino, long long *tapesize, char *directory)); #endif int mapdirs __P((dump_ino_t maxino, long 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 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 #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 dump-0.4b44/dump/unctime.c0000644000175000017500000000722007641607765015314 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #ifdef __STDC__ #include #include #endif #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #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); } dump-0.4b44/dump/Makefile.in0000644000175000017500000000254210072266614015535 0ustar stelianstelian# $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 # dump-0.4b44/dump/optr.c0000644000175000017500000004330711477167647014644 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.41 2010/12/06 14:13:59 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #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", "ext4", "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; if (tabfs->mnt_freq > 3659) quit("Dump frequency in fstab/mtab for %s is too big: %d > 3659\n", tabfs->mnt_fsname, tabfs->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; if (new->mnt_freq > 3659) quit("Dump frequency in fstab/mtab for %s %s is too big: %d > 3659\n", new->mnt_dir, new->mnt_fsname, new->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 (level >= 0 && 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. * * UGLY HACK: values in 0-3659 range indicate * original value from /etc/fstab (maximum * 10 years...) * * Values bigger than 3659 indicate that * the fs is to be dumped, and the latest * dump level was x-3660 * * Negative values indicate that the fs is * not to be dumped, and the latest dump * level was -x-1 */ dt->mnt_passno = dtwalk->dd_ddate; if (dt->mnt_freq > 0 && (dtwalk->dd_ddate < tnow - (dt->mnt_freq * 86400))) dt->mnt_freq = 3660 + dtwalk->dd_level; else dt->mnt_freq = -dtwalk->dd_level - 1; #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 - 1 : dt->mnt_freq < 3660 ? -1 : dt->mnt_freq - 3660), 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); } dump-0.4b44/dump/itime.c0000644000175000017500000002056010064256733014745 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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 #include #include #include #ifdef __STDC__ #include #include #endif #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #include #elif defined sunos #include #include #include #include #else #include #endif #include #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); } dump-0.4b44/dump/main.c0000644000175000017500000011131311366000016014542 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.97 2010/04/28 09:29:50 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #include /* for definition of BLKFLSBUF */ #elif defined sunos #include #include #include #else #include #include #endif #include #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 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); /* Default dump level is zero. */ level[0] = '0'; 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 %lld blocks.\n", tapesize); } else { double fetapes; if (blocksperfiles) { long 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 %lld 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); } } dump-0.4b44/dump/tape.c0000644000175000017500000011642611565434723014602 0ustar stelianstelian/* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 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.93 2011/05/20 09:52:19 stelian Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #ifdef __STDC__ #include #include #include #else int write(), read(); #endif #ifdef __linux__ #include #include #include #include /* for definition of BLKFLSBUF */ #ifndef BLKFLSBUF /* last resort... */ #define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */ #endif #include #endif #include #include #include #include #ifdef __linux__ #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #include #endif #include #include #include #elif defined sunos #include #include #include #else #include #include #endif /* __linux__ */ #include #ifdef HAVE_ZLIB #include #endif /* HAVE_ZLIB */ #ifdef HAVE_BZLIB #include #endif /* HAVE_BZLIB */ #ifdef HAVE_LZO #include #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 /* * Determine if we can use Linux' clone system call. If so, call it * with the CLONE_IO flag so that all processes will share the same I/O * context, allowing the I/O schedulers to make better scheduling decisions. */ #ifdef __linux__ /* first, pull in the header files that define sys_clone and CLONE_IO */ #include #define _GNU_SOURCE #include #include #undef _GNU_SOURCE /* If either is not present, fall back on the fork behaviour */ #if ! defined(SYS_clone) || ! defined (CLONE_IO) #define fork_clone_io fork #else /* SYS_clone */ /* CLONE_IO is available, determine which version of sys_clone to use */ #include /* * Kernel 2.5.49 introduced two extra parameters to the clone system call. * Neither is useful in our case, so this is easy to handle. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,49) /* * Parameters of the sys_clone syscall are * clone_flags, child_stack, parent_tidptr, child_tidptr * on all architectures except s390 and s390x * s390* have child_stack, clone_flags, parent_tidptr, child_tidptr */ #if defined(__s390__) || defined(__s390x__) #define CLONE_ARGS 0, SIGCHLD|CLONE_IO, NULL, NULL #else #define CLONE_ARGS SIGCHLD|CLONE_IO, 0, NULL, NULL #endif #else #define CLONE_ARGS SIGCHLD|CLONE_IO, 0 #endif /* LINUX_VERSION_CODE */ pid_t fork_clone_io(void); #endif /* SYS_clone */ #else /* __linux__ not defined */ #define fork_clone_io fork #endif /* __linux__ */ 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 && !(spcl.c_flags & DR_EXTATTRIBUTES)) { /* 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; /* make sure returned has sane values in case we don't read * them from the slave in this pass */ returned.unclen = returned.clen = writesize; 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_CLRI || spcl.c_type == TS_BITS) blks = spcl.c_count; else { 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]; /* make sure returned has sane values in case we don't read * them from the slave in this pass */ returned.unclen = returned.clen = writesize; /* * 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 } #ifdef __linux__ #if defined(SYS_clone) && defined(CLONE_IO) pid_t fork_clone_io(void) { return syscall(SYS_clone, CLONE_ARGS); } #endif #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_clone_io(); 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_clone_io()) < 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) && !(spclptr->c_flags & DR_EXTATTRIBUTES) ) { 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 */ dump-0.4b44/MCONFIG.in0000644000175000017500000000500611574405523014135 0ustar stelianstelianVERSION= 0.4b44 DATE= June 10, 2011 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+= @EXT2FS_CFLAGS@ # # 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 @EXT2FS_LIBS@ # # 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 dump-0.4b44/config.h.in0000644000175000017500000000706411566414053014553 0ustar stelianstelian/* 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 header file. */ #undef HAVE_EXT2FS_EXT2_FS_H /* Define this if your ext2fs libs have the ext2fs_read_inode_full function. */ #undef HAVE_EXT2FS_READ_INODE_FULL /* 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 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 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 header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the 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 home page for this package. */ #undef PACKAGE_URL /* 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 does not define. */ #undef quad_t /* Define to `uint64_t' if does not define. */ #undef u_quad_t