1.1 --- a/cdbackup.c Sat Dec 29 15:23:55 2007 +0100
1.2 +++ b/cdbackup.c Sat Dec 29 15:25:21 2007 +0100
1.3 @@ -1,5 +1,5 @@
1.4 /* cdbackup.c
1.5 -Copyright (c) 2000-2002 Craig Condit, Stefan Hülswitt.
1.6 +Copyright (c) 2000-2004 Craig Condit, Stefan Hülswitt.
1.7
1.8 Redistribution and use in source and binary forms, with or without
1.9 modification, are permitted provided that the following conditions are met:
1.10 @@ -24,69 +24,135 @@
1.11 */
1.12
1.13 #define _LARGEFILE64_SOURCE
1.14 +#define _GNU_SOURCE
1.15
1.16 #include <stdlib.h>
1.17 #include <stdio.h>
1.18 +#include <stdarg.h>
1.19 #include <unistd.h>
1.20 #include <fcntl.h>
1.21 #include <string.h>
1.22 #include <time.h>
1.23 #include <errno.h>
1.24 -#include <getopt.h>
1.25 #include <sys/wait.h>
1.26 #include <sys/ioctl.h>
1.27 #include <netinet/in.h>
1.28 -#include <linux/cdrom.h>
1.29 +
1.30 +#ifndef sun
1.31 +#include <getopt.h>
1.32 +#endif
1.33
1.34 #include "cdbackup.h"
1.35 #include "cdrom.h"
1.36 +#include "virtual.h"
1.37 #include "misc.h"
1.38 #include "debug.h"
1.39 #include "version.h"
1.40
1.41 -/* #define DEBUGOUT */
1.42 -
1.43 /* defaults */
1.44 -char * prg_name ="cdbackup";
1.45 -char * cd_dev ="/dev/burner";
1.46 -char * cdr_dev =0; /* no default here, too dangerous */
1.47 -char * cd_label ="CDBackup Track";
1.48 -int cd_speed =4;
1.49 -long cd_len =333000; /* blocks */
1.50 -int padsize =15; /* blocks */
1.51 -int multidisk=0;
1.52 -char * multicmd =0;
1.53 -int verbose =0;
1.54 -int xamode2 =0;
1.55 -int debug =0;
1.56 +char *prg_name ="cdbackup";
1.57 +char *cd_dev ="/dev/burner";
1.58 +char *cdr_dev =0; /* no default here, too dangerous */
1.59 +char *cd_label ="CDBackup Track";
1.60 +int cd_speed =4;
1.61 +long cd_len =-1; /* blocks */
1.62 +int padsize =15; /* blocks */
1.63 +int multidisk=0;
1.64 +char *multicmd =0;
1.65 +int verbose =0;
1.66 +int xamode2 =0;
1.67 +int crc =1;
1.68 +int debug =0;
1.69 +int virtual =0;
1.70 +char *virt_name=0;
1.71 +int virt_dump=0;
1.72 +int dvd =0;
1.73
1.74 char **cdrec_opt=0;
1.75 int cdrec_opt_count=0;
1.76
1.77 -long long totalSize;
1.78 +long long totalSize=0;
1.79 +int disknum=1;
1.80 +int secs;
1.81 struct tm curtime; /* global, so multi-disks get all the same time */
1.82 -
1.83 -/****************************************************************************/
1.84 -
1.85 -void usage()
1.86 -{
1.87 - fprintf(stderr,
1.88 - "Usage: %s [options ...] [-- cdrecord-options ...]\n"
1.89 - "Reads from standard input, block formats and writes to CD-R(W).\n\n"
1.90 - " -d DEVICE DEVICE for CD queries (default /dev/burner)\n"
1.91 - " -l N CD-R has a size of N MB (default 650)\n"
1.92 - " -r DEVICE DEVICE for CD recording (e.g. 0,4,0)\n"
1.93 - " -s N record CD at speed N (default 4)\n"
1.94 - " -X enable CDROM XA2 mode in cdrecord\n"
1.95 - " -a LABEL use LABEL as CD session title\n"
1.96 - " -p N use a padsize of N sectors for the session (default 15)\n"
1.97 - " -m enable multi-disk mode\n"
1.98 - " -c COMMAND call COMMAND on disk change in multi-disk mode\n"
1.99 - " -v be verbose\n"
1.100 - " -D enable DEBUG output\n"
1.101 - " -V prints version & exits\n"
1.102 - " -- pass rest of commandline to cdrecord\n"
1.103 - "\n", prg_name);
1.104 +int auto_size=0;
1.105 +
1.106 +/****************************************************************************/
1.107 +
1.108 +char *make_arg(const char *format, ...)
1.109 +{
1.110 + char *ptr;
1.111 + va_list ap;
1.112 + va_start(ap,format);
1.113 + if(vasprintf(&ptr,format,ap)<0) serror("No memory for cdrecord args\n");
1.114 + va_end(ap);
1.115 + return ptr;
1.116 +}
1.117 +
1.118 +void start_cdrecord(void)
1.119 +{
1.120 + char **args, **p, *exname;
1.121 + int l;
1.122 +
1.123 + if(!(p=args=calloc(cdrec_opt_count+10,sizeof(char *))))
1.124 + serror("No memory for cdrecord args\n");
1.125 +
1.126 + if(dvd) exname="dvdrecord"; else exname="cdrecord";
1.127 + *p++=exname;
1.128 +
1.129 + if(virt_dump || dvd) {
1.130 + *p++="-dao";
1.131 + *p++=make_arg("tsize=%ds",secs);
1.132 + }
1.133 + else {
1.134 + *p++="-multi";
1.135 + *p++=make_arg("padsize=%ds",padsize);
1.136 + }
1.137 +
1.138 + *p++=make_arg("speed=%d",cd_speed);
1.139 + *p++=make_arg("dev=%s",cdr_dev);
1.140 +
1.141 + for(l=0 ; l<cdrec_opt_count ; l++) *p++=cdrec_opt[l];
1.142 +
1.143 + if(xamode2 && !dvd) *p++="-xa2"; else *p++="-data";
1.144 + *p++="-";
1.145 + *p++=0;
1.146 +
1.147 + if(debug) {
1.148 + fprintf(stderr,"%s: cdrecord command:",prg_name);
1.149 + for(p=args ; *p ; p++) fprintf(stderr," %s",*p);
1.150 + fprintf(stderr,"\n");
1.151 + }
1.152 +
1.153 + execvp(exname,args);
1.154 + error("Exec failed (cdrecord)");
1.155 +}
1.156 +
1.157 +long atip_cdrecord(void)
1.158 +{
1.159 + char *cmd;
1.160 + FILE *p;
1.161 + long size=-1;
1.162 +
1.163 + asprintf(&cmd,"%srecord 2>&1 dev=%s -atip",dvd ? "dvd":"cd",cdr_dev);
1.164 + DEBUG("%s: cdrecord atip command: %s\n",prg_name,cmd);
1.165 +
1.166 + p=popen(cmd,"r");
1.167 + if(!p) fprintf(stderr,"%s: atip command failed\n",prg_name);
1.168 + else {
1.169 + char buff[256];
1.170 + while(fgets(buff,sizeof(buff),p)) {
1.171 + if(dvd && !strncmp(buff,"rzone size:",11)) size=strtol(&buff[12],NULL,10);
1.172 + else if(!strncmp(buff," ATIP start of lead out:",25)) size=strtol(&buff[26],NULL,10);
1.173 + }
1.174 + }
1.175 + pclose(p);
1.176 + free(cmd);
1.177 + if(size>0 && verbose) {
1.178 + char buff[16];
1.179 + fprintf(stderr,"%s: auto-detected media size %s (%ld blocks)\n",prg_name,FlexSize(buff,(long long)size*CD_FRAMESIZE),size);
1.180 + }
1.181 + return size;
1.182 }
1.183
1.184 /****************************************************************************/
1.185 @@ -94,11 +160,24 @@
1.186 void parse_cmdline(char argc, char *argv[])
1.187 {
1.188 int i;
1.189 -
1.190 - while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVXD"))>0) {
1.191 + char *val;
1.192 +
1.193 + /* get some default from the environment */
1.194 + val=getenv("CDR_DEVICE");
1.195 + if(val) {
1.196 + cdr_dev=strdup(val);
1.197 + DEBUG("cdbackup: using recording device %s from CDR_DEVICE\n",cdr_dev);
1.198 + }
1.199 + val=getenv("CDR_SPEED");
1.200 + if(val) {
1.201 + cd_speed=strtol(val,NULL,10);
1.202 + DEBUG("cdbackup: using speed %d from CDR_SPEED\n",cd_speed);
1.203 + }
1.204 +
1.205 + while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVXDCi:wR"))>0) {
1.206 switch (i) {
1.207 case 'V': fprintf(stderr,"cdbackup "VERSION" (compiled "__DATE__")\n"
1.208 - "Copyright (C) 2000-2002\n"
1.209 + "Copyright (C) 2000-2004\n"
1.210 "This is free software; see the source for copying conditions.\n"
1.211 "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
1.212 "PARTICULAR PURPOSE.\n");
1.213 @@ -110,20 +189,45 @@
1.214 case 'd': cd_dev=optarg; break;
1.215 case 'r': cdr_dev=optarg; break;
1.216 case 'a': cd_label=optarg; break;
1.217 + case 'C': crc=0; break;
1.218 + case 'i': virt_name=optarg; virtual=1; break;
1.219 + case 'w': virt_dump=1; break;
1.220 + case 'R': dvd=1;
1.221 + DEBUG("cdbackup: DVD mode enabled\n");
1.222 + break;
1.223 case 'D': verbose=1; debug=1;
1.224 DEBUG("cdbackup: DEBUG output enabled ("VERSION")\n");
1.225 break;
1.226 - case 'l': errno=0; cd_len=strtol(optarg,NULL,10);
1.227 - if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n");
1.228 - cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */
1.229 - break;
1.230 + case 'l': cd_len=(long)(FlexLen(optarg)/CD_FRAMESIZE);
1.231 + break;
1.232 case 's': errno=0; cd_speed=strtol(optarg,NULL,10);
1.233 if(errno==ERANGE || cd_speed<1) serror("Option -s: speed out of range (must be >=1)\n");
1.234 break;
1.235 case 'p': errno=0; padsize=strtol(optarg,NULL,10);
1.236 if(errno==ERANGE || padsize<15) serror("Option -p: padsize out of range (must be >=15)\n");
1.237 break;
1.238 - default: usage(); exit(0);
1.239 + default: fprintf(stderr,
1.240 + "Usage: %s [options ...] [-- cdrecord-options ...]\n"
1.241 + "Reads from standard input, block formats and writes to CD-R(W).\n\n"
1.242 + " -d DEVICE DEVICE for CD queries (default /dev/burner)\n"
1.243 + " -l N set media size, disable auto-detect\n"
1.244 + " -r DEVICE DEVICE for CD recording (e.g. 0,4,0)\n"
1.245 + " -s N record CD at speed N (default 4)\n"
1.246 + " -X enable CDROM XA2 mode in cdrecord\n"
1.247 + " -a LABEL use LABEL as CD session title\n"
1.248 + " -p N use a padsize of N sectors for the session (default 15)\n"
1.249 + " -m enable multi-disk mode\n"
1.250 + " -c COMMAND call COMMAND on disk change in multi-disk mode\n"
1.251 + " -C disable checksum creation for datablocks\n"
1.252 + " -i IMAGE use virtual image IMAGE for recording\n"
1.253 + " -w dump virtual image to media\n"
1.254 + " -R enables DVD mode\n"
1.255 + " -v be verbose\n"
1.256 + " -D enable DEBUG output\n"
1.257 + " -V prints version & exits\n"
1.258 + " -- pass rest of commandline to cdrecord\n"
1.259 + "\n", prg_name);
1.260 + exit(0);
1.261 }
1.262 }
1.263
1.264 @@ -132,173 +236,215 @@
1.265 cdrec_opt=&argv[optind];
1.266 }
1.267
1.268 - if(!cdr_dev) serror("You must specify a device for cdrecord with -r\n");
1.269 -}
1.270 -
1.271 -/****************************************************************************/
1.272 -
1.273 -#define MARG(ptr,len,form,arg) { int l=(len);\
1.274 - if(!(*ptr=(char *)malloc(l+1))) serror("No memory for cdrecord args\n");\
1.275 - snprintf(*ptr++,l,form,arg);\
1.276 - }
1.277 -
1.278 -void start_cdrecord()
1.279 -{
1.280 - char **args, **p;
1.281 - int l;
1.282 -
1.283 - if(!(p=args=calloc(cdrec_opt_count+8,sizeof(char *))))
1.284 - serror("No memory for cdrecord args\n");
1.285 -
1.286 - *p++="cdrecord";
1.287 - *p++="-multi";
1.288 - MARG(p,16,"speed=%d",cd_speed);
1.289 - MARG(p,6+strlen(cdr_dev),"dev=%s",cdr_dev);
1.290 -
1.291 - for(l=0 ; l<cdrec_opt_count ; l++) *p++=cdrec_opt[l];
1.292 -
1.293 - MARG(p,20,"padsize=%ds",padsize);
1.294 - if(xamode2) *p++="-xa2"; else *p++="-data";
1.295 - *p++="-";
1.296 - *p++=0;
1.297 -
1.298 - if(debug) {
1.299 - fprintf(stderr,"%s: cdrecord command:",prg_name);
1.300 - for(p=args ; *p ; p++) fprintf(stderr," %s",*p);
1.301 - fprintf(stderr,"\n");
1.302 - }
1.303 -
1.304 - execvp("cdrecord",args);
1.305 - error("Unable to launch cdrecord");
1.306 -}
1.307 -
1.308 -/****************************************************************************/
1.309 -
1.310 -int backup(char disk_set)
1.311 -{
1.312 - pid_t childpid;
1.313 - int fd[2];
1.314 - int outpipe, bytes;
1.315 + if(cd_len<0) {
1.316 + auto_size=1;
1.317 + if(virtual && !virt_dump) serror("Can't auto-detect media size in virtual mode. Use option -l to set media size\n");
1.318 + }
1.319 + if(virtual && dvd && !virt_dump) {
1.320 + fprintf(stderr,"Option -R ignored in virtual mode\n");
1.321 + dvd=0;
1.322 + }
1.323 + if(dvd) {
1.324 + if(xamode2) fprintf(stderr,"Option -X ignored in DVD mode\n");
1.325 + padsize=0;
1.326 + }
1.327 + if(virt_dump && !virtual) serror("To dump an image you must supply the image name with -i\n");
1.328 + if(!cdr_dev && (!virtual || virt_dump)) serror("You must specify a device for cdrecord with -r\n");
1.329 +}
1.330 +
1.331 +/****************************************************************************/
1.332 +
1.333 +void autosize(void)
1.334 +{
1.335 + if(auto_size) {
1.336 + cd_len=atip_cdrecord();
1.337 + if(cd_len<0) serror("Media size detection failed. Use option -l to set media size\n");
1.338 + }
1.339 +}
1.340 +
1.341 +/****************************************************************************/
1.342 +
1.343 +void dump(void)
1.344 +{
1.345 + int n, cont;
1.346 + char buffer[CD_FRAMESIZE];
1.347 + long long grandTotal;
1.348 +
1.349 + do {
1.350 + int change;
1.351 + do {
1.352 + autosize();
1.353 + virtual=1;
1.354 + Vopen(1); n=VreadToc(0);
1.355 + if(n<1) serror("It's not usefull to dump an empty image");
1.356 + secs=Vsize(); cont=VhasCont();
1.357 + if(cd_avail<secs*CD_FRAMESIZE) serror("Image doesn't fits to media");
1.358 + Vseek(-1); VprepareDump();
1.359 +
1.360 + virtual=0; change=0;
1.361 + Vopen(0); n=VreadToc(0); VprintSpace();
1.362 + if(n!=0) {
1.363 + fprintf(stderr,"Can't dump to non-empty disk! Try another disk\n");
1.364 + change=1;
1.365 + }
1.366 +
1.367 + if(change) {
1.368 + Vclose();
1.369 + diskchange(multicmd,cd_dev);
1.370 + }
1.371 + } while(change);
1.372 +
1.373 + if(verbose)
1.374 + fprintf(stderr,"%s: Dumping image (%d blocks) to %s\n",prg_name,secs,VdevName());
1.375 + VnewTrack();
1.376 +
1.377 + grandTotal=0;
1.378 + while(secs>0) {
1.379 + VvirtRead(buffer);
1.380 + Vwrite(buffer); grandTotal+=CD_FRAMESIZE;
1.381 + secs--;
1.382 + }
1.383 +
1.384 + VcloseTrack(0);
1.385 +
1.386 + totalSize+=grandTotal;
1.387 + if(verbose) {
1.388 + char str1[16], str2[16];
1.389 + fprintf(stderr,"%s: Dumping finished. %s written (%s on this disk)\n",
1.390 + prg_name,FlexSize(str1,totalSize),FlexSize(str2,grandTotal));
1.391 + }
1.392 +
1.393 + if(multidisk==0) {
1.394 + if(cont) fprintf(stderr,"Multi-disk not enabled, ignoring continuation image(s)!\n");
1.395 + cont=0;
1.396 + }
1.397 + else {
1.398 + disknum++;
1.399 + diskchange(multicmd,cd_dev);
1.400 + }
1.401 + } while(cont);
1.402 +}
1.403 +
1.404 +/****************************************************************************/
1.405 +
1.406 +int backup(void)
1.407 +{
1.408 long long grandTotal=0;
1.409 struct header_block header;
1.410 + int flags, datasize, result=0;
1.411
1.412 char buffer[CD_FRAMESIZE];
1.413 struct data_block *db=(struct data_block *)&buffer[0];
1.414
1.415 - sprintf(buffer, "%04d%02d%02d%02d%02d", curtime.tm_year + 1900,
1.416 - curtime.tm_mon + 1, curtime.tm_mday, curtime.tm_hour, curtime.tm_min);
1.417 + flags=F_NONE;
1.418 + datasize=DATASIZE;
1.419 + if(crc) { flags|=F_CRC; datasize-=4; }
1.420 +
1.421 + sprintf(buffer,"%04d%02d%02d%02d%02d",curtime.tm_year+1900,
1.422 + curtime.tm_mon+1,curtime.tm_mday,curtime.tm_hour,curtime.tm_min);
1.423
1.424 - strncpy(header.id_str,HDR_STRING,32); header.id_str[32] = 0;
1.425 - strncpy(header.vol_id,cd_label,32); header.vol_id[32] = 0;
1.426 - strncpy(header.t_stamp,buffer,12); header.t_stamp[12] = 0;
1.427 - header.disk_set = disk_set;
1.428 + strncpy(header.id_str,HDR_STRING,32); header.id_str[32]=0;
1.429 + strncpy(header.vol_id,cd_label,32); header.vol_id[32]=0;
1.430 + strncpy(header.t_stamp,buffer,12); header.t_stamp[12]=0;
1.431 + header.disk_set = disknum;
1.432 + header.flags = flags;
1.433
1.434 if(verbose)
1.435 - fprintf(stderr,"%s: Recording to device %s, multidisk %s, disk %d\n",prg_name,cdr_dev,multidisk?"enabled":"disabled",disk_set);
1.436 -
1.437 -#ifndef DEBUGOUT /* the "real" code */
1.438 - /* launch cdrecord */
1.439 - if(pipe(fd) == -1) error("Unable to create pipe handles");
1.440 - if((childpid=fork()) == -1) error("Fork failed");
1.441 - if(childpid == 0) { /* child */
1.442 - close(fd[1]);
1.443 - close(0); /* stdin */
1.444 - dup2(fd[0], 0);
1.445 - start_cdrecord(); /* doesn't return */
1.446 - }
1.447 -
1.448 - close(fd[0]); outpipe=fd[1];
1.449 -
1.450 - /* output the header block */
1.451 + fprintf(stderr,"%s: Recording to %s, multidisk %s, CRC %s, disk %d\n",
1.452 + prg_name,VdevName(),
1.453 + multidisk?"enabled":"disabled",
1.454 + crc?"enabled":"disabled",
1.455 + disknum);
1.456 + secs=cd_len;
1.457 + VnewTrack();
1.458 +
1.459 memset(buffer,0,CD_FRAMESIZE);
1.460 memcpy(buffer,&header,sizeof(struct header_block));
1.461 - if((bytes=write(outpipe, buffer, CD_FRAMESIZE)) != CD_FRAMESIZE) error("Error writing header block");
1.462 -
1.463 - cd_avail-=bytes; grandTotal+=bytes;
1.464 - /* account for the padsize */
1.465 - cd_avail-=padsize*CD_FRAMESIZE;
1.466 -#else
1.467 - /* debug code; send data to /dev/null. Don't need the pipe. */
1.468 - fprintf(stderr, "DEBUG CODE: sending data to /dev/null!\n");
1.469 - outpipe = open("/dev/null", O_WRONLY);
1.470 - if (outpipe < 0) { perror("/dev/null"); exit(1); }
1.471 -#endif
1.472 -
1.473 - db->reserved = 0;
1.474 + Vwrite(buffer); grandTotal+=CD_FRAMESIZE;
1.475
1.476 do {
1.477 - /* read a block */
1.478 - db->status = 0; /* this isn't the last block (for now) */
1.479 - bytes=full_read(0,&buffer[DBSIZE],DATASIZE);
1.480 - if (bytes < 0) error("Error reading input");
1.481 - if (bytes != DATASIZE) db->status=1; /* EOF, this is the last block */
1.482 - db->datasize = htons(bytes);
1.483 -
1.484 - /* check for free space */
1.485 - if(cd_avail < (CD_FRAMESIZE*2)) { /* less than 2 block free */
1.486 - if(db->status==0) db->status=2; /* if not last block, mark disk as full */
1.487 - }
1.488 -
1.489 - /* write a block */
1.490 - bytes = write(outpipe, buffer, CD_FRAMESIZE);
1.491 - if(bytes != CD_FRAMESIZE) error("Error writing data block");
1.492 -
1.493 - grandTotal+=bytes; cd_avail-=bytes;
1.494 + int bytes;
1.495 +
1.496 + db->flags=flags;
1.497 + db->status=0; /* this isn't the last block (for now) */
1.498 + bytes=full_read(0,&buffer[DBSIZE],datasize);
1.499 + if(bytes!=datasize) db->status=1; /* EOF, this is the last block */
1.500 + db->datasize=htons(bytes);
1.501 +
1.502 + if(cd_avail<(CD_FRAMESIZE*2)) { /* less than 2 block free */
1.503 + if(db->status==0) { /* if not last block, mark disk as full */
1.504 + db->status=2;
1.505 + result=1;
1.506 + }
1.507 + }
1.508 + if(crc) {
1.509 + int l=crc32(buffer,bytes+DBSIZE);
1.510 + *((unsigned long *)(&buffer[CD_FRAMESIZE-4]))=l;
1.511 + }
1.512 + Vwrite(buffer); grandTotal+=CD_FRAMESIZE;
1.513 } while(db->status==0);
1.514
1.515 - /* close pipe and wait for child termination */
1.516 - close(outpipe);
1.517 - while (wait(0) != childpid);
1.518 + if(dvd && cd_avail>=CD_FRAMESIZE) { /* pad up the track with zeros */
1.519 + memset(buffer,0,CD_FRAMESIZE);
1.520 + if(verbose) fprintf(stderr,"%s: padding up the track\n",prg_name);
1.521 + while(cd_avail>=CD_FRAMESIZE) Vwrite(buffer);
1.522 + }
1.523 +
1.524 + VcloseTrack(result);
1.525
1.526 totalSize+=grandTotal;
1.527 - if(verbose) fprintf(stderr,"%s: Recording finished. %lld kB written (%lld kB on this disk)\n",
1.528 - prg_name,totalSize/1024,grandTotal/1024);
1.529 -
1.530 - if(db->status==2) return 1; /* disk was full */
1.531 + if(verbose) {
1.532 + char str1[16], str2[16];
1.533 + fprintf(stderr,"%s: Recording finished. %s written (%s on this disk)\n",
1.534 + prg_name,FlexSize(str1,totalSize),FlexSize(str2,grandTotal));
1.535 + }
1.536 + return result;
1.537 +}
1.538 +
1.539 +/****************************************************************************/
1.540 +
1.541 +int main(int argc, char *argv[])
1.542 +{
1.543 + int result, loop;
1.544 + time_t curtime_t;
1.545 +
1.546 + curtime_t=time(0); curtime=*localtime(&curtime_t);
1.547 + parse_cmdline(argc,argv);
1.548 +
1.549 + if(virt_dump) {
1.550 + dump();
1.551 + }
1.552 + else {
1.553 + do {
1.554 + do {
1.555 + autosize();
1.556 + Vopen(0); result=VreadToc(0); VprintSpace();
1.557 + loop=1;
1.558 +
1.559 + if(disknum>1 && result!=0) {
1.560 + Vclose();
1.561 + fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name);
1.562 + diskchange(multicmd,cd_dev);
1.563 + }
1.564 + else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) {
1.565 + Vclose();
1.566 + if(multidisk) {
1.567 + fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name);
1.568 + diskchange(multicmd,cd_dev);
1.569 + }
1.570 + else serror("Not enough free space on disk");
1.571 + }
1.572 + else loop=0;
1.573 + } while(loop);
1.574 +
1.575 + result=backup();
1.576 + if(result==1) {
1.577 + if(multidisk==0) serror("Disk full, multi-disk not enabled. Aborting");
1.578 +
1.579 + disknum++;
1.580 + if(!VisRegular()) diskchange(multicmd,cd_dev);
1.581 + }
1.582 + } while(result!=0);
1.583 + }
1.584 return 0;
1.585 }
1.586 -
1.587 -/****************************************************************************/
1.588 -
1.589 -int main(int argc, char *argv[])
1.590 -{
1.591 - int cdr;
1.592 - int disknum, result, loop;
1.593 - time_t curtime_t;
1.594 -
1.595 - disknum=1; totalSize=0;
1.596 - curtime_t=time(0); curtime=*localtime(&curtime_t);
1.597 -
1.598 - parse_cmdline(argc,argv);
1.599 -
1.600 - do {
1.601 - do {
1.602 - cdr=open_cdr(cd_dev); result=read_toc(cdr,0); close_cdr(cdr);
1.603 - print_space();
1.604 - loop=1;
1.605 -
1.606 - if(disknum>1 && result!=0) {
1.607 - fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name);
1.608 - if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
1.609 - }
1.610 - else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) {
1.611 - if(multidisk) {
1.612 - fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name);
1.613 - if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
1.614 - }
1.615 - else serror("Not enough free space on disk");
1.616 - }
1.617 - else loop=0;
1.618 - } while(loop);
1.619 -
1.620 - result = backup(disknum);
1.621 - if(result == 1) {
1.622 - if(multidisk == 0) serror("Disk full, multi-disk not enabled. Aborting");
1.623 -
1.624 - disknum++;
1.625 - if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed");
1.626 - }
1.627 - } while (result != 0);
1.628 -
1.629 - return 0;
1.630 -}