22 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
22 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
23 SUCH DAMAGE. |
23 SUCH DAMAGE. |
24 */ |
24 */ |
25 |
25 |
26 #define _LARGEFILE64_SOURCE |
26 #define _LARGEFILE64_SOURCE |
|
27 #define _GNU_SOURCE |
27 |
28 |
28 #include <stdlib.h> |
29 #include <stdlib.h> |
29 #include <stdio.h> |
30 #include <stdio.h> |
|
31 #include <stdarg.h> |
30 #include <unistd.h> |
32 #include <unistd.h> |
31 #include <fcntl.h> |
33 #include <fcntl.h> |
32 #include <string.h> |
34 #include <string.h> |
33 #include <time.h> |
35 #include <time.h> |
34 #include <errno.h> |
36 #include <errno.h> |
35 #include <getopt.h> |
|
36 #include <sys/wait.h> |
37 #include <sys/wait.h> |
37 #include <sys/ioctl.h> |
38 #include <sys/ioctl.h> |
38 #include <netinet/in.h> |
39 #include <netinet/in.h> |
39 #include <linux/cdrom.h> |
40 |
|
41 #ifndef sun |
|
42 #include <getopt.h> |
|
43 #endif |
40 |
44 |
41 #include "cdbackup.h" |
45 #include "cdbackup.h" |
42 #include "cdrom.h" |
46 #include "cdrom.h" |
|
47 #include "virtual.h" |
43 #include "misc.h" |
48 #include "misc.h" |
44 #include "debug.h" |
49 #include "debug.h" |
45 #include "version.h" |
50 #include "version.h" |
46 |
51 |
47 /* #define DEBUGOUT */ |
|
48 |
|
49 /* defaults */ |
52 /* defaults */ |
50 char * prg_name ="cdbackup"; |
53 char *prg_name ="cdbackup"; |
51 char * cd_dev ="/dev/burner"; |
54 char *cd_dev ="/dev/burner"; |
52 char * cdr_dev =0; /* no default here, too dangerous */ |
55 char *cdr_dev =0; /* no default here, too dangerous */ |
53 char * cd_label ="CDBackup Track"; |
56 char *cd_label ="CDBackup Track"; |
54 int cd_speed =4; |
57 int cd_speed =4; |
55 long cd_len =333000; /* blocks */ |
58 long cd_len =-1; /* blocks */ |
56 int padsize =15; /* blocks */ |
59 int padsize =15; /* blocks */ |
57 int multidisk=0; |
60 int multidisk=0; |
58 char * multicmd =0; |
61 char *multicmd =0; |
59 int verbose =0; |
62 int verbose =0; |
60 int xamode2 =0; |
63 int xamode2 =0; |
61 int debug =0; |
64 int crc =1; |
|
65 int debug =0; |
|
66 int virtual =0; |
|
67 char *virt_name=0; |
|
68 int virt_dump=0; |
|
69 int dvd =0; |
62 |
70 |
63 char **cdrec_opt=0; |
71 char **cdrec_opt=0; |
64 int cdrec_opt_count=0; |
72 int cdrec_opt_count=0; |
65 |
73 |
66 long long totalSize; |
74 long long totalSize=0; |
|
75 int disknum=1; |
|
76 int secs; |
67 struct tm curtime; /* global, so multi-disks get all the same time */ |
77 struct tm curtime; /* global, so multi-disks get all the same time */ |
68 |
78 int auto_size=0; |
69 /****************************************************************************/ |
79 |
70 |
80 /****************************************************************************/ |
71 void usage() |
81 |
72 { |
82 char *make_arg(const char *format, ...) |
73 fprintf(stderr, |
83 { |
74 "Usage: %s [options ...] [-- cdrecord-options ...]\n" |
84 char *ptr; |
75 "Reads from standard input, block formats and writes to CD-R(W).\n\n" |
85 va_list ap; |
76 " -d DEVICE DEVICE for CD queries (default /dev/burner)\n" |
86 va_start(ap,format); |
77 " -l N CD-R has a size of N MB (default 650)\n" |
87 if(vasprintf(&ptr,format,ap)<0) serror("No memory for cdrecord args\n"); |
78 " -r DEVICE DEVICE for CD recording (e.g. 0,4,0)\n" |
88 va_end(ap); |
79 " -s N record CD at speed N (default 4)\n" |
89 return ptr; |
80 " -X enable CDROM XA2 mode in cdrecord\n" |
90 } |
81 " -a LABEL use LABEL as CD session title\n" |
91 |
82 " -p N use a padsize of N sectors for the session (default 15)\n" |
92 void start_cdrecord(void) |
83 " -m enable multi-disk mode\n" |
93 { |
84 " -c COMMAND call COMMAND on disk change in multi-disk mode\n" |
94 char **args, **p, *exname; |
85 " -v be verbose\n" |
95 int l; |
86 " -D enable DEBUG output\n" |
96 |
87 " -V prints version & exits\n" |
97 if(!(p=args=calloc(cdrec_opt_count+10,sizeof(char *)))) |
88 " -- pass rest of commandline to cdrecord\n" |
98 serror("No memory for cdrecord args\n"); |
89 "\n", prg_name); |
99 |
|
100 if(dvd) exname="dvdrecord"; else exname="cdrecord"; |
|
101 *p++=exname; |
|
102 |
|
103 if(virt_dump || dvd) { |
|
104 *p++="-dao"; |
|
105 *p++=make_arg("tsize=%ds",secs); |
|
106 } |
|
107 else { |
|
108 *p++="-multi"; |
|
109 *p++=make_arg("padsize=%ds",padsize); |
|
110 } |
|
111 |
|
112 *p++=make_arg("speed=%d",cd_speed); |
|
113 *p++=make_arg("dev=%s",cdr_dev); |
|
114 |
|
115 for(l=0 ; l<cdrec_opt_count ; l++) *p++=cdrec_opt[l]; |
|
116 |
|
117 if(xamode2 && !dvd) *p++="-xa2"; else *p++="-data"; |
|
118 *p++="-"; |
|
119 *p++=0; |
|
120 |
|
121 if(debug) { |
|
122 fprintf(stderr,"%s: cdrecord command:",prg_name); |
|
123 for(p=args ; *p ; p++) fprintf(stderr," %s",*p); |
|
124 fprintf(stderr,"\n"); |
|
125 } |
|
126 |
|
127 execvp(exname,args); |
|
128 error("Exec failed (cdrecord)"); |
|
129 } |
|
130 |
|
131 long atip_cdrecord(void) |
|
132 { |
|
133 char *cmd; |
|
134 FILE *p; |
|
135 long size=-1; |
|
136 |
|
137 asprintf(&cmd,"%srecord 2>&1 dev=%s -atip",dvd ? "dvd":"cd",cdr_dev); |
|
138 DEBUG("%s: cdrecord atip command: %s\n",prg_name,cmd); |
|
139 |
|
140 p=popen(cmd,"r"); |
|
141 if(!p) fprintf(stderr,"%s: atip command failed\n",prg_name); |
|
142 else { |
|
143 char buff[256]; |
|
144 while(fgets(buff,sizeof(buff),p)) { |
|
145 if(dvd && !strncmp(buff,"rzone size:",11)) size=strtol(&buff[12],NULL,10); |
|
146 else if(!strncmp(buff," ATIP start of lead out:",25)) size=strtol(&buff[26],NULL,10); |
|
147 } |
|
148 } |
|
149 pclose(p); |
|
150 free(cmd); |
|
151 if(size>0 && verbose) { |
|
152 char buff[16]; |
|
153 fprintf(stderr,"%s: auto-detected media size %s (%ld blocks)\n",prg_name,FlexSize(buff,(long long)size*CD_FRAMESIZE),size); |
|
154 } |
|
155 return size; |
90 } |
156 } |
91 |
157 |
92 /****************************************************************************/ |
158 /****************************************************************************/ |
93 |
159 |
94 void parse_cmdline(char argc, char *argv[]) |
160 void parse_cmdline(char argc, char *argv[]) |
95 { |
161 { |
96 int i; |
162 int i; |
97 |
163 char *val; |
98 while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVXD"))>0) { |
164 |
|
165 /* get some default from the environment */ |
|
166 val=getenv("CDR_DEVICE"); |
|
167 if(val) { |
|
168 cdr_dev=strdup(val); |
|
169 DEBUG("cdbackup: using recording device %s from CDR_DEVICE\n",cdr_dev); |
|
170 } |
|
171 val=getenv("CDR_SPEED"); |
|
172 if(val) { |
|
173 cd_speed=strtol(val,NULL,10); |
|
174 DEBUG("cdbackup: using speed %d from CDR_SPEED\n",cd_speed); |
|
175 } |
|
176 |
|
177 while ((i=getopt(argc,argv,"d:r:l:s:p:a:c:mvVXDCi:wR"))>0) { |
99 switch (i) { |
178 switch (i) { |
100 case 'V': fprintf(stderr,"cdbackup "VERSION" (compiled "__DATE__")\n" |
179 case 'V': fprintf(stderr,"cdbackup "VERSION" (compiled "__DATE__")\n" |
101 "Copyright (C) 2000-2002\n" |
180 "Copyright (C) 2000-2004\n" |
102 "This is free software; see the source for copying conditions.\n" |
181 "This is free software; see the source for copying conditions.\n" |
103 "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n" |
182 "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n" |
104 "PARTICULAR PURPOSE.\n"); |
183 "PARTICULAR PURPOSE.\n"); |
105 exit(0); |
184 exit(0); |
106 case 'v': verbose=1; break; |
185 case 'v': verbose=1; break; |
108 case 'X': xamode2=1; break; |
187 case 'X': xamode2=1; break; |
109 case 'c': multicmd=optarg; break; |
188 case 'c': multicmd=optarg; break; |
110 case 'd': cd_dev=optarg; break; |
189 case 'd': cd_dev=optarg; break; |
111 case 'r': cdr_dev=optarg; break; |
190 case 'r': cdr_dev=optarg; break; |
112 case 'a': cd_label=optarg; break; |
191 case 'a': cd_label=optarg; break; |
|
192 case 'C': crc=0; break; |
|
193 case 'i': virt_name=optarg; virtual=1; break; |
|
194 case 'w': virt_dump=1; break; |
|
195 case 'R': dvd=1; |
|
196 DEBUG("cdbackup: DVD mode enabled\n"); |
|
197 break; |
113 case 'D': verbose=1; debug=1; |
198 case 'D': verbose=1; debug=1; |
114 DEBUG("cdbackup: DEBUG output enabled ("VERSION")\n"); |
199 DEBUG("cdbackup: DEBUG output enabled ("VERSION")\n"); |
115 break; |
200 break; |
116 case 'l': errno=0; cd_len=strtol(optarg,NULL,10); |
201 case 'l': cd_len=(long)(FlexLen(optarg)/CD_FRAMESIZE); |
117 if(errno==ERANGE || cd_len<1) serror("Option -l: length out of range (must be >=1)\n"); |
202 break; |
118 cd_len = (long long)cd_len * (1024*1024) / CD_FRAMESIZE; /* convert to blocks */ |
|
119 break; |
|
120 case 's': errno=0; cd_speed=strtol(optarg,NULL,10); |
203 case 's': errno=0; cd_speed=strtol(optarg,NULL,10); |
121 if(errno==ERANGE || cd_speed<1) serror("Option -s: speed out of range (must be >=1)\n"); |
204 if(errno==ERANGE || cd_speed<1) serror("Option -s: speed out of range (must be >=1)\n"); |
122 break; |
205 break; |
123 case 'p': errno=0; padsize=strtol(optarg,NULL,10); |
206 case 'p': errno=0; padsize=strtol(optarg,NULL,10); |
124 if(errno==ERANGE || padsize<15) serror("Option -p: padsize out of range (must be >=15)\n"); |
207 if(errno==ERANGE || padsize<15) serror("Option -p: padsize out of range (must be >=15)\n"); |
125 break; |
208 break; |
126 default: usage(); exit(0); |
209 default: fprintf(stderr, |
|
210 "Usage: %s [options ...] [-- cdrecord-options ...]\n" |
|
211 "Reads from standard input, block formats and writes to CD-R(W).\n\n" |
|
212 " -d DEVICE DEVICE for CD queries (default /dev/burner)\n" |
|
213 " -l N set media size, disable auto-detect\n" |
|
214 " -r DEVICE DEVICE for CD recording (e.g. 0,4,0)\n" |
|
215 " -s N record CD at speed N (default 4)\n" |
|
216 " -X enable CDROM XA2 mode in cdrecord\n" |
|
217 " -a LABEL use LABEL as CD session title\n" |
|
218 " -p N use a padsize of N sectors for the session (default 15)\n" |
|
219 " -m enable multi-disk mode\n" |
|
220 " -c COMMAND call COMMAND on disk change in multi-disk mode\n" |
|
221 " -C disable checksum creation for datablocks\n" |
|
222 " -i IMAGE use virtual image IMAGE for recording\n" |
|
223 " -w dump virtual image to media\n" |
|
224 " -R enables DVD mode\n" |
|
225 " -v be verbose\n" |
|
226 " -D enable DEBUG output\n" |
|
227 " -V prints version & exits\n" |
|
228 " -- pass rest of commandline to cdrecord\n" |
|
229 "\n", prg_name); |
|
230 exit(0); |
127 } |
231 } |
128 } |
232 } |
129 |
233 |
130 if(optind<argc) { /* save position/count of cdrecord options */ |
234 if(optind<argc) { /* save position/count of cdrecord options */ |
131 cdrec_opt_count=argc-optind; |
235 cdrec_opt_count=argc-optind; |
132 cdrec_opt=&argv[optind]; |
236 cdrec_opt=&argv[optind]; |
133 } |
237 } |
134 |
238 |
135 if(!cdr_dev) serror("You must specify a device for cdrecord with -r\n"); |
239 if(cd_len<0) { |
136 } |
240 auto_size=1; |
137 |
241 if(virtual && !virt_dump) serror("Can't auto-detect media size in virtual mode. Use option -l to set media size\n"); |
138 /****************************************************************************/ |
242 } |
139 |
243 if(virtual && dvd && !virt_dump) { |
140 #define MARG(ptr,len,form,arg) { int l=(len);\ |
244 fprintf(stderr,"Option -R ignored in virtual mode\n"); |
141 if(!(*ptr=(char *)malloc(l+1))) serror("No memory for cdrecord args\n");\ |
245 dvd=0; |
142 snprintf(*ptr++,l,form,arg);\ |
246 } |
143 } |
247 if(dvd) { |
144 |
248 if(xamode2) fprintf(stderr,"Option -X ignored in DVD mode\n"); |
145 void start_cdrecord() |
249 padsize=0; |
146 { |
250 } |
147 char **args, **p; |
251 if(virt_dump && !virtual) serror("To dump an image you must supply the image name with -i\n"); |
148 int l; |
252 if(!cdr_dev && (!virtual || virt_dump)) serror("You must specify a device for cdrecord with -r\n"); |
149 |
253 } |
150 if(!(p=args=calloc(cdrec_opt_count+8,sizeof(char *)))) |
254 |
151 serror("No memory for cdrecord args\n"); |
255 /****************************************************************************/ |
152 |
256 |
153 *p++="cdrecord"; |
257 void autosize(void) |
154 *p++="-multi"; |
258 { |
155 MARG(p,16,"speed=%d",cd_speed); |
259 if(auto_size) { |
156 MARG(p,6+strlen(cdr_dev),"dev=%s",cdr_dev); |
260 cd_len=atip_cdrecord(); |
157 |
261 if(cd_len<0) serror("Media size detection failed. Use option -l to set media size\n"); |
158 for(l=0 ; l<cdrec_opt_count ; l++) *p++=cdrec_opt[l]; |
262 } |
159 |
263 } |
160 MARG(p,20,"padsize=%ds",padsize); |
264 |
161 if(xamode2) *p++="-xa2"; else *p++="-data"; |
265 /****************************************************************************/ |
162 *p++="-"; |
266 |
163 *p++=0; |
267 void dump(void) |
164 |
268 { |
165 if(debug) { |
269 int n, cont; |
166 fprintf(stderr,"%s: cdrecord command:",prg_name); |
270 char buffer[CD_FRAMESIZE]; |
167 for(p=args ; *p ; p++) fprintf(stderr," %s",*p); |
271 long long grandTotal; |
168 fprintf(stderr,"\n"); |
272 |
169 } |
273 do { |
170 |
274 int change; |
171 execvp("cdrecord",args); |
275 do { |
172 error("Unable to launch cdrecord"); |
276 autosize(); |
173 } |
277 virtual=1; |
174 |
278 Vopen(1); n=VreadToc(0); |
175 /****************************************************************************/ |
279 if(n<1) serror("It's not usefull to dump an empty image"); |
176 |
280 secs=Vsize(); cont=VhasCont(); |
177 int backup(char disk_set) |
281 if(cd_avail<secs*CD_FRAMESIZE) serror("Image doesn't fits to media"); |
178 { |
282 Vseek(-1); VprepareDump(); |
179 pid_t childpid; |
283 |
180 int fd[2]; |
284 virtual=0; change=0; |
181 int outpipe, bytes; |
285 Vopen(0); n=VreadToc(0); VprintSpace(); |
|
286 if(n!=0) { |
|
287 fprintf(stderr,"Can't dump to non-empty disk! Try another disk\n"); |
|
288 change=1; |
|
289 } |
|
290 |
|
291 if(change) { |
|
292 Vclose(); |
|
293 diskchange(multicmd,cd_dev); |
|
294 } |
|
295 } while(change); |
|
296 |
|
297 if(verbose) |
|
298 fprintf(stderr,"%s: Dumping image (%d blocks) to %s\n",prg_name,secs,VdevName()); |
|
299 VnewTrack(); |
|
300 |
|
301 grandTotal=0; |
|
302 while(secs>0) { |
|
303 VvirtRead(buffer); |
|
304 Vwrite(buffer); grandTotal+=CD_FRAMESIZE; |
|
305 secs--; |
|
306 } |
|
307 |
|
308 VcloseTrack(0); |
|
309 |
|
310 totalSize+=grandTotal; |
|
311 if(verbose) { |
|
312 char str1[16], str2[16]; |
|
313 fprintf(stderr,"%s: Dumping finished. %s written (%s on this disk)\n", |
|
314 prg_name,FlexSize(str1,totalSize),FlexSize(str2,grandTotal)); |
|
315 } |
|
316 |
|
317 if(multidisk==0) { |
|
318 if(cont) fprintf(stderr,"Multi-disk not enabled, ignoring continuation image(s)!\n"); |
|
319 cont=0; |
|
320 } |
|
321 else { |
|
322 disknum++; |
|
323 diskchange(multicmd,cd_dev); |
|
324 } |
|
325 } while(cont); |
|
326 } |
|
327 |
|
328 /****************************************************************************/ |
|
329 |
|
330 int backup(void) |
|
331 { |
182 long long grandTotal=0; |
332 long long grandTotal=0; |
183 struct header_block header; |
333 struct header_block header; |
|
334 int flags, datasize, result=0; |
184 |
335 |
185 char buffer[CD_FRAMESIZE]; |
336 char buffer[CD_FRAMESIZE]; |
186 struct data_block *db=(struct data_block *)&buffer[0]; |
337 struct data_block *db=(struct data_block *)&buffer[0]; |
187 |
338 |
188 sprintf(buffer, "%04d%02d%02d%02d%02d", curtime.tm_year + 1900, |
339 flags=F_NONE; |
189 curtime.tm_mon + 1, curtime.tm_mday, curtime.tm_hour, curtime.tm_min); |
340 datasize=DATASIZE; |
|
341 if(crc) { flags|=F_CRC; datasize-=4; } |
|
342 |
|
343 sprintf(buffer,"%04d%02d%02d%02d%02d",curtime.tm_year+1900, |
|
344 curtime.tm_mon+1,curtime.tm_mday,curtime.tm_hour,curtime.tm_min); |
190 |
345 |
191 strncpy(header.id_str,HDR_STRING,32); header.id_str[32] = 0; |
346 strncpy(header.id_str,HDR_STRING,32); header.id_str[32]=0; |
192 strncpy(header.vol_id,cd_label,32); header.vol_id[32] = 0; |
347 strncpy(header.vol_id,cd_label,32); header.vol_id[32]=0; |
193 strncpy(header.t_stamp,buffer,12); header.t_stamp[12] = 0; |
348 strncpy(header.t_stamp,buffer,12); header.t_stamp[12]=0; |
194 header.disk_set = disk_set; |
349 header.disk_set = disknum; |
|
350 header.flags = flags; |
195 |
351 |
196 if(verbose) |
352 if(verbose) |
197 fprintf(stderr,"%s: Recording to device %s, multidisk %s, disk %d\n",prg_name,cdr_dev,multidisk?"enabled":"disabled",disk_set); |
353 fprintf(stderr,"%s: Recording to %s, multidisk %s, CRC %s, disk %d\n", |
198 |
354 prg_name,VdevName(), |
199 #ifndef DEBUGOUT /* the "real" code */ |
355 multidisk?"enabled":"disabled", |
200 /* launch cdrecord */ |
356 crc?"enabled":"disabled", |
201 if(pipe(fd) == -1) error("Unable to create pipe handles"); |
357 disknum); |
202 if((childpid=fork()) == -1) error("Fork failed"); |
358 secs=cd_len; |
203 if(childpid == 0) { /* child */ |
359 VnewTrack(); |
204 close(fd[1]); |
360 |
205 close(0); /* stdin */ |
|
206 dup2(fd[0], 0); |
|
207 start_cdrecord(); /* doesn't return */ |
|
208 } |
|
209 |
|
210 close(fd[0]); outpipe=fd[1]; |
|
211 |
|
212 /* output the header block */ |
|
213 memset(buffer,0,CD_FRAMESIZE); |
361 memset(buffer,0,CD_FRAMESIZE); |
214 memcpy(buffer,&header,sizeof(struct header_block)); |
362 memcpy(buffer,&header,sizeof(struct header_block)); |
215 if((bytes=write(outpipe, buffer, CD_FRAMESIZE)) != CD_FRAMESIZE) error("Error writing header block"); |
363 Vwrite(buffer); grandTotal+=CD_FRAMESIZE; |
216 |
|
217 cd_avail-=bytes; grandTotal+=bytes; |
|
218 /* account for the padsize */ |
|
219 cd_avail-=padsize*CD_FRAMESIZE; |
|
220 #else |
|
221 /* debug code; send data to /dev/null. Don't need the pipe. */ |
|
222 fprintf(stderr, "DEBUG CODE: sending data to /dev/null!\n"); |
|
223 outpipe = open("/dev/null", O_WRONLY); |
|
224 if (outpipe < 0) { perror("/dev/null"); exit(1); } |
|
225 #endif |
|
226 |
|
227 db->reserved = 0; |
|
228 |
364 |
229 do { |
365 do { |
230 /* read a block */ |
366 int bytes; |
231 db->status = 0; /* this isn't the last block (for now) */ |
367 |
232 bytes=full_read(0,&buffer[DBSIZE],DATASIZE); |
368 db->flags=flags; |
233 if (bytes < 0) error("Error reading input"); |
369 db->status=0; /* this isn't the last block (for now) */ |
234 if (bytes != DATASIZE) db->status=1; /* EOF, this is the last block */ |
370 bytes=full_read(0,&buffer[DBSIZE],datasize); |
235 db->datasize = htons(bytes); |
371 if(bytes!=datasize) db->status=1; /* EOF, this is the last block */ |
236 |
372 db->datasize=htons(bytes); |
237 /* check for free space */ |
373 |
238 if(cd_avail < (CD_FRAMESIZE*2)) { /* less than 2 block free */ |
374 if(cd_avail<(CD_FRAMESIZE*2)) { /* less than 2 block free */ |
239 if(db->status==0) db->status=2; /* if not last block, mark disk as full */ |
375 if(db->status==0) { /* if not last block, mark disk as full */ |
240 } |
376 db->status=2; |
241 |
377 result=1; |
242 /* write a block */ |
378 } |
243 bytes = write(outpipe, buffer, CD_FRAMESIZE); |
379 } |
244 if(bytes != CD_FRAMESIZE) error("Error writing data block"); |
380 if(crc) { |
245 |
381 int l=crc32(buffer,bytes+DBSIZE); |
246 grandTotal+=bytes; cd_avail-=bytes; |
382 *((unsigned long *)(&buffer[CD_FRAMESIZE-4]))=l; |
|
383 } |
|
384 Vwrite(buffer); grandTotal+=CD_FRAMESIZE; |
247 } while(db->status==0); |
385 } while(db->status==0); |
248 |
386 |
249 /* close pipe and wait for child termination */ |
387 if(dvd && cd_avail>=CD_FRAMESIZE) { /* pad up the track with zeros */ |
250 close(outpipe); |
388 memset(buffer,0,CD_FRAMESIZE); |
251 while (wait(0) != childpid); |
389 if(verbose) fprintf(stderr,"%s: padding up the track\n",prg_name); |
|
390 while(cd_avail>=CD_FRAMESIZE) Vwrite(buffer); |
|
391 } |
|
392 |
|
393 VcloseTrack(result); |
252 |
394 |
253 totalSize+=grandTotal; |
395 totalSize+=grandTotal; |
254 if(verbose) fprintf(stderr,"%s: Recording finished. %lld kB written (%lld kB on this disk)\n", |
396 if(verbose) { |
255 prg_name,totalSize/1024,grandTotal/1024); |
397 char str1[16], str2[16]; |
256 |
398 fprintf(stderr,"%s: Recording finished. %s written (%s on this disk)\n", |
257 if(db->status==2) return 1; /* disk was full */ |
399 prg_name,FlexSize(str1,totalSize),FlexSize(str2,grandTotal)); |
|
400 } |
|
401 return result; |
|
402 } |
|
403 |
|
404 /****************************************************************************/ |
|
405 |
|
406 int main(int argc, char *argv[]) |
|
407 { |
|
408 int result, loop; |
|
409 time_t curtime_t; |
|
410 |
|
411 curtime_t=time(0); curtime=*localtime(&curtime_t); |
|
412 parse_cmdline(argc,argv); |
|
413 |
|
414 if(virt_dump) { |
|
415 dump(); |
|
416 } |
|
417 else { |
|
418 do { |
|
419 do { |
|
420 autosize(); |
|
421 Vopen(0); result=VreadToc(0); VprintSpace(); |
|
422 loop=1; |
|
423 |
|
424 if(disknum>1 && result!=0) { |
|
425 Vclose(); |
|
426 fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name); |
|
427 diskchange(multicmd,cd_dev); |
|
428 } |
|
429 else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) { |
|
430 Vclose(); |
|
431 if(multidisk) { |
|
432 fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name); |
|
433 diskchange(multicmd,cd_dev); |
|
434 } |
|
435 else serror("Not enough free space on disk"); |
|
436 } |
|
437 else loop=0; |
|
438 } while(loop); |
|
439 |
|
440 result=backup(); |
|
441 if(result==1) { |
|
442 if(multidisk==0) serror("Disk full, multi-disk not enabled. Aborting"); |
|
443 |
|
444 disknum++; |
|
445 if(!VisRegular()) diskchange(multicmd,cd_dev); |
|
446 } |
|
447 } while(result!=0); |
|
448 } |
258 return 0; |
449 return 0; |
259 } |
450 } |
260 |
|
261 /****************************************************************************/ |
|
262 |
|
263 int main(int argc, char *argv[]) |
|
264 { |
|
265 int cdr; |
|
266 int disknum, result, loop; |
|
267 time_t curtime_t; |
|
268 |
|
269 disknum=1; totalSize=0; |
|
270 curtime_t=time(0); curtime=*localtime(&curtime_t); |
|
271 |
|
272 parse_cmdline(argc,argv); |
|
273 |
|
274 do { |
|
275 do { |
|
276 cdr=open_cdr(cd_dev); result=read_toc(cdr,0); close_cdr(cdr); |
|
277 print_space(); |
|
278 loop=1; |
|
279 |
|
280 if(disknum>1 && result!=0) { |
|
281 fprintf(stderr,"%s: Can't do multidisk continuation on non-empty disk! Try another disk\n", prg_name); |
|
282 if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); |
|
283 } |
|
284 else if(cd_avail<(padsize+MIN_BLOCKS)*CD_FRAMESIZE) { |
|
285 if(multidisk) { |
|
286 fprintf(stderr,"%s: Not enough free space on disk! Try another disk\n", prg_name); |
|
287 if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); |
|
288 } |
|
289 else serror("Not enough free space on disk"); |
|
290 } |
|
291 else loop=0; |
|
292 } while(loop); |
|
293 |
|
294 result = backup(disknum); |
|
295 if(result == 1) { |
|
296 if(multidisk == 0) serror("Disk full, multi-disk not enabled. Aborting"); |
|
297 |
|
298 disknum++; |
|
299 if(start_diskchange(multicmd,cd_dev)) serror("Diskchange command failed"); |
|
300 } |
|
301 } while (result != 0); |
|
302 |
|
303 return 0; |
|
304 } |
|