# HG changeset patch # User nathan # Date 1198938152 -3600 # Node ID d85c12073deaa1b5048d3a8c761d9dd55d8169a1 release 0.6.2 diff -r 000000000000 -r d85c12073dea CHANGES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CHANGES Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,37 @@ +0.6.2 +----- +1. some more fixes to allow >2GB data on a single disk (SH) +2. added commandline option to specify padsize and enable CDROM + XA2 mode (SH) +3. changed gcc options in Makefile (SH) +4. code cleanup (SH) +5. added man page, updated README (SH) + +0.6.1 +----- +1. fixed size calculations with multi-disk backups > 2GB (SH) +2. minor message cleanups (CC) + +0.6 +--- +1. multidisk-support (SH) +2. unix-like commandline options (SH) +3. can pass additional options to cdrecord (SH) +4. code cleanup (SH) +5. various bugs fixed (SH) + +0.5.2 +----- +1. Revamped Makefile (CC) + +0.5.1 +----- +1. Fixed bug in command-line parsing (JY) +2. Added error messages to command-line parsing (JY, CC) +3. Various sloppy code fixes (JY, CC) +4. Changed Makefile to check for compiler warnings (JY, CC) + +0.5.0 +----- +Initial public release. + diff -r 000000000000 -r d85c12073dea CREDITS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CREDITS Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,22 @@ + This is list of people who have contributed to cdbackup. It is + sorted by name and formatted to allow easy grepping and + beautification by scripts. The fields are: name (N), email (E), + web-address (W), PGP key ID and fingerprint (P), description (D), + and snail-mail address (S). + +---------- + +N: Craig Condit +E: ccondit@cableone.net +D: Initial development +S: Fargo, ND USA + +N: James Youngman +E: jay@gnu.org +D: Various bugfixes +S: Manchester, UK + +N: Stefan Huelswitt +E: huels@iname.com +D: multidisk support, code cleanup, bugfixes +S: Monheim, Germany diff -r 000000000000 -r d85c12073dea LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,22 @@ +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. diff -r 000000000000 -r d85c12073dea Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,45 @@ +# compiler selection and options +CC=gcc +CFLAGS=-g -O2 -Wall + +# install location +PREFIX=/usr/local + +BINDIR=$(PREFIX)/bin +MANDIR=$(PREFIX)/man + +############################################### + +# executables +TARGETS=cdbackup cdrestore + +all: $(TARGETS) + +# ruleset +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +cdbackup: cdbackup.o cdrom.o misc.o + $(CC) $(CFLAGS) -o cdbackup cdbackup.o cdrom.o misc.o + +cdrestore: cdrestore.o cdrom.o misc.o + $(CC) $(CFLAGS) -o cdrestore cdrestore.o cdrom.o misc.o + +cdbackup.o: cdbackup.c cdbackup.h cdrom.h misc.h version.h +cdrestore.o: cdrestore.c cdbackup.h cdrom.h misc.h version.h +cdrom.o: cdrom.c cdbackup.h misc.h +misc.o: misc.c misc.h + +# targets +strip: $(TARGETS) + strip $(TARGETS) + +clean: + rm -f $(TARGETS) core *.core *.o + +install: + install -d $(BINDIR) + install $(TARGETS) $(BINDIR) + install -d $(MANDIR)/man1 + gzip -c cdbackup.1 >$(MANDIR)/man1/cdbackup.1.gz + gzip -c cdrestore.1 >$(MANDIR)/man1/cdrestore.1.gz diff -r 000000000000 -r d85c12073dea README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,52 @@ +cdbackup, cdrestore - CD archive utilities version 0.6.2 +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. All rights reserved. + +This software is released under a BSD-style license - see the LICENSE file. + +cdbackup and cdrestore are a pair of utilities designed to facilitiate +streaming backup to and from CD-R(W) disks. Specificially, they were +designed to work with dump/restore, but tar/cpio/whatever you want should +work, so long as it writes to stdout for backups and reads from stdin for +restores. + +NOTE: this program REQUIRES that a recent version of cdrecord be present +in the PATH. + +See manpages for further details. + + +INSTALL: +-------- + +Look at the Makefile, adjust options as you like. The default +install location is under /usr/local. + +make +make strip (optionaly) +make install + + +DISCLAIMER: +----------- + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. + + +CONTACT: +-------- + +Project maintainer is: Stefan Hülswitt +Homepage: http://www.muempf.de/ + +Any comments, suggestions, bug reports, patches and fixes +welcome. diff -r 000000000000 -r d85c12073dea cdbackup.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdbackup.1 Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,124 @@ +.TH "cdbackup" "1" "0.6.2" "Stefan Hülswitt" "" +.SH "NAME" +.LP +cdbackup \- Streaming backup to CD\-R(W) +.SH "SYNOPSIS" +.LP +cdbackup [\-mvVX] [\-d \fIdevice\fP] [\-r \fIscsi\-dev\fP] [\-s \fIspeed\fP] + [\-p \fInum\fP] [\-l \fIsize\fP] [\-a \fIlabel\fP] [\-c \fIcommand\fP] + [\-\- \fIcdrecord\-options\fP] +.SH "DESCRIPTION" +.LP +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). +.LP +NOTE: this program REQUIRES that a recent version of cdrecord is present in the PATH. +.LP +WARNING! When using this program under Linux, be sure not to use dump with +kernels in the 2.4.x series. Using dump on an ext2 filesystem has a very +high potential for causing filesystem corruption. As of kernel version +2.4.18, this has not been fixed and it may not be fixed at all. +.SH "OPTIONS" +.LP +.TP +\fB\-d\fR \fIdevice\fP +The device name which is used for reading things like the TOC from a (partly written) media. +.br +(default: /dev/burner) + +.TP +\fB\-r\fR \fIscsi\-device\fP +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. +.br +(default: none) + +.TP +\fB\-s\fR \fIspeed\fP +The writing speed which is passed to cdrecord (via speed=\fIspeed\fP). +.br +(default: 4) + +.TP +\fB\-p\fR \fInum\fP +The number of sectors (of 2048 byte) to use for padding (see \fBcdrecord\fR(1) padsize). +.br +(default: 15) + +.TP +\fB\-X\fR +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). + +.TP +\fB\-l\fR \fIsize\fP +The media size in megabytes. This value is used to calculate how much data can be stored on the media. +.br +(default: 650) + +.TP +\fB\-a\fR \fIlabel\fP +A text label to identify the backup set. The first 32 characters of this string are save with the backup. +.br +(default: "CDBackup Track") + +.TP +\fB\-c\fR \fIcommand\fP +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. +.br +(default: use internal diskchange prompt) + +.TP +\fB\-m\fR +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. + +.TP +\fB\-v\fR +Enables verbose mode. + +.TP +\fB\-V\fR +Prints out version information and exits. + +.TP +\fB\-\-\fR \fIcdrecord\-options\fP +All options following \fB\-\-\fR are passed to cdrecord. +.SH "EXAMPLES" +.LP +To create a tar archive of /home and +output it to a 700 MB CD\-R(W) on /dev/scd0 (scsi device 2,0): +.IP +tar cvf \- /home | cdbackup \-d /dev/scd0 \-r 2,0 \-l 700 \-a "Test Backup" + +.LP +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: +.IP +tar cf \- /usr | cdbackup \-d /dev/sr1 \-r 1,4,0 \-s 12 \-m \-v +.SH "AUTHORS" +.LP +Stefan Hülswitt +.SH "SEE ALSO" +.LP +\fBcdrestore\fR(1), \fBcdrecord\fR(1) +.SH "LICENSE" +Copyright (c) 2000\-2002 Craig Condit, Stefan Hülswitt. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +.TP +1. +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +.TP +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. + +.LP +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. diff -r 000000000000 -r d85c12073dea cdbackup.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdbackup.c Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,298 @@ +/* cdbackup.c +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +*/ + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdbackup.h" +#include "cdrom.h" +#include "misc.h" +#include "version.h" + +/* #define DEBUGOUT */ + +/* defaults */ +char * prg_name ="cdbackup"; +char * cd_dev ="/dev/burner"; +char * cdr_dev =0; /* no default here, too dangerous */ +char * cd_label ="CDBackup Track"; +int cd_speed =4; +long cd_len =333000; /* blocks */ +int padsize =15; /* blocks */ +int multidisk=0; +char * multicmd =0; +int verbose =0; +int xamode2 =0; + +char **cdrec_opt=0; +int cdrec_opt_count=0; + +long long totalSize; +struct tm curtime; /* global, so multi-disks get all the same time */ + +/****************************************************************************/ + +void usage() +{ + fprintf(stderr, + "Usage: %s [options ...] [-- cdrecord-options ...]\n" + "Reads from standard input, block formats and writes to CD-R(W).\n\n" + " -d DEVICE DEVICE for CD queries (default /dev/burner)\n" + " -l N CD-R has a size of N MB (default 650)\n" + " -r DEVICE DEVICE for CD recording (e.g. 0,4,0)\n" + " -s N record CD at speed N (default 4)\n" + " -X enable CDROM XA2 mode in cdrecord\n" + " -a LABEL use LABEL as CD session title\n" + " -p N use a padsize of N sectors for the session (default 15)\n" + " -m enable multi-disk mode\n" + " -c COMMAND call COMMAND on disk change in multi-disk mode\n" + " -v be verbose\n" + " -V prints version & exits\n" + " -- pass rest of commandline to cdrecord\n" + "\n", prg_name); +} + +/****************************************************************************/ + +void parse_cmdline(char argc, char *argv[]) +{ + int i; + + while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVX"))>0) { + switch (i) { + case 'V': fprintf(stderr,"cdbackup "VERSION" (compiled "__DATE__")\n" + "Copyright (C) 2000-2002\n" + "This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n" + "PARTICULAR PURPOSE.\n"); + exit(0); + case 'v': verbose=1; break; + case 'm': multidisk=1; break; + case 'X': xamode2=1; break; + case 'c': multicmd=optarg; break; + case 'd': cd_dev=optarg; break; + case 'r': cdr_dev=optarg; break; + case 'a': cd_label=optarg; break; + case 'l': errno=0; cd_len=strtol(optarg,NULL,10); + if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n"); + cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */ + break; + case 's': errno=0; cd_speed=strtol(optarg,NULL,10); + if(errno==ERANGE || cd_speed<1) serror("Option -s: speed out of range (must be >=1)\n"); + break; + case 'p': errno=0; padsize=strtol(optarg,NULL,10); + if(errno==ERANGE || padsize<15) serror("Option -p: padsize out of range (must be >=15)\n"); + break; + default: usage(); exit(0); + } + } + + if(optindreserved = 0; + + do { + /* read a block */ + db->status = 0; /* this isn't the last block (for now) */ + bytes=full_read(0,&buffer[DBSIZE],DATASIZE); + if (bytes < 0) error("Error reading input"); + if (bytes != DATASIZE) db->status=1; /* EOF, this is the last block */ + db->datasize = htons(bytes); + + /* check for free space */ + if(cd_avail < (CD_FRAMESIZE*2)) { /* less than 2 block free */ + if(db->status==0) db->status=2; /* if not last block, mark disk as full */ + } + + /* write a block */ + bytes = write(outpipe, buffer, CD_FRAMESIZE); + if(bytes != CD_FRAMESIZE) error("Error writing data block"); + + grandTotal+=bytes; cd_avail-=bytes; + } while(db->status==0); + + /* close pipe and wait for child termination */ + close(outpipe); + while (wait(0) != childpid); + + totalSize+=grandTotal; + if(verbose) fprintf(stderr,"%s: Recording finished. %lld kB written (%lld kB on this disk)\n", + prg_name,totalSize/1024,grandTotal/1024); + + if(db->status==2) return 1; /* disk was full */ + return 0; +} + +/****************************************************************************/ + +int main(int argc, char *argv[]) +{ + int cdr; + int disknum, result, loop; + time_t curtime_t; + + disknum=1; totalSize=0; + curtime_t=time(0); curtime=*localtime(&curtime_t); + + parse_cmdline(argc,argv); + + do { + do { + cdr=open_cdr(cd_dev); result=read_toc(cdr,0); close_cdr(cdr); + print_space(); + loop=1; + + if(disknum>1 && result!=0) { + fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name); + if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); + } + else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) { + if(multidisk) { + fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name); + if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); + } + else serror("Not enough free space on disk"); + } + else loop=0; + } while(loop); + + result = backup(disknum); + if(result == 1) { + if(multidisk == 0) serror("Disk full, multi-disk not enabled. Aborting"); + + disknum++; + if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); + } + } while (result != 0); + + return 0; +} diff -r 000000000000 -r d85c12073dea cdbackup.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdbackup.h Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,64 @@ +/* cdbackup.h. +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 _CDBACKUP_H +#define _CDBACKUP_H + +#include "version.h" + +#define NO_LABEL "CD-Backup Track" +#define SHORT_HDR "cdbackup" +#define HDR_STRING SHORT_HDR" "VERSION + +#define MIN_BLOCKS 2 /* min. required blocks for a session: header block, one data block */ + +struct toc_entry { + u_char track_no; /* track number */ + char is_data; /* 1 = data track */ + char is_cdbackup; /* was it created by CD-Backup? */ + int sec_start; /* start sector */ + char id_str[33]; /* recorder id string (32 chars) */ + char vol_id[33]; /* volume label (32 characters) */ + char t_stamp[13]; /* time stamp: yyyymmddhhmm */ + char disk_set; /* disk number */ +}; + +struct header_block { + char id_str[33]; /* recorder id string (32 chars) */ + char vol_id[33]; /* volume label (32 characters) */ + char t_stamp[13]; /* timestamp */ + char disk_set; /* disk number - starts with 1 on multi-disk set */ +}; + +struct data_block { + char status; /* status of block (0=continue, 1=done, 2=disk full) */ + char reserved; /* reserved byte to make structure 4 bytes long */ + short datasize; /* # of bytes in block (max = CD_FRAMESIZE-this) */ +}; + +#define DBSIZE sizeof(struct data_block) +#define DATASIZE (CD_FRAMESIZE-DBSIZE) + +#endif diff -r 000000000000 -r d85c12073dea cdrestore.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdrestore.1 Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,85 @@ +.TH "cdrestore" "1" "0.6.2" "Stefan Hülswitt" "" +.SH "NAME" +.LP +cdrestore \- Streaming restore from CD\-R(W) +.SH "SYNOPSIS" +.LP +cdrestore [\-qV] [\-d \fIdevice\fP] [\-l \fIsize\fP] [\-t \fItrack\fP] + [\-c \fIcommand\fP] +.SH "DESCRIPTION" +.LP +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). +.SH "OPTIONS" +.LP +.TP +\fB\-d\fR \fIdevice\fP +The device name which is used for reading the backup. +.br +(default: /dev/cdrom) + +.TP +\fB\-l\fR \fIsize\fP +The media size in megabytes. This value is used to calculate the free space on the media. +.br +(default: 650) + +.TP +\fB\-t\fR \fItrack\fP +The number of the data track on the media for reading the backup. +.br +(default: none) + +.TP +\fB\-c\fR \fIcommand\fP +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. +.br +(default: use internal diskchange prompt) + +.TP +\fB\-q\fR +Queries the media, prints out the contents and exits. + +.TP +\fB\-V\fR +Prints out version information and exits. +.SH "EXAMPLES" +.LP +To query the 700 MB media on /dev/sr0: +.IP +cdrestore \-d /dev/sr0 \-l 700 \-q + +.LP +To restore a tar archive to the current directory from track 2 of a 702 MB media on /dev/scd0: +.IP +cdrestore \-d /dev/scd0 \-l 702 \-t 2 | tar xf \- +.SH "AUTHORS" +.LP +Stefan Hülswitt +.SH "SEE ALSO" +.LP +\fBcdbackup\fR(1) +.SH "LICENSE" +Copyright (c) 2000\-2002 Craig Condit, Stefan Hülswitt. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +.TP +1. +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +.TP +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. + +.LP +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. diff -r 000000000000 -r d85c12073dea cdrestore.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdrestore.c Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,261 @@ +/* cdrestore.c +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +*/ + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdbackup.h" +#include "cdrom.h" +#include "misc.h" +#include "version.h" + +/* defaults */ +char * prg_name ="cdrestore"; +int cd_mode =0; +int cd_track =-1; +char * cd_dev ="/dev/cdrom"; +long cd_len =333000; /* blocks */ +char * multicmd =0; +int verbose =1; + +int tracks; +long long totalSize; +struct header_block headersave; + +/****************************************************************************/ + +void usage() +{ + fprintf(stderr, + "Usage: %s [OPTION]...\n" + "Reads block input from CD-R(W) and writes it to standard output.\n\n" + " -d DEVICE DEVICE for CD queries (e.g. /dev/sr0)\n" + " -q query disk and print TOC only\n" + " -t N restore from track N\n" + " -l N CD-R has a size of N MB\n" + " -c COMMAND call COMMAND on disk change in multi-disk mode\n" + " -V prints version & exits\n" + "\n", prg_name); +} + +/****************************************************************************/ + +void parse_cmdline(char argc, char *argv[]) +{ + int i; + + while ((i=getopt(argc,argv,"d:l:c:t:qV"))>0) { + switch (i) { + case 'V': fprintf(stderr,"cdrestore "VERSION" (compiled "__DATE__")\n" + "Copyright (C) 2000-2002\n" + "This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n" + "PARTICULAR PURPOSE.\n"); + exit(0); + case 'c': multicmd=optarg; break; + case 'd': cd_dev=optarg; break; + case 'q': cd_mode=1; break; + case 't': errno=0; cd_track=strtol(optarg,NULL,10); + if(errno==ERANGE || cd_track<1) serror("Option -t: invalid track (must be >=1)\n"); + break; + case 'l': errno=0; cd_len=strtol(optarg,NULL,10); + if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n"); + cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */ + break; + default: usage(); exit(0); + } + } + + if(!cd_mode && cd_track<0) /* need track number */ + serror("A track number is required.\n"); +} + +/****************************************************************************/ + +void print_track(int track, char *stamp, char *id, int disk, int startsec, int endsec) +{ + char timestr[32], size[32]; + + snprintf(timestr,sizeof(timestr)-1,"%02d/%02d/%04d %02d:%02d", + (stamp[4]-'0')*10 + (stamp[5]-'0'), + (stamp[6]-'0')*10 + (stamp[7]-'0'), + (stamp[0]-'0')*1000 + (stamp[1]-'0')*100 + (stamp[2]-'0')*10 + (stamp[3]-'0'), + (stamp[8]-'0')*10 + (stamp[9]-'0'), + (stamp[10]-'0')*10 + (stamp[11]-'0')); + + if(startsec>=0) snprintf(size,sizeof(size)-1," %3ld MB:",(long)((long long)(endsec-startsec)*CD_FRAMESIZE/(1024*1024))); + else size[0]=0; + + fprintf(stderr,"Track %02d:%s %s Part %d: %s\n", track, size, timestr, disk, id); +} + +/****************************************************************************/ + +int restore(int disknum, int disktrack) +{ + int infile; + int result=0, i, bytes; + long long totalRead; + struct header_block header; + char buffer[CD_FRAMESIZE]; + struct data_block *db=(struct data_block *)&buffer[0]; + + if ((infile = open(cd_dev, O_RDONLY)) < 0) error("Error opening device"); + + /* seek to proper CD-R(W) track */ + for(i=tracks;i>0;i--) if(toc[i].track_no==disktrack) break; + if(!i) { fprintf(stderr, "%s: Can't find track %d\n", prg_name, disktrack); exit(1); } + + totalRead=(long long)toc[i].sec_start*CD_FRAMESIZE; + if(lseek64(infile,totalRead,SEEK_SET) != totalRead) error("Error seeking to track"); + + /* read header block */ + bytes=full_read(infile,buffer,CD_FRAMESIZE); + if (bytes < 0) error("Error reading header block"); + if (bytes != CD_FRAMESIZE) error("Unexpected EOF reading header block"); + totalRead = bytes; + + memcpy(&header,buffer,sizeof(header)); + + if(!strncmp(SHORT_HDR,header.id_str,strlen(SHORT_HDR))) { + fprintf(stderr,"%s: ", prg_name); + print_track(disktrack, header.t_stamp, header.vol_id, header.disk_set, -1, -1); + + if(disknum==1) { + if(header.disk_set!=1) { + 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); + exit(1); + } + headersave=header; /* save header for use with disk 2-n */ + } + else { + if(strcmp(header.t_stamp,headersave.t_stamp) || strcmp(header.vol_id,headersave.vol_id)) { + fprintf(stderr,"%s: This disk doesn't belong to the current set!\n",prg_name); + result=2; + } + else if(header.disk_set!=disknum) { + fprintf(stderr,"%s: Wrong sequence. You need disk %d now!\n",prg_name,disknum); + result=2; + } + else fprintf(stderr, "%s: Beginning restore (Disk %d)\n", prg_name,disknum); + } + } + else { + fprintf(stderr, "%s: Track %02d was not created with 'cdbackup'\n", prg_name,disktrack); + if(disknum==1) exit(1); + result=2; + } + + while(!result) { + int size; + + /* read data block */ + bytes = full_read(infile, buffer, CD_FRAMESIZE); + if (bytes < 0) error("Error reading data"); + if (bytes != CD_FRAMESIZE) error("Unexpected EOF reading data"); + totalRead += bytes; + + /* sanity check */ + size=ntohs(db->datasize); + if(size>DATASIZE) { + fprintf(stderr,"%s: Warning! Bad datasize at %lld\n",prg_name,totalRead); + size=DATASIZE; + } + + /* write the data block */ + bytes=write(1,&buffer[DBSIZE], size); + if(bytes!=size) error("Error writing data"); + + if(db->status == 1) break; /* end of backup*/ + if(db->status == 2) result=1; /* disk full */ + } + + /* print status */ + totalSize+=totalRead; + if(result!=2) fprintf(stderr, "%s: Restore complete. %lld kB read (%lld kB from this disk)\n",prg_name, totalSize/1024, totalRead/1024); + + close(infile); + return(result); +} + +/****************************************************************************/ + +void print_toc() +{ + int i; + + fprintf(stderr,"Tracks: %d\n",tracks); + print_space(); + fprintf(stderr,"\n"); + + for (i = 1; i <= tracks; i++) { + if(toc[i].is_data==0) fprintf(stderr,"Track %02d: Non-data\n", toc[i].track_no); + else if (toc[i].is_cdbackup == 1) + 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); + else fprintf(stderr,"Track %02d: Data\n", toc[i].track_no); + } +} + +/****************************************************************************/ + +int main(int argc, char *argv[]) +{ + int cdr; + + parse_cmdline(argc, argv); + + if(!cd_mode) { + int disknum=1, result; + totalSize=0; + do { + cdr=open_cdr(cd_dev); tracks=read_toc(cdr,0); close_cdr(cdr); + + result=restore(disknum,cd_track); + if(result) { + if(result==1) { disknum++; cd_track=1; } + fprintf(stderr,"%s: Next disk needed: disk %d from %s\n",prg_name,disknum,headersave.vol_id); + if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); + } + } while(result); + } + else { + cdr=open_cdr(cd_dev); tracks=read_toc(cdr,1); close_cdr(cdr); + print_toc(); + } + + return 0; +} diff -r 000000000000 -r d85c12073dea cdrom.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdrom.c Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,168 @@ +/* cdrom.c +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +*/ + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include "cdbackup.h" +#include "misc.h" + +/* size of leadin/out depending of how many tracks are on cd */ +#define MIN_FREE_1 (11400*CD_FRAMESIZE) /* 1th track */ +#define MIN_FREE_2 (6900*CD_FRAMESIZE) /* 2nd and more tracks */ + +struct toc_entry *toc=0; +long long cd_used, cd_avail; + +extern long cd_len; +extern int verbose; +extern char *prg_name; + +/****************************************************************************/ + +int open_cdr(char *device) +{ + return open(device, O_RDONLY | O_NONBLOCK); +} + +/****************************************************************************/ + +void close_cdr(int cd_fd) +{ + close(cd_fd); +} + +/****************************************************************************/ + +int full_read(int fd, void *buf, int count) +{ + int total=0; + + while(count>0) { + int bytes; + bytes=read(fd,buf,count); if(bytes<0) return bytes; + if(bytes==0) break; + count-=bytes; total+=bytes; buf+=bytes; + } + return total; +} + +/****************************************************************************/ + +void free_toc() +{ + if(toc) { free(toc); toc=0; } +} + +/****************************************************************************/ + +int read_toc(int cd_fd, int trackinfos) +{ + int i; + struct cdrom_tochdr cd_header; + struct cdrom_tocentry cd_entry; + int tracks,start_track; + + /* read table of contents header */ + if(ioctl(cd_fd,CDROMREADTOCHDR,&cd_header)) { + if(verbose) fprintf(stderr,"%s: Unable to read CD header, assuming empty CD-R\n", prg_name); + cd_used=0; cd_avail=(long long)cd_len*CD_FRAMESIZE; return 0; + } + + /* get start and end tracks */ + start_track = cd_header.cdth_trk0; + tracks = cd_header.cdth_trk1-start_track+1; + + free_toc(); + if(!(toc=calloc(tracks+1,sizeof(struct toc_entry)))) serror("No memory for TOC"); + + /* set some parameters */ + cd_entry.cdte_format=CDROM_LBA; + + /* read lead-out */ + cd_entry.cdte_track=CDROM_LEADOUT; + if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading lead-out"); + + toc[0].track_no=CDROM_LEADOUT; /* not a real track */ + toc[0].sec_start=cd_entry.cdte_addr.lba; + + cd_used=(long long)toc[0].sec_start*CD_FRAMESIZE; cd_avail=(long long)cd_len*CD_FRAMESIZE-cd_used; + cd_avail-=(tracks>1?MIN_FREE_2:MIN_FREE_1); + if(cd_avail<0) cd_avail=0; /* can be <0 due to assumed additional lead-in/out */ + + /* read rest of tracks */ + for(i=1; i<=tracks; i++) { + cd_entry.cdte_track=start_track+i-1; + if(ioctl(cd_fd,CDROMREADTOCENTRY,&cd_entry)) error("Error reading TOC"); + + toc[i].track_no=start_track+i-1; + toc[i].sec_start=cd_entry.cdte_addr.lba; + if(cd_entry.cdte_ctrl&CDROM_DATA_TRACK) toc[i].is_data=1; + } + + if(trackinfos) + /* now loop through tracks and read header info */ + for(i=1; i<=tracks; i++) { + char inbuffer[CD_FRAMESIZE]; + struct header_block *track_header=(struct header_block *)&inbuffer[0]; + + if (toc[i].is_data == 1) { + if(lseek64(cd_fd,(long long)toc[i].sec_start*CD_FRAMESIZE,SEEK_SET)<0) error("Seek failed"); + + if(full_read(cd_fd,inbuffer,CD_FRAMESIZE)==CD_FRAMESIZE) { + if(!strncmp(SHORT_HDR,track_header->id_str,strlen(SHORT_HDR))) { + toc[i].is_cdbackup=1; + strncpy(toc[i].id_str,track_header->id_str,32); toc[i].id_str[32]=0; + strncpy(toc[i].vol_id, track_header->vol_id,32); toc[i].vol_id[32]=0; + strncpy(toc[i].t_stamp, track_header->t_stamp,12); toc[i].t_stamp[12]=0; + toc[i].disk_set = track_header->disk_set; + } + } + } + } + + return tracks; +} + +/****************************************************************************/ + +void print_space() +{ + if(verbose) + fprintf(stderr, + "Disk size: %7lld kB (%7ld blocks)\n" + "Space used: %7lld kB (%7lld blocks)\n" + "Space avail:%7lld kB (%7lld blocks)\n", + (long long)cd_len*CD_FRAMESIZE/1024,cd_len, + cd_used/1024, cd_used/CD_FRAMESIZE, + cd_avail/1024, cd_avail/CD_FRAMESIZE); +} diff -r 000000000000 -r d85c12073dea cdrom.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdrom.h Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,39 @@ +/* cdrom.h +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 _CDBACKUP_CDROM_H +#define _CDBACKUP_CDROM_H + +extern struct toc_entry *toc; +extern long long cd_used, cd_avail; + +int open_cdr(char *device); +void close_cdr(int cd_fd); +int full_read(int fd, void *buf, int count); +int read_toc(int cd_fd, int trackinfos); +void free_toc(); +void print_space(); + +#endif diff -r 000000000000 -r d85c12073dea examples/cdbackup-diskchange --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/cdbackup-diskchange Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,15 @@ +#!/bin/bash +# +# This is an example diskchange-script +# +# $1 is the cdrom-device e.g. /dev/sr0 + +echo +echo +echo "Disk full!!" +eject $1 +echo "Please replace and press RETURN" +echo +echo +read + diff -r 000000000000 -r d85c12073dea examples/cdrestore-diskchange --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/cdrestore-diskchange Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,13 @@ +#!/bin/bash +# +# This is an example diskchange-script +# +# $1 is the cdrom-device e.g. /dev/sr0 + +eject $1 +echo +echo +echo "Please insert next disk and press RETURN" +echo +echo +read diff -r 000000000000 -r d85c12073dea misc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc.c Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,83 @@ +/* misc.c +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 +#include +#include +#include + +extern char *prg_name; + +/****************************************************************************/ + +void error(char *text) +{ + fprintf(stderr,"%s: %s: %s\n",prg_name,text,strerror(errno)); + exit(1); +} + +/****************************************************************************/ + +void serror(char *text) +{ + fprintf(stderr,"%s: %s\n",prg_name,text); + exit(1); +} + +/****************************************************************************/ + +int start_diskchange(char *multicmd, char *cd_dev) +{ +int pid, status=0; +char buffer[12]; + +if(multicmd) { /* we have an external script */ + if((pid=fork())<0) error("Fork failed in diskchange"); + if(pid==0) { /* child */ + char *argv[3]; + + dup2(2,0); dup2(2,1); /* duplicate stderr as stdin/stdout */ + argv[0] = multicmd; + argv[1] = cd_dev; + argv[2] = 0; + execvp(multicmd, argv); + error("Starting diskchange command failed"); + } + + while(1) { + if(waitpid(pid,&status,0)==-1) { if (errno != EINTR) { status=-1; break; } } + else break; + } + } +else { /* use internal diskchange */ + fprintf(stderr,"\n\nPlease insert next disk and press RETURN\n\n\n"); + do { + pid=read(2,buffer,sizeof(buffer)); + } while(pid==sizeof(buffer) && buffer[sizeof(buffer)-1]!='\n'); + } +return status; +} diff -r 000000000000 -r d85c12073dea misc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc.h Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,33 @@ +/* misc.h +Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt. + +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 _CDBACKUP_MISC_H +#define _CDBACKUP_MISC_H + +int start_diskchange(char *multicmd, char *cd_dev); +void error(char *text); +void serror(char *text); + +#endif diff -r 000000000000 -r d85c12073dea version.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/version.h Sat Dec 29 15:22:32 2007 +0100 @@ -0,0 +1,8 @@ +#ifndef _CDBACKUP_VERSION_H +#define _CDBACKUP_VERSION_H + +#ifndef VERSION +#define VERSION "0.6.2" +#endif + +#endif