1
2
3 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
4
5 Copyright 2007-2017 Thomas Schmitt, <scdbackup@gmx.net>
6
7 Provided under GPL version 2 or later.
8
9 This file contains functions which are needed to write sessions.
10 */
11
12 #ifdef HAVE_CONFIG_H
13 #include "../config.h"
14 #endif
15
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <errno.h>
26
27 #include <fcntl.h>
28
29 #ifdef HAVE_STDINT_H
30 #include <stdint.h>
31 #else
32 #ifdef HAVE_INTTYPES_H
33 #include <inttypes.h>
34 #endif
35 #endif
36
37 /* O_BINARY is needed for Cygwin but undefined elsewhere */
38 #ifndef O_BINARY
39 #define O_BINARY 0
40 #endif
41
42
43 #ifdef Xorriso_standalonE
44
45 #ifdef Xorriso_with_libjtE
46 #include "../libjte/libjte.h"
47 #endif
48
49 #else
50
51 #ifdef Xorriso_with_libjtE
52 #include <libjte/libjte.h>
53 #endif
54
55 #endif /* ! Xorriso_standalonE */
56
57 #include "xorriso.h"
58 #include "xorriso_private.h"
59
60 #include "lib_mgt.h"
61 #include "drive_mgt.h"
62 #include "iso_img.h"
63 #include "iso_tree.h"
64 #include "write_run.h"
65
66
67 /* @param flag bit0= talk of -as cdrecord -multi rather than of -close
68 */
Xorriso_check_multi(struct XorrisO * xorriso,struct burn_drive * drive,int flag)69 int Xorriso_check_multi(struct XorrisO *xorriso, struct burn_drive *drive,
70 int flag)
71 {
72 int profile_no= 0, ret;
73 struct burn_multi_caps *caps= NULL;
74 char profile_name[80];
75
76 if(xorriso->auto_close)
77 xorriso->do_close= 0;
78 if(!xorriso->do_close) {
79 burn_disc_get_profile(drive, &profile_no, profile_name);
80 if(profile_no == 0x14) { /* DVD-RW sequential */
81 ret= burn_disc_get_multi_caps(drive, BURN_WRITE_TAO, &caps, 0);
82 if(caps != NULL)
83 burn_disc_free_multi_caps(&caps);
84 if(ret == 0) {
85 if(xorriso->auto_close) {
86 sprintf(xorriso->info_text,
87 "-close \"as_needed\" triggered -close \"on\"");
88 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
89 xorriso->do_close= 1;
90 } else if(flag & 1) {
91 sprintf(xorriso->info_text,
92 "This DVD-RW media can only be written without option -multi");
93 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
94 sprintf(xorriso->info_text,
95 "Possibly it was blanked by blank=deformat_quickest");
96 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
97 sprintf(xorriso->info_text,
98 "After writing a session without -multi, apply blank=all");
99 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
100 return(0);
101 } else {
102 sprintf(xorriso->info_text,
103 "This DVD-RW media can only be written with -close \"on\"");
104 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
105 sprintf(xorriso->info_text,
106 "Possibly it was blanked by -blank \"deformat_quickest\"");
107 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
108 sprintf(xorriso->info_text,
109 "After writing a session with -close \"on\", apply -blank \"all\"");
110 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
111 return(0);
112 }
113 }
114 } else if(profile_no == 0x15) { /* DVD-RW DL */
115 if(xorriso->auto_close) {
116 sprintf(xorriso->info_text,
117 "-close \"as_needed\" triggered -close \"on\"");
118 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
119 xorriso->do_close= 1;
120 } else if(flag & 1) {
121 sprintf(xorriso->info_text,
122 "DVD-R DL media can only be written without option -multi");
123 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
124 return(0);
125 } else {
126 sprintf(xorriso->info_text,
127 "DVD-R DL media can only be written with -close \"on\"");
128 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
129 return(0);
130 }
131 }
132 }
133 return(1);
134 }
135
136
Xorriso_make_write_options(struct XorrisO * xorriso,struct burn_drive * drive,struct burn_write_opts ** burn_options,int flag)137 int Xorriso_make_write_options(
138 struct XorrisO *xorriso, struct burn_drive *drive,
139 struct burn_write_opts **burn_options, int flag)
140 {
141 int drive_role, stream_mode= 0, ret, profile;
142 char profile_name[80];
143 enum burn_disc_status s;
144
145 *burn_options= burn_write_opts_new(drive);
146 if(*burn_options==NULL) {
147 Xorriso_process_msg_queues(xorriso,0);
148 sprintf(xorriso->info_text,"Cannot allocate option set");
149 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
150 return(0);
151 }
152 burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy);
153 drive_role= burn_drive_get_drive_role(drive);
154 burn_write_opts_set_multi(*burn_options,
155 !(xorriso->do_close || drive_role==0 || drive_role==3));
156
157 ret= burn_disc_get_profile(drive, &profile, profile_name);
158 if(ret > 0) {
159 s= isoburn_disc_get_status(drive);
160 if(xorriso->auto_close && xorriso->do_close == 0 &&
161 profile == 0x14 && s == BURN_DISC_BLANK)
162 /* Prepare for missing feature 21h despite drive's announcement */
163 burn_write_opts_set_fail21h_sev(*burn_options, "NOTE");
164 }
165
166 if(xorriso->write_speed != -2)
167 burn_drive_set_speed(drive, 0, xorriso->write_speed);
168 burn_drive_set_buffer_waiting(drive, xorriso->modesty_on_drive,
169 xorriso->min_buffer_usec,
170 xorriso->max_buffer_usec,
171 xorriso->buffer_timeout_sec,
172 xorriso->min_buffer_percent,
173 xorriso->max_buffer_percent);
174 if(xorriso->do_stream_recording == 1)
175 stream_mode= 1;
176 else if(xorriso->do_stream_recording == 2)
177 stream_mode= 51200; /* 100 MB */
178 else if(xorriso->do_stream_recording >= 16)
179 stream_mode= xorriso->do_stream_recording;
180 burn_write_opts_set_stream_recording(*burn_options, stream_mode);
181
182 #ifdef Xorriso_dvd_obs_default_64K
183 if(xorriso->dvd_obs == 0)
184 burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024);
185 else
186 #endif
187 burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs);
188
189 burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync);
190 burn_write_opts_set_underrun_proof(*burn_options, 1);
191 return(1);
192 }
193
194
195 /* @param flag bit0= do not write but only prepare and return size in sectors
196 bit1= do not use isoburn wrappers, do not assume libisofs
197 */
Xorriso_sanitize_image_size(struct XorrisO * xorriso,struct burn_drive * drive,struct burn_disc * disc,struct burn_write_opts * burn_options,int flag)198 int Xorriso_sanitize_image_size(struct XorrisO *xorriso,
199 struct burn_drive *drive, struct burn_disc *disc,
200 struct burn_write_opts *burn_options, int flag)
201 {
202 int ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile;
203 off_t media_space;
204 int lba, nwa, multi_emul_blocks= 0;
205 char profile_name[80];
206 struct burn_session **sessions;
207 struct burn_track **tracks;
208 enum burn_disc_status s;
209
210 img_sectors= burn_disc_get_sectors(disc);
211
212 sessions= burn_disc_get_sessions(disc, &num_sessions);
213 if(sessions==NULL || num_sessions < 1) {
214 no_track:;
215 Xorriso_process_msg_queues(xorriso,0);
216 sprintf(xorriso->info_text,"Program error : no track in prepared disc");
217 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
218 {ret= -1; goto ex;}
219 }
220 tracks= burn_session_get_tracks(sessions[0], &num_tracks);
221 if(tracks==NULL || num_tracks < 1)
222 goto no_track;
223
224 padding= 0;
225 ret= burn_disc_get_profile(drive, &profile, profile_name);
226 padding= xorriso->padding / 2048;
227 if(xorriso->padding > padding * 2048)
228 padding++;
229 if(img_sectors>0 && ret>0 &&
230 (profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */
231 if(img_sectors + padding < Xorriso_cd_min_track_sizE) {
232 padding= Xorriso_cd_min_track_sizE - img_sectors;
233 sprintf(xorriso->info_text,
234 "Expanded track to minimum size of %d sectors",
235 Xorriso_cd_min_track_sizE);
236 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
237 }
238 }
239 if(xorriso->alignment == 0 && ! (xorriso->no_emul_toc & 1)) {
240 ret= isoburn_needs_emulation(drive);
241 if(ret > 0) {
242 /* Take care that the session is padded up to the future NWA.
243 Else with padding < 32 it could happen that PVDs from older
244 sessions survive and confuse -rom_toc_scan.
245 */
246 xorriso->alignment= 32;
247 s= isoburn_disc_get_status(drive);
248 if(s == BURN_DISC_BLANK) {
249 /* Count blocks before nwa as part of the image */;
250 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
251 if(ret <= 0)
252 nwa= 0;
253 multi_emul_blocks= nwa;
254 }
255 }
256 }
257
258 if(!(flag & 2)) {
259
260 #ifdef Xorriso_with_libjtE
261 /* JTE : no multi-session, no_emul_toc, padding in libisofs */
262 if(xorriso->libjte_handle != NULL)
263 padding= 0;
264 #endif /* ! Xorriso_with_libjtE */
265
266 if(xorriso->do_padding_by_libisofs)
267 padding= 0;
268 }
269
270 if(xorriso->alignment > 0) {
271 if(img_sectors > 0) {
272 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
273 if(ret <= 0)
274 nwa= 0;
275 lba= (nwa + img_sectors + padding) % xorriso->alignment;
276 if(lba > 0)
277 padding+= xorriso->alignment - lba;
278 }
279 }
280
281 burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1);
282 Xorriso_process_msg_queues(xorriso,0);
283
284 if(flag&2)
285 media_space= burn_disc_available_space(drive, burn_options) /
286 (off_t) 2048;
287 else
288 media_space= isoburn_disc_available_space(drive, burn_options) /
289 (off_t) 2048;
290 if(media_space < img_sectors + padding) {
291 Xorriso_process_msg_queues(xorriso,0);
292 sprintf(xorriso->info_text,
293 "Image size %ds exceeds free space on media %.fs",
294 img_sectors + padding, (double) media_space);
295 if(flag & 1) {
296 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
297 } else {
298 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
299 {ret= 0; goto ex;}
300 }
301 }
302 if(flag&1) {
303 ret= multi_emul_blocks + img_sectors + padding;
304 } else
305 ret= 1;
306 ex:;
307 return(ret);
308 }
309
310
Xorriso_auto_format(struct XorrisO * xorriso,int flag)311 int Xorriso_auto_format(struct XorrisO *xorriso, int flag)
312 {
313 int ret, profile, status, num_formats;
314 char profile_name[80];
315 struct burn_drive_info *dinfo;
316 struct burn_drive *drive;
317 off_t size;
318 unsigned dummy;
319
320 ret= Xorriso_may_burn(xorriso, 0);
321 if(ret <= 0)
322 return(0);
323
324 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
325 "on attempt to autoformat", 2);
326 if(ret<=0)
327 return(0);
328 ret= burn_disc_get_profile(drive, &profile, profile_name);
329 if(ret>0 && (profile==0x12 || profile==0x43)) { /* DVD-RAM or BD-RE */
330 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
331 if(ret>0 && status==BURN_FORMAT_IS_UNFORMATTED) {
332 sprintf(xorriso->info_text,
333 "Unformatted %s medium detected. Trying -format fast.",
334 profile_name);
335 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
336 ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4);
337 if(ret<=0) {
338 sprintf(xorriso->info_text, "Automatic formatting of %s failed",
339 profile_name);
340 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
341 return(ret);
342 }
343 }
344 }
345 return(1);
346 }
347
348
349 /* @param flag bit0= fail on indev == outdev with "imported_iso"
350 bit1= fail on indev == NULL with "imported_iso"
351 */
Xorriso_check_intvl_string(struct XorrisO * xorriso,char ** part_image,int flag)352 int Xorriso_check_intvl_string(struct XorrisO *xorriso, char **part_image,
353 int flag)
354 {
355 char *cpt, *ipt, *orig;
356
357 orig= *part_image;
358 if(strncmp(*part_image, "--interval:", 11) != 0)
359 return(0);
360 if(strchr(*part_image + 11, ':') == NULL)
361 return(0);
362 (*part_image)+= 11;
363 if(!(flag & 3))
364 return(1);
365
366 cpt= strchr(*part_image, ':');
367 ipt= strstr(*part_image, "imported_iso");
368 if(ipt == NULL || ipt > cpt)
369 return(1);
370
371 if((flag & 2) && xorriso->in_drive_handle == NULL) {
372 sprintf(xorriso->info_text,
373 "Interval reader lacks of -indev to read from \"imported_iso\"");
374 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
375 goto failure;
376 }
377
378 if(!(flag & 1))
379 return(1);
380 if(xorriso->out_drive_handle != xorriso->in_drive_handle)
381 return(1);
382 sprintf(xorriso->info_text,
383 "Interval reader may not read from \"imported_iso\" during write run to same drive");
384 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
385
386 failure:;
387 sprintf(xorriso->info_text, "Rejected: ");
388 Text_shellsafe(orig, xorriso->info_text, 1);
389 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
390 return(-1);
391 }
392
393
Xorriso_set_system_area(struct XorrisO * xorriso,struct burn_drive * drive,IsoImage * img,struct isoburn_imgen_opts * sopts,int flag)394 int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
395 IsoImage *img, struct isoburn_imgen_opts *sopts,
396 int flag)
397 {
398 int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks;
399 int sa_loaded, read_count, i, read_sum= 0;
400 char volid[33];
401 FILE *fp= NULL;
402 char *buf= NULL, *bufpt= NULL, *intvl;
403 uint8_t *intvl_buf;
404 off_t hd_lba, byte_count;
405 unsigned char *ub;
406 ElToritoBootImage *bootimg;
407 IsoFile *bootimg_node;
408 IsoNode *sparc_core_node;
409 uint32_t offst;
410 enum burn_disc_status state;
411 struct iso_interval_reader *ivr = NULL;
412
413 if(xorriso->grub2_sparc_core[0]) {
414 ret= Xorriso_node_from_path(xorriso, img, xorriso->grub2_sparc_core,
415 &sparc_core_node, 1);
416 if(ret <= 0) {
417 sprintf(xorriso->info_text,
418 "Cannot find in ISO image: -boot_image grub grub2_sparc_core=");
419 Text_shellsafe(xorriso->grub2_sparc_core, xorriso->info_text, 1);
420 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
421 {ret= 0; goto ex;}
422 }
423 if(!ISO_NODE_IS_FILE(sparc_core_node)) {
424 sprintf(xorriso->info_text,
425 "Not a data file: -boot_image grub grub2_sparc_core=");
426 Text_shellsafe(xorriso->grub2_sparc_core, xorriso->info_text, 1);
427 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
428 {ret= 0; goto ex;}
429 }
430 ret = iso_image_set_sparc_core(img, (IsoFile *) sparc_core_node, 0);
431 if(ret < 0) {
432 Xorriso_process_msg_queues(xorriso,0);
433 Xorriso_report_iso_error(xorriso, "", ret,
434 "Error when setting up -boot_image grub grub2_sparc_core=",
435 0, "FAILURE", 1);
436 {ret= 0; goto ex;}
437 }
438 }
439
440 Xorriso_alloc_meM(buf, char, 32768);
441 memset(buf, 0, 32768);
442 system_area_options= xorriso->system_area_options;
443 if(xorriso->system_area_clear_loaded)
444 sa_loaded= 0;
445 else
446 sa_loaded= iso_image_get_system_area(img, buf, &options, 0);
447 if(sa_loaded < 0) {
448 Xorriso_process_msg_queues(xorriso,0);
449 Xorriso_report_iso_error(xorriso, "", sa_loaded,
450 "Error when inquiring System Area data of ISO 9660 image",
451 0, "FAILURE", 1);
452 {ret= 0; goto ex;}
453 } if(sa_loaded > 0)
454 bufpt= buf;
455 if(xorriso->system_area_disk_path[0] == 0) {
456 if(xorriso->patch_system_area && xorriso->system_area_options == 0 &&
457 sa_loaded > 0) {
458 system_area_options= xorriso->patch_system_area;
459 /* Check whether partition 1 ends at image end */;
460 ub= (unsigned char *) buf;
461 hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) |
462 (((unsigned int) ub[457]) << 24)) +
463 (ub[458] | (ub[459] << 8) | (ub[460] << 16) |
464 (((unsigned int) ub[461]) << 24));
465
466 iso_lba= -1;
467 ret= isoburn_disc_get_msc1(drive, &start_lba);
468 if(ret > 0) {
469 ret= isoburn_read_iso_head(drive, start_lba, &image_blocks,
470 volid, 1);
471 if(ret > 0)
472 iso_lba= start_lba + image_blocks;
473 }
474 if(((off_t) iso_lba) * (off_t) 4 > hd_lba) {
475 system_area_options= 0;
476 } else if((xorriso->patch_system_area & 1) &&
477 ((off_t) iso_lba) * (off_t) 4 != hd_lba) {
478 system_area_options= 0;
479 } else if((xorriso->patch_system_area & 2) &&
480 ((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) {
481 system_area_options= 0;
482 } else if(xorriso->patch_system_area & 2) { /* isohybrid patching */
483 /* Check whether bytes 432-345 point to ElTorito LBA */
484 hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) |
485 (((unsigned int) ub[435]) << 24);
486 ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL);
487 if(ret != 1) {
488 system_area_options= 0;
489 } else if(bootimg_node != NULL) {
490 Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0);
491 if(((off_t) iso_lba) * (off_t) 4 != hd_lba)
492 system_area_options= 0;
493 }
494 }
495 if(system_area_options == 0) {
496 Xorriso_msgs_submit(xorriso, 0,
497 "Loaded System Area data are not suitable for MBR patching.",
498 0, "DEBUG", 0);
499 }
500 }
501 {ret= 1; goto do_set;}
502 }
503
504 bufpt= buf;
505 if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0) {
506 memset(buf, 0, 32768);
507 {ret= 1; goto do_set;}
508 }
509
510 intvl= xorriso->system_area_disk_path;
511 ret= Xorriso_check_intvl_string(xorriso, &intvl, 2);
512 if(ret < 0) {
513 {ret= 0; goto ex;}
514 } else if(ret > 0) {
515 ret= iso_interval_reader_new(img, intvl, &ivr, &byte_count, 0);
516 Xorriso_process_msg_queues(xorriso, 0);
517 if(ret < 0) {
518 intvl_reader_err:;
519 sprintf(xorriso->info_text,
520 "Error when reading -boot_image system_area=");
521 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
522 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
523 {ret= 0; goto ex;}
524 }
525 for(i= 0; i < 16; i++) {
526 intvl_buf= (uint8_t *) (buf + 2048 * i);
527 ret= iso_interval_reader_read(ivr, intvl_buf, &read_count, 0);
528 Xorriso_process_msg_queues(xorriso, 0);
529 if(ret == 0)
530 break;
531 if(ret < 0)
532 goto intvl_reader_err;
533 read_sum+= read_count;
534 }
535 ret= read_sum;
536 } else {
537 ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path,
538 "rb", &fp, 2);
539 if(ret <= 0)
540 {ret= 0; goto ex;}
541 ret= fread(buf, 1, 32768, fp);
542 if(ret < 32768) {
543 if(ferror(fp)) {
544 sprintf(xorriso->info_text,
545 "Error when reading -boot_image system_area=");
546 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
547 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
548 {ret= 0; goto ex;}
549 }
550 }
551 }
552
553 do_set:;
554 if(ret > 0 && xorriso->system_area_disk_path[0]) {
555 sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ",
556 ret);
557 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
558 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
559 }
560 ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options);
561 if(ret != ISO_SUCCESS) {
562 Xorriso_process_msg_queues(xorriso,0);
563 Xorriso_report_iso_error(xorriso, "", ret,
564 "Error when attaching System Area data to ISO 9660 image",
565 0, "FAILURE", 1);
566 {ret= 0; goto ex;}
567 }
568 offst= xorriso->partition_offset;
569 state= isoburn_disc_get_status(drive);
570 if(state == BURN_DISC_APPENDABLE) {
571 ret= isoburn_get_img_partition_offset(drive, &offst);
572 if(ret == 1) {
573 sprintf(xorriso->info_text,
574 "Preserving in ISO image: -boot_image any partition_offset=%lu",
575 (unsigned long) offst);
576 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
577 } else
578 offst= xorriso->partition_offset;
579 }
580 ret= isoburn_igopt_set_part_offset(sopts, offst,
581 xorriso->partition_secs_per_head,
582 xorriso->partition_heads_per_cyl);
583 if(ret != ISO_SUCCESS) {
584 Xorriso_process_msg_queues(xorriso,0);
585 Xorriso_report_iso_error(xorriso, "", ret,
586 "Error when setting partition offset", 0, "FAILURE", 1);
587 {ret= 0; goto ex;}
588 }
589 ret= 1;
590 ex:;
591 if(fp != NULL && fp != stdin)
592 fclose(fp);
593 iso_interval_reader_destroy(&ivr, 0);
594 Xorriso_free_meM(buf);
595 return(ret);
596 }
597
598
599 /* @param flag bit0= do not increment boot_count
600 and do not reset boot parameters
601 bit1= dispose attached boot images
602 */
Xorriso_attach_boot_image(struct XorrisO * xorriso,int flag)603 int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag)
604 {
605 int ret;
606 char *cpt;
607 struct burn_drive_info *source_dinfo;
608 struct burn_drive *source_drive;
609 IsoImage *image= NULL;
610 IsoNode *node= NULL;
611 ElToritoBootImage *bootimg;
612 enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
613 char *bin_path;
614 int emul, platform_id;
615 off_t load_size;
616 struct stat stbuf;
617 int hflag= 0, is_interval= 0;
618
619 if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) {
620
621 /* >>> no boot image path given : no op */;
622
623 ret= 2; goto ex;
624 }
625
626 if(xorriso->in_drive_handle == NULL)
627 hflag= 2;
628 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
629 "on attempt to attach boot image", hflag);
630 if(ret<=0)
631 goto ex;
632 image= isoburn_get_attached_image(source_drive);
633 if(image == NULL) {
634 /* (should not happen) */
635 sprintf(xorriso->info_text,
636 "No ISO image present on attempt to attach boot image");
637 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
638 ret= 0; goto ex;
639 }
640 if(flag & 2) {
641 iso_image_remove_boot_image(image);
642 xorriso->boot_count= 0;
643 ret= 1; goto ex;
644 }
645
646 bin_path= xorriso->boot_image_bin_path;
647 emul= xorriso->boot_image_emul;
648 platform_id= xorriso->boot_platform_id;
649 load_size= xorriso->boot_image_load_size;
650 if(strncmp(bin_path, "--interval:appended_partition_", 30) == 0) {
651 is_interval= 1;
652 if(load_size <= 0)
653 load_size= 512;
654 }
655
656 if(xorriso->boot_efi_default) {
657 emul= 0;
658 platform_id= 0xef;
659 xorriso->patch_isolinux_image= (xorriso->patch_isolinux_image & ~3) | 0;
660 }
661 if((platform_id == 0xef || load_size < 0) && !is_interval) {
662 ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
663 if(ret != 0)
664 {ret= 0; goto ex;}
665 load_size= ((stbuf.st_size / (off_t) 512) +
666 !!(stbuf.st_size % (off_t) 512)) * 512;
667 }
668 sprintf(xorriso->info_text, "Adding boot image ");
669 Text_shellsafe(bin_path, xorriso->info_text, 1);
670 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
671
672 if(emul == 0)
673 emul_type= ELTORITO_NO_EMUL;
674 else if(emul == 1)
675 emul_type= ELTORITO_HARD_DISC_EMUL;
676 else if(emul == 2)
677 emul_type= ELTORITO_FLOPPY_EMUL;
678
679 if (!is_interval) {
680 ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1);
681 if(ret <= 0) {
682 sprintf(xorriso->info_text,
683 "Cannot find in ISO image: -boot_image ... bin_path=");
684 Text_shellsafe(bin_path, xorriso->info_text, 1);
685 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
686 {ret= 0; goto ex;}
687 }
688 }
689
690 if(xorriso->boot_count == 0) {
691 if(xorriso->boot_image_cat_path[0] == 0) {
692 strcpy(xorriso->boot_image_cat_path, bin_path);
693 cpt= strrchr(xorriso->boot_image_cat_path, '/');
694 if(cpt == NULL)
695 cpt= xorriso->boot_image_cat_path;
696 else
697 cpt++;
698 strcpy(cpt, "boot.cat");
699 }
700 ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
701 &node, 1);
702 if(ret > 0) {
703 if(!xorriso->do_overwrite) {
704 sprintf(xorriso->info_text,
705 "May not overwrite existing -boot_image ... cat_path=");
706 Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
707 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
708 {ret= 0; goto ex;}
709 }
710 ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
711 8 | (xorriso->do_overwrite == 1));
712 if(ret != 1) {
713 sprintf(xorriso->info_text,
714 "Could not remove existing -boot_image cat_path=");
715 Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
716 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
717 {ret= 0; goto ex;}
718 }
719 }
720
721 /* Discard old boot image, set new one */
722 ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
723 if(ret == 1)
724 iso_image_remove_boot_image(image);
725 ret= iso_image_set_boot_image(image, bin_path, emul_type,
726 xorriso->boot_image_cat_path, &bootimg);
727 if(ret > 0)
728 iso_image_set_boot_catalog_weight(image, 1000000000);
729 } else {
730 ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg);
731 }
732 if(ret < 0) {
733 Xorriso_process_msg_queues(xorriso,0);
734 Xorriso_report_iso_error(xorriso, "", ret,
735 "Error when attaching El-Torito boot image to ISO 9660 image",
736 0, "FAILURE", 1);
737 sprintf(xorriso->info_text,
738 "Could not attach El-Torito boot image to ISO 9660 image");
739 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
740 {ret= 0; goto ex;}
741 }
742 el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id);
743 if(load_size / 512 > 65535) {
744 sprintf(xorriso->info_text,
745 "Boot image load size exceeds 65535 blocks of 512 bytes. ");
746 if(platform_id == 0xef) {
747 strcat(xorriso->info_text,
748 "Will record 0 in El Torito to extend ESP to end-of-medium.");
749 load_size= 0;
750 } else {
751 strcat(xorriso->info_text, "Will record 65535 in El Torito.");
752 load_size= 65535 * 512;
753 }
754 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
755 }
756
757 if(xorriso->boot_img_full_size) {
758 el_torito_set_full_load(bootimg, 1);
759 } else {
760 /* The function will understand negative short as positive unsigned */
761 el_torito_set_load_size(bootimg, (short) (load_size / 512));
762 }
763
764 el_torito_set_id_string(bootimg, xorriso->boot_id_string);
765 el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit);
766 ret= Xorriso_set_isolinux_options(xorriso, image, 1);
767 if(!(flag & 1)) {
768 /* Register attachment and reset even in case of error return */
769 xorriso->boot_count++;
770 xorriso->boot_platform_id= 0;
771 xorriso->patch_isolinux_image= 0;
772 xorriso->boot_image_bin_path[0]= 0;
773 xorriso->boot_image_bin_form[0]= 0;
774 xorriso->boot_image_emul= 0;
775 xorriso->boot_emul_default= 1;
776 xorriso->boot_image_load_size= 4 * 512;
777 xorriso->boot_img_size_default= 1;
778 xorriso->boot_img_full_size= 0;
779 memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string));
780 memset(xorriso->boot_selection_crit, 0,
781 sizeof(xorriso->boot_selection_crit));
782 xorriso->boot_efi_default= 0;
783 }
784 if(ret <= 0)
785 goto ex;
786
787 ret= 1;
788 ex:;
789 if(image != NULL)
790 iso_image_unref(image);
791 return(ret);
792 }
793
794
Xorriso_write_application_use(struct XorrisO * xorriso,IsoImage * image,int flag)795 int Xorriso_write_application_use(struct XorrisO *xorriso,
796 IsoImage *image, int flag)
797 {
798 int l, ret, count= 512;
799 unsigned int byte= 0;
800 char *path, data[512];
801 FILE *fp= NULL;
802
803 path= xorriso->application_use;
804 l= strlen(path);
805 if(l <= 1) {
806 memset(data, path[0], 512);
807 } else if(l == 4 && path[0] == '0' && path[1] == 'x' &&
808 isxdigit(path[2]) && isxdigit(path[3])) {
809 sscanf(path + 2, "%x", &byte);
810 memset(data, (int) byte, 512);
811 } else {
812 /* Read up to 512 bytes from file path */
813 ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0);
814 if(ret <= 0)
815 {ret= 0; goto ex;}
816 ret= fread(data, 1, 512, fp);
817 if(ret < 512) {
818 if(ferror(fp)) {
819 sprintf(xorriso->info_text,
820 "-application_use: Error while reading file ");
821 Text_shellsafe(path, xorriso->info_text, 1);
822 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
823 errno, "FAILURE", 0);
824 ret= 0; goto ex;
825 }
826 }
827 if(ret < 0)
828 count= 0;
829 else
830 count= ret;
831 }
832 iso_image_set_app_use(image, data, count);
833 ret= 1;
834 ex:
835 if(fp != NULL && fp != stdin)
836 fclose(fp);
837 return(ret);
838 }
839
840
Xorriso_retry_write_session(struct XorrisO * xorriso,int flag)841 int Xorriso_retry_write_session(struct XorrisO *xorriso, int flag)
842 {
843 int ret, auto_close_mem, do_close_mem;
844
845 if(xorriso->do_tao == 1) {
846 Xorriso_msgs_submit(xorriso, 0,
847 "There is no hope for a re-try with -close \"on\" as long as -write_type is \"tao\"",
848 0, "FAILURE", 0);
849 return(0);
850 }
851 Xorriso_msgs_submit(xorriso, 0, "Re-trying with -close \"on\"", 0, "NOTE", 0);
852 do_close_mem= xorriso->do_close;
853 auto_close_mem= xorriso->auto_close;
854 xorriso->do_close= 1;
855 xorriso->auto_close= 0;
856 ret= Xorriso_write_session(xorriso, 0);
857 xorriso->do_close= do_close_mem;
858 xorriso->auto_close= auto_close_mem;
859 return(ret);
860 }
861
862
Xorriso_make_iso_write_opts(struct XorrisO * xorriso,IsoImage * image,struct isoburn_imgen_opts * sopts,int flag)863 int Xorriso_make_iso_write_opts(struct XorrisO *xorriso, IsoImage *image,
864 struct isoburn_imgen_opts *sopts, int flag)
865 {
866 int ext, i, ret, pad_by_libisofs= 0, is_bootable= 0, relax, intvl_string= 0;
867 int intvl_check= 2; /* 3 forbids "imported_iso" */
868 char *out_cs, *part_image;
869 IsoNode *root_node;
870 uint32_t padding;
871
872 relax= xorriso->relax_compliance;
873 if(image != NULL)
874 is_bootable= iso_image_get_boot_image(image, NULL, NULL, NULL);
875
876 /* xorriso->patch_isolinux_image gets reset in Xorriso_attach_boot_image()
877 So this applies only to -boot_image ... "patch" or "keep".
878 >>> Better would be to analyze and keep the relaxations of the loaded image.
879 */
880 if((xorriso->patch_isolinux_image & 1) && is_bootable == 1)
881 relax|= isoburn_igopt_allow_full_ascii;
882
883 out_cs= xorriso->out_charset;
884 if(out_cs == NULL)
885 Xorriso_get_local_charset(xorriso, &out_cs, 0);
886
887 isoburn_igopt_set_level(sopts, xorriso->iso_level);
888 ext= ((!!xorriso->do_rockridge) * isoburn_igopt_rockridge) |
889 ((!!xorriso->do_joliet) * isoburn_igopt_joliet) |
890 ((!!xorriso->do_hfsplus) * isoburn_igopt_hfsplus) |
891 ((!!xorriso->do_fat) * isoburn_igopt_fat) |
892 ((!!xorriso->do_iso1999) * isoburn_igopt_iso1999) |
893 (( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
894 (( (!(xorriso->ino_behavior & 2)) ||
895 (xorriso->do_aaip & (2 | 8 | 16 | 256)) ||
896 (xorriso->do_md5 & (2 | 4)) ||
897 xorriso->do_hfsplus
898 ) * isoburn_igopt_aaip) |
899 ((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) |
900 ((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) |
901 ((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability) |
902 ((!!xorriso->do_old_empty) * isoburn_igopt_old_empty) |
903 ((flag & 1) * isoburn_igopt_will_cancel);
904 if(xorriso->no_emul_toc & 1)
905 ext|= isoburn_igopt_no_emul_toc;
906 isoburn_igopt_set_extensions(sopts, ext);
907 isoburn_igopt_set_relaxed(sopts, relax);
908 ret = isoburn_igopt_set_rr_reloc(sopts, xorriso->rr_reloc_dir,
909 xorriso->rr_reloc_flags);
910 if(ret <= 0)
911 {ret= 0; goto ex;}
912 ret= isoburn_igopt_set_untranslated_name_len(sopts,
913 xorriso->untranslated_name_len);
914 if(ret <= 0)
915 {ret= 0; goto ex;}
916 isoburn_igopt_set_sort_files(sopts, 1);
917 isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0);
918 isoburn_igopt_set_over_ugid(sopts, 2 * !!xorriso->do_global_uid,
919 2 * !!xorriso->do_global_gid,
920 (uid_t) xorriso->global_uid,
921 (gid_t) xorriso->global_gid);
922 isoburn_igopt_set_out_charset(sopts, out_cs);
923 isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048);
924 Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8);
925 isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name,
926 xorriso->scdbackup_tag_time,
927 xorriso->scdbackup_tag_written);
928 if(xorriso->prep_partition[0]) {
929 part_image= xorriso->prep_partition;
930 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
931 if(intvl_string < 0)
932 {ret= 0; goto ex;}
933 ret= isoburn_igopt_set_prep_partition(sopts, part_image, intvl_string);
934 if(ret <= 0)
935 {ret= 0; goto ex;}
936 }
937 if(xorriso->efi_boot_partition[0]) {
938 part_image= xorriso->efi_boot_partition;
939 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
940 if(intvl_string < 0)
941 {ret= 0; goto ex;}
942 ret= isoburn_igopt_set_efi_bootp(sopts, part_image, intvl_string);
943 if(ret <= 0)
944 {ret= 0; goto ex;}
945 }
946 for(i= 0; i < Xorriso_max_appended_partitionS; i++) {
947 if(xorriso->appended_partitions[i] == NULL)
948 continue;
949 if(xorriso->appended_partitions[i][0] == 0)
950 continue;
951 if(strcmp(xorriso->appended_partitions[i], ".") == 0)
952 part_image= "";
953 else
954 part_image= xorriso->appended_partitions[i];
955 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
956 if(intvl_string < 0)
957 {ret= 0; goto ex;}
958 isoburn_igopt_set_partition_img(sopts, i + 1,
959 xorriso->appended_part_types[i], part_image);
960 isoburn_igopt_set_part_flag(sopts, i + 1, intvl_string);
961 }
962 isoburn_igopt_set_appended_as_gpt(sopts, xorriso->appended_as_gpt);
963 isoburn_igopt_set_appended_as_apm(sopts, xorriso->appended_as_apm);
964 isoburn_igopt_set_part_like_isohybrid(sopts, xorriso->part_like_isohybrid);
965 isoburn_igopt_set_iso_mbr_part_type(sopts, xorriso->iso_mbr_part_type);
966 isoburn_igopt_set_gpt_guid(sopts, xorriso->gpt_guid, xorriso->gpt_guid_mode);
967 isoburn_igopt_set_disc_label(sopts, xorriso->ascii_disc_label);
968 isoburn_igopt_set_hfsp_serial_number(sopts, xorriso->hfsp_serial_number);
969 isoburn_igopt_set_hfsp_block_size(sopts, xorriso->hfsp_block_size,
970 xorriso->apm_block_size);
971 isoburn_igopt_set_pvd_times(sopts,
972 xorriso->vol_creation_time, xorriso->vol_modification_time,
973 xorriso->vol_expiration_time, xorriso->vol_effective_time,
974 xorriso->vol_uuid);
975
976 #ifdef Xorriso_with_libjtE
977 if(xorriso->libjte_handle && (xorriso->libjte_params_given & (4 | 8))) {
978
979 /* >>> Check whether the mandatory parameters are set */;
980
981 ret= libjte_set_outfile(xorriso->libjte_handle, xorriso->outdev);
982 Xorriso_process_msg_queues(xorriso, 0);
983 if(ret <= 0)
984 goto ex;
985 isoburn_igopt_attach_jte(sopts, xorriso->libjte_handle);
986 pad_by_libisofs= 1;
987 }
988 #endif /* Xorriso_with_libjtE */
989
990 if(xorriso->do_padding_by_libisofs || pad_by_libisofs) {
991 /* Padding to be done by libisofs, not by libburn.
992 */
993 padding= xorriso->padding / 2048;
994 if((uint32_t) xorriso->padding > padding * 2048)
995 padding++;
996 /*
997 fprintf(stderr, "XORRISO_DEBUG: isoburn_igopt_set_tail_blocks(%d)\n",
998 (int) padding);
999 */
1000 isoburn_igopt_set_tail_blocks(sopts, padding);
1001 }
1002
1003 /* Make final abort check before starting expensive activities */
1004 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1005 if(ret<0)
1006 {ret= 0; goto ex;}
1007
1008 if(xorriso->zisofs_by_magic && image != NULL) {
1009 sprintf(xorriso->info_text,
1010 "Checking disk file content for zisofs compression headers.");
1011 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1012 root_node= (IsoNode *) iso_image_get_root(image);
1013 ret= iso_node_zf_by_magic(root_node,
1014 (xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16);
1015 if(ret<0) {
1016 Xorriso_report_iso_error(xorriso, "", ret,
1017 "Error when examining file content for zisofs headers",
1018 0, "FAILURE", 1);
1019 }
1020 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1021 if(ret<0)
1022 {ret= 0; goto ex;}
1023 sprintf(xorriso->info_text,
1024 "Check for zisofs compression headers done.");
1025 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1026 }
1027
1028 ret = isoburn_igopt_set_write_type(sopts, xorriso->do_tao);
1029 if(ret <= 0)
1030 goto ex;
1031 ret = isoburn_igopt_set_stdio_endsync(sopts, xorriso->stdio_sync >= 0);
1032 if(ret <= 0)
1033 goto ex;
1034
1035 ret= 1;
1036 ex:;
1037 return(ret);
1038 }
1039
1040
Xorriso_set_all_file_dates(struct XorrisO * xorriso,int flag)1041 int Xorriso_set_all_file_dates(struct XorrisO *xorriso, int flag)
1042 {
1043 int idx, ret, was_failure= 0;
1044 char *hargv[4];
1045
1046 if(xorriso->all_file_dates[0] == 0)
1047 return(2);
1048 if(strcmp(xorriso->all_file_dates, "set_to_mtime") == 0) {
1049 hargv[0]= "/";
1050 hargv[1]= "-exec";
1051 hargv[2]= "set_to_mtime";
1052 hargv[3]= "--";
1053 idx= 0;
1054 ret= Xorriso_option_find(xorriso, 4, hargv, &idx, 0);
1055 if(ret <= 0)
1056 was_failure= 1;
1057 } else {
1058 hargv[0]= "/";
1059 idx= 0;
1060 ret= Xorriso_option_alter_date(xorriso, "b", xorriso->all_file_dates,
1061 1, hargv, &idx, 1);
1062 if(ret <= 0)
1063 was_failure= 1;
1064 idx= 0;
1065 ret= Xorriso_option_alter_date(xorriso, "c", xorriso->all_file_dates,
1066 1, hargv, &idx, 1);
1067 if(ret <= 0)
1068 was_failure= 1;
1069 }
1070 Xorriso_relax_compliance(xorriso, "always_gmt", 0);
1071 return(!was_failure);
1072 }
1073
1074
1075 /* @param flag bit0= do not write but only prepare and return size in sectors
1076 @return <=0 error , 1= success
1077 2= failure with DVD-RW, please call Xorriso_retry_write_session()
1078 */
Xorriso_write_session(struct XorrisO * xorriso,int flag)1079 int Xorriso_write_session(struct XorrisO *xorriso, int flag)
1080 {
1081 int ret, i, pacifier_speed= 0, data_lba, is_bootable= 0;
1082 int freshly_bootable= 0, hide_attr, signal_mode, role, is_bdr_pow= 0;
1083 char *xorriso_id= NULL, *img_id, *sfe= NULL, *out_cs;
1084 struct isoburn_imgen_opts *sopts= NULL;
1085 struct burn_drive_info *dinfo, *source_dinfo;
1086 struct burn_drive *drive, *source_drive;
1087 struct burn_disc *disc= NULL;
1088 struct burn_write_opts *burn_options= NULL;
1089 off_t readcounter= 0,writecounter= 0;
1090 int num_sessions= 0, num_tracks= 0;
1091 struct burn_session **sessions;
1092 struct burn_track **tracks;
1093 enum burn_disc_status s;
1094 IsoImage *image= NULL;
1095 int profile_number;
1096 char *profile_name= NULL, *reasons= NULL;
1097 IsoBoot *bootcat_node;
1098
1099 Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
1100 Xorriso_alloc_meM(xorriso_id, char, 256);
1101 Xorriso_alloc_meM(profile_name, char, 80);
1102 Xorriso_alloc_meM(reasons, char, BURN_REASONS_LEN);
1103
1104 ret= Xorriso_finish_hl_update(xorriso, 0);
1105 if(ret <= 0)
1106 goto ex;
1107
1108 ret= Xorriso_set_all_file_dates(xorriso, 1);
1109 if(ret <= 0)
1110 goto ex;
1111
1112 out_cs= xorriso->out_charset;
1113 if(out_cs == NULL)
1114 Xorriso_get_local_charset(xorriso, &out_cs, 0);
1115
1116 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1117 "on attempt to write", 2);
1118 if(ret<=0)
1119 goto ex;
1120 if(!(flag & 1)) {
1121 ret= Xorriso_auto_format(xorriso, 0);
1122 if(ret <=0 )
1123 {ret= 0; goto ex;}
1124 }
1125
1126 is_bdr_pow= burn_drive_get_bd_r_pow(drive);
1127 if(is_bdr_pow) {
1128 sprintf(xorriso->info_text,
1129 "May not write to Pseudo Overwrite formatted BD-R medium");
1130 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1131 {ret= 0; goto ex;}
1132 }
1133
1134 s= isoburn_disc_get_status(drive);
1135 if (xorriso->do_hfsplus && (
1136 (xorriso->grow_blindly_msc2 >= 0 &&
1137 xorriso->out_drive_handle != xorriso->in_drive_handle)
1138 ||
1139 (xorriso->out_drive_handle == xorriso->in_drive_handle &&
1140 s != BURN_DISC_BLANK)
1141 )) {
1142 sprintf(xorriso->info_text,
1143 "May not grow ISO image while -hfsplus is enabled");
1144 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1145 {ret= 0; goto ex;}
1146 }
1147 if(xorriso->out_drive_handle == xorriso->in_drive_handle) {
1148 if(abs(xorriso->displacement_sign) == 1 && xorriso->displacement != 0 &&
1149 s != BURN_DISC_BLANK) {
1150 sprintf(xorriso->info_text,
1151 "May not grow ISO image while -displacement is non-zero");
1152 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1153 {ret= 0; goto ex;}
1154 }
1155 source_drive= drive;
1156 } else {
1157 if(xorriso->in_drive_handle == NULL) {
1158 source_drive= drive;
1159 } else {
1160 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
1161 "on attempt to get source for write", 0);
1162 if(ret<=0)
1163 goto ex;
1164 }
1165 if(s!=BURN_DISC_BLANK) {
1166 s= burn_disc_get_status(drive);
1167 if(s!=BURN_DISC_BLANK)
1168 sprintf(xorriso->info_text,
1169 "-indev differs from -outdev and -outdev media is not blank");
1170 else
1171 sprintf(xorriso->info_text,
1172 "-indev differs from -outdev and -outdev media holds non-zero data");
1173 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1174 {ret= 0; goto ex;}
1175 }
1176 }
1177 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
1178 if(ret == 2)
1179 pacifier_speed= 1;
1180 else if(ret == 3)
1181 pacifier_speed= 2;
1182
1183 ret= Xorriso_check_multi(xorriso, drive, 0);
1184 if(ret<=0)
1185 goto ex;
1186
1187 ret= isoburn_igopt_new(&sopts, 0);
1188 if(ret<=0) {
1189 Xorriso_process_msg_queues(xorriso, 0);
1190 goto ex;
1191 }
1192
1193 xorriso->alignment= 0;
1194 image= isoburn_get_attached_image(source_drive);
1195 if(image != NULL) {
1196 iso_image_set_application_id(image, xorriso->application_id);
1197 iso_image_set_publisher_id(image, xorriso->publisher);
1198 iso_image_set_system_id(image, xorriso->system_id);
1199 iso_image_set_volset_id(image, xorriso->volset_id);
1200 iso_image_set_copyright_file_id(image, xorriso->copyright_file);
1201 iso_image_set_biblio_file_id(image, xorriso->biblio_file);
1202 iso_image_set_abstract_file_id(image, xorriso->abstract_file);
1203 Xorriso_write_application_use(xorriso, image, 0);
1204 Xorriso_process_msg_queues(xorriso,0);
1205 }
1206
1207 if((xorriso->do_aaip & 256) && out_cs != NULL) {
1208 static char *names = "isofs.cs";
1209 size_t value_lengths[1];
1210
1211 value_lengths[0]= strlen(out_cs);
1212 ret= Xorriso_setfattr(xorriso, NULL, "/",
1213 (size_t) 1, &names, value_lengths, &out_cs, 2 | 8);
1214 if(ret<=0)
1215 goto ex;
1216 }
1217 if(iso_image_was_blind_attrs(image, 0))
1218 Xorriso_msgs_submit(xorriso, 0,
1219 "Some file xattr namespace could not be explored",
1220 0, "WARNING", 0);
1221
1222 if(image!=NULL && 12+strlen(Xorriso_timestamP)<80) {
1223 strcpy(xorriso_id, xorriso->preparer_id);
1224 img_id= (char *) iso_image_get_data_preparer_id(image);
1225 if(img_id!=NULL) {
1226 for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--);
1227 if(i>0) {
1228 sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'",
1229 img_id);
1230 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
1231 }
1232 }
1233 iso_image_set_data_preparer_id(image, xorriso_id);
1234 }
1235 ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0);
1236 if(ret <= 0)
1237 goto ex;
1238
1239 /* Activate, adjust or discard boot image */
1240 if(image!=NULL) {
1241 if(xorriso->boot_image_bin_path[0]) {
1242 ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0);
1243 if(ret <= 0)
1244 goto ex;
1245 freshly_bootable= 1;
1246 }
1247 is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node);
1248 }
1249 if(image!=NULL && !(flag&1)) {
1250 if(xorriso->boot_count > 0 || freshly_bootable) {
1251 /* Eventually rename boot catalog node to changed boot_image_cat_path */
1252 if(is_bootable > 0) {
1253 ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0);
1254 if(ret > 0) {
1255 if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) {
1256 ret= Xorriso_rename(xorriso, NULL, sfe,
1257 xorriso->boot_image_cat_path, 0);
1258 if(ret <= 0)
1259 goto ex;
1260 }
1261 }
1262 }
1263 hide_attr= !!(xorriso->boot_image_cat_hidden);
1264 if(xorriso->boot_image_cat_hidden & 1)
1265 hide_attr|= LIBISO_HIDE_ON_RR;
1266 if(xorriso->boot_image_cat_hidden & 2)
1267 hide_attr|= LIBISO_HIDE_ON_JOLIET;
1268 if(xorriso->boot_image_cat_hidden & 4)
1269 hide_attr|= LIBISO_HIDE_ON_HFSPLUS;
1270 iso_image_set_boot_catalog_hidden(image, hide_attr);
1271 } else if(xorriso->patch_isolinux_image & 1) {
1272 if(is_bootable == 1) {
1273 /* will imply isoburn_igopt_allow_full_ascii */
1274 sprintf(xorriso->info_text, "Patching boot info table");
1275 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1276
1277 ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
1278 sfe, 1);
1279 if(ret < 0)
1280 goto ex;
1281 if(ret == 0) {
1282 sprintf(xorriso->info_text,
1283 "Cannot patch boot image: no file found for its LBA.");
1284 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1285 sprintf(xorriso->info_text,
1286 "Probably the loaded boot image file was deleted in this session.");
1287 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1288 sprintf(xorriso->info_text,
1289 "Use -boot_image \"any\" \"discard\" or set new boot image");
1290 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
1291 goto ex;
1292 }
1293 ret= Xorriso_set_isolinux_options(xorriso, image, 0);
1294 if(ret <= 0)
1295 goto ex;
1296 } else if(!freshly_bootable) {
1297 sprintf(xorriso->info_text,
1298 "Could not find any boot image for -boot_image patching");
1299 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1300 }
1301 } else if(xorriso->keep_boot_image && is_bootable == 1) {
1302 /* will imply isoburn_igopt_allow_full_ascii */
1303 sprintf(xorriso->info_text, "Keeping boot image unchanged");
1304 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1305 } else if(is_bootable == 1) {
1306 iso_image_remove_boot_image(image);
1307 sprintf(xorriso->info_text, "Discarded boot image from old session");
1308 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1309 }
1310 /* hardcoded and regardless whether a catalog will get written */
1311 iso_image_set_boot_catalog_weight(image, 1000000000);
1312 }
1313
1314 if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) {
1315 /* Overwrite isofs.st of root node by xorriso->isofs_st_out */
1316 char *name= "isofs.st";
1317 char timestamp[16], *value= timestamp;
1318 size_t value_length;
1319
1320 sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out);
1321 value_length= strlen(timestamp);
1322 Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name,
1323 &value_length, &value, 2 | 8);
1324 }
1325
1326 ret= Xorriso_make_iso_write_opts(xorriso, image, sopts, flag & 1);
1327 if(ret <= 0)
1328 goto ex;
1329
1330 /* >>> omit iso_image_update_sizes if the image was filled up very quickly */;
1331
1332 ret= iso_image_update_sizes(image);
1333 if(ret < 0) {
1334 Xorriso_process_msg_queues(xorriso, 0);
1335 if(ret<0) {
1336 Xorriso_report_iso_error(xorriso, "", ret,
1337 "Error when updating file sizes",
1338 0, "FAILURE", 1);
1339 }
1340 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1341 if(ret<0)
1342 {ret= 0; goto ex;}
1343 }
1344
1345 Xorriso_set_abort_severity(xorriso, 1);
1346 if (xorriso->grow_blindly_msc2 >= 0 &&
1347 xorriso->out_drive_handle != xorriso->in_drive_handle) {
1348 ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive,
1349 xorriso->grow_blindly_msc2);
1350 if(ret>0) {
1351 /* Allow the consumer of output to access the input drive */
1352 source_drive= NULL;
1353 ret= Xorriso_give_up_drive(xorriso, 1|8);
1354 if(ret<=0)
1355 goto ex;
1356 }
1357 } else if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
1358 xorriso->in_drive_handle == NULL) {
1359 ret= isoburn_prepare_disc(source_drive, &disc, sopts);
1360 } else {
1361 ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
1362 }
1363 if(ret <= 0) {
1364 Xorriso_process_msg_queues(xorriso,0);
1365 sprintf(xorriso->info_text,"Failed to prepare session write run");
1366 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1367 {ret= 0; goto ex;}
1368 }
1369
1370 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
1371 if(ret<=0)
1372 goto cancel_iso;
1373 isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba));
1374 if(xorriso->do_stream_recording == 2) {
1375 ret= isoburn_igopt_get_data_start(sopts, &data_lba);
1376 if(ret > 0 && data_lba >= 16)
1377 burn_write_opts_set_stream_recording(burn_options, data_lba);
1378 }
1379
1380 ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1);
1381 if(ret<=0 || (flag&1)) {
1382 Xorriso_process_msg_queues(xorriso,0);
1383 if(flag&1) /* set queue severity to FAILURE */
1384 Xorriso_set_image_severities(xorriso, 2);
1385 if(flag&1) /* reset queue severity */
1386 Xorriso_set_image_severities(xorriso, 0);
1387 goto cancel_iso;
1388 }
1389
1390 ret= Xorriso_may_burn(xorriso, 0);
1391 if(ret <= 0)
1392 goto cancel_iso;
1393
1394 role= burn_drive_get_drive_role(drive);
1395
1396 /* Important: do not return until burn_is_aborting() was checked */
1397
1398 signal_mode= 1;
1399 if(role == 1)
1400 signal_mode|= 2;
1401 Xorriso_set_signal_handling(xorriso, signal_mode);
1402
1403 /* De-activate eventual target file truncation in dummy mode */
1404 ret= isoburn_set_truncate(drive, (!xorriso->do_dummy) | 2 | 4);
1405 if(ret < 0)
1406 goto cancel_iso;
1407
1408 xorriso->run_state= 1; /* Indicate that burning has started */
1409 isoburn_disc_write(burn_options, disc);
1410 burn_write_opts_free(burn_options);
1411 burn_options= NULL;
1412
1413 ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4);
1414 if(burn_is_aborting(0))
1415 Xorriso_abort(xorriso, 0); /* Never comes back */
1416 Xorriso_set_signal_handling(xorriso, 0);
1417 if(ret<=0)
1418 goto ex;
1419 if(!isoburn_drive_wrote_well(drive)) {
1420 isoburn_cancel_prepared_write(source_drive, drive, 0);
1421 Xorriso_process_msg_queues(xorriso,0);
1422 if(xorriso->auto_close && xorriso->do_close == 0) {
1423 if(burn_drive_was_feat21_failure(drive)) {
1424 sprintf(xorriso->info_text,
1425 "libburn indicates failure with writing DVD-RW to appendable state.");
1426 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1427 /* Urge caller to call Xorriso_retry_write_session() */
1428 ret= 2; goto ex;
1429 }
1430 }
1431 sprintf(xorriso->info_text,
1432 "libburn indicates failure with writing.");
1433 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1434 ret= 0; goto ex;
1435 }
1436 Xorriso_process_msg_queues(xorriso,0);
1437
1438 sessions= burn_disc_get_sessions(disc, &num_sessions);
1439 if(num_sessions>0) {
1440 tracks= burn_session_get_tracks(sessions[0], &num_tracks);
1441 if(tracks!=NULL && num_tracks>0) {
1442 burn_track_get_counters(tracks[0],&readcounter,&writecounter);
1443 xorriso->session_blocks= (int) (writecounter/ (off_t) 2048);
1444 sprintf(xorriso->info_text,
1445 "ISO image produced: %d sectors\nWritten to medium : %d sectors at LBA %d\n",
1446 (int) (readcounter/ (off_t) 2048),
1447 xorriso->session_blocks, xorriso->session_lba);
1448 Xorriso_info(xorriso, 0);
1449 }
1450 }
1451 ret= isoburn_activate_session(drive);
1452 Xorriso_process_msg_queues(xorriso,0);
1453 if(ret<=0) {
1454 sprintf(xorriso->info_text,
1455 "Could not write new set of volume descriptors");
1456 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1457 goto ex;
1458 }
1459 /* Done early to free any reference to the libisofs resources via disc */
1460 if(disc!=NULL)
1461 burn_disc_free(disc);
1462 disc= NULL;
1463 /* To wait for the end of the libisofs threads and their messages. */
1464 isoburn_sync_after_write(source_drive, drive, 0);
1465 Xorriso_process_msg_queues(xorriso,0);
1466
1467 sprintf(xorriso->info_text, "Writing to %s completed successfully.\n\n",
1468 Text_shellsafe(xorriso->outdev,sfe,0));
1469 Xorriso_info(xorriso, 0);
1470 ret= 1;
1471 ex:;
1472 xorriso->run_state= 0; /* Indicate that burning has ended */
1473 Xorriso_set_abort_severity(xorriso, 0);
1474
1475 if(ret<=0) {
1476
1477 /* >>> ??? revive discarded boot image */;
1478
1479 /* suppress automatic -commit at program end */
1480 xorriso->volset_change_pending= 3;
1481 }
1482 if(disc!=NULL)
1483 burn_disc_free(disc);
1484 if(image != NULL)
1485 iso_image_unref(image);
1486 isoburn_igopt_destroy(&sopts, 0);
1487 if(burn_options != NULL)
1488 burn_write_opts_free(burn_options);
1489 Xorriso_process_msg_queues(xorriso,0);
1490 Xorriso_append_scdbackup_record(xorriso, 0);
1491 Xorriso_free_meM(sfe);
1492 Xorriso_free_meM(xorriso_id);
1493 Xorriso_free_meM(profile_name);
1494 Xorriso_free_meM(reasons);
1495 return(ret);
1496
1497 cancel_iso:;
1498 isoburn_cancel_prepared_write(source_drive, drive, 0);
1499 goto ex;
1500 }
1501
1502
Xorriso_check_burn_abort(struct XorrisO * xorriso,int flag)1503 int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag)
1504 {
1505 int ret;
1506 struct burn_drive_info *dinfo;
1507 struct burn_drive *drive;
1508
1509 if(burn_is_aborting(0))
1510 return(2);
1511 if(xorriso->run_state!=1)
1512 return(0);
1513 ret= Xorriso_eval_problem_status(xorriso, 1, 1);
1514 if(ret>=0)
1515 return(0);
1516 sprintf(xorriso->info_text,
1517 "-abort_on '%s' encountered '%s' during image writing",
1518 xorriso->abort_on_text, xorriso->problem_status_text);
1519 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
1520 xorriso->problem_status_text, 0);
1521
1522 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1523 "on attempt to abort burn run", 2);
1524 if(ret<=0)
1525 return(0);
1526
1527 burn_drive_cancel(drive);
1528 sprintf(xorriso->info_text,
1529 "libburn has now been urged to cancel its operation");
1530 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1531 return(1);
1532 }
1533
1534
1535 /* This loop watches burn runs until they end.
1536 It issues pacifying update messages to the user.
1537 @param flag bit0-3 = emulation mode
1538 0= xorriso
1539 1= mkisofs
1540 2= cdrecord
1541 bit4= report speed in CD units
1542 bit5= report speed in BD units
1543 */
Xorriso_pacifier_loop(struct XorrisO * xorriso,struct burn_drive * drive,int flag)1544 int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
1545 int flag)
1546 {
1547 int ret, size, free_bytes, i, aborting= 0, emul, buffer_fill= 50, last_sector;
1548 int iso_wait_counter= 0, iso_cancel_limit= 5;
1549 struct burn_progress progress;
1550 char *status_text, date_text[80], *speed_unit, mem_text[8];
1551 enum burn_drive_status drive_status;
1552 double start_time, current_time, last_time, base_time= 0.0, base_count= 0.0;
1553 double next_base_time= 0.0, next_base_count= 0.0, first_base_time= 0.0;
1554 double first_base_count= 0.0, norm= 0.0, now_time, fract_offset= 0.0;
1555 double measured_speed, speed_factor= 1385000, quot, speed_min_time;
1556 double tdiff, now_fract;
1557 time_t time_prediction;
1558 IsoImage *image= NULL;
1559
1560 image= isoburn_get_attached_image(drive);
1561
1562 start_time= Sfile_microtime(0);
1563 while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
1564 usleep(100002);
1565
1566 emul= flag&15;
1567 if(emul==0)
1568 emul= xorriso->pacifier_style;
1569 fract_offset= 1.0 / 3.0 * (double) emul - ((int) (1.0 / 3.0 * (double) emul));
1570 speed_min_time= 0.2 * xorriso->pacifier_interval;
1571 speed_unit= "D";
1572 if(flag&16) {
1573 speed_factor= 150.0*1024;
1574 speed_unit= "C";
1575 } else if(flag & 32) {
1576 speed_factor= 4495625;
1577 speed_unit= "B";
1578 }
1579 progress.sector= 0;
1580 current_time= Sfile_microtime(0);
1581 measured_speed= 0.0;
1582 while(1) {
1583 last_time= current_time;
1584 last_sector= progress.sector;
1585 drive_status= burn_drive_get_status(drive, &progress);
1586
1587 if(drive_status == BURN_DRIVE_IDLE) {
1588 /* To avoid a race condition between burn_source and libisofs
1589 writer thread: Wait for ISO generator thread to have finished.
1590 After some seconds kick it by isoburn_cancel_prepared_write()
1591 which waits for the write thread to end.
1592 */
1593 if(image == NULL)
1594 break;
1595 if(!iso_image_generator_is_running(image))
1596 break;
1597 iso_wait_counter++;
1598 if(iso_wait_counter > iso_cancel_limit) {
1599 isoburn_cancel_prepared_write(drive, NULL, 0);
1600 break;
1601 }
1602 }
1603 current_time= Sfile_microtime(0);
1604 if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) {
1605 if(current_time-last_time > speed_min_time)
1606 measured_speed= (progress.sector - last_sector) * 2048.0 /
1607 (current_time - last_time);
1608 buffer_fill= 50;
1609 if(progress.buffer_capacity>0)
1610 buffer_fill= (double) (progress.buffer_capacity
1611 - progress.buffer_available) * 100.0
1612 / (double) progress.buffer_capacity;
1613 if(emul==2) {
1614 if(progress.sector<=progress.sectors)
1615 sprintf(xorriso->info_text, "%4d of %4d MB written",
1616 progress.sector / 512, progress.sectors / 512);
1617 else
1618 sprintf(xorriso->info_text, "%4d MB written",
1619 progress.sector / 512);
1620
1621 if(xorriso->pacifier_fifo!=NULL)
1622 ret= burn_fifo_inquire_status(xorriso->pacifier_fifo,
1623 &size, &free_bytes, &status_text);
1624 else
1625 ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
1626 if(ret>0 )
1627 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1628 " (fifo %2d%%)",
1629 (int) (100.0-100.0*((double) free_bytes)/(double) size));
1630
1631 sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]",
1632 buffer_fill);
1633
1634 if(current_time-last_time > speed_min_time)
1635 sprintf(xorriso->info_text+strlen(xorriso->info_text), " %4.1fx.",
1636 measured_speed/speed_factor);
1637
1638 } else if(emul == 1 &&
1639 progress.sectors > 0 && progress.sector <= progress.sectors) {
1640 /* "37.87% done, estimate finish Tue Jul 15 18:55:07 2008" */
1641
1642 quot= ((double) progress.sector) / ((double) progress.sectors);
1643 sprintf(xorriso->info_text, " %2.2f%% done", quot*100.0);
1644 if(current_time - start_time >= 2 && quot > 0.0 &&
1645 (quot >= 0.02 || progress.sector >= 5*1024)) {
1646 if(base_time == 0.0 && progress.sector >= 16*1024) {
1647 first_base_time= base_time= next_base_time= current_time;
1648 first_base_count= next_base_count= progress.sector;
1649 } else if(next_base_time > 0 && current_time - next_base_time >= 10) {
1650 base_time= next_base_time;
1651 base_count= next_base_count;
1652 next_base_time= current_time;
1653 next_base_count= progress.sector;
1654 }
1655 if(first_base_time > 0 &&
1656 current_time - first_base_time >= 10 &&
1657 progress.sectors > first_base_count &&
1658 progress.sector > first_base_count) {
1659 norm= (1.0 - quot);
1660 if(norm < 0.0001)
1661 norm= 0.0001;
1662 quot= ((double) progress.sector - first_base_count)
1663 / ((double) progress.sectors - first_base_count);
1664 time_prediction= norm * (1.0 - quot) / quot
1665 * (current_time - first_base_time);
1666 } else {
1667 time_prediction= (1.0 - quot) / quot * (current_time - start_time);
1668 norm= 1.0;
1669 }
1670 if(base_time > 0 &&
1671 current_time - base_time >= 10 && progress.sectors > base_count) {
1672 quot= ((double) progress.sector - base_count)
1673 / ((double) progress.sectors - base_count);
1674 time_prediction+= (1.0 - quot) / quot * (current_time - base_time);
1675 norm+= 1.0;
1676 }
1677 time_prediction/= norm;
1678 if(time_prediction < 30*86400 && time_prediction > 0) {
1679 time_prediction+= current_time + 1;
1680 Ftimetxt(time_prediction, date_text, 4);
1681 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1682 ", estimate finish %s", date_text);
1683 }
1684 }
1685 } else {
1686 if(progress.sector<=progress.sectors) {
1687 if(progress.sectors <= 0)
1688 strcpy(mem_text, " 99.9");
1689 else
1690 sprintf(mem_text, "%5.1f",
1691 100.0 * ((double) progress.sector) / ((double) progress.sectors));
1692 mem_text[5]= 0;
1693 sprintf(xorriso->info_text, "Writing: %10ds %s%% ",
1694 progress.sector, mem_text);
1695 } else {
1696 Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1);
1697 sprintf(xorriso->info_text, "Writing: %10ds %s ",
1698 progress.sector, mem_text);
1699 }
1700 ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
1701 if(ret>0 )
1702 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1703 " fifo %3d%% buf %3d%%",
1704 (int) (100.0-100.0*((double) free_bytes)/(double) size),
1705 buffer_fill);
1706 if(current_time - last_time > speed_min_time)
1707 sprintf(xorriso->info_text+strlen(xorriso->info_text), " %5.1fx%s ",
1708 measured_speed/speed_factor, speed_unit);
1709 }
1710 } else if(drive_status == BURN_DRIVE_CLOSING_SESSION ||
1711 drive_status == BURN_DRIVE_CLOSING_TRACK)
1712 sprintf(xorriso->info_text,
1713 "Closing track/session. Working since %.f seconds",
1714 current_time-start_time);
1715 else if(drive_status == BURN_DRIVE_FORMATTING)
1716 sprintf(xorriso->info_text, "Formatting. Working since %.f seconds",
1717 current_time-start_time);
1718 else
1719 sprintf(xorriso->info_text,
1720 "Thank you for being patient. Working since %.f seconds.",
1721 current_time-start_time);
1722 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1723
1724 for(i= 0; i < 20; i++) { /* 10 usleeps more than supposed to be needed */
1725 Xorriso_process_msg_queues(xorriso, 0);
1726 if(aborting<=0)
1727 aborting= Xorriso_check_burn_abort(xorriso, 0);
1728 usleep((unsigned long) (100000.0 * xorriso->pacifier_interval));
1729 now_time= Sfile_microtime(0);
1730 tdiff= ((off_t)(now_time / xorriso->pacifier_interval)) -
1731 (off_t)(current_time / xorriso->pacifier_interval);
1732 now_fract= (now_time / xorriso->pacifier_interval -
1733 (off_t)(now_time / xorriso->pacifier_interval));
1734 if(tdiff < 1.0)
1735 continue;
1736 if(fract_offset <= 0.0) /* "xorriso" pacifier shall not wait for slot */
1737 break;
1738 if((now_fract >= fract_offset && now_fract < fract_offset + 0.3) ||
1739 tdiff >= 2.0)
1740 break;
1741 }
1742 }
1743 iso_image_unref(image);
1744 return(1);
1745 }
1746
1747
1748 /* @param flag bit0= fast
1749 bit1= deformat
1750 bit2= do not re-aquire drive
1751 @return 0=failure, did not touch medium , -1=failure, altered medium
1752 1=success, altered medium , 2=success, did not touch medium
1753 */
Xorriso_blank_media(struct XorrisO * xorriso,int flag)1754 int Xorriso_blank_media(struct XorrisO *xorriso, int flag)
1755 {
1756 int ret, do_deformat= 0, signal_mode, using_immed;
1757 struct burn_drive_info *dinfo;
1758 struct burn_drive *drive;
1759 enum burn_disc_status disc_state;
1760 struct burn_progress p;
1761 double percent = 1.0;
1762 int current_profile;
1763 char current_profile_name[80];
1764 time_t start_time;
1765 char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"};
1766 char progress_text[40];
1767
1768 ret= Xorriso_may_burn(xorriso, 0);
1769 if(ret <= 0)
1770 return(0);
1771 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1772 "on attempt to -blank", 2);
1773 if(ret<=0)
1774 return(0);
1775
1776 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
1777
1778 disc_state = isoburn_disc_get_status(drive);
1779 if(current_profile == 0x13) { /* overwriteable DVD-RW */
1780 /* Depending on flag bit1 formatted DVD-RW will get blanked to sequential
1781 state or pseudo blanked by invalidating an eventual ISO image. */
1782 if(flag&2)
1783 do_deformat= 1;
1784 } else if(current_profile == 0x14) { /* sequential DVD-RW */
1785 if((flag&1) && !(flag&2)) {
1786 sprintf(xorriso->info_text,
1787 "-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'.");
1788 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1789 sprintf(xorriso->info_text,
1790 "Mode 'deformat_quickest' produces single-session-only media.");
1791 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
1792 flag&= ~1;
1793 }
1794 }
1795 if(disc_state == BURN_DISC_BLANK) {
1796 if(!do_deformat) {
1797 sprintf(xorriso->info_text,
1798 "Blank medium detected. Will leave it untouched");
1799 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1800 return 2;
1801 }
1802 } else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) {
1803 ;
1804 } else if(disc_state == BURN_DISC_EMPTY) {
1805 sprintf(xorriso->info_text,"No media detected in drive");
1806 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1807 return 0;
1808 } else {
1809 sprintf(xorriso->info_text, "Unsuitable drive and media state");
1810 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1811 return 0;
1812 }
1813 if(!isoburn_disc_erasable(drive)) {
1814 sprintf(xorriso->info_text, "Media is not of erasable type");
1815 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1816 return 0;
1817 }
1818 if(xorriso->do_dummy) {
1819 sprintf(xorriso->info_text,
1820 "-dummy mode prevents blanking of medium in mode '%s'.",
1821 mode_names[flag&3]);
1822 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1823 return(1);
1824 }
1825 using_immed= burn_drive_get_immed(drive);
1826 sprintf(xorriso->info_text, "Beginning to blank medium in mode '%s'.\n",
1827 mode_names[flag&3]);
1828 Xorriso_info(xorriso,0);
1829
1830 /* Important: do not return until burn_is_aborting() was checked */
1831 signal_mode= 1;
1832 ret= burn_drive_get_drive_role(drive);
1833 if(ret == 1)
1834 signal_mode|= 2;
1835 Xorriso_set_signal_handling(xorriso, signal_mode);
1836
1837 if(do_deformat)
1838 burn_disc_erase(drive, (flag&1));
1839 else
1840 isoburn_disc_erase(drive, (flag&1));
1841 start_time= time(0);
1842 usleep(1000000);
1843 if(!using_immed)
1844 sprintf(progress_text, "synchronously since");
1845 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
1846 Xorriso_process_msg_queues(xorriso,0);
1847 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
1848 percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
1849 if(using_immed)
1850 sprintf(progress_text, "%.1f%% done in", percent);
1851 sprintf(xorriso->info_text, "Blanking ( %s %d seconds )",
1852 progress_text, (int) (time(0) - start_time));
1853 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1854 usleep(1000000);
1855 }
1856 Xorriso_process_msg_queues(xorriso,0);
1857 if(burn_is_aborting(0))
1858 Xorriso_abort(xorriso, 0); /* Never comes back */
1859 Xorriso_set_signal_handling(xorriso, 0);
1860 if(burn_drive_wrote_well(drive)) {
1861 sprintf(xorriso->info_text, "Blanking done\n");
1862 Xorriso_info(xorriso,0);
1863 } else {
1864 sprintf(xorriso->info_text, "Blanking failed.");
1865 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1866 }
1867 if(!(flag & 4)) {
1868 ret= Xorriso_reaquire_outdev(xorriso,
1869 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
1870 if(ret <= 0)
1871 return(-1);
1872 }
1873 return(1);
1874 }
1875
1876
1877 /* @param flag bit0= try to achieve faster formatting
1878 bit1= use parameter size (else use default size)
1879 bit2= do not re-aquire drive
1880 bit5= try to disable Defect Management
1881 bit7= by_index mode:
1882 bit8 to bit15 contain the index of the format to use.
1883 @return 0=failure, did not touch medium , -1=failure, altered medium
1884 1=success, altered medium , 2=success, did not touch medium
1885 */
Xorriso_format_media(struct XorrisO * xorriso,off_t in_size,int flag)1886 int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag)
1887 {
1888 int ret, mode_flag= 0, index, status, num_formats, signal_mode, using_immed;
1889 unsigned dummy;
1890 struct burn_drive_info *dinfo;
1891 struct burn_drive *drive;
1892 struct burn_progress p;
1893 double percent = 1.0;
1894 int current_profile;
1895 char current_profile_name[80], progress_text[40];
1896 off_t size= 0;
1897 time_t start_time;
1898 enum burn_disc_status disc_state;
1899
1900 ret= Xorriso_may_burn(xorriso, 0);
1901 if(ret <= 0)
1902 return(0);
1903 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1904 "on attempt to -format", 2);
1905 if(ret<=0)
1906 return(0);
1907
1908 if(flag & 2) {
1909 mode_flag= 0; /* format to given size */
1910 } else {
1911 mode_flag= 4; /* format to full size */
1912 }
1913 if(flag & 32)
1914 mode_flag|= 32; /* try to disable Defect Management */
1915
1916 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
1917
1918 if(flag&128) { /* by_index */
1919 index= (flag>>8) & 0xff;
1920 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
1921 if(ret<=0)
1922 num_formats= 0;
1923 if(ret<=0 || index<0 || index>=num_formats) {
1924 if(num_formats>0)
1925 sprintf(xorriso->info_text,
1926 "-format by_index_%d: format descriptors range from index 0 to %d",
1927 index, num_formats-1);
1928 else
1929 sprintf(xorriso->info_text,
1930 "-format by_index_%d: no format descriptors available", index);
1931 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1932 return(0);
1933 }
1934 mode_flag|= (flag & 0xff80);
1935 if(flag&1)
1936 mode_flag|= (1<<6);
1937
1938 } else if(current_profile == 0x12) { /* DVD+RAM */
1939 if(!(flag & 2))
1940 mode_flag= 6; /* format to default payload size */
1941 if(flag&1)
1942 mode_flag|= (1<<6);
1943
1944 } else if(current_profile == 0x13) { /* DVD-RW */
1945 if(flag&1) {
1946 sprintf(xorriso->info_text,
1947 "Detected formatted DVD-RW. Thus omitting desired fast format run.");
1948 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1949 return(2);
1950 }
1951
1952 } else if(current_profile == 0x14) { /* DVD-RW sequential */
1953 if(flag & 1) {
1954 size= 128*1024*1024;
1955 mode_flag= 1; /* format to size, then write size of zeros */
1956 } else
1957 mode_flag= 4;
1958
1959 } else if(current_profile == 0x1a) { /* DVD+RW */
1960 if(flag&1) {
1961 sprintf(xorriso->info_text,
1962 "Detected DVD+RW. Thus omitting desired fast format run.");
1963 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1964 return(2);
1965 }
1966
1967 } else if(current_profile == 0x41) { /* BD-R SRM */
1968 if(!(flag & 2))
1969 mode_flag= 6; /* format to default payload size */
1970 if(flag&1)
1971 mode_flag|= (1<<6);
1972
1973 } else if(current_profile == 0x43) { /* BD-RE */
1974 if(!(flag & (2 | 32)))
1975 mode_flag= 6; /* format to default payload size */
1976 if(flag&1)
1977 mode_flag|= (1<<6);
1978
1979 } else {
1980 sprintf(xorriso->info_text,
1981 "-format: Unsuitable media detected.");
1982 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1983 sprintf(xorriso->info_text,"Media current: %s (%4.4xh)",
1984 current_profile_name, current_profile);
1985 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1986 return(0);
1987 }
1988 if(!(flag & 1))
1989 mode_flag|= 16; /* enable re-formatting */
1990
1991 if(xorriso->do_dummy) {
1992 sprintf(xorriso->info_text, "-dummy mode prevents formatting of medium.");
1993 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1994 return(1);
1995 }
1996 using_immed= burn_drive_get_immed(drive);
1997 sprintf(xorriso->info_text, "Beginning to format medium.\n");
1998 Xorriso_info(xorriso, 0);
1999 if(flag & 2)
2000 size= in_size;
2001
2002 /* Important: do not return until burn_is_aborting() was checked */
2003 signal_mode= 1;
2004 ret= burn_drive_get_drive_role(drive);
2005 if(ret == 1)
2006 signal_mode|= 2;
2007 Xorriso_set_signal_handling(xorriso, signal_mode);
2008
2009 burn_disc_format(drive, size, mode_flag);
2010
2011 start_time= time(0);
2012 usleep(1000000);
2013 if(!using_immed)
2014 sprintf(progress_text, "synchronously since");
2015 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
2016 Xorriso_process_msg_queues(xorriso,0);
2017 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
2018 percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
2019 if(using_immed)
2020 sprintf(progress_text, "%.1f%% done in", percent);
2021 sprintf(xorriso->info_text, "Formatting ( %s %d seconds )",
2022 progress_text, (int) (time(0) - start_time));
2023 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2024 usleep(1000000);
2025 }
2026 Xorriso_process_msg_queues(xorriso,0);
2027 if(burn_is_aborting(0))
2028 Xorriso_abort(xorriso, 0); /* Never comes back */
2029 Xorriso_set_signal_handling(xorriso, 0);
2030
2031 if(burn_drive_wrote_well(drive)) {
2032 sprintf(xorriso->info_text, "Formatting done\n");
2033 Xorriso_info(xorriso,0);
2034 } else {
2035 sprintf(xorriso->info_text,
2036 "libburn indicates failure with formatting.");
2037 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2038 return(-1);
2039 }
2040
2041 if(!(flag & 4)) {
2042 ret= Xorriso_reaquire_outdev(xorriso,
2043 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
2044 if(ret <= 0)
2045 return(-1);
2046 }
2047 disc_state = isoburn_disc_get_status(drive);
2048 if(disc_state==BURN_DISC_FULL && !(flag&1)) {
2049 /* Blank because full format certification pattern might be non-zero */
2050 ret= Xorriso_blank_media(xorriso, 1);
2051 if(ret <= 0)
2052 return(0);
2053 }
2054 return(1);
2055 }
2056
2057
2058 /* @param flag bit2= formatting rather than blanking
2059 @return 0=failure, did not touch medium , -1=failure, altered medium
2060 1=success, altered medium , 2=success, did not touch medium
2061 */
Xorriso_blank_as_needed(struct XorrisO * xorriso,int flag)2062 int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag)
2063 {
2064 int ret, is_formatted= -1, status, num_formats, did_work= 0;
2065 struct burn_drive_info *dinfo;
2066 struct burn_drive *drive;
2067 enum burn_disc_status disc_state;
2068 unsigned dummy;
2069 int current_profile;
2070 char current_profile_name[80];
2071 off_t size;
2072
2073 ret= Xorriso_may_burn(xorriso, 0);
2074 if(ret <= 0)
2075 return(0);
2076 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2077 "on attempt to blank or format", 2);
2078 if(ret<=0)
2079 return(0);
2080
2081 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
2082
2083 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
2084 if(ret>0) {
2085 if(status==BURN_FORMAT_IS_FORMATTED)
2086 is_formatted= 1;
2087 else if(status == BURN_FORMAT_IS_UNFORMATTED)
2088 is_formatted= 0;
2089 }
2090 if(current_profile == 0x12 || current_profile == 0x43) { /* DVD+RAM , BD-RE */
2091 if(is_formatted<0) {
2092 sprintf(xorriso->info_text,
2093 "-blank or -format: Unclear formatting status of %s",
2094 current_profile_name);
2095 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2096 return(0);
2097 }
2098 if(!is_formatted) {
2099 ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43));
2100 if(ret <= 0)
2101 return(ret);
2102 did_work= (ret == 1);
2103 }
2104 } else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */
2105 ret= Xorriso_format_media(xorriso, (off_t) 0, 0);
2106 if(ret <= 0)
2107 return(ret);
2108 did_work= (ret == 1);
2109 } else if(current_profile == 0x41) { /* BD-R SRM */
2110 if((flag & 4) && !is_formatted) {
2111 ret= Xorriso_format_media(xorriso, (off_t) 0, 1);
2112 if(ret <= 0)
2113 return(ret);
2114 did_work= (ret == 1);
2115 }
2116 }
2117
2118 disc_state = isoburn_disc_get_status(drive);
2119 if(disc_state != BURN_DISC_BLANK && !(flag&4)) {
2120 ret= Xorriso_blank_media(xorriso, 1);
2121 return(ret);
2122 }
2123 if(did_work)
2124 return(1);
2125 sprintf(xorriso->info_text, "%s as_needed: no need for action detected",
2126 (flag&4) ? "-format" : "-blank");
2127 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2128 return(2);
2129 }
2130
2131
Xorriso_retry_burn_track(struct XorrisO * xorriso,off_t write_start_address,char * track_source,off_t tsize,int flag)2132 int Xorriso_retry_burn_track(struct XorrisO *xorriso,
2133 off_t write_start_address,
2134 char *track_source, off_t tsize, int flag)
2135 {
2136 int ret, auto_close_mem, do_close_mem;
2137
2138 if(xorriso->do_tao == 1) {
2139 Xorriso_msgs_submit(xorriso, 0,
2140 "There is no hope for a re-try with -close \"on\" as long as -write_type is \"tao\"",
2141 0, "FAILURE", 0);
2142 return(0);
2143 }
2144 Xorriso_msgs_submit(xorriso, 0, "Re-trying with -close \"on\"", 0, "NOTE", 0);
2145 do_close_mem= xorriso->do_close;
2146 auto_close_mem= xorriso->auto_close;
2147 xorriso->do_close= 1;
2148 xorriso->auto_close= 0;
2149 ret= Xorriso_burn_track(xorriso, write_start_address, track_source, tsize,
2150 flag);
2151 xorriso->do_close= do_close_mem;
2152 xorriso->auto_close= auto_close_mem;
2153 return(ret);
2154 }
2155
2156
2157 /* @param write_start_address is valid if >=0
2158 @param tsize is valid if >0
2159 @param flag bit0= grow_overwriteable_iso
2160 bit1= do_isosize
2161 bit2= do_xa1 conversion
2162 @return <=0 error , 1= success
2163 2= failure with DVD-RW, please call Xorriso_retry_burn_track()
2164 */
Xorriso_burn_track(struct XorrisO * xorriso,off_t write_start_address,char * track_source,off_t tsize,int flag)2165 int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
2166 char *track_source, off_t tsize, int flag)
2167 {
2168 int ret, fd, profile_number, is_cd= 0, dummy, nwa= -1;
2169 int isosize= -1, do_isosize, is_bd= 0, signal_mode;
2170 struct burn_drive_info *dinfo;
2171 struct burn_drive *drive;
2172 struct burn_write_opts *burn_options= NULL;
2173 struct burn_disc *disc= NULL;
2174 struct burn_session *session= NULL;
2175 struct burn_track *track= NULL;
2176 struct stat stbuf;
2177 off_t fixed_size= 0;
2178 struct burn_source *data_src= NULL, *fifo_src= NULL;
2179 enum burn_disc_status disc_state;
2180 char *reasons= NULL, *profile_name= NULL;
2181 char *head_buffer= NULL;
2182
2183 Xorriso_alloc_meM(reasons, char, BURN_REASONS_LEN);
2184 Xorriso_alloc_meM(profile_name, char, 80);
2185 Xorriso_alloc_meM(head_buffer, char, 64 * 1024);
2186
2187 ret= Xorriso_may_burn(xorriso, 0);
2188 if(ret <= 0)
2189 {ret= 0; goto ex;}
2190 ret= Xorriso_auto_format(xorriso, 0);
2191 if(ret <=0 )
2192 {ret= 0; goto ex;}
2193
2194 do_isosize= !!(flag&2);
2195 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2196 "on attempt to burn track", 2);
2197 if(ret<=0)
2198 {ret= 0; goto ex;}
2199
2200 ret= Xorriso_check_multi(xorriso, drive, 1);
2201 if(ret<=0)
2202 goto ex;
2203 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
2204 if(ret<=0)
2205 goto ex;
2206
2207 disc= burn_disc_create();
2208 session= burn_session_create();
2209 ret= burn_disc_add_session(disc,session,BURN_POS_END);
2210 if(ret==0) {
2211 sprintf(xorriso->info_text, "Cannot add session object to disc object.");
2212 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2213 goto ex;
2214 }
2215 track= burn_track_create();
2216 if(track_source[0] == '-' && track_source[1] == 0) {
2217 fd= 0;
2218 } else {
2219 if(xorriso->fs >= 64)
2220 fd= burn_os_open_track_src(track_source, O_RDONLY, 0);
2221 else
2222 fd= open(track_source, O_RDONLY | O_BINARY);
2223 if(fd>=0)
2224 if(fstat(fd,&stbuf)!=-1)
2225 if((stbuf.st_mode&S_IFMT)==S_IFREG)
2226 fixed_size= stbuf.st_size;
2227 }
2228
2229 if(fd>=0)
2230 data_src= burn_fd_source_new(fd, -1, fixed_size);
2231 if(data_src==NULL) {
2232 sprintf(xorriso->info_text, "Could not open data source ");
2233 Text_shellsafe(track_source, xorriso->info_text, 1);
2234 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2235 ret= 0; goto ex;
2236 }
2237 if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64)
2238 xorriso->fs= 64;
2239 if(xorriso->fs > 0) {
2240 fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4),
2241 xorriso->fs, 1);
2242 if(fifo_src == NULL) {
2243 sprintf(xorriso->info_text, "Could not create fifo object of %.f MB",
2244 ((double) xorriso->fs) / 1024.0 / 1024.0);
2245 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2246 ret= 0; goto ex;
2247 }
2248 }
2249 xorriso->pacifier_fifo= fifo_src;
2250 if(burn_track_set_source(track, fifo_src == NULL ? data_src : fifo_src)
2251 != BURN_SOURCE_OK) {
2252 sprintf(xorriso->info_text,
2253 "Cannot attach source object to track object");
2254 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2255 ret= 0; goto ex;
2256 }
2257 burn_track_set_cdxa_conv(track, !!(flag & 4));
2258 burn_session_add_track(session, track, BURN_POS_END);
2259 burn_source_free(data_src);
2260
2261 if(flag&1)
2262 /* consider overwriteables with ISO as appendable */
2263 disc_state= isoburn_disc_get_status(drive);
2264 else
2265 /* handle overwriteables as always blank */
2266 disc_state= burn_disc_get_status(drive);
2267
2268 if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) {
2269 /* ok */;
2270 } else {
2271 if(disc_state == BURN_DISC_FULL) {
2272 sprintf(xorriso->info_text,
2273 "Closed media with data detected. Need blank or appendable media.");
2274 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2275 if(burn_disc_erasable(drive)) {
2276 sprintf(xorriso->info_text, "Try -blank as_needed\n");
2277 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
2278 }
2279 } else if(disc_state == BURN_DISC_EMPTY) {
2280 sprintf(xorriso->info_text, "No media detected in drive");
2281 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2282 } else {
2283 sprintf(xorriso->info_text,
2284 "Cannot recognize state of drive and media");
2285 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2286 }
2287 ret= 0; goto ex;
2288 }
2289 if(isoburn_needs_emulation(drive))
2290 burn_write_opts_set_multi(burn_options, 0);
2291
2292 if(tsize > 0) {
2293 fixed_size= tsize;
2294 burn_track_set_size(track, fixed_size);
2295 }
2296 if(do_isosize) {
2297 ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0);
2298 if(ret<=0) {
2299 Xorriso_process_msg_queues(xorriso,0);
2300 sprintf(xorriso->info_text,
2301 "Cannot obtain first 64 kB from input stream.");
2302 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2303 ret= 0; goto ex;
2304 }
2305 /* read isosize from head_buffer, not from medium */
2306 ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13));
2307 if(ret<=0) {
2308 Xorriso_process_msg_queues(xorriso,0);
2309 sprintf(xorriso->info_text,
2310 "Option -isosize given but data stream seems not to be ISO 9660");
2311 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2312 ret= 0; goto ex;
2313 }
2314 sprintf(xorriso->info_text, "Size of ISO 9660 image: %ds", isosize);
2315 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2316 fixed_size= ((off_t) (isosize)) * (off_t) 2048;
2317 burn_track_set_size(track, fixed_size);
2318 }
2319
2320 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
2321 is_cd= (ret==2);
2322 is_bd= (ret == 3);
2323
2324 if(isoburn_needs_emulation(drive)) {
2325 if(flag&1) {
2326 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
2327 Xorriso_process_msg_queues(xorriso,0);
2328 if(ret<=0) {
2329 sprintf(xorriso->info_text,
2330 "Cannot obtain next writeable address of emulated multi-session media\n");
2331 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2332 ret= 0; goto ex;
2333 }
2334 if(nwa == 32 && disc_state != BURN_DISC_APPENDABLE)
2335 nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */
2336 } else {
2337 nwa= 0;
2338 if (disc_state == BURN_DISC_APPENDABLE) {
2339 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
2340 Xorriso_process_msg_queues(xorriso,0);
2341 if(ret<=0) {
2342 sprintf(xorriso->info_text,
2343 "Cannot obtain next writeable address of emulated appendable media\n");
2344 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2345 ret= 0; goto ex;
2346 }
2347 }
2348 }
2349 burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048);
2350 }
2351
2352 if(write_start_address>=0) {
2353 nwa= write_start_address / (off_t) 2048;
2354 if(((off_t) nwa) * (off_t) 2048 < write_start_address )
2355 nwa++;
2356 burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048);
2357 }
2358
2359 if(xorriso->do_tao) {
2360 if (xorriso->do_tao > 0)
2361 burn_write_opts_set_write_type(burn_options,
2362 BURN_WRITE_TAO, BURN_BLOCK_MODE1);
2363 else
2364 burn_write_opts_set_write_type(burn_options,
2365 BURN_WRITE_SAO, BURN_BLOCK_SAO);
2366
2367 ret = burn_precheck_write(burn_options, disc, reasons, 0);
2368 if(ret<=0) {
2369 sprintf(xorriso->info_text,
2370 "Cannot set write type %s for this medium.\n",
2371 xorriso->do_tao > 0 ? "TAO" : "SAO");
2372 sprintf(xorriso->info_text+strlen(xorriso->info_text),
2373 "Reasons given:\n%s", reasons);
2374 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2375 ret= 0; goto ex;
2376 }
2377 sprintf(xorriso->info_text, "Explicitly chosen write type: %s",
2378 xorriso->do_tao > 0 ? "TAO" : "SAO");
2379 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
2380 } else {
2381 if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) ==
2382 BURN_WRITE_NONE) {
2383 sprintf(xorriso->info_text,
2384 "Failed to find a suitable write mode with this media.\n");
2385 sprintf(xorriso->info_text+strlen(xorriso->info_text),
2386 "Reasons given:\n%s", reasons);
2387 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2388 ret= 0; goto ex;
2389 }
2390 }
2391
2392 ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2);
2393 if(ret<=0)
2394 goto ex;
2395
2396 sprintf(xorriso->info_text, "Beginning to write data track.\n");
2397 Xorriso_info(xorriso,0);
2398
2399 /* Important: do not return until burn_is_aborting() was checked */
2400 signal_mode= 1;
2401 ret= burn_drive_get_drive_role(drive);
2402 if(ret == 1)
2403 signal_mode|= 2;
2404 Xorriso_set_signal_handling(xorriso, signal_mode);
2405
2406 xorriso->run_state= 1; /* Indicate that burning has started */
2407 burn_disc_write(burn_options, disc);
2408
2409 ret= Xorriso_pacifier_loop(xorriso, drive, 2 | (is_cd << 4) | (is_bd << 5));
2410 if(burn_is_aborting(0))
2411 Xorriso_abort(xorriso, 0); /* Never comes back */
2412 Xorriso_set_signal_handling(xorriso, 0);
2413 if(ret<=0)
2414 goto ex;
2415 if(!burn_drive_wrote_well(drive)) {
2416 Xorriso_process_msg_queues(xorriso,0);
2417 if(xorriso->auto_close && xorriso->do_close == 0) {
2418 if(burn_drive_was_feat21_failure(drive)) {
2419 sprintf(xorriso->info_text,
2420 "libburn indicates failure with writing DVD-RW to appendable state.");
2421 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2422 /* Urge caller to call Xorriso_retry_burn_rack() */
2423 ret= 2; goto ex;
2424 }
2425 }
2426 sprintf(xorriso->info_text,
2427 "libburn indicates failure with writing.");
2428 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2429 ret= 0; goto ex;
2430 }
2431
2432 if(flag & 1) {
2433 ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL,
2434 flag & 2);
2435 if(ret <= 0)
2436 goto ex;
2437 }
2438 sprintf(xorriso->info_text, "Writing to ");
2439 Text_shellsafe(xorriso->outdev, xorriso->info_text, 1);
2440 strcat(xorriso->info_text, " completed successfully.\n\n");
2441 Xorriso_info(xorriso, 0);
2442 ret= 1;
2443 ex:;
2444 Xorriso_process_msg_queues(xorriso,0);
2445 if(disc!=NULL)
2446 burn_disc_free(disc);
2447 if(session != NULL)
2448 burn_session_free(session);
2449 if(track != NULL)
2450 burn_track_free(track);
2451 if(burn_options != NULL)
2452 burn_write_opts_free(burn_options);
2453 if(xorriso->pacifier_fifo!=NULL)
2454 burn_source_free(xorriso->pacifier_fifo);
2455 xorriso->pacifier_fifo= NULL;
2456 xorriso->run_state= 0; /* Indicate that burning has ended */
2457 Xorriso_free_meM(reasons);
2458 Xorriso_free_meM(profile_name);
2459 Xorriso_free_meM(head_buffer);
2460 return(ret);
2461 }
2462
2463
Xorriso_relax_compliance(struct XorrisO * xorriso,char * mode,int flag)2464 int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode,
2465 int flag)
2466 {
2467 char *npt, *cpt;
2468 int l, was, value, ret;
2469 struct isoburn_imgen_opts *opts= NULL;
2470 char *msg= NULL;
2471 off_t limit;
2472
2473 was= xorriso->relax_compliance;
2474 npt= cpt= mode;
2475 for(; npt!=NULL; cpt= npt+1) {
2476 npt= strchr(cpt,':');
2477 if(npt==NULL)
2478 l= strlen(cpt);
2479 else
2480 l= npt-cpt;
2481 if(l == 0)
2482 continue;
2483 if((l == 6 && strncmp(cpt, "strict", l) == 0) ||
2484 (l == 5 && strncmp(cpt, "clear", l) == 0)) {
2485 xorriso->relax_compliance= 0;
2486 } else if(l == 7 && strncmp(cpt, "default", l) == 0) {
2487 xorriso->relax_compliance= Xorriso_relax_compliance_defaulT;
2488
2489 } else if((l == 18 && strncmp(cpt, "untranslated_names", l) == 0) ||
2490 (l == 21 && strncmp(cpt, "untranslated_names_on", l) == 0) ) {
2491 xorriso->untranslated_name_len = -1;
2492 } else if((l == 22 && strncmp(cpt, "untranslated_names_off", l) == 0)) {
2493 xorriso->untranslated_name_len = 0;
2494 } else if((l >= 22 && strncmp(cpt, "untranslated_name_len=", 22) == 0)) {
2495 value= -1;
2496 sscanf(cpt + 22, "%d", &value);
2497 /* Let libisoburn check the value */
2498 ret= isoburn_igopt_new(&opts, 0);
2499 if(ret != 1)
2500 return(-1);
2501 ret= isoburn_igopt_set_untranslated_name_len(opts, value);
2502 isoburn_igopt_destroy(&opts, 0);
2503 if(ret <= 0) { /* Not a tasty value */
2504 xorriso->relax_compliance= was;
2505 return(0);
2506 }
2507 xorriso->untranslated_name_len = value;
2508
2509 } else if((l == 16 && strncmp(cpt, "allow_dir_id_ext", l) == 0) ||
2510 (l == 19 && strncmp(cpt, "allow_dir_id_ext_on", l) == 0) ) {
2511 xorriso->relax_compliance|= isoburn_igopt_allow_dir_id_ext;
2512 xorriso->allow_dir_id_ext_dflt= 0;
2513 } else if((l == 20 && strncmp(cpt, "allow_dir_id_ext_off", l) == 0)) {
2514 xorriso->relax_compliance&= ~isoburn_igopt_allow_dir_id_ext;
2515 xorriso->allow_dir_id_ext_dflt= 0;
2516
2517 } else if((l == 12 && strncmp(cpt, "omit_version", l) == 0) ||
2518 (l == 15 && strncmp(cpt, "omit_version_on", l) == 0) ) {
2519 xorriso->relax_compliance|= isoburn_igopt_omit_version_numbers;
2520 } else if((l == 16 && strncmp(cpt, "omit_version_off", l) == 0)) {
2521 xorriso->relax_compliance&= ~isoburn_igopt_omit_version_numbers;
2522
2523 } else if((l == 16 && strncmp(cpt, "only_iso_version", l) == 0) ||
2524 (l == 19 && strncmp(cpt, "only_iso_version_on", l) == 0) ) {
2525 xorriso->relax_compliance|= isoburn_igopt_only_iso_versions;
2526 } else if((l == 20 && strncmp(cpt, "only_iso_version_off", l) == 0)) {
2527 xorriso->relax_compliance&= ~isoburn_igopt_only_iso_versions;
2528
2529 } else if((l == 10 && strncmp(cpt, "deep_paths", l) == 0) ||
2530 (l == 13 && strncmp(cpt, "deep_paths_on", l) == 0)) {
2531 xorriso->relax_compliance|= isoburn_igopt_allow_deep_paths;
2532 } else if(l == 14 && strncmp(cpt, "deep_paths_off", l) == 0) {
2533 xorriso->relax_compliance&= ~isoburn_igopt_allow_deep_paths;
2534
2535 } else if((l == 10 && strncmp(cpt, "long_paths", l) == 0) ||
2536 (l == 13 && strncmp(cpt, "long_paths_on", l) == 0) ) {
2537 xorriso->relax_compliance|= isoburn_igopt_allow_longer_paths;
2538 } else if(l == 14 && strncmp(cpt, "long_paths_off", l) == 0) {
2539 xorriso->relax_compliance&= ~isoburn_igopt_allow_longer_paths;
2540
2541 } else if((l == 10 && strncmp(cpt, "long_names", l) == 0) ||
2542 (l == 13 && strncmp(cpt, "long_names_on", l) == 0)) {
2543 xorriso->relax_compliance|= isoburn_igopt_max_37_char_filenames;
2544 } else if(l == 14 && strncmp(cpt, "long_names_off", l) == 0) {
2545 xorriso->relax_compliance&= ~isoburn_igopt_max_37_char_filenames;
2546
2547 } else if((l == 13 && strncmp(cpt, "no_force_dots", l) == 0) ||
2548 (l == 16 && strncmp(cpt, "no_force_dots_on", l) == 0)) {
2549 xorriso->relax_compliance|= isoburn_igopt_no_force_dots;
2550 } else if(l == 17 && strncmp(cpt, "no_force_dots_off", l) == 0) {
2551 xorriso->relax_compliance&= ~isoburn_igopt_no_force_dots;
2552
2553 } else if((l == 15 && strncmp(cpt, "no_j_force_dots", l) == 0) ||
2554 (l == 18 && strncmp(cpt, "no_j_force_dots_on", l) == 0)) {
2555 xorriso->relax_compliance|= isoburn_igopt_no_j_force_dots;
2556 } else if(l == 19 && strncmp(cpt, "no_j_force_dots_off", l) == 0) {
2557 xorriso->relax_compliance&= ~isoburn_igopt_no_j_force_dots;
2558
2559 } else if((l == 9 && strncmp(cpt, "lowercase", l) == 0) ||
2560 (l == 12 && strncmp(cpt, "lowercase_on", l) == 0)) {
2561 xorriso->relax_compliance|= isoburn_igopt_allow_lowercase;
2562 } else if(l == 13 && strncmp(cpt, "lowercase_off", l) == 0) {
2563 xorriso->relax_compliance&= ~isoburn_igopt_allow_lowercase;
2564
2565 } else if((l == 10 && strncmp(cpt, "full_ascii", l) == 0) ||
2566 (l == 13 && strncmp(cpt, "full_ascii_on", l) == 0)) {
2567 xorriso->relax_compliance|= isoburn_igopt_allow_full_ascii;
2568 } else if(l == 14 && strncmp(cpt, "full_ascii_off", l) == 0) {
2569 xorriso->relax_compliance&= ~isoburn_igopt_allow_full_ascii;
2570
2571 } else if((l == 10 && strncmp(cpt, "7bit_ascii", l) == 0) ||
2572 (l == 13 && strncmp(cpt, "7bit_ascii_on", l) == 0)) {
2573 xorriso->relax_compliance|= isoburn_igopt_allow_7bit_ascii;
2574 } else if(l == 14 && strncmp(cpt, "7bit_ascii_off", l) == 0) {
2575 xorriso->relax_compliance&= ~isoburn_igopt_allow_7bit_ascii;
2576
2577 } else if((l == 17 && strncmp(cpt, "joliet_long_paths", l) == 0) ||
2578 (l == 20 && strncmp(cpt, "joliet_long_paths_on", l) == 0)) {
2579 xorriso->relax_compliance|= isoburn_igopt_joliet_longer_paths;
2580 } else if(l == 21 && strncmp(cpt, "joliet_long_paths_off", l) == 0) {
2581 xorriso->relax_compliance&= ~isoburn_igopt_joliet_longer_paths;
2582
2583 } else if((l == 17 && strncmp(cpt, "joliet_long_names", l) == 0) ||
2584 (l == 20 && strncmp(cpt, "joliet_long_names_on", l) == 0)) {
2585 xorriso->relax_compliance|= isoburn_igopt_joliet_long_names;
2586 } else if(l == 21 && strncmp(cpt, "joliet_long_names_off", l) == 0) {
2587 xorriso->relax_compliance&= ~isoburn_igopt_joliet_long_names;
2588
2589 } else if((l == 12 && strncmp(cpt, "joliet_utf16", l) == 0) ||
2590 (l == 15 && strncmp(cpt, "joliet_utf16_on", l) == 0)) {
2591 xorriso->relax_compliance|= isoburn_igopt_joliet_utf16;
2592 } else if(l == 16 && strncmp(cpt, "joliet_utf16_off", l) == 0) {
2593 xorriso->relax_compliance&= ~isoburn_igopt_joliet_utf16;
2594
2595 } else if((l == 10 && strncmp(cpt, "always_gmt", l) == 0) ||
2596 (l == 13 && strncmp(cpt, "always_gmt_on", l) == 0)) {
2597 xorriso->relax_compliance|= isoburn_igopt_always_gmt;
2598 } else if(l == 14 && strncmp(cpt, "always_gmt_off", l) == 0) {
2599 xorriso->relax_compliance&= ~isoburn_igopt_always_gmt;
2600
2601 } else if((l == 9 && strncmp(cpt, "rec_mtime", l) == 0) ||
2602 (l == 12 && strncmp(cpt, "rec_mtime_on", l) == 0)) {
2603 xorriso->relax_compliance|= (isoburn_igopt_dir_rec_mtime |
2604 isoburn_igopt_joliet_rec_mtime |
2605 isoburn_igopt_iso1999_rec_mtime);
2606 } else if(l == 13 && strncmp(cpt, "rec_mtime_off", l) == 0) {
2607 xorriso->relax_compliance&= ~(isoburn_igopt_dir_rec_mtime |
2608 isoburn_igopt_joliet_rec_mtime |
2609 isoburn_igopt_iso1999_rec_mtime);
2610
2611 } else if((l == 6 && strncmp(cpt, "old_rr", l) == 0) ||
2612 (l == 9 && strncmp(cpt, "old_rr_on", l) == 0) ||
2613 (l == 10 && strncmp(cpt, "new_rr_off", l) == 0)) {
2614 xorriso->relax_compliance|=
2615 isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10;
2616 } else if((l == 10 && strncmp(cpt, "old_rr_off", l) == 0) ||
2617 (l == 9 && strncmp(cpt, "new_rr_on", l) == 0) ||
2618 (l == 6 && strncmp(cpt, "new_rr", l) == 0)) {
2619 xorriso->relax_compliance&=
2620 ~(isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10);
2621
2622 } else if((l == 14 && strncmp(cpt, "aaip_susp_1_10", l) == 0) ||
2623 (l == 17 && strncmp(cpt, "aaip_susp_1_10_on", l) == 0) ||
2624 (l == 18 && strncmp(cpt, "aaip_susp_1_12_off", l) == 0)) {
2625 xorriso->relax_compliance|= isoburn_igopt_aaip_susp_1_10;
2626 } else if((l == 18 && strncmp(cpt, "aaip_susp_1_10_off", l) == 0) ||
2627 (l == 17 && strncmp(cpt, "aaip_susp_1_12_on", l) == 0) ||
2628 (l == 14 && strncmp(cpt, "aaip_susp_1_12", l) == 0)) {
2629 xorriso->relax_compliance&= ~isoburn_igopt_aaip_susp_1_10;
2630
2631 } else if((l == 11 && strncmp(cpt, "no_emul_toc", l) == 0) ||
2632 (l == 14 && strncmp(cpt, "no_emul_toc_on", l) == 0)) {
2633 xorriso->no_emul_toc|= 1;
2634 } else if((l == 15 && strncmp(cpt, "no_emul_toc_off", l) == 0) ||
2635 (l == 8 && strncmp(cpt, "emul_toc", l) == 0)) {
2636 xorriso->no_emul_toc&= ~1;
2637
2638 } else if((l == 13 && strncmp(cpt, "iso_9660_1999", l) == 0) ||
2639 (l == 16 && strncmp(cpt, "iso_9660_1999_on", l) == 0)) {
2640 xorriso->do_iso1999= 1;
2641 } else if(l == 17 && strncmp(cpt, "iso_9660_1999_off", l) == 0) {
2642 xorriso->do_iso1999= 0;
2643
2644 } else if((l >= 15 && strncmp(cpt, "iso_9660_level=", 15) == 0)) {
2645 value= 0;
2646 sscanf(cpt + 15, "%d", &value);
2647 if(value == 1 || value == 2) {
2648 limit= ((off_t) 4) * ((off_t) 1024*1024*1024) - ((off_t) 1);
2649 xorriso->iso_level= value;
2650 xorriso->iso_level_is_default= 0;
2651 if(xorriso->file_size_limit > limit)
2652 xorriso->file_size_limit= limit;
2653 } else if(value == 3) {
2654 xorriso->iso_level= value;
2655 xorriso->iso_level_is_default= 0;
2656 if(xorriso->file_size_limit < Xorriso_default_file_size_limiT)
2657 xorriso->file_size_limit= Xorriso_default_file_size_limiT;
2658 } else {
2659 Xorriso_alloc_meM(msg, char, 160);
2660 sprintf(msg,
2661 "-compliance iso_9660_level=%d : Only 1, 2, or 3 are permissible",
2662 value);
2663 Xorriso_msgs_submit(xorriso, 0, msg, 0, "FAILURE", 0);
2664 Xorriso_free_meM(msg);
2665 msg= NULL;
2666 xorriso->relax_compliance= was;
2667 return(0);
2668 }
2669
2670 } else if((l == 8 && strncmp(cpt, "iso_9660", l) == 0) ||
2671 (l == 11 && strncmp(cpt, "iso_9660_on", l) == 0)) {
2672 /* may have a meaning in future */;
2673 } else if(l == 12 && strncmp(cpt, "iso_9660_off", l) == 0) {
2674 /* may have a meaning in future */;
2675 Xorriso_msgs_submit(xorriso, 0,
2676 "-compliance -iso_9660_off : Cannot do anything else but ISO 9660",
2677 0, "FAILURE", 0);
2678 xorriso->relax_compliance= was;
2679 return(0);
2680
2681 } else if((l == 9 && strncmp(cpt, "old_empty", l) == 0) ||
2682 (l == 12 && strncmp(cpt, "old_empty_on", l) == 0)) {
2683 xorriso->do_old_empty= 1;
2684 } else if(l == 13 && strncmp(cpt, "old_empty_off", l) == 0) {
2685 xorriso->do_old_empty= 0;
2686
2687 } else {
2688 if(l<SfileadrL)
2689 sprintf(xorriso->info_text, "-compliance: unknown rule '%s'",
2690 cpt);
2691 else
2692 sprintf(xorriso->info_text,
2693 "-compliance: oversized rule parameter (%d)", l);
2694 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2695 xorriso->relax_compliance= was;
2696 return(0);
2697 }
2698 }
2699 return(1);
2700 ex:;
2701 Xorriso_free_meM(msg);
2702 return(ret);
2703 }
2704
2705
2706 /* @return 1=ok 2=ok, is default setting */
Xorriso_get_relax_text(struct XorrisO * xorriso,char mode[1024],int flag)2707 int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024],
2708 int flag)
2709 {
2710 int r;
2711
2712 r= xorriso->relax_compliance;
2713 if(r == 0) {
2714 strcpy(mode, "strict");
2715 return(1);
2716 }
2717 strcpy(mode, "clear");
2718 sprintf(mode + strlen(mode), ":iso_9660_level=%d", xorriso->iso_level);
2719 if(r & isoburn_igopt_allow_dir_id_ext)
2720 strcat(mode, ":allow_dir_id_ext");
2721 if(r & isoburn_igopt_omit_version_numbers)
2722 strcat(mode, ":omit_version");
2723 if(r & isoburn_igopt_only_iso_versions)
2724 strcat(mode, ":only_iso_version");
2725 if(r & isoburn_igopt_allow_deep_paths)
2726 strcat(mode, ":deep_paths");
2727 if(r & isoburn_igopt_allow_longer_paths)
2728 strcat(mode, ":long_paths");
2729 if(r & isoburn_igopt_max_37_char_filenames)
2730 strcat(mode, ":long_names");
2731 if(r & isoburn_igopt_no_force_dots)
2732 strcat(mode, ":no_force_dots");
2733 if(r & isoburn_igopt_no_j_force_dots)
2734 strcat(mode, ":no_j_force_dots");
2735 if(r & isoburn_igopt_allow_lowercase)
2736 strcat(mode, ":lowercase");
2737 if(r & isoburn_igopt_allow_full_ascii)
2738 strcat(mode, ":full_ascii");
2739 else if(r & isoburn_igopt_allow_7bit_ascii)
2740 strcat(mode, ":7bit_ascii");
2741 if(r & isoburn_igopt_joliet_longer_paths)
2742 strcat(mode, ":joliet_long_paths");
2743 if(r & isoburn_igopt_joliet_long_names)
2744 strcat(mode, ":joliet_long_names");
2745 if(r & isoburn_igopt_joliet_utf16)
2746 strcat(mode, ":joliet_utf16");
2747 if(r & isoburn_igopt_always_gmt)
2748 strcat(mode, ":always_gmt");
2749 if(r & isoburn_igopt_dir_rec_mtime)
2750 strcat(mode, ":rec_mtime");
2751 if(r & isoburn_igopt_rrip_version_1_10) {
2752 strcat(mode, ":old_rr");
2753 if(!(r & isoburn_igopt_aaip_susp_1_10))
2754 strcat(mode, ":aaip_susp_1_10_off");
2755 } else {
2756 strcat(mode, ":new_rr");
2757 if(r & isoburn_igopt_aaip_susp_1_10)
2758 strcat(mode, ":aaip_susp_1_10");
2759 }
2760 if(xorriso->no_emul_toc & 1)
2761 strcat(mode, ":no_emul_toc");
2762 if(xorriso->untranslated_name_len != 0)
2763 sprintf(mode + strlen(mode), ":untranslated_name_len=%d",
2764 xorriso->untranslated_name_len);
2765 if(xorriso->do_iso1999)
2766 sprintf(mode + strlen(mode), ":iso_9660_1999");
2767 if(xorriso->do_old_empty)
2768 sprintf(mode + strlen(mode), ":old_empty");
2769 return(1 +
2770 (r == Xorriso_relax_compliance_defaulT && !(xorriso->no_emul_toc & 1)
2771 && xorriso->untranslated_name_len == 0 && !xorriso->do_iso1999 &&
2772 xorriso->iso_level == 3));
2773 }
2774
2775
2776 /* @param flag bit0= operating on newly attached boot image
2777 */
Xorriso_set_isolinux_options(struct XorrisO * xorriso,IsoImage * image,int flag)2778 int Xorriso_set_isolinux_options(struct XorrisO *xorriso,
2779 IsoImage *image, int flag)
2780 {
2781 int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i;
2782 ElToritoBootImage *bootimg, **boots = NULL;
2783 IsoFile *bootimg_node, **bootnodes = NULL;
2784
2785 ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL);
2786 Xorriso_process_msg_queues(xorriso,0);
2787 if(ret != 1) {
2788 sprintf(xorriso->info_text, "Programming error: No boot image available in Xorriso_set_isolinux_options()");
2789 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2790 ret= -1; goto ex;
2791 }
2792 ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
2793 Xorriso_process_msg_queues(xorriso,0);
2794 if(ret != 1) {
2795 Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0,
2796 "FATAL", 1);
2797 ret= -1; goto ex;
2798 }
2799
2800 /* bit0 : 1=boot-info-table , bit2-7 : 1=EFI , 2=HFS+ , bit8 : 1=APM */
2801 patch_table = xorriso->patch_isolinux_image & 0x3fd;
2802 if((flag & 1) && num_boots > 1) {
2803 ret= el_torito_set_isolinux_options(boots[num_boots - 1], patch_table, 0);
2804 ret= (ret == 1); goto ex;
2805 }
2806
2807 /* Handle patching of first attached boot image or of imported boot images
2808 */
2809 for(i= 0; i < num_boots; i++) {
2810 patch_table = xorriso->patch_isolinux_image & 0x3fd;
2811 if(patch_table && !(flag & 1)) {
2812 if(!el_torito_seems_boot_info_table(boots[i], 0))
2813 patch_table&= ~1;
2814 else if((xorriso->patch_isolinux_image & 2) &&
2815 el_torito_get_boot_platform_id(boots[i]) == 0xef)
2816 patch_table&= ~1;
2817 }
2818 if(i > 0 || xorriso->boot_image_isohybrid == 0) {
2819 ret= el_torito_set_isolinux_options(boots[i], patch_table, 0);
2820 if(ret != 1)
2821 {ret= 0; goto ex;}
2822 continue;
2823 }
2824
2825 /* <<< From here on only with first boot image and
2826 deprecated builtin isohybrid MBR */
2827
2828 if(xorriso->boot_image_isohybrid == 3) {
2829 make_isohybrid_mbr= 1;
2830 } else {
2831 ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
2832 if(ret < 0)
2833 {ret= 0; goto ex;}
2834 if(ret > 0)
2835 make_isohybrid_mbr= 1;
2836 }
2837
2838 if(xorriso->boot_image_isohybrid == 2 && !make_isohybrid_mbr) {
2839 sprintf(xorriso->info_text,
2840 "Isohybrid signature is demanded but not found in boot image file.");
2841 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2842 {ret= 0; goto ex;}
2843 }
2844 if(make_isohybrid_mbr) {
2845 sprintf(xorriso->info_text, "Will write isohybrid MBR.");
2846 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2847 }
2848 ret= el_torito_set_isolinux_options(bootimg,
2849 patch_table | (make_isohybrid_mbr << 1),0);
2850 if(ret != 1)
2851 {ret= 0; goto ex;}
2852 }
2853 ex:
2854 Xorriso_process_msg_queues(xorriso,0);
2855 if(boots != NULL)
2856 free(boots);
2857 if(bootnodes != NULL)
2858 free(bootnodes);
2859 return(ret);
2860 }
2861
2862
2863 /*
2864 @param flag bit0= obtain iso_lba from indev
2865 bit1= head_buffer already contains a valid head
2866 bit2= issue message about success
2867 bit3= check whether source blocks are banned by in_sector_map
2868 */
Xorriso_update_iso_lba0(struct XorrisO * xorriso,int iso_lba,int isosize,char * head_buffer,struct CheckmediajoB * job,int flag)2869 int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
2870 char *head_buffer, struct CheckmediajoB *job,
2871 int flag)
2872 {
2873 int ret, full_size, i;
2874 char *headpt;
2875 struct burn_drive_info *dinfo;
2876 struct burn_drive *drive = NULL;
2877 off_t seek_ret, to_write;
2878 int tag_type;
2879 uint32_t pos, range_start, range_size, next_tag;
2880 char md5[16];
2881
2882 ret= Xorriso_may_burn(xorriso, 0);
2883 if(ret <= 0)
2884 return(0);
2885 if(flag & 1) {
2886 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2887 "on attempt to learn current session lba", 1);
2888 if(ret<=0)
2889 return(0);
2890 ret= isoburn_disc_get_msc1(drive, &iso_lba);
2891 if(ret<=0)
2892 return(0);
2893 drive= NULL; /* indev will not be used furtherly */
2894 }
2895 if(job == NULL) {
2896 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2897 "on attempt to update at lba 0 to 31", 2);
2898 if(ret<=0)
2899 return(0);
2900 }
2901 if(iso_lba < 32)
2902 return(2);
2903
2904 if(!(flag & 2)) {
2905 /* head_buffer was not filled yet. Read it from output media. */
2906 if(drive != NULL)
2907 if(burn_drive_get_drive_role(drive) == 5) /* write-only */
2908 return(2);
2909 if(job != NULL && job->data_to_fd >= 0) {
2910 if((flag & 8) && job->sector_map != NULL) {
2911 ret= Sectorbitmap_bytes_are_set(job->sector_map,
2912 ((off_t) iso_lba) * (off_t) 2048,
2913 ((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0);
2914 if(ret <= 0) {
2915 sprintf(xorriso->info_text,
2916 "ISO image head at lba %d is marked as invalid blocks in file copy",
2917 iso_lba);
2918 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
2919 0);
2920 return(0);
2921 }
2922 }
2923 seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba,
2924 SEEK_SET);
2925 if(seek_ret == -1)
2926 ret= 0;
2927 else
2928 ret= read(job->data_to_fd, head_buffer, 64 * 1024);
2929 if(ret < 64 * 1024) {
2930 Xorriso_process_msg_queues(xorriso,0);
2931 sprintf(xorriso->info_text,
2932 "Cannot read ISO image head from file copy");
2933 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
2934 return(0);
2935 }
2936 ret= isoburn_read_iso_head(NULL, 0, &isosize, head_buffer, 1 << 13);
2937 if(ret<=0) {
2938 Xorriso_process_msg_queues(xorriso,0);
2939 sprintf(xorriso->info_text,
2940 "Alleged session start does not look like ISO 9660.");
2941 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
2942 return(0);
2943 }
2944 } else {
2945 ret= 0;
2946 if(drive != NULL)
2947 ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2);
2948 if(ret<=0) {
2949 Xorriso_process_msg_queues(xorriso,0);
2950 sprintf(xorriso->info_text,
2951 "Cannot read freshly written ISO image head");
2952 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2953 return(0);
2954 }
2955 }
2956 }
2957 /* patch ISO header */
2958 full_size= iso_lba + isosize;
2959 headpt= head_buffer + 32*1024;
2960 for(i=0;i<4;i++)
2961 headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
2962
2963
2964 if(job != NULL) {
2965 /* This is a check_media superblock relocation:
2966 Invalidate eventual libisofs checksum tags.
2967 Write only up to PVD end plus eventual invalidated tag.
2968 */
2969 /* Look for volume descriptor end */
2970 for(i= 16; i < 32; i++)
2971 if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
2972 strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0)
2973 break;
2974 /* Check whether the next one is a libisofs checksum tag */
2975 if(i < 32) {
2976 i++;
2977 ret= iso_util_decode_md5_tag(head_buffer + i * 2048, &tag_type, &pos,
2978 &range_start, &range_size, &next_tag, md5, 0);
2979 if(ret != 0) /* corrupted or not: invalidate */
2980 memset(head_buffer + i * 2048, 0, 8);
2981 }
2982 to_write= 2048 * (i + 1);
2983
2984 seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
2985 if(seek_ret == -1)
2986 ret= 0;
2987 else
2988 ret= write(job->data_to_fd, head_buffer, to_write);
2989 if(ret < to_write) {
2990 Xorriso_process_msg_queues(xorriso,0);
2991 sprintf(xorriso->info_text,
2992 "Cannot write ISO image head to file copy");
2993 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
2994 return(0);
2995 }
2996 } else {
2997 /* This is a regular superblock relocation. Write full 64 kB. */
2998 to_write= 64 * 1024;
2999 burn_drive_reset_simulate(drive, xorriso->do_dummy);
3000 ret= burn_random_access_write(drive, (off_t) 0, head_buffer, to_write, 1);
3001 if(ret<=0) {
3002 Xorriso_process_msg_queues(xorriso,0);
3003 sprintf(xorriso->info_text,
3004 "Cannot write new ISO image head to LBA 0");
3005 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3006 return(0);
3007 }
3008 }
3009 if(flag & 4) {
3010 sprintf(xorriso->info_text,
3011 "Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba);
3012 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
3013 }
3014 return(1);
3015 }
3016
3017
Xorriso_set_system_area_path(struct XorrisO * xorriso,char * path,int flag)3018 int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag)
3019 {
3020 int ret;
3021 char *eff_src= NULL, *intvl;
3022 struct iso_interval_reader *ivr= NULL;
3023 off_t byte_count;
3024 IsoImage *img= NULL;
3025 struct burn_drive_info *source_dinfo;
3026 struct burn_drive *source_drive;
3027
3028 if(path[0] == 0) {
3029 xorriso->system_area_disk_path[0]= 0;
3030 {ret= 1; goto ex;}
3031 }
3032 Xorriso_alloc_meM(eff_src, char, SfileadrL);
3033
3034 intvl = path;
3035 ret = Xorriso_check_intvl_string(xorriso, &intvl, 0);
3036 if(ret > 0) {
3037 /* Check for syntactical correctness */
3038 if(xorriso->in_drive_handle != NULL) {
3039 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
3040 "on attempt to verify interval reader string", 0);
3041 if(ret<=0)
3042 goto ex;
3043 img= isoburn_get_attached_image(source_drive);
3044 }
3045 ret= iso_interval_reader_new(img, intvl, &ivr, &byte_count, 1);
3046 Xorriso_process_msg_queues(xorriso, 0);
3047 if(ret < 0) {
3048 sprintf(xorriso->info_text,
3049 "Given path for system area is not accepted by interval reader");
3050 Text_shellsafe(eff_src, xorriso->info_text, 1);
3051 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3052 {ret= 0; goto ex;}
3053 }
3054 iso_interval_reader_destroy(&ivr, 0);
3055 ret= Sfile_str(xorriso->system_area_disk_path, path, 0);
3056 if(ret <= 0)
3057 {ret= -1; goto ex;}
3058 ret= 1; goto ex;
3059 }
3060 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_src, 2|4|16);
3061 if(ret < 0)
3062 goto ex;
3063 if(ret == 0) {
3064 sprintf(xorriso->info_text,
3065 "Given path does not exist on disk: -boot_image system_area=");
3066 Text_shellsafe(eff_src, xorriso->info_text, 1);
3067 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3068 }
3069 if(ret == 2) {
3070 sprintf(xorriso->info_text,
3071 "Given path leads to a directory: -boot_image system_area=");
3072 Text_shellsafe(eff_src, xorriso->info_text, 1);
3073 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3074 {ret= 0; goto ex;}
3075 }
3076 ret= Sfile_str(xorriso->system_area_disk_path, eff_src, 0);
3077 if(ret <= 0)
3078 {ret= -1; goto ex;}
3079 ret= 1;
3080 ex:
3081 Xorriso_free_meM(eff_src);
3082 if(img != NULL)
3083 iso_image_unref(img);
3084 return(ret);
3085 }
3086
3087
3088 /* @param flag bit0=force burn_disc_close_damaged()
3089 */
Xorriso_close_damaged(struct XorrisO * xorriso,int flag)3090 int Xorriso_close_damaged(struct XorrisO *xorriso, int flag)
3091 {
3092 int ret;
3093 struct burn_drive_info *dinfo;
3094 struct burn_drive *drive;
3095 struct burn_write_opts *burn_options= NULL;
3096
3097 if(Xorriso_change_is_pending(xorriso, 0)) {
3098 sprintf(xorriso->info_text,
3099 "Image changes pending. -commit or -rollback first");
3100 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3101 ret= 0; goto ex;
3102 }
3103 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
3104 "on attempt to close damaged session", 2);
3105 if(ret<=0)
3106 goto ex;
3107 ret= Xorriso_check_multi(xorriso, drive, 0);
3108 if(ret<=0)
3109 goto ex;
3110 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
3111 if(ret <= 0)
3112 goto ex;
3113 ret= burn_disc_close_damaged(burn_options, flag & 1);
3114 Xorriso_process_msg_queues(xorriso, 0);
3115 Xorriso_option_dev(xorriso, "", 3 | 4); /* Give up drives */
3116 if(ret <= 0)
3117 goto ex;
3118
3119 ret= 1;
3120 ex:;
3121 Xorriso_process_msg_queues(xorriso, 0);
3122 if(burn_options != NULL)
3123 burn_write_opts_free(burn_options);
3124 return(ret);
3125 }
3126
3127
Xorriso_parse_gpt_guid(struct XorrisO * xorriso,char * text,int flag)3128 int Xorriso_parse_gpt_guid(struct XorrisO *xorriso, char *text, int flag)
3129 {
3130 int bin_count= 0, ret;
3131 uint8_t u[16], tr;
3132
3133 if(strcmp(text, "random") == 0) {
3134 xorriso->gpt_guid_mode= 0;
3135 return(1);
3136 }
3137 if(strcmp(text, "modification-date") == 0 ||
3138 strcmp(text, "volume_date_uuid") == 0) {
3139 xorriso->gpt_guid_mode= 2;
3140 return(1);
3141 }
3142 /* Try RFC 4122 : big endian XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
3143 Translate to UEFI: first three components to little-endian
3144 */
3145 if(strlen(text) == 36) {
3146 if(text[8] == '-' && text[13] == '-' && text[18] == '-' && text[23] == '-'){
3147 ret= Hex_to_bin(text, 4, &bin_count, u, 0);
3148 if(ret < 0 || bin_count != 4)
3149 goto malformed;
3150 tr= u[0]; u[0]= u[3]; u[3]= tr;
3151 tr= u[1]; u[1]= u[2]; u[2]= tr;
3152 ret= Hex_to_bin(text + 9, 2, &bin_count, u + 4, 0);
3153 if(ret < 0 || bin_count != 2)
3154 goto malformed;
3155 tr= u[4]; u[4]= u[5]; u[5]= tr;
3156 ret= Hex_to_bin(text + 14, 2, &bin_count, u + 6, 0);
3157 if(ret < 0 || bin_count != 2)
3158 goto malformed;
3159 tr= u[6]; u[6]= u[7]; u[7]= tr;
3160 ret= Hex_to_bin(text + 19, 2, &bin_count, u + 8, 0);
3161 if(ret < 0 || bin_count != 2)
3162 goto malformed;
3163 ret= Hex_to_bin(text + 24, 6, &bin_count, u + 10, 0);
3164 if(ret < 0 || bin_count != 6)
3165 goto malformed;
3166 xorriso->gpt_guid_mode= 1;
3167 memcpy(xorriso->gpt_guid, u, 16);
3168 return(1);
3169 }
3170 }
3171 if(strlen(text) == 32) {
3172 ret= Hex_to_bin(text, 16, &bin_count, u, 0);
3173 if(ret < 0 || bin_count != 16)
3174 goto malformed;
3175 xorriso->gpt_guid_mode= 1;
3176 memcpy(xorriso->gpt_guid, u, 16);
3177 return(1);
3178 }
3179
3180 malformed:;
3181 sprintf(xorriso->info_text, "Malformed GUID string: ");
3182 Text_shellsafe(text, xorriso->info_text, 1);
3183 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3184 return(0);
3185 }
3186
3187