release 0.6.2 trunk 0.6.2
authornathan
Sat, 29 Dec 2007 15:22:32 +0100
branchtrunk
changeset 0d85c12073dea
child 1 6b6864d2c4ce
release 0.6.2
CHANGES
CREDITS
LICENSE
Makefile
README
cdbackup.1
cdbackup.c
cdbackup.h
cdrestore.1
cdrestore.c
cdrom.c
cdrom.h
examples/cdbackup-diskchange
examples/cdrestore-diskchange
misc.c
misc.h
version.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/CHANGES	Sat Dec 29 15:22:32 2007 +0100
     1.3 @@ -0,0 +1,37 @@
     1.4 +0.6.2
     1.5 +-----
     1.6 +1. some more fixes to allow >2GB data on a single disk (SH)
     1.7 +2. added commandline option to specify padsize and enable CDROM
     1.8 +   XA2 mode (SH)
     1.9 +3. changed gcc options in Makefile (SH)
    1.10 +4. code cleanup (SH)
    1.11 +5. added man page, updated README (SH)
    1.12 + 
    1.13 +0.6.1
    1.14 +-----
    1.15 +1. fixed size calculations with multi-disk backups > 2GB (SH)
    1.16 +2. minor message cleanups (CC)
    1.17 +
    1.18 +0.6
    1.19 +---
    1.20 +1. multidisk-support (SH)
    1.21 +2. unix-like commandline options (SH)
    1.22 +3. can pass additional options to cdrecord (SH)
    1.23 +4. code cleanup (SH)
    1.24 +5. various bugs fixed (SH)
    1.25 +
    1.26 +0.5.2
    1.27 +-----
    1.28 +1. Revamped Makefile (CC)
    1.29 +
    1.30 +0.5.1
    1.31 +-----
    1.32 +1. Fixed bug in command-line parsing (JY)
    1.33 +2. Added error messages to command-line parsing (JY, CC)
    1.34 +3. Various sloppy code fixes (JY, CC)
    1.35 +4. Changed Makefile to check for compiler warnings (JY, CC)
    1.36 +
    1.37 +0.5.0
    1.38 +-----
    1.39 +Initial public release.
    1.40 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/CREDITS	Sat Dec 29 15:22:32 2007 +0100
     2.3 @@ -0,0 +1,22 @@
     2.4 +	This is list of people who have contributed to cdbackup. It is
     2.5 +	sorted by name and formatted to allow easy grepping and
     2.6 +	beautification by scripts.  The fields are: name (N), email (E),
     2.7 +	web-address (W), PGP key ID and fingerprint (P), description (D),
     2.8 +	and snail-mail address (S).
     2.9 +
    2.10 +----------
    2.11 +
    2.12 +N: Craig Condit
    2.13 +E: ccondit@cableone.net
    2.14 +D: Initial development
    2.15 +S: Fargo, ND USA
    2.16 +
    2.17 +N: James Youngman
    2.18 +E: jay@gnu.org
    2.19 +D: Various bugfixes
    2.20 +S: Manchester, UK
    2.21 +
    2.22 +N: Stefan Huelswitt
    2.23 +E: huels@iname.com
    2.24 +D: multidisk support, code cleanup, bugfixes
    2.25 +S: Monheim, Germany
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/LICENSE	Sat Dec 29 15:22:32 2007 +0100
     3.3 @@ -0,0 +1,22 @@
     3.4 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
     3.5 +
     3.6 +Redistribution and use in source and binary forms, with or without
     3.7 +modification, are permitted provided that the following conditions are met: 
     3.8 +
     3.9 +1. Redistributions of source code must retain the above copyright notice,
    3.10 +   this list of conditions and the following disclaimer. 
    3.11 +2. Redistributions in binary form must reproduce the above copyright notice,
    3.12 +   this list of conditions and the following disclaimer in the documentation
    3.13 +   and/or other materials provided with the distribution. 
    3.14 +
    3.15 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    3.16 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    3.17 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    3.18 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
    3.19 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    3.20 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    3.21 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    3.22 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    3.23 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    3.24 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    3.25 +SUCH DAMAGE.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Makefile	Sat Dec 29 15:22:32 2007 +0100
     4.3 @@ -0,0 +1,45 @@
     4.4 +# compiler selection and options
     4.5 +CC=gcc
     4.6 +CFLAGS=-g -O2 -Wall
     4.7 +
     4.8 +# install location
     4.9 +PREFIX=/usr/local
    4.10 +
    4.11 +BINDIR=$(PREFIX)/bin
    4.12 +MANDIR=$(PREFIX)/man
    4.13 +
    4.14 +###############################################
    4.15 +
    4.16 +# executables
    4.17 +TARGETS=cdbackup cdrestore
    4.18 +
    4.19 +all: $(TARGETS)
    4.20 +
    4.21 +# ruleset
    4.22 +%.o: %.c
    4.23 +	$(CC) $(CFLAGS) -c $< -o $@
    4.24 +
    4.25 +cdbackup: cdbackup.o cdrom.o misc.o
    4.26 +	$(CC) $(CFLAGS) -o cdbackup cdbackup.o cdrom.o misc.o
    4.27 +
    4.28 +cdrestore: cdrestore.o cdrom.o misc.o
    4.29 +	$(CC) $(CFLAGS) -o cdrestore cdrestore.o cdrom.o misc.o
    4.30 +
    4.31 +cdbackup.o: cdbackup.c cdbackup.h cdrom.h misc.h version.h
    4.32 +cdrestore.o: cdrestore.c cdbackup.h cdrom.h misc.h version.h
    4.33 +cdrom.o: cdrom.c cdbackup.h misc.h
    4.34 +misc.o: misc.c misc.h
    4.35 +
    4.36 +# targets
    4.37 +strip: $(TARGETS)
    4.38 +	strip $(TARGETS)
    4.39 +
    4.40 +clean:
    4.41 +	rm -f $(TARGETS) core *.core *.o
    4.42 +
    4.43 +install:
    4.44 +	install -d $(BINDIR)
    4.45 +	install $(TARGETS) $(BINDIR)
    4.46 +	install -d $(MANDIR)/man1
    4.47 +	gzip -c cdbackup.1 >$(MANDIR)/man1/cdbackup.1.gz
    4.48 +	gzip -c cdrestore.1 >$(MANDIR)/man1/cdrestore.1.gz
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/README	Sat Dec 29 15:22:32 2007 +0100
     5.3 @@ -0,0 +1,52 @@
     5.4 +cdbackup, cdrestore - CD archive utilities version 0.6.2
     5.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. All rights reserved.
     5.6 +
     5.7 +This software is released under a BSD-style license - see the LICENSE file.
     5.8 +
     5.9 +cdbackup and cdrestore are a pair of utilities designed to facilitiate
    5.10 +streaming backup to and from CD-R(W) disks.  Specificially, they were
    5.11 +designed to work with dump/restore, but tar/cpio/whatever you want should
    5.12 +work, so long as it writes to stdout for backups and reads from stdin for
    5.13 +restores.
    5.14 +
    5.15 +NOTE: this program REQUIRES that a recent version of cdrecord be present
    5.16 +in the PATH.
    5.17 +
    5.18 +See manpages for further details.
    5.19 +
    5.20 +
    5.21 +INSTALL:
    5.22 +--------
    5.23 +
    5.24 +Look at the Makefile, adjust options as you like. The default
    5.25 +install location is under /usr/local.
    5.26 +
    5.27 +make
    5.28 +make strip      (optionaly)
    5.29 +make install
    5.30 +
    5.31 +
    5.32 +DISCLAIMER:
    5.33 +-----------
    5.34 +
    5.35 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    5.36 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    5.37 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    5.38 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
    5.39 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    5.40 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    5.41 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    5.42 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    5.43 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    5.44 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    5.45 +SUCH DAMAGE.
    5.46 +
    5.47 +
    5.48 +CONTACT:
    5.49 +--------
    5.50 +
    5.51 +Project maintainer is: Stefan Hülswitt <huels@iname.com>
    5.52 +Homepage:              http://www.muempf.de/
    5.53 +
    5.54 +Any comments, suggestions, bug reports, patches and fixes
    5.55 +welcome.
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/cdbackup.1	Sat Dec 29 15:22:32 2007 +0100
     6.3 @@ -0,0 +1,124 @@
     6.4 +.TH "cdbackup" "1" "0.6.2" "Stefan Hülswitt" ""
     6.5 +.SH "NAME"
     6.6 +.LP 
     6.7 +cdbackup \- Streaming backup to CD\-R(W)
     6.8 +.SH "SYNOPSIS"
     6.9 +.LP 
    6.10 +cdbackup [\-mvVX] [\-d \fIdevice\fP] [\-r \fIscsi\-dev\fP] [\-s \fIspeed\fP]
    6.11 +         [\-p \fInum\fP] [\-l \fIsize\fP] [\-a \fIlabel\fP] [\-c \fIcommand\fP]
    6.12 +         [\-\- \fIcdrecord\-options\fP]
    6.13 +.SH "DESCRIPTION"
    6.14 +.LP 
    6.15 +cdbackup is a utility to make streaming backups to CD\-R(W) disks. It's designed to work with any backup tool which writes the backup to stdout (like tar/cpio/afio).
    6.16 +.LP 
    6.17 +NOTE: this program REQUIRES that a recent version of cdrecord is present in the PATH.
    6.18 +.LP 
    6.19 +WARNING! When using this program under Linux, be sure not to use dump with
    6.20 +kernels in the 2.4.x series. Using dump on an ext2 filesystem has a very
    6.21 +high potential for causing filesystem corruption. As of kernel version
    6.22 +2.4.18, this has not been fixed and it may not be fixed at all.
    6.23 +.SH "OPTIONS"
    6.24 +.LP 
    6.25 +.TP 
    6.26 +\fB\-d\fR \fIdevice\fP
    6.27 +The device name which is used for reading things like the TOC from a (partly written) media.
    6.28 +.br 
    6.29 +(default: /dev/burner)
    6.30 +
    6.31 +.TP 
    6.32 +\fB\-r\fR \fIscsi\-device\fP
    6.33 +The scsi device which is passed to cdrecord (via dev=\fIscsi\-device\fP). Must be given as three, comma seperated number: \fIscsibus\fR,\fItarget\fR,\fIlun\fR.
    6.34 +.br 
    6.35 +(default: none)
    6.36 +
    6.37 +.TP 
    6.38 +\fB\-s\fR \fIspeed\fP
    6.39 +The writing speed which is passed to cdrecord (via speed=\fIspeed\fP).
    6.40 +.br 
    6.41 +(default: 4)
    6.42 +
    6.43 +.TP 
    6.44 +\fB\-p\fR \fInum\fP
    6.45 +The number of sectors (of 2048 byte) to use for padding (see \fBcdrecord\fR(1) padsize).
    6.46 +.br 
    6.47 +(default: 15)
    6.48 +
    6.49 +.TP 
    6.50 +\fB\-X\fR
    6.51 +Enables the use of CDROM XA2 mode in cdrecord. By default CDROM mode 1 is used. The default is possibly causing problems during restore on certain kernel version/CDROM hardware combinations at the end of the last session on a media. Sony drives doesn't support CDROM XA 2 mode (see \fBcdrecord\fR(1) multi).
    6.52 +
    6.53 +.TP 
    6.54 +\fB\-l\fR \fIsize\fP
    6.55 +The media size in megabytes. This value is used to calculate how much data can be stored on the media.
    6.56 +.br 
    6.57 +(default: 650)
    6.58 +
    6.59 +.TP 
    6.60 +\fB\-a\fR \fIlabel\fP
    6.61 +A text label to identify the backup set. The first 32 characters of this string are save with the backup.
    6.62 +.br 
    6.63 +(default: "CDBackup Track")
    6.64 +
    6.65 +.TP 
    6.66 +\fB\-c\fR \fIcommand\fP
    6.67 +The command which is executed whenever cdbackup needs to request a new media in multi\-disk mode. This command (or script) should prompt the user and return after the recording device is ready again. The command receives one argument, which is the device name passed with \fB\-d\fR. This can be used to issue commands to the device like ejecting the media.
    6.68 +.br 
    6.69 +(default: use internal diskchange prompt)
    6.70 +
    6.71 +.TP 
    6.72 +\fB\-m\fR
    6.73 +Enables multi\-disk mode. When the current media is filled, a new media is requested (see option \fB\-c\fR) and the backup is continued. Backups can only be continued to empty media, this means you cannot insert a partly filled media for continuation.
    6.74 +
    6.75 +.TP 
    6.76 +\fB\-v\fR
    6.77 +Enables verbose mode.
    6.78 +
    6.79 +.TP 
    6.80 +\fB\-V\fR
    6.81 +Prints out version information and exits.
    6.82 +
    6.83 +.TP 
    6.84 +\fB\-\-\fR \fIcdrecord\-options\fP
    6.85 +All options following \fB\-\-\fR are passed to cdrecord.
    6.86 +.SH "EXAMPLES"
    6.87 +.LP 
    6.88 +To create a tar archive of /home and
    6.89 +output it to a 700 MB CD\-R(W) on /dev/scd0 (scsi device 2,0):
    6.90 +.IP 
    6.91 +tar cvf \- /home | cdbackup \-d /dev/scd0 \-r 2,0 \-l 700 \-a "Test Backup"
    6.92 +
    6.93 +.LP 
    6.94 +To create a tar archive of /usr and output it to a series (multi\-disk mode) of 650 MB CD\-R(W) on /dev/sr1 (scsi device 1,4,0) with writting speed 12 and verbose output:
    6.95 +.IP 
    6.96 +tar cf \- /usr | cdbackup \-d /dev/sr1 \-r 1,4,0 \-s 12 \-m \-v
    6.97 +.SH "AUTHORS"
    6.98 +.LP 
    6.99 +Stefan Hülswitt <huels@iname.com>
   6.100 +.SH "SEE ALSO"
   6.101 +.LP 
   6.102 +\fBcdrestore\fR(1), \fBcdrecord\fR(1)
   6.103 +.SH "LICENSE"
   6.104 +Copyright (c) 2000\-2002 Craig Condit, Stefan Hülswitt.
   6.105 +
   6.106 +Redistribution and use in source and binary forms, with or without
   6.107 +modification, are permitted provided that the following conditions are met: 
   6.108 +
   6.109 +.TP 
   6.110 +1.
   6.111 +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
   6.112 +.TP 
   6.113 +2.
   6.114 +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.
   6.115 +
   6.116 +.LP 
   6.117 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   6.118 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   6.119 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   6.120 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   6.121 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   6.122 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   6.123 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   6.124 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   6.125 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   6.126 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   6.127 +SUCH DAMAGE.
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/cdbackup.c	Sat Dec 29 15:22:32 2007 +0100
     7.3 @@ -0,0 +1,298 @@
     7.4 +/* cdbackup.c
     7.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
     7.6 +
     7.7 +Redistribution and use in source and binary forms, with or without
     7.8 +modification, are permitted provided that the following conditions are met: 
     7.9 +
    7.10 +1. Redistributions of source code must retain the above copyright notice,
    7.11 +   this list of conditions and the following disclaimer. 
    7.12 +2. Redistributions in binary form must reproduce the above copyright notice,
    7.13 +   this list of conditions and the following disclaimer in the documentation
    7.14 +   and/or other materials provided with the distribution. 
    7.15 +
    7.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    7.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    7.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    7.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
    7.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    7.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    7.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    7.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    7.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    7.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    7.26 +SUCH DAMAGE.
    7.27 +*/
    7.28 +
    7.29 +#define _LARGEFILE64_SOURCE
    7.30 +
    7.31 +#include <stdlib.h>
    7.32 +#include <stdio.h>
    7.33 +#include <unistd.h>
    7.34 +#include <fcntl.h>
    7.35 +#include <string.h>
    7.36 +#include <time.h>
    7.37 +#include <errno.h>
    7.38 +#include <getopt.h>
    7.39 +#include <sys/wait.h>
    7.40 +#include <sys/ioctl.h>
    7.41 +#include <netinet/in.h>
    7.42 +#include <linux/cdrom.h>
    7.43 +
    7.44 +#include "cdbackup.h"
    7.45 +#include "cdrom.h"
    7.46 +#include "misc.h"
    7.47 +#include "version.h"
    7.48 +
    7.49 +/* #define DEBUGOUT */
    7.50 +
    7.51 +/* defaults */
    7.52 +char * prg_name ="cdbackup";
    7.53 +char * cd_dev   ="/dev/burner";
    7.54 +char * cdr_dev  =0;			/* no default here, too dangerous */
    7.55 +char * cd_label ="CDBackup Track";
    7.56 +int    cd_speed =4;
    7.57 +long   cd_len   =333000;		/* blocks */
    7.58 +int    padsize  =15;			/* blocks */
    7.59 +int    multidisk=0;
    7.60 +char * multicmd =0;
    7.61 +int    verbose  =0;
    7.62 +int    xamode2  =0;
    7.63 +
    7.64 +char **cdrec_opt=0;
    7.65 +int    cdrec_opt_count=0;
    7.66 +
    7.67 +long long totalSize;
    7.68 +struct tm curtime;  /* global, so multi-disks get all the same time */
    7.69 +
    7.70 +/****************************************************************************/
    7.71 +
    7.72 +void usage()
    7.73 +{
    7.74 +  fprintf(stderr,
    7.75 +    "Usage: %s [options ...] [-- cdrecord-options ...]\n"
    7.76 +    "Reads from standard input, block formats and writes to CD-R(W).\n\n"
    7.77 +    "  -d DEVICE      DEVICE for CD queries (default /dev/burner)\n"
    7.78 +    "  -l N           CD-R has a size of N MB (default 650)\n"
    7.79 +    "  -r DEVICE      DEVICE for CD recording (e.g. 0,4,0)\n"
    7.80 +    "  -s N           record CD at speed N (default 4)\n"
    7.81 +    "  -X             enable CDROM XA2 mode in cdrecord\n"
    7.82 +    "  -a LABEL       use LABEL as CD session title\n"
    7.83 +    "  -p N           use a padsize of N sectors for the session (default 15)\n"
    7.84 +    "  -m             enable multi-disk mode\n"
    7.85 +    "  -c COMMAND     call COMMAND on disk change in multi-disk mode\n"
    7.86 +    "  -v             be verbose\n"
    7.87 +    "  -V             prints version & exits\n"
    7.88 +    "  --             pass rest of commandline to cdrecord\n"
    7.89 +    "\n", prg_name);
    7.90 +}
    7.91 +
    7.92 +/****************************************************************************/
    7.93 +
    7.94 +void parse_cmdline(char argc, char *argv[]) 
    7.95 +{
    7.96 +  int i;
    7.97 +
    7.98 +  while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVX"))>0) {
    7.99 +    switch (i) {
   7.100 +       case 'V': fprintf(stderr,"cdbackup "VERSION" (compiled "__DATE__")\n"
   7.101 +	                        "Copyright (C) 2000-2002\n"
   7.102 +			        "This is free software; see the source for copying conditions.\n"
   7.103 +			        "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
   7.104 +			        "PARTICULAR PURPOSE.\n");
   7.105 +                 exit(0);
   7.106 +       case 'v': verbose=1; break;
   7.107 +       case 'm': multidisk=1; break;
   7.108 +       case 'X': xamode2=1; break;
   7.109 +       case 'c': multicmd=optarg; break;
   7.110 +       case 'd': cd_dev=optarg; break;
   7.111 +       case 'r': cdr_dev=optarg; break;
   7.112 +       case 'a': cd_label=optarg; break;
   7.113 +       case 'l': errno=0; cd_len=strtol(optarg,NULL,10);
   7.114 +                 if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n");
   7.115 +	         cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */
   7.116 +	         break;
   7.117 +       case 's': errno=0; cd_speed=strtol(optarg,NULL,10);
   7.118 +                 if(errno==ERANGE || cd_speed<1) serror("Option -s: speed out of range (must be >=1)\n");
   7.119 +	         break;
   7.120 +       case 'p': errno=0; padsize=strtol(optarg,NULL,10);
   7.121 +                 if(errno==ERANGE || padsize<15) serror("Option -p: padsize out of range (must be >=15)\n");
   7.122 +	         break;
   7.123 +       default:  usage(); exit(0);
   7.124 +       }
   7.125 +    }
   7.126 +
   7.127 +  if(optind<argc) { /* save position/count of cdrecord options */
   7.128 +    cdrec_opt_count=argc-optind;
   7.129 +    cdrec_opt=&argv[optind];
   7.130 +    }
   7.131 +    
   7.132 +  if(!cdr_dev) serror("You must specify a device for cdrecord with -r\n");
   7.133 +}
   7.134 +
   7.135 +/****************************************************************************/
   7.136 +
   7.137 +#define MARG(ptr,len,form,arg) { int l=(len);\
   7.138 +                               if(!(*ptr=(char *)malloc(l+1))) serror("No memory for cdrecord args\n");\
   7.139 +                               snprintf(*ptr++,l,form,arg);\
   7.140 +                             }
   7.141 +
   7.142 +void start_cdrecord() 
   7.143 +{
   7.144 +  char **args, **p;
   7.145 +  int l;
   7.146 +  
   7.147 +  if(!(p=args=calloc(cdrec_opt_count+8,sizeof(char *))))
   7.148 +    serror("No memory for cdrecord args\n");
   7.149 +
   7.150 +  *p++="cdrecord";
   7.151 +  *p++="-multi";
   7.152 +  MARG(p,16,"speed=%d",cd_speed);
   7.153 +  MARG(p,6+strlen(cdr_dev),"dev=%s",cdr_dev);
   7.154 +
   7.155 +  for(l=0 ; l<cdrec_opt_count ; l++) *p++=cdrec_opt[l];
   7.156 +
   7.157 +  MARG(p,20,"padsize=%ds",padsize);
   7.158 +  if(xamode2) *p++="-xa2"; else *p++="-data";
   7.159 +  *p++="-";
   7.160 +  *p++=0;
   7.161 +
   7.162 +  if(verbose) {
   7.163 +    fprintf(stderr,"%s: cdrecord command:",prg_name);
   7.164 +    for(p=args ; *p ; p++) fprintf(stderr," %s",*p);
   7.165 +    fprintf(stderr,"\n");
   7.166 +    }
   7.167 +
   7.168 +  execvp("cdrecord",args);
   7.169 +  error("Unable to launch cdrecord");
   7.170 +}
   7.171 +
   7.172 +/****************************************************************************/
   7.173 +
   7.174 +int backup(char disk_set)
   7.175 +{
   7.176 +  pid_t childpid;
   7.177 +  int fd[2];
   7.178 +  int outpipe, bytes;
   7.179 +  long long grandTotal=0;
   7.180 +  struct header_block header;
   7.181 +
   7.182 +  char buffer[CD_FRAMESIZE];
   7.183 +  struct data_block *db=(struct data_block *)&buffer[0];
   7.184 +
   7.185 +  sprintf(buffer, "%04d%02d%02d%02d%02d", curtime.tm_year + 1900,
   7.186 +    curtime.tm_mon + 1, curtime.tm_mday, curtime.tm_hour, curtime.tm_min);
   7.187 +  
   7.188 +  strncpy(header.id_str,HDR_STRING,32); header.id_str[32] = 0;
   7.189 +  strncpy(header.vol_id,cd_label,32); header.vol_id[32] = 0;
   7.190 +  strncpy(header.t_stamp,buffer,12); header.t_stamp[12] = 0;
   7.191 +  header.disk_set = disk_set;
   7.192 +
   7.193 +  if(verbose)
   7.194 +    fprintf(stderr,"%s: Recording to device %s, multidisk %s, disk %d\n",prg_name,cdr_dev,multidisk?"enabled":"disabled",disk_set); 
   7.195 +
   7.196 +#ifndef DEBUGOUT /* the "real" code */
   7.197 +  /* launch cdrecord */
   7.198 +  if(pipe(fd) == -1) error("Unable to create pipe handles");
   7.199 +  if((childpid=fork()) == -1) error("Fork failed");
   7.200 +  if(childpid == 0) {        /* child */
   7.201 +    close(fd[1]);
   7.202 +    close(0);		     /* stdin */
   7.203 +    dup2(fd[0], 0);
   7.204 +    start_cdrecord();        /* doesn't return */
   7.205 +    }
   7.206 +
   7.207 +  close(fd[0]); outpipe=fd[1];
   7.208 +  
   7.209 +  /* output the header block */
   7.210 +  memset(buffer,0,CD_FRAMESIZE);
   7.211 +  memcpy(buffer,&header,sizeof(struct header_block));
   7.212 +  if((bytes=write(outpipe, buffer, CD_FRAMESIZE)) != CD_FRAMESIZE) error("Error writing header block");
   7.213 +
   7.214 +  cd_avail-=bytes; grandTotal+=bytes;
   7.215 +  /* account for the padsize */
   7.216 +  cd_avail-=padsize*CD_FRAMESIZE;
   7.217 +#else
   7.218 +  /* debug code; send data to /dev/null.  Don't need the pipe. */
   7.219 +  fprintf(stderr, "DEBUG CODE: sending data to /dev/null!\n");
   7.220 +  outpipe = open("/dev/null", O_WRONLY);
   7.221 +  if (outpipe < 0) { perror("/dev/null"); exit(1); }
   7.222 +#endif
   7.223 +
   7.224 +  db->reserved = 0;
   7.225 +
   7.226 +  do {
   7.227 +    /* read a block */
   7.228 +    db->status = 0;		         /* this isn't the last block (for now) */
   7.229 +    bytes=full_read(0,&buffer[DBSIZE],DATASIZE);
   7.230 +    if (bytes < 0) error("Error reading input");
   7.231 +    if (bytes != DATASIZE) db->status=1; /* EOF, this is the last block */
   7.232 +    db->datasize = htons(bytes);
   7.233 +
   7.234 +    /* check for free space */
   7.235 +    if(cd_avail < (CD_FRAMESIZE*2)) {	/* less than 2 block free */
   7.236 +      if(db->status==0) db->status=2;   /* if not last block, mark disk as full */
   7.237 +      }
   7.238 +
   7.239 +    /* write a block */
   7.240 +    bytes = write(outpipe, buffer, CD_FRAMESIZE);
   7.241 +    if(bytes != CD_FRAMESIZE) error("Error writing data block");
   7.242 +
   7.243 +    grandTotal+=bytes; cd_avail-=bytes;
   7.244 +    } while(db->status==0);
   7.245 +
   7.246 +  /* close pipe and wait for child termination */
   7.247 +  close(outpipe);
   7.248 +  while (wait(0) != childpid);
   7.249 +
   7.250 +  totalSize+=grandTotal;
   7.251 +  if(verbose) fprintf(stderr,"%s: Recording finished. %lld kB written (%lld kB on this disk)\n",
   7.252 +                      prg_name,totalSize/1024,grandTotal/1024);
   7.253 +
   7.254 +  if(db->status==2) return 1; /* disk was full */
   7.255 +  return 0;
   7.256 +}
   7.257 +
   7.258 +/****************************************************************************/
   7.259 +
   7.260 +int main(int argc, char *argv[]) 
   7.261 +{
   7.262 +  int cdr;
   7.263 +  int disknum, result, loop;
   7.264 +  time_t curtime_t;
   7.265 +
   7.266 +  disknum=1; totalSize=0;
   7.267 +  curtime_t=time(0); curtime=*localtime(&curtime_t);
   7.268 +
   7.269 +  parse_cmdline(argc,argv);
   7.270 +
   7.271 +  do {
   7.272 +    do {
   7.273 +      cdr=open_cdr(cd_dev); result=read_toc(cdr,0); close_cdr(cdr);
   7.274 +      print_space();
   7.275 +      loop=1;
   7.276 +  
   7.277 +      if(disknum>1 && result!=0) {
   7.278 +        fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name);
   7.279 +        if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
   7.280 +        }
   7.281 +      else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) {
   7.282 +        if(multidisk) {
   7.283 +          fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name);
   7.284 +          if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
   7.285 +          }
   7.286 +        else serror("Not enough free space on disk");
   7.287 +        }
   7.288 +      else loop=0;
   7.289 +      } while(loop);
   7.290 +
   7.291 +    result = backup(disknum);
   7.292 +    if(result == 1) {
   7.293 +      if(multidisk == 0) serror("Disk full, multi-disk not enabled. Aborting");
   7.294 +      
   7.295 +      disknum++;
   7.296 +      if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
   7.297 +      }
   7.298 +    } while (result != 0);
   7.299 +
   7.300 +  return 0;
   7.301 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/cdbackup.h	Sat Dec 29 15:22:32 2007 +0100
     8.3 @@ -0,0 +1,64 @@
     8.4 +/* cdbackup.h.
     8.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
     8.6 +
     8.7 +Redistribution and use in source and binary forms, with or without
     8.8 +modification, are permitted provided that the following conditions are met: 
     8.9 +
    8.10 +1. Redistributions of source code must retain the above copyright notice,
    8.11 +   this list of conditions and the following disclaimer. 
    8.12 +2. Redistributions in binary form must reproduce the above copyright notice,
    8.13 +   this list of conditions and the following disclaimer in the documentation
    8.14 +   and/or other materials provided with the distribution. 
    8.15 +
    8.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    8.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    8.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    8.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
    8.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    8.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    8.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    8.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    8.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    8.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    8.26 +SUCH DAMAGE.
    8.27 +*/
    8.28 +
    8.29 +#ifndef _CDBACKUP_H
    8.30 +#define _CDBACKUP_H
    8.31 +
    8.32 +#include "version.h"
    8.33 +
    8.34 +#define NO_LABEL	"CD-Backup Track"
    8.35 +#define SHORT_HDR	"cdbackup"
    8.36 +#define HDR_STRING	SHORT_HDR" "VERSION
    8.37 +
    8.38 +#define MIN_BLOCKS	2   /* min. required blocks for a session: header block, one data block */
    8.39 +
    8.40 +struct toc_entry {
    8.41 +  u_char track_no;	/* track number */
    8.42 +  char is_data;		/* 1 = data track */
    8.43 +  char is_cdbackup;	/* was it created by CD-Backup? */
    8.44 +  int sec_start;	/* start sector */
    8.45 +  char id_str[33];	/* recorder id string (32 chars) */
    8.46 +  char vol_id[33];	/* volume label (32 characters) */
    8.47 +  char t_stamp[13];	/* time stamp: yyyymmddhhmm */
    8.48 +  char disk_set;	/* disk number */
    8.49 +};
    8.50 +
    8.51 +struct header_block {
    8.52 +  char id_str[33];	/* recorder id string (32 chars) */
    8.53 +  char vol_id[33];	/* volume label (32 characters) */
    8.54 +  char t_stamp[13];	/* timestamp */
    8.55 +  char disk_set;	/* disk number - starts with 1 on multi-disk set */
    8.56 +};
    8.57 +
    8.58 +struct data_block {
    8.59 +  char status;		/* status of block (0=continue, 1=done, 2=disk full) */
    8.60 +  char reserved;	/* reserved byte to make structure 4 bytes long */
    8.61 +  short datasize;	/* # of bytes in block (max = CD_FRAMESIZE-this) */
    8.62 +};
    8.63 +
    8.64 +#define DBSIZE   sizeof(struct data_block)
    8.65 +#define DATASIZE (CD_FRAMESIZE-DBSIZE)
    8.66 +
    8.67 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/cdrestore.1	Sat Dec 29 15:22:32 2007 +0100
     9.3 @@ -0,0 +1,85 @@
     9.4 +.TH "cdrestore" "1" "0.6.2" "Stefan Hülswitt" ""
     9.5 +.SH "NAME"
     9.6 +.LP 
     9.7 +cdrestore \- Streaming restore from CD\-R(W)
     9.8 +.SH "SYNOPSIS"
     9.9 +.LP 
    9.10 +cdrestore [\-qV] [\-d \fIdevice\fP] [\-l \fIsize\fP] [\-t \fItrack\fP]
    9.11 +          [\-c \fIcommand\fP]
    9.12 +.SH "DESCRIPTION"
    9.13 +.LP 
    9.14 +cdrestore is a utility to make streaming restores from CD\-R(W) disks. It's designed to work with any backup tool which is able to restore from stdin (like tar/cpio/afio).
    9.15 +.SH "OPTIONS"
    9.16 +.LP 
    9.17 +.TP 
    9.18 +\fB\-d\fR \fIdevice\fP
    9.19 +The device name which is used for reading the backup.
    9.20 +.br 
    9.21 +(default: /dev/cdrom)
    9.22 +
    9.23 +.TP 
    9.24 +\fB\-l\fR \fIsize\fP
    9.25 +The media size in megabytes. This value is used to calculate the free space on the media.
    9.26 +.br 
    9.27 +(default: 650)
    9.28 +
    9.29 +.TP 
    9.30 +\fB\-t\fR \fItrack\fP
    9.31 +The number of the data track on the media for reading the backup.
    9.32 +.br 
    9.33 +(default: none)
    9.34 +
    9.35 +.TP 
    9.36 +\fB\-c\fR \fIcommand\fP
    9.37 +The command which is executed whenever cdrestore needs to request a new media for multi\-disk backups. This command (or script) should prompt the user and return after the device is ready again. The command receives one argument, which is the device name passed with \fB\-d\fR. This can be used to issue commands to the device like ejecting the media.
    9.38 +.br 
    9.39 +(default: use internal diskchange prompt)
    9.40 +
    9.41 +.TP 
    9.42 +\fB\-q\fR
    9.43 +Queries the media, prints out the contents and exits.
    9.44 +
    9.45 +.TP 
    9.46 +\fB\-V\fR
    9.47 +Prints out version information and exits.
    9.48 +.SH "EXAMPLES"
    9.49 +.LP 
    9.50 +To query the 700 MB media on /dev/sr0:
    9.51 +.IP 
    9.52 +cdrestore \-d /dev/sr0 \-l 700 \-q
    9.53 +
    9.54 +.LP 
    9.55 +To restore a tar archive to the current directory from track 2 of a 702 MB media on /dev/scd0:
    9.56 +.IP 
    9.57 +cdrestore \-d /dev/scd0 \-l 702 \-t 2 | tar xf \-
    9.58 +.SH "AUTHORS"
    9.59 +.LP 
    9.60 +Stefan Hülswitt <huels@iname.com>
    9.61 +.SH "SEE ALSO"
    9.62 +.LP 
    9.63 +\fBcdbackup\fR(1)
    9.64 +.SH "LICENSE"
    9.65 +Copyright (c) 2000\-2002 Craig Condit, Stefan Hülswitt.
    9.66 +
    9.67 +Redistribution and use in source and binary forms, with or without
    9.68 +modification, are permitted provided that the following conditions are met: 
    9.69 +
    9.70 +.TP 
    9.71 +1.
    9.72 +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
    9.73 +.TP 
    9.74 +2.
    9.75 +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.
    9.76 +
    9.77 +.LP 
    9.78 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    9.79 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    9.80 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    9.81 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
    9.82 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    9.83 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    9.84 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    9.85 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    9.86 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    9.87 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    9.88 +SUCH DAMAGE.
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/cdrestore.c	Sat Dec 29 15:22:32 2007 +0100
    10.3 @@ -0,0 +1,261 @@
    10.4 +/* cdrestore.c
    10.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
    10.6 +
    10.7 +Redistribution and use in source and binary forms, with or without
    10.8 +modification, are permitted provided that the following conditions are met: 
    10.9 +
   10.10 +1. Redistributions of source code must retain the above copyright notice,
   10.11 +   this list of conditions and the following disclaimer. 
   10.12 +2. Redistributions in binary form must reproduce the above copyright notice,
   10.13 +   this list of conditions and the following disclaimer in the documentation
   10.14 +   and/or other materials provided with the distribution. 
   10.15 +
   10.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   10.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   10.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   10.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   10.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   10.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   10.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   10.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   10.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   10.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   10.26 +SUCH DAMAGE.
   10.27 +*/
   10.28 +
   10.29 +#define _LARGEFILE64_SOURCE
   10.30 +
   10.31 +#include <stdio.h>
   10.32 +#include <stdlib.h>
   10.33 +#include <string.h>
   10.34 +#include <unistd.h>
   10.35 +#include <fcntl.h>
   10.36 +#include <time.h>
   10.37 +#include <errno.h>
   10.38 +#include <getopt.h>
   10.39 +#include <sys/ioctl.h>
   10.40 +#include <sys/wait.h>
   10.41 +#include <netinet/in.h>
   10.42 +#include <linux/cdrom.h>
   10.43 +
   10.44 +#include "cdbackup.h"
   10.45 +#include "cdrom.h"
   10.46 +#include "misc.h"
   10.47 +#include "version.h"
   10.48 +
   10.49 +/* defaults */
   10.50 +char * prg_name ="cdrestore";
   10.51 +int    cd_mode  =0;
   10.52 +int    cd_track =-1;
   10.53 +char * cd_dev   ="/dev/cdrom";
   10.54 +long   cd_len   =333000; /* blocks */
   10.55 +char * multicmd =0;
   10.56 +int    verbose  =1;
   10.57 +
   10.58 +int tracks;
   10.59 +long long totalSize;
   10.60 +struct header_block headersave;
   10.61 +
   10.62 +/****************************************************************************/
   10.63 +
   10.64 +void usage()
   10.65 +{
   10.66 +  fprintf(stderr,
   10.67 +    "Usage: %s [OPTION]...\n"
   10.68 +    "Reads block input from CD-R(W) and writes it to standard output.\n\n"
   10.69 +    "  -d DEVICE      DEVICE for CD queries (e.g. /dev/sr0)\n"
   10.70 +    "  -q             query disk and print TOC only\n"
   10.71 +    "  -t N           restore from track N\n"
   10.72 +    "  -l N           CD-R has a size of N MB\n"
   10.73 +    "  -c COMMAND     call COMMAND on disk change in multi-disk mode\n"
   10.74 +    "  -V             prints version & exits\n"
   10.75 +    "\n", prg_name);
   10.76 +}
   10.77 +
   10.78 +/****************************************************************************/
   10.79 +
   10.80 +void parse_cmdline(char argc, char *argv[]) 
   10.81 +{
   10.82 +  int i;
   10.83 +
   10.84 +  while ((i=getopt(argc,argv,"d:l:c:t:qV"))>0) {
   10.85 +    switch (i) {
   10.86 +       case 'V': fprintf(stderr,"cdrestore "VERSION" (compiled "__DATE__")\n"
   10.87 +	                        "Copyright (C) 2000-2002\n"
   10.88 +			        "This is free software; see the source for copying conditions.\n"
   10.89 +			        "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
   10.90 +			        "PARTICULAR PURPOSE.\n");
   10.91 +	         exit(0);
   10.92 +       case 'c': multicmd=optarg; break;
   10.93 +       case 'd': cd_dev=optarg; break;
   10.94 +       case 'q': cd_mode=1; break;
   10.95 +       case 't': errno=0; cd_track=strtol(optarg,NULL,10);
   10.96 +                 if(errno==ERANGE || cd_track<1) serror("Option -t: invalid track (must be >=1)\n");
   10.97 +	         break;
   10.98 +       case 'l': errno=0; cd_len=strtol(optarg,NULL,10);
   10.99 +                 if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n");
  10.100 +	         cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */
  10.101 +	         break;
  10.102 +       default:  usage(); exit(0);
  10.103 +       }
  10.104 +    }
  10.105 +
  10.106 +  if(!cd_mode && cd_track<0) /* need track number */
  10.107 +    serror("A track number is required.\n");
  10.108 +}
  10.109 +
  10.110 +/****************************************************************************/
  10.111 +
  10.112 +void print_track(int track, char *stamp, char *id, int disk, int startsec, int endsec)
  10.113 +{
  10.114 +  char timestr[32], size[32];
  10.115 +
  10.116 +  snprintf(timestr,sizeof(timestr)-1,"%02d/%02d/%04d %02d:%02d",
  10.117 +    (stamp[4]-'0')*10   + (stamp[5]-'0'), 
  10.118 +    (stamp[6]-'0')*10   + (stamp[7]-'0'),
  10.119 +    (stamp[0]-'0')*1000 + (stamp[1]-'0')*100 + (stamp[2]-'0')*10 + (stamp[3]-'0'),
  10.120 +    (stamp[8]-'0')*10   + (stamp[9]-'0'),
  10.121 +    (stamp[10]-'0')*10  + (stamp[11]-'0'));
  10.122 +
  10.123 +  if(startsec>=0) snprintf(size,sizeof(size)-1," %3ld MB:",(long)((long long)(endsec-startsec)*CD_FRAMESIZE/(1024*1024)));
  10.124 +  else size[0]=0;
  10.125 +
  10.126 +  fprintf(stderr,"Track %02d:%s %s  Part %d: %s\n", track, size, timestr, disk, id);
  10.127 +}
  10.128 +
  10.129 +/****************************************************************************/
  10.130 +
  10.131 +int restore(int disknum, int disktrack)
  10.132 +{
  10.133 +  int infile;
  10.134 +  int result=0, i, bytes;
  10.135 +  long long totalRead;
  10.136 +  struct header_block header;
  10.137 +  char buffer[CD_FRAMESIZE];
  10.138 +  struct data_block *db=(struct data_block *)&buffer[0];
  10.139 +
  10.140 +  if ((infile = open(cd_dev, O_RDONLY)) < 0) error("Error opening device");
  10.141 +
  10.142 +  /* seek to proper CD-R(W) track */
  10.143 +  for(i=tracks;i>0;i--) if(toc[i].track_no==disktrack) break;
  10.144 +  if(!i) { fprintf(stderr, "%s: Can't find track %d\n", prg_name, disktrack); exit(1); }
  10.145 +
  10.146 +  totalRead=(long long)toc[i].sec_start*CD_FRAMESIZE;
  10.147 +  if(lseek64(infile,totalRead,SEEK_SET) != totalRead) error("Error seeking to track");
  10.148 +
  10.149 +  /* read header block */
  10.150 +  bytes=full_read(infile,buffer,CD_FRAMESIZE);
  10.151 +  if (bytes < 0) error("Error reading header block");
  10.152 +  if (bytes != CD_FRAMESIZE) error("Unexpected EOF reading header block");
  10.153 +  totalRead = bytes;
  10.154 +
  10.155 +  memcpy(&header,buffer,sizeof(header));
  10.156 +
  10.157 +  if(!strncmp(SHORT_HDR,header.id_str,strlen(SHORT_HDR))) {
  10.158 +    fprintf(stderr,"%s: ", prg_name);
  10.159 +    print_track(disktrack, header.t_stamp, header.vol_id, header.disk_set, -1, -1);
  10.160 +
  10.161 +    if(disknum==1) {
  10.162 +      if(header.disk_set!=1) {
  10.163 +        fprintf(stderr,"%s: This is disk %d of a multi-disk set. Restore can only be started with disk 1!\n",prg_name,header.disk_set);
  10.164 +        exit(1);
  10.165 +        }
  10.166 +      headersave=header;		/* save header for use with disk 2-n */
  10.167 +      }
  10.168 +    else {
  10.169 +      if(strcmp(header.t_stamp,headersave.t_stamp) || strcmp(header.vol_id,headersave.vol_id)) {
  10.170 +        fprintf(stderr,"%s: This disk doesn't belong to the current set!\n",prg_name);
  10.171 +        result=2;
  10.172 +        }
  10.173 +      else if(header.disk_set!=disknum) {
  10.174 +        fprintf(stderr,"%s: Wrong sequence. You need disk %d now!\n",prg_name,disknum);
  10.175 +        result=2;
  10.176 +        }
  10.177 +      else fprintf(stderr, "%s: Beginning restore (Disk %d)\n", prg_name,disknum);
  10.178 +      }
  10.179 +    }
  10.180 +  else {
  10.181 +    fprintf(stderr, "%s: Track %02d was not created with 'cdbackup'\n", prg_name,disktrack);
  10.182 +    if(disknum==1) exit(1);
  10.183 +    result=2;
  10.184 +    }
  10.185 +
  10.186 +  while(!result) {
  10.187 +    int size;
  10.188 +
  10.189 +    /* read data block */
  10.190 +    bytes = full_read(infile, buffer, CD_FRAMESIZE);
  10.191 +    if (bytes < 0) error("Error reading data");
  10.192 +    if (bytes != CD_FRAMESIZE) error("Unexpected EOF reading data");
  10.193 +    totalRead += bytes;
  10.194 +
  10.195 +    /* sanity check */
  10.196 +    size=ntohs(db->datasize);
  10.197 +    if(size>DATASIZE) {
  10.198 +      fprintf(stderr,"%s: Warning! Bad datasize at %lld\n",prg_name,totalRead);
  10.199 +      size=DATASIZE;
  10.200 +      }
  10.201 +
  10.202 +    /* write the data block */
  10.203 +    bytes=write(1,&buffer[DBSIZE], size);
  10.204 +    if(bytes!=size) error("Error writing data");
  10.205 +
  10.206 +    if(db->status == 1) break; 	  /* end of backup*/
  10.207 +    if(db->status == 2) result=1; /* disk full */
  10.208 +    }
  10.209 +
  10.210 +  /* print status */
  10.211 +  totalSize+=totalRead;
  10.212 +  if(result!=2) fprintf(stderr, "%s: Restore complete. %lld kB read (%lld kB from this disk)\n",prg_name, totalSize/1024, totalRead/1024);
  10.213 +
  10.214 +  close(infile);
  10.215 +  return(result);
  10.216 +}
  10.217 +
  10.218 +/****************************************************************************/
  10.219 +
  10.220 +void print_toc()
  10.221 +{
  10.222 +  int i;
  10.223 +
  10.224 +  fprintf(stderr,"Tracks: %d\n",tracks);
  10.225 +  print_space();
  10.226 +  fprintf(stderr,"\n");
  10.227 +  
  10.228 +  for (i = 1; i <= tracks; i++) {
  10.229 +    if(toc[i].is_data==0) fprintf(stderr,"Track %02d: Non-data\n", toc[i].track_no);
  10.230 +    else if (toc[i].is_cdbackup == 1)
  10.231 +      print_track(i, toc[i].t_stamp, toc[i].vol_id, toc[i].disk_set, toc[i].sec_start, i==tracks?toc[0].sec_start:toc[i+1].sec_start);
  10.232 +    else fprintf(stderr,"Track %02d: Data\n", toc[i].track_no);
  10.233 +    }
  10.234 +}
  10.235 +
  10.236 +/****************************************************************************/
  10.237 +
  10.238 +int main(int argc, char *argv[])
  10.239 +{
  10.240 +  int cdr;
  10.241 +
  10.242 +  parse_cmdline(argc, argv);
  10.243 +
  10.244 +  if(!cd_mode) {
  10.245 +    int disknum=1, result;
  10.246 +    totalSize=0;
  10.247 +    do {
  10.248 +      cdr=open_cdr(cd_dev); tracks=read_toc(cdr,0); close_cdr(cdr);
  10.249 +
  10.250 +      result=restore(disknum,cd_track);
  10.251 +      if(result) {
  10.252 +        if(result==1) { disknum++; cd_track=1; }
  10.253 +        fprintf(stderr,"%s: Next disk needed: disk %d from %s\n",prg_name,disknum,headersave.vol_id);
  10.254 +        if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
  10.255 +	}
  10.256 +      } while(result);
  10.257 +    }
  10.258 +  else {
  10.259 +    cdr=open_cdr(cd_dev); tracks=read_toc(cdr,1); close_cdr(cdr);
  10.260 +    print_toc();
  10.261 +    }
  10.262 +
  10.263 +  return 0;
  10.264 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/cdrom.c	Sat Dec 29 15:22:32 2007 +0100
    11.3 @@ -0,0 +1,168 @@
    11.4 +/* cdrom.c
    11.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
    11.6 +
    11.7 +Redistribution and use in source and binary forms, with or without
    11.8 +modification, are permitted provided that the following conditions are met: 
    11.9 +
   11.10 +1. Redistributions of source code must retain the above copyright notice,
   11.11 +   this list of conditions and the following disclaimer. 
   11.12 +2. Redistributions in binary form must reproduce the above copyright notice,
   11.13 +   this list of conditions and the following disclaimer in the documentation
   11.14 +   and/or other materials provided with the distribution. 
   11.15 +
   11.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   11.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   11.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   11.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   11.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   11.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   11.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   11.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   11.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   11.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   11.26 +SUCH DAMAGE.
   11.27 +*/
   11.28 +
   11.29 +#define _LARGEFILE64_SOURCE
   11.30 +
   11.31 +#include <stdlib.h>
   11.32 +#include <stdio.h>
   11.33 +#include <unistd.h>
   11.34 +#include <fcntl.h>
   11.35 +#include <string.h>
   11.36 +#include <linux/cdrom.h>
   11.37 +#include <sys/ioctl.h>
   11.38 +
   11.39 +#include "cdbackup.h"
   11.40 +#include "misc.h"
   11.41 +
   11.42 +/* size of leadin/out depending of how many tracks are on cd */
   11.43 +#define MIN_FREE_1	(11400*CD_FRAMESIZE) /* 1th track */
   11.44 +#define MIN_FREE_2	(6900*CD_FRAMESIZE)  /* 2nd and more tracks */
   11.45 +
   11.46 +struct toc_entry *toc=0;
   11.47 +long long cd_used, cd_avail;
   11.48 +
   11.49 +extern long cd_len;
   11.50 +extern int verbose;
   11.51 +extern char *prg_name;
   11.52 +
   11.53 +/****************************************************************************/
   11.54 +
   11.55 +int open_cdr(char *device) 
   11.56 +{
   11.57 +  return open(device, O_RDONLY | O_NONBLOCK);
   11.58 +}
   11.59 +
   11.60 +/****************************************************************************/
   11.61 +
   11.62 +void close_cdr(int cd_fd)
   11.63 +{
   11.64 +  close(cd_fd);
   11.65 +}
   11.66 +
   11.67 +/****************************************************************************/
   11.68 +
   11.69 +int full_read(int fd, void *buf, int count)
   11.70 +{
   11.71 +  int total=0;
   11.72 +
   11.73 +  while(count>0) {
   11.74 +    int bytes;
   11.75 +    bytes=read(fd,buf,count); if(bytes<0) return bytes;
   11.76 +    if(bytes==0) break;
   11.77 +    count-=bytes; total+=bytes; buf+=bytes;
   11.78 +    }
   11.79 +  return total;
   11.80 +}
   11.81 +
   11.82 +/****************************************************************************/
   11.83 +
   11.84 +void free_toc()
   11.85 +{
   11.86 +  if(toc) { free(toc); toc=0; }
   11.87 +}
   11.88 +
   11.89 +/****************************************************************************/
   11.90 +
   11.91 +int read_toc(int cd_fd, int trackinfos)
   11.92 +{
   11.93 +  int i;
   11.94 +  struct cdrom_tochdr cd_header;
   11.95 +  struct cdrom_tocentry cd_entry;
   11.96 +  int tracks,start_track;
   11.97 + 
   11.98 +  /* read table of contents header */
   11.99 +  if(ioctl(cd_fd,CDROMREADTOCHDR,&cd_header)) {
  11.100 +    if(verbose) fprintf(stderr,"%s: Unable to read CD header, assuming empty CD-R\n", prg_name);
  11.101 +    cd_used=0; cd_avail=(long long)cd_len*CD_FRAMESIZE; return 0;
  11.102 +    }
  11.103 +
  11.104 +  /* get start and end tracks */
  11.105 +  start_track = cd_header.cdth_trk0;
  11.106 +  tracks = cd_header.cdth_trk1-start_track+1;
  11.107 +
  11.108 +  free_toc();
  11.109 +  if(!(toc=calloc(tracks+1,sizeof(struct toc_entry)))) serror("No memory for TOC");
  11.110 +
  11.111 +  /* set some parameters */
  11.112 +  cd_entry.cdte_format=CDROM_LBA;
  11.113 +
  11.114 +  /* read lead-out */
  11.115 +  cd_entry.cdte_track=CDROM_LEADOUT;
  11.116 +  if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading lead-out");
  11.117 +
  11.118 +  toc[0].track_no=CDROM_LEADOUT;  /* not a real track */
  11.119 +  toc[0].sec_start=cd_entry.cdte_addr.lba;
  11.120 +
  11.121 +  cd_used=(long long)toc[0].sec_start*CD_FRAMESIZE; cd_avail=(long long)cd_len*CD_FRAMESIZE-cd_used;
  11.122 +  cd_avail-=(tracks>1?MIN_FREE_2:MIN_FREE_1);
  11.123 +  if(cd_avail<0) cd_avail=0; /* can be <0 due to assumed additional lead-in/out */
  11.124 +
  11.125 +  /* read rest of tracks */
  11.126 +  for(i=1; i<=tracks; i++) {
  11.127 +    cd_entry.cdte_track=start_track+i-1;
  11.128 +    if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading TOC");  
  11.129 +
  11.130 +    toc[i].track_no=start_track+i-1;
  11.131 +    toc[i].sec_start=cd_entry.cdte_addr.lba;
  11.132 +    if(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) toc[i].is_data=1;
  11.133 +    }    
  11.134 +
  11.135 + if(trackinfos)
  11.136 +  /* now loop through tracks and read header info */
  11.137 +  for(i=1; i<=tracks; i++) {
  11.138 +    char inbuffer[CD_FRAMESIZE];
  11.139 +    struct header_block *track_header=(struct header_block *)&inbuffer[0];
  11.140 +
  11.141 +    if (toc[i].is_data == 1) {
  11.142 +      if(lseek64(cd_fd,(long long)toc[i].sec_start*CD_FRAMESIZE,SEEK_SET)<0) error("Seek failed");
  11.143 +
  11.144 +      if(full_read(cd_fd,inbuffer,CD_FRAMESIZE)==CD_FRAMESIZE) {
  11.145 +        if(!strncmp(SHORT_HDR,track_header->id_str,strlen(SHORT_HDR))) {
  11.146 +          toc[i].is_cdbackup=1;
  11.147 +          strncpy(toc[i].id_str,track_header->id_str,32); toc[i].id_str[32]=0;
  11.148 +          strncpy(toc[i].vol_id, track_header->vol_id,32); toc[i].vol_id[32]=0;
  11.149 +          strncpy(toc[i].t_stamp, track_header->t_stamp,12); toc[i].t_stamp[12]=0;
  11.150 +          toc[i].disk_set = track_header->disk_set;
  11.151 +          }
  11.152 +        }      
  11.153 +      }
  11.154 +    }
  11.155 +  
  11.156 +  return tracks;
  11.157 +}
  11.158 +
  11.159 +/****************************************************************************/
  11.160 +
  11.161 +void print_space() 
  11.162 +{
  11.163 +  if(verbose)
  11.164 +    fprintf(stderr,
  11.165 +      "Disk size:  %7lld kB (%7ld blocks)\n"
  11.166 +      "Space used: %7lld kB (%7lld blocks)\n"
  11.167 +      "Space avail:%7lld kB (%7lld blocks)\n",
  11.168 +      (long long)cd_len*CD_FRAMESIZE/1024,cd_len,
  11.169 +      cd_used/1024, cd_used/CD_FRAMESIZE,
  11.170 +      cd_avail/1024, cd_avail/CD_FRAMESIZE);
  11.171 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/cdrom.h	Sat Dec 29 15:22:32 2007 +0100
    12.3 @@ -0,0 +1,39 @@
    12.4 +/* cdrom.h
    12.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
    12.6 +
    12.7 +Redistribution and use in source and binary forms, with or without
    12.8 +modification, are permitted provided that the following conditions are met: 
    12.9 +
   12.10 +1. Redistributions of source code must retain the above copyright notice,
   12.11 +   this list of conditions and the following disclaimer. 
   12.12 +2. Redistributions in binary form must reproduce the above copyright notice,
   12.13 +   this list of conditions and the following disclaimer in the documentation
   12.14 +   and/or other materials provided with the distribution. 
   12.15 +
   12.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   12.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   12.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   12.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   12.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   12.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   12.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   12.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   12.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   12.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   12.26 +SUCH DAMAGE.
   12.27 +*/
   12.28 +
   12.29 +#ifndef _CDBACKUP_CDROM_H
   12.30 +#define _CDBACKUP_CDROM_H
   12.31 +
   12.32 +extern struct toc_entry *toc;
   12.33 +extern long long cd_used, cd_avail;
   12.34 +
   12.35 +int open_cdr(char *device);
   12.36 +void close_cdr(int cd_fd);
   12.37 +int full_read(int fd, void *buf, int count);
   12.38 +int read_toc(int cd_fd, int trackinfos);
   12.39 +void free_toc();
   12.40 +void print_space();
   12.41 +
   12.42 +#endif
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/examples/cdbackup-diskchange	Sat Dec 29 15:22:32 2007 +0100
    13.3 @@ -0,0 +1,15 @@
    13.4 +#!/bin/bash
    13.5 +#
    13.6 +# This is an example diskchange-script
    13.7 +#
    13.8 +# $1 is the cdrom-device e.g. /dev/sr0
    13.9 +
   13.10 +echo
   13.11 +echo
   13.12 +echo "Disk full!!"
   13.13 +eject $1
   13.14 +echo "Please replace and press RETURN"
   13.15 +echo 
   13.16 +echo
   13.17 +read 
   13.18 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/examples/cdrestore-diskchange	Sat Dec 29 15:22:32 2007 +0100
    14.3 @@ -0,0 +1,13 @@
    14.4 +#!/bin/bash
    14.5 +#
    14.6 +# This is an example diskchange-script
    14.7 +#
    14.8 +# $1 is the cdrom-device e.g. /dev/sr0
    14.9 +
   14.10 +eject $1
   14.11 +echo 
   14.12 +echo 
   14.13 +echo  "Please insert next disk and press RETURN"
   14.14 +echo 
   14.15 +echo 
   14.16 +read 
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/misc.c	Sat Dec 29 15:22:32 2007 +0100
    15.3 @@ -0,0 +1,83 @@
    15.4 +/* misc.c
    15.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
    15.6 +
    15.7 +Redistribution and use in source and binary forms, with or without
    15.8 +modification, are permitted provided that the following conditions are met: 
    15.9 +
   15.10 +1. Redistributions of source code must retain the above copyright notice,
   15.11 +   this list of conditions and the following disclaimer. 
   15.12 +2. Redistributions in binary form must reproduce the above copyright notice,
   15.13 +   this list of conditions and the following disclaimer in the documentation
   15.14 +   and/or other materials provided with the distribution. 
   15.15 +
   15.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   15.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   15.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   15.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   15.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   15.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   15.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   15.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   15.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   15.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   15.26 +SUCH DAMAGE.
   15.27 +*/
   15.28 +
   15.29 +#include <stdlib.h>
   15.30 +#include <stdio.h>
   15.31 +#include <unistd.h>
   15.32 +#include <string.h>
   15.33 +#include <sys/wait.h>
   15.34 +#include <errno.h>
   15.35 +
   15.36 +extern char *prg_name;
   15.37 +
   15.38 +/****************************************************************************/
   15.39 +
   15.40 +void error(char *text)
   15.41 +{
   15.42 +  fprintf(stderr,"%s: %s: %s\n",prg_name,text,strerror(errno));
   15.43 +  exit(1);
   15.44 +}
   15.45 +
   15.46 +/****************************************************************************/
   15.47 +
   15.48 +void serror(char *text)
   15.49 +{
   15.50 +  fprintf(stderr,"%s: %s\n",prg_name,text);
   15.51 +  exit(1);
   15.52 +}
   15.53 +
   15.54 +/****************************************************************************/
   15.55 +
   15.56 +int start_diskchange(char *multicmd, char *cd_dev)
   15.57 +{
   15.58 +int pid, status=0;
   15.59 +char buffer[12];
   15.60 +
   15.61 +if(multicmd) { /* we have an external script */
   15.62 +  if((pid=fork())<0) error("Fork failed in diskchange");
   15.63 +  if(pid==0) { /* child */
   15.64 +    char *argv[3];
   15.65 +
   15.66 +    dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */
   15.67 +    argv[0] = multicmd;
   15.68 +    argv[1] = cd_dev;
   15.69 +    argv[2] = 0;
   15.70 +    execvp(multicmd, argv);
   15.71 +    error("Starting diskchange command failed");
   15.72 +    }
   15.73 +
   15.74 +  while(1) {
   15.75 +    if(waitpid(pid,&status,0)==-1) { if (errno != EINTR) { status=-1; break; } }
   15.76 +    else break;
   15.77 +    }
   15.78 +  }
   15.79 +else { /* use internal diskchange */
   15.80 +  fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n");
   15.81 +  do {
   15.82 +    pid=read(2,buffer,sizeof(buffer));
   15.83 +    } while(pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n');
   15.84 +  }
   15.85 +return status;
   15.86 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/misc.h	Sat Dec 29 15:22:32 2007 +0100
    16.3 @@ -0,0 +1,33 @@
    16.4 +/* misc.h
    16.5 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
    16.6 +
    16.7 +Redistribution and use in source and binary forms, with or without
    16.8 +modification, are permitted provided that the following conditions are met: 
    16.9 +
   16.10 +1. Redistributions of source code must retain the above copyright notice,
   16.11 +   this list of conditions and the following disclaimer. 
   16.12 +2. Redistributions in binary form must reproduce the above copyright notice,
   16.13 +   this list of conditions and the following disclaimer in the documentation
   16.14 +   and/or other materials provided with the distribution. 
   16.15 +
   16.16 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   16.17 +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   16.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   16.19 +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
   16.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   16.21 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   16.22 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   16.23 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   16.24 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   16.25 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   16.26 +SUCH DAMAGE.
   16.27 +*/
   16.28 +
   16.29 +#ifndef _CDBACKUP_MISC_H
   16.30 +#define _CDBACKUP_MISC_H
   16.31 +
   16.32 +int start_diskchange(char *multicmd, char *cd_dev);
   16.33 +void error(char *text);
   16.34 +void serror(char *text);
   16.35 +
   16.36 +#endif
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/version.h	Sat Dec 29 15:22:32 2007 +0100
    17.3 @@ -0,0 +1,8 @@
    17.4 +#ifndef _CDBACKUP_VERSION_H
    17.5 +#define _CDBACKUP_VERSION_H
    17.6 +
    17.7 +#ifndef VERSION
    17.8 +#define VERSION "0.6.2"
    17.9 +#endif
   17.10 +
   17.11 +#endif