"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/xorriso/write_run.c" (30 Jan 2021, 133140 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "write_run.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.2_vs_1.5.4.
1
2
3 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
4
5 Copyright 2007-2020 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 */
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
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 */
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
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 burn_drive_re_assess(drive, 0);
344 }
345 }
346 return(1);
347 }
348
349
350 /* @param flag bit0= fail on indev == outdev with "imported_iso"
351 bit1= fail on indev == NULL with "imported_iso"
352 */
353 int Xorriso_check_intvl_string(struct XorrisO *xorriso, char **part_image,
354 int flag)
355 {
356 char *cpt, *ipt, *orig;
357
358 orig= *part_image;
359 if(strncmp(*part_image, "--interval:", 11) != 0)
360 return(0);
361 if(strchr(*part_image + 11, ':') == NULL)
362 return(0);
363 (*part_image)+= 11;
364 if(!(flag & 3))
365 return(1);
366
367 cpt= strchr(*part_image, ':');
368 ipt= strstr(*part_image, "imported_iso");
369 if(ipt == NULL || ipt > cpt)
370 return(1);
371
372 if((flag & 2) && xorriso->in_drive_handle == NULL) {
373 sprintf(xorriso->info_text,
374 "Interval reader lacks of -indev to read from \"imported_iso\"");
375 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
376 goto failure;
377 }
378
379 if(!(flag & 1))
380 return(1);
381 if(xorriso->out_drive_handle != xorriso->in_drive_handle)
382 return(1);
383 sprintf(xorriso->info_text,
384 "Interval reader may not read from \"imported_iso\" during write run to same drive");
385 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
386
387 failure:;
388 sprintf(xorriso->info_text, "Rejected: ");
389 Text_shellsafe(orig, xorriso->info_text, 1);
390 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
391 return(-1);
392 }
393
394
395 int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
396 IsoImage *img, struct isoburn_imgen_opts *sopts,
397 int flag)
398 {
399 int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks;
400 int sa_loaded, read_count, i, read_sum= 0;
401 char volid[33];
402 FILE *fp= NULL;
403 char *buf= NULL, *bufpt= NULL, *intvl;
404 uint8_t *intvl_buf;
405 off_t hd_lba, byte_count;
406 unsigned char *ub;
407 ElToritoBootImage *bootimg;
408 IsoFile *bootimg_node;
409 IsoNode *sparc_core_node;
410 uint32_t offst;
411 enum burn_disc_status state;
412 struct iso_interval_reader *ivr = NULL;
413
414 if(xorriso->grub2_sparc_core[0]) {
415 ret= Xorriso_node_from_path(xorriso, img, xorriso->grub2_sparc_core,
416 &sparc_core_node, 1);
417 if(ret <= 0) {
418 sprintf(xorriso->info_text,
419 "Cannot find in ISO image: -boot_image grub grub2_sparc_core=");
420 Text_shellsafe(xorriso->grub2_sparc_core, xorriso->info_text, 1);
421 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
422 {ret= 0; goto ex;}
423 }
424 if(!ISO_NODE_IS_FILE(sparc_core_node)) {
425 sprintf(xorriso->info_text,
426 "Not a data file: -boot_image grub grub2_sparc_core=");
427 Text_shellsafe(xorriso->grub2_sparc_core, xorriso->info_text, 1);
428 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
429 {ret= 0; goto ex;}
430 }
431 ret = iso_image_set_sparc_core(img, (IsoFile *) sparc_core_node, 0);
432 if(ret < 0) {
433 Xorriso_process_msg_queues(xorriso,0);
434 Xorriso_report_iso_error(xorriso, "", ret,
435 "Error when setting up -boot_image grub grub2_sparc_core=",
436 0, "FAILURE", 1);
437 {ret= 0; goto ex;}
438 }
439 }
440
441 Xorriso_alloc_meM(buf, char, 32768);
442 memset(buf, 0, 32768);
443 system_area_options= xorriso->system_area_options;
444 if(xorriso->system_area_clear_loaded)
445 sa_loaded= 0;
446 else
447 sa_loaded= iso_image_get_system_area(img, buf, &options, 0);
448 if(sa_loaded < 0) {
449 Xorriso_process_msg_queues(xorriso,0);
450 Xorriso_report_iso_error(xorriso, "", sa_loaded,
451 "Error when inquiring System Area data of ISO 9660 image",
452 0, "FAILURE", 1);
453 {ret= 0; goto ex;}
454 } if(sa_loaded > 0)
455 bufpt= buf;
456 if(xorriso->system_area_disk_path[0] == 0) {
457 if(xorriso->patch_system_area && xorriso->system_area_options == 0 &&
458 sa_loaded > 0) {
459 system_area_options= xorriso->patch_system_area;
460 /* Check whether partition 1 ends at image end */;
461 ub= (unsigned char *) buf;
462 hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) |
463 (((unsigned int) ub[457]) << 24)) +
464 (ub[458] | (ub[459] << 8) | (ub[460] << 16) |
465 (((unsigned int) ub[461]) << 24));
466
467 iso_lba= -1;
468 ret= isoburn_disc_get_msc1(drive, &start_lba);
469 if(ret > 0) {
470 ret= isoburn_read_iso_head(drive, start_lba, &image_blocks,
471 volid, 1);
472 if(ret > 0)
473 iso_lba= start_lba + image_blocks;
474 }
475 if(((off_t) iso_lba) * (off_t) 4 > hd_lba) {
476 system_area_options= 0;
477 } else if((xorriso->patch_system_area & 1) &&
478 ((off_t) iso_lba) * (off_t) 4 != hd_lba) {
479 system_area_options= 0;
480 } else if((xorriso->patch_system_area & 2) &&
481 ((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) {
482 system_area_options= 0;
483 } else if(xorriso->patch_system_area & 2) { /* isohybrid patching */
484 /* Check whether bytes 432-345 point to ElTorito LBA */
485 hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) |
486 (((unsigned int) ub[435]) << 24);
487 ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL);
488 if(ret != 1) {
489 system_area_options= 0;
490 } else if(bootimg_node != NULL) {
491 Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0);
492 if(((off_t) iso_lba) * (off_t) 4 != hd_lba)
493 system_area_options= 0;
494 }
495 }
496 if(system_area_options == 0) {
497 Xorriso_msgs_submit(xorriso, 0,
498 "Loaded System Area data are not suitable for MBR patching.",
499 0, "DEBUG", 0);
500 }
501 }
502 {ret= 1; goto do_set;}
503 }
504
505 bufpt= buf;
506 if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0) {
507 memset(buf, 0, 32768);
508 {ret= 1; goto do_set;}
509 }
510
511 intvl= xorriso->system_area_disk_path;
512 ret= Xorriso_check_intvl_string(xorriso, &intvl, 2);
513 if(ret < 0) {
514 {ret= 0; goto ex;}
515 } else if(ret > 0) {
516 ret= iso_interval_reader_new(img, intvl, &ivr, &byte_count, 0);
517 Xorriso_process_msg_queues(xorriso, 0);
518 if(ret < 0) {
519 intvl_reader_err:;
520 sprintf(xorriso->info_text,
521 "Error when reading -boot_image system_area=");
522 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
523 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
524 {ret= 0; goto ex;}
525 }
526 for(i= 0; i < 16; i++) {
527 intvl_buf= (uint8_t *) (buf + 2048 * i);
528 ret= iso_interval_reader_read(ivr, intvl_buf, &read_count, 0);
529 Xorriso_process_msg_queues(xorriso, 0);
530 if(ret == 0)
531 break;
532 if(ret < 0)
533 goto intvl_reader_err;
534 read_sum+= read_count;
535 }
536 ret= read_sum;
537 } else {
538 ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path,
539 "rb", &fp, 2);
540 if(ret <= 0)
541 {ret= 0; goto ex;}
542 ret= fread(buf, 1, 32768, fp);
543 if(ret < 32768) {
544 if(ferror(fp)) {
545 sprintf(xorriso->info_text,
546 "Error when reading -boot_image system_area=");
547 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
548 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
549 {ret= 0; goto ex;}
550 }
551 }
552 }
553
554 do_set:;
555 if(ret > 0 && xorriso->system_area_disk_path[0]) {
556 sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ",
557 ret);
558 Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
559 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
560 }
561 ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options);
562 if(ret != ISO_SUCCESS) {
563 Xorriso_process_msg_queues(xorriso,0);
564 Xorriso_report_iso_error(xorriso, "", ret,
565 "Error when attaching System Area data to ISO 9660 image",
566 0, "FAILURE", 1);
567 {ret= 0; goto ex;}
568 }
569 offst= xorriso->partition_offset;
570 state= isoburn_disc_get_status(drive);
571 if(state == BURN_DISC_APPENDABLE) {
572 ret= isoburn_get_img_partition_offset(drive, &offst);
573 if(ret == 1) {
574 sprintf(xorriso->info_text,
575 "Preserving in ISO image: -boot_image any partition_offset=%lu",
576 (unsigned long) offst);
577 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
578 } else
579 offst= xorriso->partition_offset;
580 }
581 ret= isoburn_igopt_set_part_offset(sopts, offst,
582 xorriso->partition_secs_per_head,
583 xorriso->partition_heads_per_cyl);
584 if(ret != ISO_SUCCESS) {
585 Xorriso_process_msg_queues(xorriso,0);
586 Xorriso_report_iso_error(xorriso, "", ret,
587 "Error when setting partition offset", 0, "FAILURE", 1);
588 {ret= 0; goto ex;}
589 }
590 ret= 1;
591 ex:;
592 if(fp != NULL && fp != stdin)
593 fclose(fp);
594 iso_interval_reader_destroy(&ivr, 0);
595 Xorriso_free_meM(buf);
596 return(ret);
597 }
598
599
600 /* @param flag bit0= do not increment boot_count
601 and do not reset boot parameters
602 bit1= dispose attached boot images
603 */
604 int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag)
605 {
606 int ret;
607 char *cpt;
608 struct burn_drive_info *source_dinfo;
609 struct burn_drive *source_drive;
610 IsoImage *image= NULL;
611 IsoNode *node= NULL;
612 ElToritoBootImage *bootimg;
613 enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
614 char *bin_path;
615 int emul, platform_id;
616 off_t load_size;
617 struct stat stbuf;
618 int hflag= 0, is_interval= 0;
619
620 if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) {
621
622 /* >>> no boot image path given : no op */;
623
624 ret= 2; goto ex;
625 }
626
627 if(xorriso->in_drive_handle == NULL)
628 hflag= 2;
629 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
630 "on attempt to attach boot image", hflag);
631 if(ret<=0)
632 goto ex;
633 image= isoburn_get_attached_image(source_drive);
634 if(image == NULL) {
635 /* (should not happen) */
636 sprintf(xorriso->info_text,
637 "No ISO image present on attempt to attach boot image");
638 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
639 ret= 0; goto ex;
640 }
641 if(flag & 2) {
642 iso_image_remove_boot_image(image);
643 xorriso->boot_count= 0;
644 ret= 1; goto ex;
645 }
646
647 bin_path= xorriso->boot_image_bin_path;
648 emul= xorriso->boot_image_emul;
649 platform_id= xorriso->boot_platform_id;
650 load_size= xorriso->boot_image_load_size;
651 if(strncmp(bin_path, "--interval:appended_partition_", 30) == 0) {
652 is_interval= 1;
653 if(load_size <= 0)
654 load_size= 512;
655 }
656
657 if(xorriso->boot_efi_default) {
658 emul= 0;
659 platform_id= 0xef;
660 xorriso->patch_isolinux_image= (xorriso->patch_isolinux_image & ~3) | 0;
661 }
662 if((platform_id == 0xef || load_size < 0) && !is_interval) {
663 ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
664 if(ret != 0)
665 {ret= 0; goto ex;}
666 load_size= ((stbuf.st_size / (off_t) 512) +
667 !!(stbuf.st_size % (off_t) 512)) * 512;
668 }
669 sprintf(xorriso->info_text, "Adding boot image ");
670 Text_shellsafe(bin_path, xorriso->info_text, 1);
671 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
672
673 if(emul == 0)
674 emul_type= ELTORITO_NO_EMUL;
675 else if(emul == 1)
676 emul_type= ELTORITO_HARD_DISC_EMUL;
677 else if(emul == 2)
678 emul_type= ELTORITO_FLOPPY_EMUL;
679
680 if (!is_interval) {
681 ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1);
682 if(ret <= 0) {
683 sprintf(xorriso->info_text,
684 "Cannot find in ISO image: -boot_image ... bin_path=");
685 Text_shellsafe(bin_path, xorriso->info_text, 1);
686 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
687 {ret= 0; goto ex;}
688 }
689 }
690
691 if(xorriso->boot_count == 0) {
692 if(xorriso->boot_image_cat_path[0] == 0) {
693 strcpy(xorriso->boot_image_cat_path, bin_path);
694 cpt= strrchr(xorriso->boot_image_cat_path, '/');
695 if(cpt == NULL) {
696 strcpy(xorriso->boot_image_cat_path, "/");
697 cpt= xorriso->boot_image_cat_path + 1;
698 } else {
699 cpt++;
700 }
701 strcpy(cpt, "boot.cat");
702 }
703 ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
704 &node, 1);
705 if(ret > 0) {
706 if(!xorriso->do_overwrite) {
707 sprintf(xorriso->info_text,
708 "May not overwrite existing -boot_image ... cat_path=");
709 Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
710 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
711 {ret= 0; goto ex;}
712 }
713 ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
714 8 | (xorriso->do_overwrite == 1));
715 if(ret != 1) {
716 sprintf(xorriso->info_text,
717 "Could not remove existing -boot_image cat_path=");
718 Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
719 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
720 {ret= 0; goto ex;}
721 }
722 }
723
724 /* Discard old boot image, set new one */
725 ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
726 if(ret == 1)
727 iso_image_remove_boot_image(image);
728 ret= iso_image_set_boot_image(image, bin_path, emul_type,
729 xorriso->boot_image_cat_path, &bootimg);
730 if(ret > 0)
731 iso_image_set_boot_catalog_weight(image, 1000000000);
732 } else {
733 ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg);
734 }
735 if(ret < 0) {
736 Xorriso_process_msg_queues(xorriso,0);
737 Xorriso_report_iso_error(xorriso, "", ret,
738 "Error when attaching El-Torito boot image to ISO 9660 image",
739 0, "FAILURE", 1);
740 sprintf(xorriso->info_text,
741 "Could not attach El-Torito boot image to ISO 9660 image");
742 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
743 {ret= 0; goto ex;}
744 }
745 el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id);
746 if(load_size / 512 > 65535) {
747 sprintf(xorriso->info_text,
748 "Boot image load size exceeds 65535 blocks of 512 bytes. ");
749 if(platform_id == 0xef) {
750 strcat(xorriso->info_text,
751 "Will record 0 in El Torito to extend ESP to end-of-medium.");
752 load_size= 0;
753 } else {
754 strcat(xorriso->info_text, "Will record 65535 in El Torito.");
755 load_size= 65535 * 512;
756 }
757 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
758 }
759
760 if(xorriso->boot_img_full_size) {
761 el_torito_set_full_load(bootimg, 1);
762 } else {
763 /* The function will understand negative short as positive unsigned */
764 el_torito_set_load_size(bootimg, (short) (load_size / 512));
765 }
766
767 el_torito_set_id_string(bootimg, xorriso->boot_id_string);
768 el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit);
769 ret= Xorriso_set_isolinux_options(xorriso, image, 1);
770 if(!(flag & 1)) {
771 /* Register attachment and reset even in case of error return */
772 xorriso->boot_count++;
773 xorriso->boot_platform_id= 0;
774 xorriso->patch_isolinux_image= 0;
775 xorriso->boot_image_bin_path[0]= 0;
776 xorriso->boot_image_bin_form[0]= 0;
777 xorriso->boot_image_emul= 0;
778 xorriso->boot_emul_default= 1;
779 xorriso->boot_image_load_size= 4 * 512;
780 xorriso->boot_img_size_default= 1;
781 xorriso->boot_img_full_size= 0;
782 memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string));
783 memset(xorriso->boot_selection_crit, 0,
784 sizeof(xorriso->boot_selection_crit));
785 xorriso->boot_efi_default= 0;
786 }
787 if(ret <= 0)
788 goto ex;
789
790 ret= 1;
791 ex:;
792 if(image != NULL)
793 iso_image_unref(image);
794 return(ret);
795 }
796
797
798 int Xorriso_write_application_use(struct XorrisO *xorriso,
799 IsoImage *image, int flag)
800 {
801 int l, ret, count= 512;
802 unsigned int byte= 0;
803 char *path, data[512];
804 FILE *fp= NULL;
805
806 path= xorriso->application_use;
807 l= strlen(path);
808 if(l <= 1) {
809 memset(data, path[0], 512);
810 } else if(l == 4 && path[0] == '0' && path[1] == 'x' &&
811 isxdigit(path[2]) && isxdigit(path[3])) {
812 sscanf(path + 2, "%x", &byte);
813 memset(data, (int) byte, 512);
814 } else {
815 /* Read up to 512 bytes from file path */
816 ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0);
817 if(ret <= 0)
818 {ret= 0; goto ex;}
819 ret= fread(data, 1, 512, fp);
820 if(ret < 512) {
821 if(ferror(fp)) {
822 sprintf(xorriso->info_text,
823 "-application_use: Error while reading file ");
824 Text_shellsafe(path, xorriso->info_text, 1);
825 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
826 errno, "FAILURE", 0);
827 ret= 0; goto ex;
828 }
829 }
830 if(ret < 0)
831 count= 0;
832 else
833 count= ret;
834 }
835 iso_image_set_app_use(image, data, count);
836 ret= 1;
837 ex:
838 if(fp != NULL && fp != stdin)
839 fclose(fp);
840 return(ret);
841 }
842
843
844 int Xorriso_retry_write_session(struct XorrisO *xorriso, int flag)
845 {
846 int ret, auto_close_mem, do_close_mem;
847
848 if(xorriso->do_tao == 1) {
849 Xorriso_msgs_submit(xorriso, 0,
850 "There is no hope for a re-try with -close \"on\" as long as -write_type is \"tao\"",
851 0, "FAILURE", 0);
852 return(0);
853 }
854 Xorriso_msgs_submit(xorriso, 0, "Re-trying with -close \"on\"", 0, "NOTE", 0);
855 do_close_mem= xorriso->do_close;
856 auto_close_mem= xorriso->auto_close;
857 xorriso->do_close= 1;
858 xorriso->auto_close= 0;
859 ret= Xorriso_write_session(xorriso, 0);
860 xorriso->do_close= do_close_mem;
861 xorriso->auto_close= auto_close_mem;
862 return(ret);
863 }
864
865
866 int Xorriso_make_iso_write_opts(struct XorrisO *xorriso, IsoImage *image,
867 struct isoburn_imgen_opts *sopts, int flag)
868 {
869 int ext, i, ret, pad_by_libisofs= 0, is_bootable= 0, relax, intvl_string= 0;
870 int intvl_check= 2; /* 3 forbids "imported_iso" */
871 char *out_cs, *part_image;
872 IsoNode *root_node;
873 uint32_t padding;
874
875 relax= xorriso->relax_compliance;
876 if(image != NULL)
877 is_bootable= iso_image_get_boot_image(image, NULL, NULL, NULL);
878
879 /* xorriso->patch_isolinux_image gets reset in Xorriso_attach_boot_image()
880 So this applies only to -boot_image ... "patch" or "keep".
881 >>> Better would be to analyze and keep the relaxations of the loaded image.
882 */
883 if((xorriso->patch_isolinux_image & 1) && is_bootable == 1)
884 relax|= isoburn_igopt_allow_full_ascii;
885
886 out_cs= xorriso->out_charset;
887 if(out_cs == NULL)
888 Xorriso_get_local_charset(xorriso, &out_cs, 0);
889
890 isoburn_igopt_set_level(sopts, xorriso->iso_level);
891 ext= ((!!xorriso->do_rockridge) * isoburn_igopt_rockridge) |
892 ((!!xorriso->do_joliet) * isoburn_igopt_joliet) |
893 ((!!xorriso->do_hfsplus) * isoburn_igopt_hfsplus) |
894 ((!!xorriso->do_fat) * isoburn_igopt_fat) |
895 ((!!xorriso->do_iso1999) * isoburn_igopt_iso1999) |
896 (( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
897 (( (!(xorriso->ino_behavior & 2)) ||
898 (xorriso->do_aaip & (2 | 8 | 16 | 256)) ||
899 (xorriso->do_md5 & (2 | 4)) ||
900 xorriso->do_hfsplus
901 ) * isoburn_igopt_aaip) |
902 ((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) |
903 ((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) |
904 ((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability) |
905 ((!!xorriso->do_old_empty) * isoburn_igopt_old_empty) |
906 ((flag & 1) * isoburn_igopt_will_cancel);
907 if(xorriso->no_emul_toc & 1)
908 ext|= isoburn_igopt_no_emul_toc;
909 isoburn_igopt_set_extensions(sopts, ext);
910 isoburn_igopt_set_relaxed(sopts, relax);
911 ret = isoburn_igopt_set_rr_reloc(sopts, xorriso->rr_reloc_dir,
912 xorriso->rr_reloc_flags);
913 if(ret <= 0)
914 {ret= 0; goto ex;}
915 ret= isoburn_igopt_set_untranslated_name_len(sopts,
916 xorriso->untranslated_name_len);
917 if(ret <= 0)
918 {ret= 0; goto ex;}
919 isoburn_igopt_set_sort_files(sopts, 1);
920 isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0);
921 isoburn_igopt_set_over_ugid(sopts, 2 * !!xorriso->do_global_uid,
922 2 * !!xorriso->do_global_gid,
923 (uid_t) xorriso->global_uid,
924 (gid_t) xorriso->global_gid);
925 isoburn_igopt_set_out_charset(sopts, out_cs);
926 isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048);
927 Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8);
928 isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name,
929 xorriso->scdbackup_tag_time,
930 xorriso->scdbackup_tag_written);
931 if(xorriso->prep_partition[0]) {
932 part_image= xorriso->prep_partition;
933 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
934 if(intvl_string < 0)
935 {ret= 0; goto ex;}
936 ret= isoburn_igopt_set_prep_partition(sopts, part_image, intvl_string);
937 if(ret <= 0)
938 {ret= 0; goto ex;}
939 }
940 if(xorriso->efi_boot_partition[0]) {
941 part_image= xorriso->efi_boot_partition;
942 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
943 if(intvl_string < 0)
944 {ret= 0; goto ex;}
945 ret= isoburn_igopt_set_efi_bootp(sopts, part_image, intvl_string);
946 if(ret <= 0)
947 {ret= 0; goto ex;}
948 }
949 for(i= 0; i < Xorriso_max_appended_partitionS; i++) {
950 if(xorriso->appended_partitions[i] == NULL)
951 continue;
952 if(xorriso->appended_partitions[i][0] == 0)
953 continue;
954 if(strcmp(xorriso->appended_partitions[i], ".") == 0)
955 part_image= "";
956 else
957 part_image= xorriso->appended_partitions[i];
958 intvl_string= Xorriso_check_intvl_string(xorriso, &part_image, intvl_check);
959 if(intvl_string < 0)
960 {ret= 0; goto ex;}
961 isoburn_igopt_set_partition_img(sopts, i + 1,
962 xorriso->appended_part_types[i], part_image);
963 isoburn_igopt_set_part_flag(sopts, i + 1, intvl_string);
964 isoburn_igopt_set_part_type_guid(sopts, i + 1,
965 xorriso->appended_part_type_guids[i],
966 xorriso->appended_part_gpt_flags[i] & 1);
967 }
968 isoburn_igopt_set_appended_as_gpt(sopts, xorriso->appended_as_gpt);
969 isoburn_igopt_set_appended_as_apm(sopts, xorriso->appended_as_apm);
970 isoburn_igopt_set_part_like_isohybrid(sopts, xorriso->part_like_isohybrid);
971 isoburn_igopt_set_iso_mbr_part_type(sopts, xorriso->iso_mbr_part_type);
972 isoburn_igopt_set_iso_type_guid(sopts, xorriso->iso_gpt_type_guid,
973 xorriso->iso_mbr_part_flag & 1);
974 isoburn_igopt_set_gpt_guid(sopts, xorriso->gpt_guid, xorriso->gpt_guid_mode);
975 isoburn_igopt_set_disc_label(sopts, xorriso->ascii_disc_label);
976 isoburn_igopt_set_hfsp_serial_number(sopts, xorriso->hfsp_serial_number);
977 isoburn_igopt_set_hfsp_block_size(sopts, xorriso->hfsp_block_size,
978 xorriso->apm_block_size);
979 isoburn_igopt_set_pvd_times(sopts,
980 xorriso->vol_creation_time, xorriso->vol_modification_time,
981 xorriso->vol_expiration_time, xorriso->vol_effective_time,
982 xorriso->vol_uuid);
983
984 #ifdef Xorriso_with_libjtE
985 if(xorriso->libjte_handle && (xorriso->libjte_params_given & (4 | 8))) {
986
987 /* >>> Check whether the mandatory parameters are set */;
988
989 ret= libjte_set_outfile(xorriso->libjte_handle, xorriso->outdev);
990 Xorriso_process_msg_queues(xorriso, 0);
991 if(ret <= 0)
992 goto ex;
993 isoburn_igopt_attach_jte(sopts, xorriso->libjte_handle);
994 pad_by_libisofs= 1;
995 }
996 #endif /* Xorriso_with_libjtE */
997
998 if(xorriso->do_padding_by_libisofs || pad_by_libisofs) {
999 /* Padding to be done by libisofs, not by libburn.
1000 */
1001 padding= xorriso->padding / 2048;
1002 if((uint32_t) xorriso->padding > padding * 2048)
1003 padding++;
1004 /*
1005 fprintf(stderr, "XORRISO_DEBUG: isoburn_igopt_set_tail_blocks(%d)\n",
1006 (int) padding);
1007 */
1008 isoburn_igopt_set_tail_blocks(sopts, padding);
1009 }
1010
1011 /* Make final abort check before starting expensive activities */
1012 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1013 if(ret<0)
1014 {ret= 0; goto ex;}
1015
1016 if(xorriso->zisofs_by_magic && image != NULL) {
1017 sprintf(xorriso->info_text,
1018 "Checking disk file content for zisofs compression headers.");
1019 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1020 root_node= (IsoNode *) iso_image_get_root(image);
1021 ret= iso_node_zf_by_magic(root_node,
1022 (xorriso->out_drive_handle == xorriso->in_drive_handle) |
1023 2 | 16 | (xorriso->zisofs_by_magic << 8));
1024 if(ret<0) {
1025 Xorriso_report_iso_error(xorriso, "", ret,
1026 "Error when examining file content for zisofs headers",
1027 0, "FAILURE", 1);
1028 }
1029 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1030 if(ret<0)
1031 {ret= 0; goto ex;}
1032 sprintf(xorriso->info_text,
1033 "Check for zisofs compression headers done.");
1034 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1035 }
1036
1037 ret = isoburn_igopt_set_write_type(sopts, xorriso->do_tao);
1038 if(ret <= 0)
1039 goto ex;
1040 ret = isoburn_igopt_set_stdio_endsync(sopts, xorriso->stdio_sync >= 0);
1041 if(ret <= 0)
1042 goto ex;
1043
1044 ret= 1;
1045 ex:;
1046 return(ret);
1047 }
1048
1049
1050 int Xorriso_set_all_file_dates(struct XorrisO *xorriso, int flag)
1051 {
1052 int idx, ret, was_failure= 0;
1053 char *hargv[4];
1054
1055 if(xorriso->all_file_dates[0] == 0)
1056 return(2);
1057 if(strcmp(xorriso->all_file_dates, "set_to_mtime") == 0) {
1058 hargv[0]= "/";
1059 hargv[1]= "-exec";
1060 hargv[2]= "set_to_mtime";
1061 hargv[3]= "--";
1062 idx= 0;
1063 ret= Xorriso_option_find(xorriso, 4, hargv, &idx, 0);
1064 if(ret <= 0)
1065 was_failure= 1;
1066 } else {
1067 hargv[0]= "/";
1068 idx= 0;
1069 ret= Xorriso_option_alter_date(xorriso, "b", xorriso->all_file_dates,
1070 1, hargv, &idx, 1);
1071 if(ret <= 0)
1072 was_failure= 1;
1073 idx= 0;
1074 ret= Xorriso_option_alter_date(xorriso, "c", xorriso->all_file_dates,
1075 1, hargv, &idx, 1);
1076 if(ret <= 0)
1077 was_failure= 1;
1078 }
1079 Xorriso_relax_compliance(xorriso, "always_gmt", 0);
1080 return(!was_failure);
1081 }
1082
1083
1084 /* @param flag bit0= do not write but only prepare and return size in sectors
1085 @return <=0 error , 1= success
1086 2= failure with DVD-RW, please call Xorriso_retry_write_session()
1087 */
1088 int Xorriso_write_session(struct XorrisO *xorriso, int flag)
1089 {
1090 int ret, i, pacifier_speed= 0, data_lba, is_bootable= 0;
1091 int freshly_bootable= 0, hide_attr, signal_mode, role, is_bdr_pow= 0;
1092 char *xorriso_id= NULL, *img_id, *sfe= NULL, *out_cs;
1093 struct isoburn_imgen_opts *sopts= NULL;
1094 struct burn_drive_info *dinfo, *source_dinfo;
1095 struct burn_drive *drive, *source_drive;
1096 struct burn_disc *disc= NULL;
1097 struct burn_write_opts *burn_options= NULL;
1098 off_t readcounter= 0,writecounter= 0;
1099 int num_sessions= 0, num_tracks= 0;
1100 struct burn_session **sessions;
1101 struct burn_track **tracks;
1102 enum burn_disc_status s;
1103 IsoImage *image= NULL;
1104 int profile_number;
1105 char *profile_name= NULL, *reasons= NULL;
1106 IsoBoot *bootcat_node;
1107
1108 Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
1109 Xorriso_alloc_meM(xorriso_id, char, 256);
1110 Xorriso_alloc_meM(profile_name, char, 80);
1111 Xorriso_alloc_meM(reasons, char, BURN_REASONS_LEN);
1112
1113 ret= Xorriso_finish_hl_update(xorriso, 0);
1114 if(ret <= 0)
1115 goto ex;
1116
1117 ret= Xorriso_set_all_file_dates(xorriso, 1);
1118 if(ret <= 0)
1119 goto ex;
1120
1121 out_cs= xorriso->out_charset;
1122 if(out_cs == NULL)
1123 Xorriso_get_local_charset(xorriso, &out_cs, 0);
1124
1125 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1126 "on attempt to write", 2);
1127 if(ret<=0)
1128 goto ex;
1129 if(!(flag & 1)) {
1130 ret= Xorriso_auto_format(xorriso, 0);
1131 if(ret <=0 )
1132 {ret= 0; goto ex;}
1133 }
1134
1135 is_bdr_pow= burn_drive_get_bd_r_pow(drive);
1136 if(is_bdr_pow) {
1137 sprintf(xorriso->info_text,
1138 "May not write to Pseudo Overwrite formatted BD-R medium");
1139 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1140 {ret= 0; goto ex;}
1141 }
1142
1143 s= isoburn_disc_get_status(drive);
1144 if (xorriso->do_hfsplus && (
1145 (xorriso->grow_blindly_msc2 >= 0 &&
1146 xorriso->out_drive_handle != xorriso->in_drive_handle)
1147 ||
1148 (xorriso->out_drive_handle == xorriso->in_drive_handle &&
1149 s != BURN_DISC_BLANK)
1150 )) {
1151 sprintf(xorriso->info_text,
1152 "May not grow ISO image while -hfsplus is enabled");
1153 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1154 {ret= 0; goto ex;}
1155 }
1156 if(xorriso->out_drive_handle == xorriso->in_drive_handle) {
1157 if(abs(xorriso->displacement_sign) == 1 && xorriso->displacement != 0 &&
1158 s != BURN_DISC_BLANK) {
1159 sprintf(xorriso->info_text,
1160 "May not grow ISO image while -displacement is non-zero");
1161 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1162 {ret= 0; goto ex;}
1163 }
1164 source_drive= drive;
1165 } else {
1166 if(xorriso->in_drive_handle == NULL) {
1167 source_drive= drive;
1168 } else {
1169 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
1170 "on attempt to get source for write", 0);
1171 if(ret<=0)
1172 goto ex;
1173 }
1174 if(s!=BURN_DISC_BLANK) {
1175 s= burn_disc_get_status(drive);
1176 if(s!=BURN_DISC_BLANK)
1177 sprintf(xorriso->info_text,
1178 "-indev differs from -outdev and -outdev media is not blank");
1179 else
1180 sprintf(xorriso->info_text,
1181 "-indev differs from -outdev and -outdev media holds non-zero data");
1182 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1183 {ret= 0; goto ex;}
1184 }
1185 }
1186 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
1187 if(ret == 2)
1188 pacifier_speed= 1;
1189 else if(ret == 3)
1190 pacifier_speed= 2;
1191
1192 ret= Xorriso_check_multi(xorriso, drive, 0);
1193 if(ret<=0)
1194 goto ex;
1195
1196 ret= isoburn_igopt_new(&sopts, 0);
1197 if(ret<=0) {
1198 Xorriso_process_msg_queues(xorriso, 0);
1199 goto ex;
1200 }
1201
1202 xorriso->alignment= 0;
1203 image= isoburn_get_attached_image(source_drive);
1204 if(image != NULL) {
1205 iso_image_set_application_id(image, xorriso->application_id);
1206 iso_image_set_publisher_id(image, xorriso->publisher);
1207 iso_image_set_system_id(image, xorriso->system_id);
1208 iso_image_set_volset_id(image, xorriso->volset_id);
1209 iso_image_set_copyright_file_id(image, xorriso->copyright_file);
1210 iso_image_set_biblio_file_id(image, xorriso->biblio_file);
1211 iso_image_set_abstract_file_id(image, xorriso->abstract_file);
1212 Xorriso_write_application_use(xorriso, image, 0);
1213 Xorriso_process_msg_queues(xorriso,0);
1214 }
1215
1216 if((xorriso->do_aaip & 256) && out_cs != NULL) {
1217 static char *names = "isofs.cs";
1218 size_t value_lengths[1];
1219
1220 value_lengths[0]= strlen(out_cs);
1221 ret= Xorriso_setfattr(xorriso, NULL, "/",
1222 (size_t) 1, &names, value_lengths, &out_cs, 2 | 8);
1223 if(ret<=0)
1224 goto ex;
1225 }
1226 if(iso_image_was_blind_attrs(image, 0))
1227 Xorriso_msgs_submit(xorriso, 0,
1228 "Some file xattr namespace could not be explored",
1229 0, "WARNING", 0);
1230
1231 if(image!=NULL && 12+strlen(Xorriso_timestamP)<80) {
1232 strcpy(xorriso_id, xorriso->preparer_id);
1233 img_id= (char *) iso_image_get_data_preparer_id(image);
1234 if(img_id!=NULL) {
1235 for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--);
1236 if(i>0) {
1237 sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'",
1238 img_id);
1239 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
1240 }
1241 }
1242 iso_image_set_data_preparer_id(image, xorriso_id);
1243 }
1244 ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0);
1245 if(ret <= 0)
1246 goto ex;
1247
1248 /* Activate, adjust or discard boot image */
1249 if(image!=NULL) {
1250 if(xorriso->boot_image_bin_path[0]) {
1251 ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0);
1252 if(ret <= 0)
1253 goto ex;
1254 freshly_bootable= 1;
1255 }
1256 is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node);
1257 }
1258 if(image!=NULL && !(flag&1)) {
1259 if(xorriso->boot_count > 0 || freshly_bootable) {
1260 /* Eventually rename boot catalog node to changed boot_image_cat_path */
1261 if(is_bootable > 0) {
1262 ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0);
1263 if(ret > 0) {
1264 if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) {
1265 ret= Xorriso_rename(xorriso, NULL, sfe,
1266 xorriso->boot_image_cat_path, 1);
1267 if(ret <= 0)
1268 goto ex;
1269 }
1270 }
1271 }
1272 hide_attr= !!(xorriso->boot_image_cat_hidden);
1273 if(xorriso->boot_image_cat_hidden & 1)
1274 hide_attr|= LIBISO_HIDE_ON_RR;
1275 if(xorriso->boot_image_cat_hidden & 2)
1276 hide_attr|= LIBISO_HIDE_ON_JOLIET;
1277 if(xorriso->boot_image_cat_hidden & 4)
1278 hide_attr|= LIBISO_HIDE_ON_HFSPLUS;
1279 iso_image_set_boot_catalog_hidden(image, hide_attr);
1280 } else if(xorriso->patch_isolinux_image & 1) {
1281 if(is_bootable == 1) {
1282 /* will imply isoburn_igopt_allow_full_ascii */
1283 sprintf(xorriso->info_text, "Patching boot info table");
1284 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1285
1286 ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
1287 sfe, 1);
1288 if(ret < 0)
1289 goto ex;
1290 if(ret == 0) {
1291 sprintf(xorriso->info_text,
1292 "Cannot patch boot image: no file found for its LBA.");
1293 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1294 sprintf(xorriso->info_text,
1295 "Probably the loaded boot image file was deleted in this session.");
1296 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1297 sprintf(xorriso->info_text,
1298 "Use -boot_image \"any\" \"discard\" or set new boot image");
1299 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
1300 goto ex;
1301 }
1302 ret= Xorriso_set_isolinux_options(xorriso, image, 0);
1303 if(ret <= 0)
1304 goto ex;
1305 } else if(!freshly_bootable) {
1306 sprintf(xorriso->info_text,
1307 "Could not find any boot image for -boot_image patching");
1308 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1309 }
1310 } else if(xorriso->keep_boot_image && is_bootable == 1) {
1311 /* will imply isoburn_igopt_allow_full_ascii */
1312 sprintf(xorriso->info_text, "Keeping boot image unchanged");
1313 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1314 } else if(is_bootable == 1) {
1315 iso_image_remove_boot_image(image);
1316 sprintf(xorriso->info_text, "Discarded boot image from old session");
1317 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1318 }
1319 /* hardcoded and regardless whether a catalog will get written */
1320 iso_image_set_boot_catalog_weight(image, 1000000000);
1321 }
1322
1323 if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) {
1324 /* Overwrite isofs.st of root node by xorriso->isofs_st_out */
1325 char *name= "isofs.st";
1326 char timestamp[16], *value= timestamp;
1327 size_t value_length;
1328
1329 sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out);
1330 value_length= strlen(timestamp);
1331 Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name,
1332 &value_length, &value, 2 | 8);
1333 }
1334
1335 ret= Xorriso_make_iso_write_opts(xorriso, image, sopts, flag & 1);
1336 if(ret <= 0)
1337 goto ex;
1338
1339 /* >>> omit iso_image_update_sizes if the image was filled up very quickly */;
1340
1341 ret= iso_image_update_sizes(image);
1342 if(ret < 0) {
1343 Xorriso_process_msg_queues(xorriso, 0);
1344 if(ret<0) {
1345 Xorriso_report_iso_error(xorriso, "", ret,
1346 "Error when updating file sizes",
1347 0, "FAILURE", 1);
1348 }
1349 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
1350 if(ret<0)
1351 {ret= 0; goto ex;}
1352 }
1353
1354 Xorriso_set_abort_severity(xorriso, 1);
1355 if (xorriso->grow_blindly_msc2 >= 0 &&
1356 xorriso->out_drive_handle != xorriso->in_drive_handle) {
1357 ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive,
1358 xorriso->grow_blindly_msc2);
1359 if(ret>0) {
1360 /* Allow the consumer of output to access the input drive */
1361 source_drive= NULL;
1362 ret= Xorriso_give_up_drive(xorriso, 1|8);
1363 if(ret<=0)
1364 goto ex;
1365 }
1366 } else if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
1367 xorriso->in_drive_handle == NULL) {
1368 ret= isoburn_prepare_disc(source_drive, &disc, sopts);
1369 } else {
1370 ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
1371 }
1372 if(ret <= 0) {
1373 Xorriso_process_msg_queues(xorriso,0);
1374 sprintf(xorriso->info_text,"Failed to prepare session write run");
1375 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1376 {ret= 0; goto ex;}
1377 }
1378
1379 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
1380 if(ret<=0)
1381 goto cancel_iso;
1382 isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba));
1383 if(xorriso->do_stream_recording == 2) {
1384 ret= isoburn_igopt_get_data_start(sopts, &data_lba);
1385 if(ret > 0 && data_lba >= 16)
1386 burn_write_opts_set_stream_recording(burn_options, data_lba);
1387 }
1388
1389 ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1);
1390 if(ret<=0 || (flag&1)) {
1391 Xorriso_process_msg_queues(xorriso,0);
1392 if(flag&1) /* set queue severity to FAILURE */
1393 Xorriso_set_image_severities(xorriso, 2);
1394 if(flag&1) /* reset queue severity */
1395 Xorriso_set_image_severities(xorriso, 0);
1396 goto cancel_iso;
1397 }
1398
1399 ret= Xorriso_may_burn(xorriso, 0);
1400 if(ret <= 0)
1401 goto cancel_iso;
1402
1403 role= burn_drive_get_drive_role(drive);
1404
1405 /* Important: do not return until burn_is_aborting() was checked */
1406
1407 signal_mode= 1;
1408 if(role == 1)
1409 signal_mode|= 2;
1410 Xorriso_set_signal_handling(xorriso, signal_mode);
1411
1412 /* De-activate eventual target file truncation in dummy mode */
1413 ret= isoburn_set_truncate(drive, (!xorriso->do_dummy) | 2 | 4);
1414 if(ret < 0)
1415 goto cancel_iso;
1416
1417 xorriso->run_state= 1; /* Indicate that burning has started */
1418 isoburn_disc_write(burn_options, disc);
1419 burn_write_opts_free(burn_options);
1420 burn_options= NULL;
1421
1422 ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4);
1423 if(burn_is_aborting(0))
1424 Xorriso_abort(xorriso, 0); /* Never comes back */
1425 Xorriso_set_signal_handling(xorriso, 0);
1426 if(ret<=0)
1427 goto ex;
1428 if(!isoburn_drive_wrote_well(drive)) {
1429 isoburn_cancel_prepared_write(source_drive, drive, 0);
1430 Xorriso_process_msg_queues(xorriso,0);
1431 if(xorriso->auto_close && xorriso->do_close == 0) {
1432 if(burn_drive_was_feat21_failure(drive)) {
1433 sprintf(xorriso->info_text,
1434 "libburn indicates failure with writing DVD-RW to appendable state.");
1435 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1436 /* Urge caller to call Xorriso_retry_write_session() */
1437 ret= 2; goto ex;
1438 }
1439 }
1440 sprintf(xorriso->info_text,
1441 "libburn indicates failure with writing.");
1442 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1443 ret= 0; goto ex;
1444 }
1445 Xorriso_process_msg_queues(xorriso,0);
1446
1447 sessions= burn_disc_get_sessions(disc, &num_sessions);
1448 if(num_sessions>0) {
1449 tracks= burn_session_get_tracks(sessions[0], &num_tracks);
1450 if(tracks!=NULL && num_tracks>0) {
1451 burn_track_get_counters(tracks[0],&readcounter,&writecounter);
1452 xorriso->session_blocks= (int) (writecounter/ (off_t) 2048);
1453 sprintf(xorriso->info_text,
1454 "ISO image produced: %d sectors\nWritten to medium : %d sectors at LBA %d\n",
1455 (int) (readcounter/ (off_t) 2048),
1456 xorriso->session_blocks, xorriso->session_lba);
1457 Xorriso_info(xorriso, 0);
1458 }
1459 }
1460 ret= isoburn_activate_session(drive);
1461 Xorriso_process_msg_queues(xorriso,0);
1462 if(ret<=0) {
1463 sprintf(xorriso->info_text,
1464 "Could not write new set of volume descriptors");
1465 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1466 goto ex;
1467 }
1468 /* Done early to free any reference to the libisofs resources via disc */
1469 if(disc!=NULL)
1470 burn_disc_free(disc);
1471 disc= NULL;
1472 /* To wait for the end of the libisofs threads and their messages. */
1473 isoburn_sync_after_write(source_drive, drive, 0);
1474 Xorriso_process_msg_queues(xorriso,0);
1475
1476 sprintf(xorriso->info_text, "Writing to %s completed successfully.\n\n",
1477 Text_shellsafe(xorriso->outdev,sfe,0));
1478 Xorriso_info(xorriso, 0);
1479 ret= 1;
1480 ex:;
1481 xorriso->run_state= 0; /* Indicate that burning has ended */
1482 Xorriso_set_abort_severity(xorriso, 0);
1483
1484 if(ret<=0) {
1485
1486 /* >>> ??? revive discarded boot image */;
1487
1488 /* suppress automatic -commit at program end */
1489 xorriso->volset_change_pending= 3;
1490 }
1491 if(disc!=NULL)
1492 burn_disc_free(disc);
1493 if(image != NULL)
1494 iso_image_unref(image);
1495 isoburn_igopt_destroy(&sopts, 0);
1496 if(burn_options != NULL)
1497 burn_write_opts_free(burn_options);
1498 Xorriso_process_msg_queues(xorriso,0);
1499 Xorriso_append_scdbackup_record(xorriso, 0);
1500 Xorriso_free_meM(sfe);
1501 Xorriso_free_meM(xorriso_id);
1502 Xorriso_free_meM(profile_name);
1503 Xorriso_free_meM(reasons);
1504 return(ret);
1505
1506 cancel_iso:;
1507 isoburn_cancel_prepared_write(source_drive, drive, 0);
1508 goto ex;
1509 }
1510
1511
1512 int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag)
1513 {
1514 int ret;
1515 struct burn_drive_info *dinfo;
1516 struct burn_drive *drive;
1517
1518 if(burn_is_aborting(0))
1519 return(2);
1520 if(xorriso->run_state!=1)
1521 return(0);
1522 ret= Xorriso_eval_problem_status(xorriso, 1, 1);
1523 if(ret>=0)
1524 return(0);
1525 sprintf(xorriso->info_text,
1526 "-abort_on '%s' encountered '%s' during image writing",
1527 xorriso->abort_on_text, xorriso->problem_status_text);
1528 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
1529 xorriso->problem_status_text, 0);
1530
1531 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1532 "on attempt to abort burn run", 2);
1533 if(ret<=0)
1534 return(0);
1535
1536 burn_drive_cancel(drive);
1537 sprintf(xorriso->info_text,
1538 "libburn has now been urged to cancel its operation");
1539 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1540 return(1);
1541 }
1542
1543
1544 /* This loop watches burn runs until they end.
1545 It issues pacifying update messages to the user.
1546 @param flag bit0-3 = emulation mode
1547 0= xorriso
1548 1= mkisofs
1549 2= cdrecord
1550 bit4= report speed in CD units
1551 bit5= report speed in BD units
1552 */
1553 int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
1554 int flag)
1555 {
1556 int ret, size, free_bytes, i, aborting= 0, emul, buffer_fill= 50, last_sector;
1557 int iso_wait_counter= 0, iso_cancel_limit= 5;
1558 struct burn_progress progress;
1559 char *status_text, date_text[80], *speed_unit, mem_text[8];
1560 enum burn_drive_status drive_status;
1561 double start_time, current_time, last_time, base_time= 0.0, base_count= 0.0;
1562 double next_base_time= 0.0, next_base_count= 0.0, first_base_time= 0.0;
1563 double first_base_count= 0.0, norm= 0.0, now_time, fract_offset= 0.0;
1564 double measured_speed, speed_factor= 1385000, quot, speed_min_time;
1565 double tdiff, now_fract;
1566 time_t time_prediction;
1567 IsoImage *image= NULL;
1568
1569 image= isoburn_get_attached_image(drive);
1570
1571 start_time= Sfile_microtime(0);
1572 while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
1573 usleep(100002);
1574
1575 emul= flag&15;
1576 if(emul==0)
1577 emul= xorriso->pacifier_style;
1578 fract_offset= 1.0 / 3.0 * (double) emul - ((int) (1.0 / 3.0 * (double) emul));
1579 speed_min_time= 0.2 * xorriso->pacifier_interval;
1580 speed_unit= "D";
1581 if(flag&16) {
1582 speed_factor= 150.0*1024;
1583 speed_unit= "C";
1584 } else if(flag & 32) {
1585 speed_factor= 4495625;
1586 speed_unit= "B";
1587 }
1588 progress.sector= 0;
1589 current_time= Sfile_microtime(0);
1590 measured_speed= 0.0;
1591 while(1) {
1592 last_time= current_time;
1593 last_sector= progress.sector;
1594 drive_status= burn_drive_get_status(drive, &progress);
1595
1596 if(drive_status == BURN_DRIVE_IDLE) {
1597 /* To avoid a race condition between burn_source and libisofs
1598 writer thread: Wait for ISO generator thread to have finished.
1599 After some seconds kick it by isoburn_cancel_prepared_write()
1600 which waits for the write thread to end.
1601 */
1602 if(image == NULL)
1603 break;
1604 if(!iso_image_generator_is_running(image))
1605 break;
1606 iso_wait_counter++;
1607 if(iso_wait_counter > iso_cancel_limit) {
1608 isoburn_cancel_prepared_write(drive, NULL, 0);
1609 break;
1610 }
1611 }
1612 current_time= Sfile_microtime(0);
1613 if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) {
1614 if(current_time-last_time > speed_min_time)
1615 measured_speed= (progress.sector - last_sector) * 2048.0 /
1616 (current_time - last_time);
1617 buffer_fill= 50;
1618 if(progress.buffer_capacity>0)
1619 buffer_fill= (double) (progress.buffer_capacity
1620 - progress.buffer_available) * 100.0
1621 / (double) progress.buffer_capacity;
1622 if(emul==2) {
1623 if(progress.sector<=progress.sectors)
1624 sprintf(xorriso->info_text, "%4d of %4d MB written",
1625 progress.sector / 512, progress.sectors / 512);
1626 else
1627 sprintf(xorriso->info_text, "%4d MB written",
1628 progress.sector / 512);
1629
1630 if(xorriso->pacifier_fifo!=NULL)
1631 ret= burn_fifo_inquire_status(xorriso->pacifier_fifo,
1632 &size, &free_bytes, &status_text);
1633 else
1634 ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
1635 if(ret>0 )
1636 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1637 " (fifo %2d%%)",
1638 (int) (100.0-100.0*((double) free_bytes)/(double) size));
1639
1640 sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]",
1641 buffer_fill);
1642
1643 if(current_time-last_time > speed_min_time)
1644 sprintf(xorriso->info_text+strlen(xorriso->info_text), " %4.1fx.",
1645 measured_speed/speed_factor);
1646
1647 } else if(emul == 1 &&
1648 progress.sectors > 0 && progress.sector <= progress.sectors) {
1649 /* "37.87% done, estimate finish Tue Jul 15 18:55:07 2008" */
1650
1651 quot= ((double) progress.sector) / ((double) progress.sectors);
1652 sprintf(xorriso->info_text, " %2.2f%% done", quot*100.0);
1653 if(current_time - start_time >= 2 && quot > 0.0 &&
1654 (quot >= 0.02 || progress.sector >= 5*1024)) {
1655 if(base_time == 0.0 && progress.sector >= 16*1024) {
1656 first_base_time= base_time= next_base_time= current_time;
1657 first_base_count= next_base_count= progress.sector;
1658 } else if(next_base_time > 0 && current_time - next_base_time >= 10) {
1659 base_time= next_base_time;
1660 base_count= next_base_count;
1661 next_base_time= current_time;
1662 next_base_count= progress.sector;
1663 }
1664 if(first_base_time > 0 &&
1665 current_time - first_base_time >= 10 &&
1666 progress.sectors > first_base_count &&
1667 progress.sector > first_base_count) {
1668 norm= (1.0 - quot);
1669 if(norm < 0.0001)
1670 norm= 0.0001;
1671 quot= ((double) progress.sector - first_base_count)
1672 / ((double) progress.sectors - first_base_count);
1673 time_prediction= norm * (1.0 - quot) / quot
1674 * (current_time - first_base_time);
1675 } else {
1676 time_prediction= (1.0 - quot) / quot * (current_time - start_time);
1677 norm= 1.0;
1678 }
1679 if(base_time > 0 &&
1680 current_time - base_time >= 10 && progress.sectors > base_count) {
1681 quot= ((double) progress.sector - base_count)
1682 / ((double) progress.sectors - base_count);
1683 time_prediction+= (1.0 - quot) / quot * (current_time - base_time);
1684 norm+= 1.0;
1685 }
1686 time_prediction/= norm;
1687 if(time_prediction < 30*86400 && time_prediction > 0) {
1688 time_prediction+= current_time + 1;
1689 Ftimetxt(time_prediction, date_text, 4);
1690 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1691 ", estimate finish %s", date_text);
1692 }
1693 }
1694 } else {
1695 if(progress.sector<=progress.sectors) {
1696 if(progress.sectors <= 0)
1697 strcpy(mem_text, " 99.9");
1698 else
1699 sprintf(mem_text, "%5.1f",
1700 100.0 * ((double) progress.sector) / ((double) progress.sectors));
1701 mem_text[5]= 0;
1702 sprintf(xorriso->info_text, "Writing: %10ds %s%% ",
1703 progress.sector, mem_text);
1704 } else {
1705 Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1);
1706 sprintf(xorriso->info_text, "Writing: %10ds %s ",
1707 progress.sector, mem_text);
1708 }
1709 ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
1710 if(ret>0 )
1711 sprintf(xorriso->info_text+strlen(xorriso->info_text),
1712 " fifo %3d%% buf %3d%%",
1713 (int) (100.0-100.0*((double) free_bytes)/(double) size),
1714 buffer_fill);
1715 if(current_time - last_time > speed_min_time)
1716 sprintf(xorriso->info_text+strlen(xorriso->info_text), " %5.1fx%s ",
1717 measured_speed/speed_factor, speed_unit);
1718 }
1719 } else if(drive_status == BURN_DRIVE_CLOSING_SESSION ||
1720 drive_status == BURN_DRIVE_CLOSING_TRACK)
1721 sprintf(xorriso->info_text,
1722 "Closing track/session. Working since %.f seconds",
1723 current_time-start_time);
1724 else if(drive_status == BURN_DRIVE_FORMATTING)
1725 sprintf(xorriso->info_text, "Formatting. Working since %.f seconds",
1726 current_time-start_time);
1727 else
1728 sprintf(xorriso->info_text,
1729 "Thank you for being patient. Working since %.f seconds.",
1730 current_time-start_time);
1731 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1732
1733 for(i= 0; i < 20; i++) { /* 10 usleeps more than supposed to be needed */
1734 Xorriso_process_msg_queues(xorriso, 0);
1735 if(aborting<=0)
1736 aborting= Xorriso_check_burn_abort(xorriso, 0);
1737 usleep((unsigned long) (100000.0 * xorriso->pacifier_interval));
1738 now_time= Sfile_microtime(0);
1739 tdiff= ((off_t)(now_time / xorriso->pacifier_interval)) -
1740 (off_t)(current_time / xorriso->pacifier_interval);
1741 now_fract= (now_time / xorriso->pacifier_interval -
1742 (off_t)(now_time / xorriso->pacifier_interval));
1743 if(tdiff < 1.0)
1744 continue;
1745 if(fract_offset <= 0.0) /* "xorriso" pacifier shall not wait for slot */
1746 break;
1747 if((now_fract >= fract_offset && now_fract < fract_offset + 0.3) ||
1748 tdiff >= 2.0)
1749 break;
1750 }
1751 }
1752 iso_image_unref(image);
1753 return(1);
1754 }
1755
1756
1757 /* @param flag bit0= fast
1758 bit1= deformat
1759 bit2= do not re-aquire drive
1760 @return 0=failure, did not touch medium , -1=failure, altered medium
1761 1=success, altered medium , 2=success, did not touch medium
1762 */
1763 int Xorriso_blank_media(struct XorrisO *xorriso, int flag)
1764 {
1765 int ret, do_deformat= 0, signal_mode, using_immed;
1766 struct burn_drive_info *dinfo;
1767 struct burn_drive *drive;
1768 enum burn_disc_status disc_state;
1769 struct burn_progress p;
1770 double percent = 1.0;
1771 int current_profile;
1772 char current_profile_name[80];
1773 time_t start_time;
1774 char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"};
1775 char progress_text[40];
1776
1777 ret= Xorriso_may_burn(xorriso, 0);
1778 if(ret <= 0)
1779 return(0);
1780 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1781 "on attempt to -blank", 2);
1782 if(ret<=0)
1783 return(0);
1784
1785 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
1786
1787 disc_state = isoburn_disc_get_status(drive);
1788 if(current_profile == 0x13) { /* overwritable DVD-RW */
1789 /* Depending on flag bit1 formatted DVD-RW will get blanked to sequential
1790 state or pseudo blanked by invalidating an eventual ISO image. */
1791 if(flag&2)
1792 do_deformat= 1;
1793 } else if(current_profile == 0x14) { /* sequential DVD-RW */
1794 if((flag&1) && !(flag&2)) {
1795 sprintf(xorriso->info_text,
1796 "-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'.");
1797 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1798 sprintf(xorriso->info_text,
1799 "Mode 'deformat_quickest' produces single-session-only media.");
1800 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
1801 flag&= ~1;
1802 }
1803 }
1804 if(disc_state == BURN_DISC_BLANK) {
1805 if(!do_deformat) {
1806 sprintf(xorriso->info_text,
1807 "Blank medium detected. Will leave it untouched");
1808 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1809 return 2;
1810 }
1811 } else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) {
1812 ;
1813 } else if(disc_state == BURN_DISC_EMPTY) {
1814 sprintf(xorriso->info_text,"No media detected in drive");
1815 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1816 return 0;
1817 } else {
1818 sprintf(xorriso->info_text, "Unsuitable drive and media state");
1819 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1820 return 0;
1821 }
1822 if(!isoburn_disc_erasable(drive)) {
1823 sprintf(xorriso->info_text, "Media is not of erasable type");
1824 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1825 return 0;
1826 }
1827 if(xorriso->do_dummy) {
1828 sprintf(xorriso->info_text,
1829 "-dummy mode prevents blanking of medium in mode '%s'.",
1830 mode_names[flag&3]);
1831 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1832 return(1);
1833 }
1834 using_immed= burn_drive_get_immed(drive);
1835 sprintf(xorriso->info_text, "Beginning to blank medium in mode '%s'.\n",
1836 mode_names[flag&3]);
1837 Xorriso_info(xorriso,0);
1838
1839 /* Important: do not return until burn_is_aborting() was checked */
1840 signal_mode= 1;
1841 ret= burn_drive_get_drive_role(drive);
1842 if(ret == 1)
1843 signal_mode|= 2;
1844 Xorriso_set_signal_handling(xorriso, signal_mode);
1845
1846 if(do_deformat)
1847 burn_disc_erase(drive, (flag&1));
1848 else
1849 isoburn_disc_erase(drive, (flag&1));
1850 start_time= time(0);
1851 usleep(1000000);
1852 if(!using_immed)
1853 sprintf(progress_text, "synchronously since");
1854 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
1855 Xorriso_process_msg_queues(xorriso,0);
1856 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
1857 percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
1858 if(using_immed)
1859 sprintf(progress_text, "%.1f%% done in", percent);
1860 sprintf(xorriso->info_text, "Blanking ( %s %d seconds )",
1861 progress_text, (int) (time(0) - start_time));
1862 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
1863 usleep(1000000);
1864 }
1865 Xorriso_process_msg_queues(xorriso,0);
1866 if(burn_is_aborting(0))
1867 Xorriso_abort(xorriso, 0); /* Never comes back */
1868 Xorriso_set_signal_handling(xorriso, 0);
1869 if(burn_drive_wrote_well(drive)) {
1870 sprintf(xorriso->info_text, "Blanking done\n");
1871 Xorriso_info(xorriso,0);
1872 } else {
1873 sprintf(xorriso->info_text, "Blanking failed.");
1874 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1875 }
1876 if(!(flag & 4)) {
1877 ret= Xorriso_reaquire_outdev(xorriso,
1878 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
1879 if(ret <= 0)
1880 return(-1);
1881 }
1882 return(1);
1883 }
1884
1885
1886 /* @param flag bit0= try to achieve faster formatting
1887 bit1= use parameter size (else use default size)
1888 bit2= do not re-aquire drive
1889 bit5= try to disable Defect Management
1890 bit7= by_index mode:
1891 bit8 to bit15 contain the index of the format to use.
1892 @return 0=failure, did not touch medium , -1=failure, altered medium
1893 1=success, altered medium , 2=success, did not touch medium
1894 */
1895 int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag)
1896 {
1897 int ret, mode_flag= 0, index, status, num_formats, signal_mode, using_immed;
1898 unsigned dummy;
1899 struct burn_drive_info *dinfo;
1900 struct burn_drive *drive;
1901 struct burn_progress p;
1902 double percent = 1.0;
1903 int current_profile;
1904 char current_profile_name[80], progress_text[40];
1905 off_t size= 0;
1906 time_t start_time;
1907 enum burn_disc_status disc_state;
1908
1909 ret= Xorriso_may_burn(xorriso, 0);
1910 if(ret <= 0)
1911 return(0);
1912 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1913 "on attempt to -format", 2);
1914 if(ret<=0)
1915 return(0);
1916
1917 if(flag & 2) {
1918 mode_flag= 0; /* format to given size */
1919 } else {
1920 mode_flag= 4; /* format to full size */
1921 }
1922 if(flag & 32)
1923 mode_flag|= 32; /* try to disable Defect Management */
1924
1925 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
1926
1927 if(flag&128) { /* by_index */
1928 index= (flag>>8) & 0xff;
1929 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
1930 if(ret<=0)
1931 num_formats= 0;
1932 if(ret<=0 || index<0 || index>=num_formats) {
1933 if(num_formats>0)
1934 sprintf(xorriso->info_text,
1935 "-format by_index_%d: format descriptors range from index 0 to %d",
1936 index, num_formats-1);
1937 else
1938 sprintf(xorriso->info_text,
1939 "-format by_index_%d: no format descriptors available", index);
1940 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1941 return(0);
1942 }
1943 mode_flag|= (flag & 0xff80);
1944 if(flag&1)
1945 mode_flag|= (1<<6);
1946
1947 } else if(current_profile == 0x12) { /* DVD+RAM */
1948 if(!(flag & 2))
1949 mode_flag= 6; /* format to default payload size */
1950 if(flag&1)
1951 mode_flag|= (1<<6);
1952
1953 } else if(current_profile == 0x13) { /* DVD-RW */
1954 if(flag&1) {
1955 sprintf(xorriso->info_text,
1956 "Detected formatted DVD-RW. Thus omitting desired fast format run.");
1957 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1958 return(2);
1959 }
1960
1961 } else if(current_profile == 0x14) { /* DVD-RW sequential */
1962 if(flag & 1) {
1963 size= 128*1024*1024;
1964 mode_flag= 1; /* format to size, then write size of zeros */
1965 } else
1966 mode_flag= 4;
1967
1968 } else if(current_profile == 0x1a) { /* DVD+RW */
1969 if(flag&1) {
1970 sprintf(xorriso->info_text,
1971 "Detected DVD+RW. Thus omitting desired fast format run.");
1972 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1973 return(2);
1974 }
1975
1976 } else if(current_profile == 0x41) { /* BD-R SRM */
1977 if(!(flag & 2))
1978 mode_flag= 6; /* format to default payload size */
1979 if(flag&1)
1980 mode_flag|= (1<<6);
1981
1982 } else if(current_profile == 0x43) { /* BD-RE */
1983 if(!(flag & (2 | 32)))
1984 mode_flag= 6; /* format to default payload size */
1985 if(flag&1)
1986 mode_flag|= (1<<6);
1987
1988 } else {
1989 sprintf(xorriso->info_text,
1990 "-format: Unsuitable media detected.");
1991 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1992 sprintf(xorriso->info_text,"Media current: %s (%4.4xh)",
1993 current_profile_name, current_profile);
1994 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1995 return(0);
1996 }
1997 if(!(flag & 1))
1998 mode_flag|= 16; /* enable re-formatting */
1999
2000 if(xorriso->do_dummy) {
2001 sprintf(xorriso->info_text, "-dummy mode prevents formatting of medium.");
2002 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2003 return(1);
2004 }
2005 using_immed= burn_drive_get_immed(drive);
2006 sprintf(xorriso->info_text, "Beginning to format medium.\n");
2007 Xorriso_info(xorriso, 0);
2008 if(flag & 2)
2009 size= in_size;
2010
2011 /* Important: do not return until burn_is_aborting() was checked */
2012 signal_mode= 1;
2013 ret= burn_drive_get_drive_role(drive);
2014 if(ret == 1)
2015 signal_mode|= 2;
2016 Xorriso_set_signal_handling(xorriso, signal_mode);
2017
2018 burn_disc_format(drive, size, mode_flag);
2019
2020 start_time= time(0);
2021 usleep(1000000);
2022 if(!using_immed)
2023 sprintf(progress_text, "synchronously since");
2024 while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
2025 Xorriso_process_msg_queues(xorriso,0);
2026 if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
2027 percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
2028 if(using_immed)
2029 sprintf(progress_text, "%.1f%% done in", percent);
2030 sprintf(xorriso->info_text, "Formatting ( %s %d seconds )",
2031 progress_text, (int) (time(0) - start_time));
2032 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2033 usleep(1000000);
2034 }
2035 Xorriso_process_msg_queues(xorriso,0);
2036 if(burn_is_aborting(0))
2037 Xorriso_abort(xorriso, 0); /* Never comes back */
2038 Xorriso_set_signal_handling(xorriso, 0);
2039
2040 if(burn_drive_wrote_well(drive)) {
2041 sprintf(xorriso->info_text, "Formatting done\n");
2042 Xorriso_info(xorriso,0);
2043 } else {
2044 sprintf(xorriso->info_text,
2045 "libburn indicates failure with formatting.");
2046 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2047 return(-1);
2048 }
2049
2050 if(!(flag & 4)) {
2051 ret= Xorriso_reaquire_outdev(xorriso,
2052 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
2053 if(ret <= 0)
2054 return(-1);
2055 }
2056 disc_state = isoburn_disc_get_status(drive);
2057 if(disc_state==BURN_DISC_FULL && !(flag&1)) {
2058 /* Blank because full format certification pattern might be non-zero */
2059 ret= Xorriso_blank_media(xorriso, 1);
2060 if(ret <= 0)
2061 return(0);
2062 }
2063 return(1);
2064 }
2065
2066
2067 /* @param flag bit2= formatting rather than blanking
2068 @return 0=failure, did not touch medium , -1=failure, altered medium
2069 1=success, altered medium , 2=success, did not touch medium
2070 */
2071 int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag)
2072 {
2073 int ret, is_formatted= -1, status, num_formats, did_work= 0;
2074 struct burn_drive_info *dinfo;
2075 struct burn_drive *drive;
2076 enum burn_disc_status disc_state;
2077 unsigned dummy;
2078 int current_profile;
2079 char current_profile_name[80];
2080 off_t size;
2081
2082 ret= Xorriso_may_burn(xorriso, 0);
2083 if(ret <= 0)
2084 return(0);
2085 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2086 "on attempt to blank or format", 2);
2087 if(ret<=0)
2088 return(0);
2089
2090 burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
2091
2092 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
2093 if(ret>0) {
2094 if(status==BURN_FORMAT_IS_FORMATTED)
2095 is_formatted= 1;
2096 else if(status == BURN_FORMAT_IS_UNFORMATTED)
2097 is_formatted= 0;
2098 }
2099 if(current_profile == 0x12 || current_profile == 0x43) { /* DVD+RAM , BD-RE */
2100 if(is_formatted<0) {
2101 sprintf(xorriso->info_text,
2102 "-blank or -format: Unclear formatting status of %s",
2103 current_profile_name);
2104 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2105 return(0);
2106 }
2107 if(!is_formatted) {
2108 ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43));
2109 if(ret <= 0)
2110 return(ret);
2111 did_work= (ret == 1);
2112 }
2113 } else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */
2114 ret= Xorriso_format_media(xorriso, (off_t) 0, 0);
2115 if(ret <= 0)
2116 return(ret);
2117 did_work= (ret == 1);
2118 } else if(current_profile == 0x41) { /* BD-R SRM */
2119 if((flag & 4) && !is_formatted) {
2120 ret= Xorriso_format_media(xorriso, (off_t) 0, 1);
2121 if(ret <= 0)
2122 return(ret);
2123 did_work= (ret == 1);
2124 }
2125 }
2126
2127 disc_state = isoburn_disc_get_status(drive);
2128 if(disc_state != BURN_DISC_BLANK && !(flag&4)) {
2129 ret= Xorriso_blank_media(xorriso, 1);
2130 return(ret);
2131 }
2132 if(did_work)
2133 return(1);
2134 sprintf(xorriso->info_text, "%s as_needed: no need for action detected",
2135 (flag&4) ? "-format" : "-blank");
2136 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2137 return(2);
2138 }
2139
2140
2141 int Xorriso_retry_burn_track(struct XorrisO *xorriso,
2142 off_t write_start_address,
2143 char *track_source, off_t tsize, int flag)
2144 {
2145 int ret, auto_close_mem, do_close_mem;
2146
2147 if(xorriso->do_tao == 1) {
2148 Xorriso_msgs_submit(xorriso, 0,
2149 "There is no hope for a re-try with -close \"on\" as long as -write_type is \"tao\"",
2150 0, "FAILURE", 0);
2151 return(0);
2152 }
2153 Xorriso_msgs_submit(xorriso, 0, "Re-trying with -close \"on\"", 0, "NOTE", 0);
2154 do_close_mem= xorriso->do_close;
2155 auto_close_mem= xorriso->auto_close;
2156 xorriso->do_close= 1;
2157 xorriso->auto_close= 0;
2158 ret= Xorriso_burn_track(xorriso, write_start_address, track_source, tsize,
2159 flag);
2160 xorriso->do_close= do_close_mem;
2161 xorriso->auto_close= auto_close_mem;
2162 return(ret);
2163 }
2164
2165
2166 /* @param write_start_address is valid if >=0
2167 @param tsize is valid if >0
2168 @param flag bit0= grow_overwriteable_iso
2169 bit1= do_isosize
2170 bit2= do_xa1 conversion
2171 @return <=0 error , 1= success
2172 2= failure with DVD-RW, please call Xorriso_retry_burn_track()
2173 */
2174 int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
2175 char *track_source, off_t tsize, int flag)
2176 {
2177 int ret, fd, profile_number, is_cd= 0, dummy, nwa= -1;
2178 int isosize= -1, do_isosize, is_bd= 0, signal_mode;
2179 struct burn_drive_info *dinfo;
2180 struct burn_drive *drive;
2181 struct burn_write_opts *burn_options= NULL;
2182 struct burn_disc *disc= NULL;
2183 struct burn_session *session= NULL;
2184 struct burn_track *track= NULL;
2185 struct stat stbuf;
2186 off_t fixed_size= 0;
2187 struct burn_source *data_src= NULL, *fifo_src= NULL;
2188 enum burn_disc_status disc_state;
2189 char *reasons= NULL, *profile_name= NULL;
2190 char *head_buffer= NULL;
2191
2192 Xorriso_alloc_meM(reasons, char, BURN_REASONS_LEN);
2193 Xorriso_alloc_meM(profile_name, char, 80);
2194 Xorriso_alloc_meM(head_buffer, char, 64 * 1024);
2195
2196 ret= Xorriso_may_burn(xorriso, 0);
2197 if(ret <= 0)
2198 {ret= 0; goto ex;}
2199 ret= Xorriso_auto_format(xorriso, 0);
2200 if(ret <=0 )
2201 {ret= 0; goto ex;}
2202
2203 do_isosize= !!(flag&2);
2204 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2205 "on attempt to burn track", 2);
2206 if(ret<=0)
2207 {ret= 0; goto ex;}
2208
2209 ret= Xorriso_check_multi(xorriso, drive, 1);
2210 if(ret<=0)
2211 goto ex;
2212 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
2213 if(ret<=0)
2214 goto ex;
2215
2216 disc= burn_disc_create();
2217 session= burn_session_create();
2218 ret= burn_disc_add_session(disc,session,BURN_POS_END);
2219 if(ret==0) {
2220 sprintf(xorriso->info_text, "Cannot add session object to disc object.");
2221 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2222 goto ex;
2223 }
2224 track= burn_track_create();
2225 if(track_source[0] == '-' && track_source[1] == 0) {
2226 fd= 0;
2227 } else {
2228 if(xorriso->fs >= 64)
2229 fd= burn_os_open_track_src(track_source, O_RDONLY, 0);
2230 else
2231 fd= open(track_source, O_RDONLY | O_BINARY);
2232 if(fd>=0)
2233 if(fstat(fd,&stbuf)!=-1)
2234 if((stbuf.st_mode&S_IFMT)==S_IFREG)
2235 fixed_size= stbuf.st_size;
2236 }
2237
2238 if(fd>=0)
2239 data_src= burn_fd_source_new(fd, -1, fixed_size);
2240 if(data_src==NULL) {
2241 sprintf(xorriso->info_text, "Could not open data source ");
2242 Text_shellsafe(track_source, xorriso->info_text, 1);
2243 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2244 ret= 0; goto ex;
2245 }
2246 if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64)
2247 xorriso->fs= 64;
2248 if(xorriso->fs > 0) {
2249 fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4),
2250 xorriso->fs, 1);
2251 if(fifo_src == NULL) {
2252 sprintf(xorriso->info_text, "Could not create fifo object of %.f MB",
2253 ((double) xorriso->fs) / 1024.0 / 1024.0);
2254 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2255 ret= 0; goto ex;
2256 }
2257 }
2258 xorriso->pacifier_fifo= fifo_src;
2259 if(burn_track_set_source(track, fifo_src == NULL ? data_src : fifo_src)
2260 != BURN_SOURCE_OK) {
2261 sprintf(xorriso->info_text,
2262 "Cannot attach source object to track object");
2263 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2264 ret= 0; goto ex;
2265 }
2266 burn_track_set_cdxa_conv(track, !!(flag & 4));
2267 burn_session_add_track(session, track, BURN_POS_END);
2268 burn_source_free(data_src);
2269
2270 if(flag&1)
2271 /* consider overwriteables with ISO as appendable */
2272 disc_state= isoburn_disc_get_status(drive);
2273 else
2274 /* handle overwriteables as always blank */
2275 disc_state= burn_disc_get_status(drive);
2276
2277 if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) {
2278 /* ok */;
2279 } else {
2280 if(disc_state == BURN_DISC_FULL) {
2281 sprintf(xorriso->info_text,
2282 "Closed media with data detected. Need blank or appendable media.");
2283 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2284 if(burn_disc_erasable(drive)) {
2285 sprintf(xorriso->info_text, "Try -blank as_needed\n");
2286 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
2287 }
2288 } else if(disc_state == BURN_DISC_EMPTY) {
2289 sprintf(xorriso->info_text, "No media detected in drive");
2290 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2291 } else {
2292 sprintf(xorriso->info_text,
2293 "Cannot recognize state of drive and media");
2294 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2295 }
2296 ret= 0; goto ex;
2297 }
2298 if(isoburn_needs_emulation(drive))
2299 burn_write_opts_set_multi(burn_options, 0);
2300
2301 if(tsize > 0) {
2302 fixed_size= tsize;
2303 burn_track_set_size(track, fixed_size);
2304 }
2305 if(do_isosize) {
2306 ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0);
2307 if(ret<=0) {
2308 Xorriso_process_msg_queues(xorriso,0);
2309 sprintf(xorriso->info_text,
2310 "Cannot obtain first 64 kB from input stream.");
2311 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2312 ret= 0; goto ex;
2313 }
2314 /* read isosize from head_buffer, not from medium */
2315 ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13));
2316 if(ret<=0) {
2317 Xorriso_process_msg_queues(xorriso,0);
2318 sprintf(xorriso->info_text,
2319 "Option -isosize given but data stream seems not to be ISO 9660");
2320 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2321 ret= 0; goto ex;
2322 }
2323 sprintf(xorriso->info_text, "Size of ISO 9660 image: %ds", isosize);
2324 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2325 fixed_size= ((off_t) (isosize)) * (off_t) 2048;
2326 burn_track_set_size(track, fixed_size);
2327 }
2328
2329 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
2330 is_cd= (ret==2);
2331 is_bd= (ret == 3);
2332
2333 if(isoburn_needs_emulation(drive)) {
2334 if(flag&1) {
2335 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
2336 Xorriso_process_msg_queues(xorriso,0);
2337 if(ret<=0) {
2338 sprintf(xorriso->info_text,
2339 "Cannot obtain next writeable address of emulated multi-session media\n");
2340 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2341 ret= 0; goto ex;
2342 }
2343 if(nwa == 32 && disc_state != BURN_DISC_APPENDABLE)
2344 nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */
2345 } else {
2346 nwa= 0;
2347 if (disc_state == BURN_DISC_APPENDABLE) {
2348 ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
2349 Xorriso_process_msg_queues(xorriso,0);
2350 if(ret<=0) {
2351 sprintf(xorriso->info_text,
2352 "Cannot obtain next writeable address of emulated appendable media\n");
2353 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2354 ret= 0; goto ex;
2355 }
2356 }
2357 }
2358 burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048);
2359 }
2360
2361 if(write_start_address>=0) {
2362 nwa= write_start_address / (off_t) 2048;
2363 if(((off_t) nwa) * (off_t) 2048 < write_start_address )
2364 nwa++;
2365 burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048);
2366 }
2367
2368 if(xorriso->do_tao) {
2369 if (xorriso->do_tao > 0)
2370 burn_write_opts_set_write_type(burn_options,
2371 BURN_WRITE_TAO, BURN_BLOCK_MODE1);
2372 else
2373 burn_write_opts_set_write_type(burn_options,
2374 BURN_WRITE_SAO, BURN_BLOCK_SAO);
2375
2376 ret = burn_precheck_write(burn_options, disc, reasons, 0);
2377 if(ret<=0) {
2378 sprintf(xorriso->info_text,
2379 "Cannot set write type %s for this medium.\n",
2380 xorriso->do_tao > 0 ? "TAO" : "SAO");
2381 sprintf(xorriso->info_text+strlen(xorriso->info_text),
2382 "Reasons given:\n%s", reasons);
2383 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2384 ret= 0; goto ex;
2385 }
2386 sprintf(xorriso->info_text, "Explicitly chosen write type: %s",
2387 xorriso->do_tao > 0 ? "TAO" : "SAO");
2388 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
2389 } else {
2390 if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) ==
2391 BURN_WRITE_NONE) {
2392 sprintf(xorriso->info_text,
2393 "Failed to find a suitable write mode with this media.\n");
2394 sprintf(xorriso->info_text+strlen(xorriso->info_text),
2395 "Reasons given:\n%s", reasons);
2396 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2397 ret= 0; goto ex;
2398 }
2399 }
2400
2401 ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2);
2402 if(ret<=0)
2403 goto ex;
2404
2405 sprintf(xorriso->info_text, "Beginning to write data track.\n");
2406 Xorriso_info(xorriso,0);
2407
2408 /* Important: do not return until burn_is_aborting() was checked */
2409 signal_mode= 1;
2410 ret= burn_drive_get_drive_role(drive);
2411 if(ret == 1)
2412 signal_mode|= 2;
2413 Xorriso_set_signal_handling(xorriso, signal_mode);
2414
2415 xorriso->run_state= 1; /* Indicate that burning has started */
2416 burn_disc_write(burn_options, disc);
2417
2418 ret= Xorriso_pacifier_loop(xorriso, drive, 2 | (is_cd << 4) | (is_bd << 5));
2419 if(burn_is_aborting(0))
2420 Xorriso_abort(xorriso, 0); /* Never comes back */
2421 Xorriso_set_signal_handling(xorriso, 0);
2422 if(ret<=0)
2423 goto ex;
2424 if(!burn_drive_wrote_well(drive)) {
2425 Xorriso_process_msg_queues(xorriso,0);
2426 if(xorriso->auto_close && xorriso->do_close == 0) {
2427 if(burn_drive_was_feat21_failure(drive)) {
2428 sprintf(xorriso->info_text,
2429 "libburn indicates failure with writing DVD-RW to appendable state.");
2430 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2431 /* Urge caller to call Xorriso_retry_burn_rack() */
2432 ret= 2; goto ex;
2433 }
2434 }
2435 sprintf(xorriso->info_text,
2436 "libburn indicates failure with writing.");
2437 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2438 ret= 0; goto ex;
2439 }
2440
2441 if(flag & 1) {
2442 ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL,
2443 flag & 2);
2444 if(ret <= 0)
2445 goto ex;
2446 }
2447 sprintf(xorriso->info_text, "Writing to ");
2448 Text_shellsafe(xorriso->outdev, xorriso->info_text, 1);
2449 strcat(xorriso->info_text, " completed successfully.\n\n");
2450 Xorriso_info(xorriso, 0);
2451 ret= 1;
2452 ex:;
2453 Xorriso_process_msg_queues(xorriso,0);
2454 if(disc!=NULL)
2455 burn_disc_free(disc);
2456 if(session != NULL)
2457 burn_session_free(session);
2458 if(track != NULL)
2459 burn_track_free(track);
2460 if(burn_options != NULL)
2461 burn_write_opts_free(burn_options);
2462 if(xorriso->pacifier_fifo!=NULL)
2463 burn_source_free(xorriso->pacifier_fifo);
2464 xorriso->pacifier_fifo= NULL;
2465 xorriso->run_state= 0; /* Indicate that burning has ended */
2466 Xorriso_free_meM(reasons);
2467 Xorriso_free_meM(profile_name);
2468 Xorriso_free_meM(head_buffer);
2469 return(ret);
2470 }
2471
2472
2473 int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode,
2474 int flag)
2475 {
2476 char *npt, *cpt;
2477 int l, was, value, ret;
2478 struct isoburn_imgen_opts *opts= NULL;
2479 char *msg= NULL;
2480 off_t limit;
2481
2482 was= xorriso->relax_compliance;
2483 npt= cpt= mode;
2484 for(; npt!=NULL; cpt= npt+1) {
2485 npt= strchr(cpt,':');
2486 if(npt==NULL)
2487 l= strlen(cpt);
2488 else
2489 l= npt-cpt;
2490 if(l == 0)
2491 continue;
2492 if((l == 6 && strncmp(cpt, "strict", l) == 0) ||
2493 (l == 5 && strncmp(cpt, "clear", l) == 0)) {
2494 xorriso->relax_compliance= 0;
2495 } else if(l == 7 && strncmp(cpt, "default", l) == 0) {
2496 xorriso->relax_compliance= Xorriso_relax_compliance_defaulT;
2497
2498 } else if((l == 18 && strncmp(cpt, "untranslated_names", l) == 0) ||
2499 (l == 21 && strncmp(cpt, "untranslated_names_on", l) == 0) ) {
2500 xorriso->untranslated_name_len = -1;
2501 } else if((l == 22 && strncmp(cpt, "untranslated_names_off", l) == 0)) {
2502 xorriso->untranslated_name_len = 0;
2503 } else if((l >= 22 && strncmp(cpt, "untranslated_name_len=", 22) == 0)) {
2504 value= -1;
2505 sscanf(cpt + 22, "%d", &value);
2506 /* Let libisoburn check the value */
2507 ret= isoburn_igopt_new(&opts, 0);
2508 if(ret != 1)
2509 return(-1);
2510 ret= isoburn_igopt_set_untranslated_name_len(opts, value);
2511 isoburn_igopt_destroy(&opts, 0);
2512 if(ret <= 0) { /* Not a tasty value */
2513 xorriso->relax_compliance= was;
2514 return(0);
2515 }
2516 xorriso->untranslated_name_len = value;
2517
2518 } else if((l == 16 && strncmp(cpt, "allow_dir_id_ext", l) == 0) ||
2519 (l == 19 && strncmp(cpt, "allow_dir_id_ext_on", l) == 0) ) {
2520 xorriso->relax_compliance|= isoburn_igopt_allow_dir_id_ext;
2521 xorriso->allow_dir_id_ext_dflt= 0;
2522 } else if((l == 20 && strncmp(cpt, "allow_dir_id_ext_off", l) == 0)) {
2523 xorriso->relax_compliance&= ~isoburn_igopt_allow_dir_id_ext;
2524 xorriso->allow_dir_id_ext_dflt= 0;
2525
2526 } else if((l == 12 && strncmp(cpt, "omit_version", l) == 0) ||
2527 (l == 15 && strncmp(cpt, "omit_version_on", l) == 0) ) {
2528 xorriso->relax_compliance|= isoburn_igopt_omit_version_numbers;
2529 } else if((l == 16 && strncmp(cpt, "omit_version_off", l) == 0)) {
2530 xorriso->relax_compliance&= ~isoburn_igopt_omit_version_numbers;
2531
2532 } else if((l == 16 && strncmp(cpt, "only_iso_version", l) == 0) ||
2533 (l == 19 && strncmp(cpt, "only_iso_version_on", l) == 0) ) {
2534 xorriso->relax_compliance|= isoburn_igopt_only_iso_versions;
2535 } else if((l == 20 && strncmp(cpt, "only_iso_version_off", l) == 0)) {
2536 xorriso->relax_compliance&= ~isoburn_igopt_only_iso_versions;
2537
2538 } else if((l == 10 && strncmp(cpt, "deep_paths", l) == 0) ||
2539 (l == 13 && strncmp(cpt, "deep_paths_on", l) == 0)) {
2540 xorriso->relax_compliance|= isoburn_igopt_allow_deep_paths;
2541 } else if(l == 14 && strncmp(cpt, "deep_paths_off", l) == 0) {
2542 xorriso->relax_compliance&= ~isoburn_igopt_allow_deep_paths;
2543
2544 } else if((l == 10 && strncmp(cpt, "long_paths", l) == 0) ||
2545 (l == 13 && strncmp(cpt, "long_paths_on", l) == 0) ) {
2546 xorriso->relax_compliance|= isoburn_igopt_allow_longer_paths;
2547 } else if(l == 14 && strncmp(cpt, "long_paths_off", l) == 0) {
2548 xorriso->relax_compliance&= ~isoburn_igopt_allow_longer_paths;
2549
2550 } else if((l == 10 && strncmp(cpt, "long_names", l) == 0) ||
2551 (l == 13 && strncmp(cpt, "long_names_on", l) == 0)) {
2552 xorriso->relax_compliance|= isoburn_igopt_max_37_char_filenames;
2553 } else if(l == 14 && strncmp(cpt, "long_names_off", l) == 0) {
2554 xorriso->relax_compliance&= ~isoburn_igopt_max_37_char_filenames;
2555
2556 } else if((l == 13 && strncmp(cpt, "no_force_dots", l) == 0) ||
2557 (l == 16 && strncmp(cpt, "no_force_dots_on", l) == 0)) {
2558 xorriso->relax_compliance|= isoburn_igopt_no_force_dots;
2559 } else if(l == 17 && strncmp(cpt, "no_force_dots_off", l) == 0) {
2560 xorriso->relax_compliance&= ~isoburn_igopt_no_force_dots;
2561
2562 } else if((l == 15 && strncmp(cpt, "no_j_force_dots", l) == 0) ||
2563 (l == 18 && strncmp(cpt, "no_j_force_dots_on", l) == 0)) {
2564 xorriso->relax_compliance|= isoburn_igopt_no_j_force_dots;
2565 } else if(l == 19 && strncmp(cpt, "no_j_force_dots_off", l) == 0) {
2566 xorriso->relax_compliance&= ~isoburn_igopt_no_j_force_dots;
2567
2568 } else if((l == 9 && strncmp(cpt, "lowercase", l) == 0) ||
2569 (l == 12 && strncmp(cpt, "lowercase_on", l) == 0)) {
2570 xorriso->relax_compliance|= isoburn_igopt_allow_lowercase;
2571 } else if(l == 13 && strncmp(cpt, "lowercase_off", l) == 0) {
2572 xorriso->relax_compliance&= ~isoburn_igopt_allow_lowercase;
2573
2574 } else if((l == 10 && strncmp(cpt, "full_ascii", l) == 0) ||
2575 (l == 13 && strncmp(cpt, "full_ascii_on", l) == 0)) {
2576 xorriso->relax_compliance|= isoburn_igopt_allow_full_ascii;
2577 } else if(l == 14 && strncmp(cpt, "full_ascii_off", l) == 0) {
2578 xorriso->relax_compliance&= ~isoburn_igopt_allow_full_ascii;
2579
2580 } else if((l == 10 && strncmp(cpt, "7bit_ascii", l) == 0) ||
2581 (l == 13 && strncmp(cpt, "7bit_ascii_on", l) == 0)) {
2582 xorriso->relax_compliance|= isoburn_igopt_allow_7bit_ascii;
2583 } else if(l == 14 && strncmp(cpt, "7bit_ascii_off", l) == 0) {
2584 xorriso->relax_compliance&= ~isoburn_igopt_allow_7bit_ascii;
2585
2586 } else if((l == 17 && strncmp(cpt, "joliet_long_paths", l) == 0) ||
2587 (l == 20 && strncmp(cpt, "joliet_long_paths_on", l) == 0)) {
2588 xorriso->relax_compliance|= isoburn_igopt_joliet_longer_paths;
2589 } else if(l == 21 && strncmp(cpt, "joliet_long_paths_off", l) == 0) {
2590 xorriso->relax_compliance&= ~isoburn_igopt_joliet_longer_paths;
2591
2592 } else if((l == 17 && strncmp(cpt, "joliet_long_names", l) == 0) ||
2593 (l == 20 && strncmp(cpt, "joliet_long_names_on", l) == 0)) {
2594 xorriso->relax_compliance|= isoburn_igopt_joliet_long_names;
2595 } else if(l == 21 && strncmp(cpt, "joliet_long_names_off", l) == 0) {
2596 xorriso->relax_compliance&= ~isoburn_igopt_joliet_long_names;
2597
2598 } else if((l == 12 && strncmp(cpt, "joliet_utf16", l) == 0) ||
2599 (l == 15 && strncmp(cpt, "joliet_utf16_on", l) == 0)) {
2600 xorriso->relax_compliance|= isoburn_igopt_joliet_utf16;
2601 } else if(l == 16 && strncmp(cpt, "joliet_utf16_off", l) == 0) {
2602 xorriso->relax_compliance&= ~isoburn_igopt_joliet_utf16;
2603
2604 } else if((l == 10 && strncmp(cpt, "always_gmt", l) == 0) ||
2605 (l == 13 && strncmp(cpt, "always_gmt_on", l) == 0)) {
2606 xorriso->relax_compliance|= isoburn_igopt_always_gmt;
2607 } else if(l == 14 && strncmp(cpt, "always_gmt_off", l) == 0) {
2608 xorriso->relax_compliance&= ~isoburn_igopt_always_gmt;
2609
2610 } else if((l == 9 && strncmp(cpt, "rec_mtime", l) == 0) ||
2611 (l == 12 && strncmp(cpt, "rec_mtime_on", l) == 0)) {
2612 xorriso->relax_compliance|= (isoburn_igopt_dir_rec_mtime |
2613 isoburn_igopt_joliet_rec_mtime |
2614 isoburn_igopt_iso1999_rec_mtime);
2615 } else if(l == 13 && strncmp(cpt, "rec_mtime_off", l) == 0) {
2616 xorriso->relax_compliance&= ~(isoburn_igopt_dir_rec_mtime |
2617 isoburn_igopt_joliet_rec_mtime |
2618 isoburn_igopt_iso1999_rec_mtime);
2619
2620 } else if((l == 6 && strncmp(cpt, "old_rr", l) == 0) ||
2621 (l == 9 && strncmp(cpt, "old_rr_on", l) == 0) ||
2622 (l == 10 && strncmp(cpt, "new_rr_off", l) == 0)) {
2623 xorriso->relax_compliance|=
2624 isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10;
2625 } else if((l == 10 && strncmp(cpt, "old_rr_off", l) == 0) ||
2626 (l == 9 && strncmp(cpt, "new_rr_on", l) == 0) ||
2627 (l == 6 && strncmp(cpt, "new_rr", l) == 0)) {
2628 xorriso->relax_compliance&=
2629 ~(isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10);
2630
2631 } else if((l == 14 && strncmp(cpt, "aaip_susp_1_10", l) == 0) ||
2632 (l == 17 && strncmp(cpt, "aaip_susp_1_10_on", l) == 0) ||
2633 (l == 18 && strncmp(cpt, "aaip_susp_1_12_off", l) == 0)) {
2634 xorriso->relax_compliance|= isoburn_igopt_aaip_susp_1_10;
2635 } else if((l == 18 && strncmp(cpt, "aaip_susp_1_10_off", l) == 0) ||
2636 (l == 17 && strncmp(cpt, "aaip_susp_1_12_on", l) == 0) ||
2637 (l == 14 && strncmp(cpt, "aaip_susp_1_12", l) == 0)) {
2638 xorriso->relax_compliance&= ~isoburn_igopt_aaip_susp_1_10;
2639
2640 } else if((l == 11 && strncmp(cpt, "no_emul_toc", l) == 0) ||
2641 (l == 14 && strncmp(cpt, "no_emul_toc_on", l) == 0)) {
2642 xorriso->no_emul_toc|= 1;
2643 } else if((l == 15 && strncmp(cpt, "no_emul_toc_off", l) == 0) ||
2644 (l == 8 && strncmp(cpt, "emul_toc", l) == 0)) {
2645 xorriso->no_emul_toc&= ~1;
2646
2647 } else if((l == 13 && strncmp(cpt, "iso_9660_1999", l) == 0) ||
2648 (l == 16 && strncmp(cpt, "iso_9660_1999_on", l) == 0)) {
2649 xorriso->do_iso1999= 1;
2650 } else if(l == 17 && strncmp(cpt, "iso_9660_1999_off", l) == 0) {
2651 xorriso->do_iso1999= 0;
2652
2653 } else if((l >= 15 && strncmp(cpt, "iso_9660_level=", 15) == 0)) {
2654 value= 0;
2655 sscanf(cpt + 15, "%d", &value);
2656 if(value == 1 || value == 2) {
2657 limit= ((off_t) 4) * ((off_t) 1024*1024*1024) - ((off_t) 1);
2658 xorriso->iso_level= value;
2659 xorriso->iso_level_is_default= 0;
2660 if(xorriso->file_size_limit > limit)
2661 xorriso->file_size_limit= limit;
2662 } else if(value == 3) {
2663 xorriso->iso_level= value;
2664 xorriso->iso_level_is_default= 0;
2665 if(xorriso->file_size_limit < Xorriso_default_file_size_limiT)
2666 xorriso->file_size_limit= Xorriso_default_file_size_limiT;
2667 } else {
2668 Xorriso_alloc_meM(msg, char, 160);
2669 sprintf(msg,
2670 "-compliance iso_9660_level=%d : Only 1, 2, or 3 are permissible",
2671 value);
2672 Xorriso_msgs_submit(xorriso, 0, msg, 0, "FAILURE", 0);
2673 Xorriso_free_meM(msg);
2674 msg= NULL;
2675 xorriso->relax_compliance= was;
2676 return(0);
2677 }
2678
2679 } else if((l == 8 && strncmp(cpt, "iso_9660", l) == 0) ||
2680 (l == 11 && strncmp(cpt, "iso_9660_on", l) == 0)) {
2681 /* may have a meaning in future */;
2682 } else if(l == 12 && strncmp(cpt, "iso_9660_off", l) == 0) {
2683 /* may have a meaning in future */;
2684 Xorriso_msgs_submit(xorriso, 0,
2685 "-compliance -iso_9660_off : Cannot do anything else but ISO 9660",
2686 0, "FAILURE", 0);
2687 xorriso->relax_compliance= was;
2688 return(0);
2689
2690 } else if((l == 9 && strncmp(cpt, "old_empty", l) == 0) ||
2691 (l == 12 && strncmp(cpt, "old_empty_on", l) == 0)) {
2692 xorriso->do_old_empty= 1;
2693 } else if(l == 13 && strncmp(cpt, "old_empty_off", l) == 0) {
2694 xorriso->do_old_empty= 0;
2695
2696 } else {
2697 if(l<SfileadrL)
2698 sprintf(xorriso->info_text, "-compliance: unknown rule '%s'",
2699 cpt);
2700 else
2701 sprintf(xorriso->info_text,
2702 "-compliance: oversized rule parameter (%d)", l);
2703 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2704 xorriso->relax_compliance= was;
2705 return(0);
2706 }
2707 }
2708 return(1);
2709 ex:;
2710 Xorriso_free_meM(msg);
2711 return(ret);
2712 }
2713
2714
2715 /* @return 1=ok 2=ok, is default setting */
2716 int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024],
2717 int flag)
2718 {
2719 int r;
2720
2721 r= xorriso->relax_compliance;
2722 if(r == 0) {
2723 strcpy(mode, "strict");
2724 return(1);
2725 }
2726 strcpy(mode, "clear");
2727 sprintf(mode + strlen(mode), ":iso_9660_level=%d", xorriso->iso_level);
2728 if(r & isoburn_igopt_allow_dir_id_ext)
2729 strcat(mode, ":allow_dir_id_ext");
2730 if(r & isoburn_igopt_omit_version_numbers)
2731 strcat(mode, ":omit_version");
2732 if(r & isoburn_igopt_only_iso_versions)
2733 strcat(mode, ":only_iso_version");
2734 if(r & isoburn_igopt_allow_deep_paths)
2735 strcat(mode, ":deep_paths");
2736 if(r & isoburn_igopt_allow_longer_paths)
2737 strcat(mode, ":long_paths");
2738 if(r & isoburn_igopt_max_37_char_filenames)
2739 strcat(mode, ":long_names");
2740 if(r & isoburn_igopt_no_force_dots)
2741 strcat(mode, ":no_force_dots");
2742 if(r & isoburn_igopt_no_j_force_dots)
2743 strcat(mode, ":no_j_force_dots");
2744 if(r & isoburn_igopt_allow_lowercase)
2745 strcat(mode, ":lowercase");
2746 if(r & isoburn_igopt_allow_full_ascii)
2747 strcat(mode, ":full_ascii");
2748 else if(r & isoburn_igopt_allow_7bit_ascii)
2749 strcat(mode, ":7bit_ascii");
2750 if(r & isoburn_igopt_joliet_longer_paths)
2751 strcat(mode, ":joliet_long_paths");
2752 if(r & isoburn_igopt_joliet_long_names)
2753 strcat(mode, ":joliet_long_names");
2754 if(r & isoburn_igopt_joliet_utf16)
2755 strcat(mode, ":joliet_utf16");
2756 if(r & isoburn_igopt_always_gmt)
2757 strcat(mode, ":always_gmt");
2758 if(r & isoburn_igopt_dir_rec_mtime)
2759 strcat(mode, ":rec_mtime");
2760 if(r & isoburn_igopt_rrip_version_1_10) {
2761 strcat(mode, ":old_rr");
2762 if(!(r & isoburn_igopt_aaip_susp_1_10))
2763 strcat(mode, ":aaip_susp_1_10_off");
2764 } else {
2765 strcat(mode, ":new_rr");
2766 if(r & isoburn_igopt_aaip_susp_1_10)
2767 strcat(mode, ":aaip_susp_1_10");
2768 }
2769 if(xorriso->no_emul_toc & 1)
2770 strcat(mode, ":no_emul_toc");
2771 if(xorriso->untranslated_name_len != 0)
2772 sprintf(mode + strlen(mode), ":untranslated_name_len=%d",
2773 xorriso->untranslated_name_len);
2774 if(xorriso->do_iso1999)
2775 sprintf(mode + strlen(mode), ":iso_9660_1999");
2776 if(xorriso->do_old_empty)
2777 sprintf(mode + strlen(mode), ":old_empty");
2778 return(1 +
2779 (r == Xorriso_relax_compliance_defaulT && !(xorriso->no_emul_toc & 1)
2780 && xorriso->untranslated_name_len == 0 && !xorriso->do_iso1999 &&
2781 xorriso->iso_level == 3));
2782 }
2783
2784
2785 /* @param flag bit0= operating on newly attached boot image
2786 */
2787 int Xorriso_set_isolinux_options(struct XorrisO *xorriso,
2788 IsoImage *image, int flag)
2789 {
2790 int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i;
2791 ElToritoBootImage *bootimg, **boots = NULL;
2792 IsoFile *bootimg_node, **bootnodes = NULL;
2793
2794 ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL);
2795 Xorriso_process_msg_queues(xorriso,0);
2796 if(ret != 1) {
2797 sprintf(xorriso->info_text, "Programming error: No boot image available in Xorriso_set_isolinux_options()");
2798 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2799 ret= -1; goto ex;
2800 }
2801 ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
2802 Xorriso_process_msg_queues(xorriso,0);
2803 if(ret != 1) {
2804 Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0,
2805 "FATAL", 1);
2806 ret= -1; goto ex;
2807 }
2808
2809 /* bit0 : 1=boot-info-table , bit2-7 : 1=EFI , 2=HFS+ , bit8 : 1=APM */
2810 patch_table = xorriso->patch_isolinux_image & 0x3fd;
2811 if((flag & 1) && num_boots > 1) {
2812 ret= el_torito_set_isolinux_options(boots[num_boots - 1], patch_table, 0);
2813 ret= (ret == 1); goto ex;
2814 }
2815
2816 /* Handle patching of first attached boot image or of imported boot images
2817 */
2818 for(i= 0; i < num_boots; i++) {
2819 patch_table = xorriso->patch_isolinux_image & 0x3fd;
2820 if(patch_table && !(flag & 1)) {
2821 if(!el_torito_seems_boot_info_table(boots[i], 0))
2822 patch_table&= ~1;
2823 else if((xorriso->patch_isolinux_image & 2) &&
2824 el_torito_get_boot_platform_id(boots[i]) == 0xef)
2825 patch_table&= ~1;
2826 }
2827 if(i > 0 || xorriso->boot_image_isohybrid == 0) {
2828 ret= el_torito_set_isolinux_options(boots[i], patch_table, 0);
2829 if(ret != 1)
2830 {ret= 0; goto ex;}
2831 continue;
2832 }
2833
2834 /* <<< From here on only with first boot image and
2835 deprecated builtin isohybrid MBR */
2836
2837 if(xorriso->boot_image_isohybrid == 3) {
2838 make_isohybrid_mbr= 1;
2839 } else {
2840 ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
2841 if(ret < 0)
2842 {ret= 0; goto ex;}
2843 if(ret > 0)
2844 make_isohybrid_mbr= 1;
2845 }
2846
2847 if(xorriso->boot_image_isohybrid == 2 && !make_isohybrid_mbr) {
2848 sprintf(xorriso->info_text,
2849 "Isohybrid signature is demanded but not found in boot image file.");
2850 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2851 {ret= 0; goto ex;}
2852 }
2853 if(make_isohybrid_mbr) {
2854 sprintf(xorriso->info_text, "Will write isohybrid MBR.");
2855 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2856 }
2857 ret= el_torito_set_isolinux_options(bootimg,
2858 patch_table | (make_isohybrid_mbr << 1),0);
2859 if(ret != 1)
2860 {ret= 0; goto ex;}
2861 }
2862 ex:
2863 Xorriso_process_msg_queues(xorriso,0);
2864 if(boots != NULL)
2865 free(boots);
2866 if(bootnodes != NULL)
2867 free(bootnodes);
2868 return(ret);
2869 }
2870
2871
2872 int Xorriso_overwrite_iso_head(struct XorrisO *xorriso,
2873 struct burn_drive *drive, char *head_buffer,
2874 int lba, int flag)
2875 {
2876 int ret;
2877 off_t to_write;
2878
2879 to_write= 64 * 1024;
2880 burn_drive_reset_simulate(drive, xorriso->do_dummy);
2881 ret= burn_random_access_write(drive, (off_t) lba * (off_t) 2048,
2882 head_buffer, to_write, 1);
2883 if(ret <= 0) {
2884 Xorriso_process_msg_queues(xorriso, 0);
2885 sprintf(xorriso->info_text,
2886 "Cannot write new ISO image head to LBA %d", lba);
2887 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2888 return(0);
2889 }
2890 return(1);
2891 }
2892
2893
2894 /* @param flag bit0= insist on tag_type 4 (relocated superblock tag)
2895 */
2896 int Xorriso_find_sb_checksum(struct XorrisO *xorriso,
2897 char *head_buffer, int *vd_end, int flag)
2898 {
2899 int i, tag_type, ret;
2900 uint32_t pos, range_start, range_size, next_tag;
2901 char md5[16];
2902
2903 *vd_end= 0;
2904
2905 /* Look for volume descriptor end */
2906 for(i= 16; i < 32; i++)
2907 if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
2908 strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0)
2909 break;
2910 /* Check whether the next one is a libisofs checksum tag */
2911 if(i < 32) {
2912 *vd_end= i;
2913 i++;
2914 ret= iso_util_decode_md5_tag(head_buffer + i * 2048, &tag_type, &pos,
2915 &range_start, &range_size, &next_tag, md5, 0);
2916 if(ret <= 0)
2917 return(ret);
2918 if((flag & 1) && tag_type != 4)
2919 return(0); /* No other tag type is supposed to occur before type 4 */
2920 }
2921 return(i + 1);
2922 }
2923
2924
2925 /* @param field_head Example: " md5="
2926 */
2927 int Xorriso__set_iso_check_tag_md5(char *tag_data, char *field_head,
2928 void **ctx, int *field_end, int flag)
2929 {
2930 char md5_bin[16], m32, *cpt;
2931 int i;
2932
2933 iso_md5_end(ctx, md5_bin);
2934 cpt= strstr(tag_data, field_head);
2935 if(cpt == NULL)
2936 return(0);
2937 cpt+= strlen(field_head);
2938 m32= cpt[32];
2939 for(i= 0; i < 16; i++)
2940 sprintf(cpt + 2 * i, "%2.2x", ((unsigned char *) md5_bin)[i]);
2941 cpt[32]= m32;
2942 *field_end= (cpt - tag_data) + 32;
2943 return(1);
2944 }
2945
2946
2947 int Xorriso_verify_sb_tag(struct XorrisO *xorriso, char *head_buffer,
2948 int checksum_block, int flag)
2949 {
2950 int tag_type, ret;
2951 uint32_t pos, range_start, range_size, next_tag;
2952 char md5_rec[16], md5_comp[16];
2953 void *ctx= NULL;
2954
2955 /* Obtain checksum */
2956 iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
2957 &tag_type, &pos, &range_start, &range_size,
2958 &next_tag, md5_rec, 0);
2959 /* Verify checksum */
2960 ret= iso_md5_start(&ctx);
2961 if(ret <= 0) {
2962 Xorriso_process_msg_queues(xorriso,0);
2963 Xorriso_no_malloc_memory(xorriso, NULL, 0);
2964 return(0);
2965 }
2966 ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
2967 iso_md5_end(&ctx, md5_comp);
2968 if(ret <= 0) {
2969 Xorriso_process_msg_queues(xorriso,0);
2970 return(0);
2971 }
2972 if(iso_md5_match(md5_rec, md5_comp))
2973 return(1);
2974 Xorriso_msgs_submit(xorriso, 0,
2975 "Superblock data do not match superblock checksum tag",
2976 0, "WARNING", 0);
2977 return(0);
2978 }
2979
2980
2981 int Xorriso_refresh_sb_tag(struct XorrisO *xorriso, char *head_buffer,
2982 int checksum_block, int flag)
2983 {
2984 int ret, field_end;
2985 char md5_bin[16];
2986 void *ctx= NULL;
2987
2988 /* Recompute checksum and update found checksum tag */;
2989 ret= iso_md5_start(&ctx);
2990 if(ret <= 0) {
2991 no_md5_ctx:;
2992 Xorriso_process_msg_queues(xorriso,0);
2993 Xorriso_no_malloc_memory(xorriso, NULL, 0);
2994 return(0);
2995 }
2996 ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
2997 if(ret <= 0) {
2998 md5_comp_failed:;
2999 iso_md5_end(&ctx, md5_bin);
3000 return(0);
3001 }
3002 Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
3003 " md5=", &ctx, &field_end, 0);
3004 if(ret <= 0)
3005 return(2);
3006 ret= iso_md5_start(&ctx);
3007 if(ret <= 0)
3008 goto no_md5_ctx;
3009 ret= iso_md5_compute(ctx, head_buffer + checksum_block * 2048,
3010 field_end);
3011 if(ret <= 0)
3012 goto md5_comp_failed;
3013 Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
3014 " self=", &ctx, &field_end, 0);
3015 return(1);
3016 }
3017
3018
3019 /*
3020 @param flag bit0= obtain iso_lba from indev
3021 bit1= head_buffer already contains a valid head
3022 bit2= issue message about success
3023 bit3= check whether source blocks are banned by in_sector_map
3024 bit4= refresh relocated sb checksum tag
3025 */
3026 int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
3027 char *head_buffer, struct CheckmediajoB *job,
3028 int flag)
3029 {
3030 int ret, full_size, i, checksum_block= -1, vd_end;
3031 char *headpt;
3032 struct burn_drive_info *dinfo;
3033 struct burn_drive *drive = NULL;
3034 off_t seek_ret, to_write;
3035
3036 ret= Xorriso_may_burn(xorriso, 0);
3037 if(ret <= 0)
3038 return(0);
3039 if(flag & 1) {
3040 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
3041 "on attempt to learn current session lba", 0);
3042 if(ret<=0)
3043 return(0);
3044 ret= isoburn_disc_get_msc1(drive, &iso_lba);
3045 if(ret<=0)
3046 return(0);
3047 drive= NULL; /* indev will not be used furtherly */
3048 }
3049 if(job == NULL) {
3050 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
3051 "on attempt to update at lba 0 to 31", 2);
3052 if(ret<=0)
3053 return(0);
3054 }
3055 if(iso_lba < 32)
3056 return(2);
3057
3058 if(!(flag & 2)) {
3059 /* head_buffer was not filled yet. Read it from output media. */
3060 if(drive != NULL)
3061 if(burn_drive_get_drive_role(drive) == 5) /* write-only */
3062 return(2);
3063 if(job != NULL && job->data_to_fd >= 0) {
3064 if((flag & 8) && job->sector_map != NULL) {
3065 ret= Sectorbitmap_bytes_are_set(job->sector_map,
3066 ((off_t) iso_lba) * (off_t) 2048,
3067 ((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0);
3068 if(ret <= 0) {
3069 sprintf(xorriso->info_text,
3070 "ISO image head at lba %d is marked as invalid blocks in file copy",
3071 iso_lba);
3072 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
3073 0);
3074 return(0);
3075 }
3076 }
3077 seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba,
3078 SEEK_SET);
3079 if(seek_ret == -1)
3080 ret= 0;
3081 else
3082 ret= read(job->data_to_fd, head_buffer, 64 * 1024);
3083 if(ret < 64 * 1024) {
3084 Xorriso_process_msg_queues(xorriso,0);
3085 sprintf(xorriso->info_text,
3086 "Cannot read ISO image head from file copy");
3087 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
3088 return(0);
3089 }
3090 ret= isoburn_read_iso_head(NULL, 0, &isosize, head_buffer, 1 << 13);
3091 if(ret<=0) {
3092 Xorriso_process_msg_queues(xorriso,0);
3093 sprintf(xorriso->info_text,
3094 "Alleged session start does not look like ISO 9660.");
3095 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
3096 return(0);
3097 }
3098 } else {
3099 ret= 0;
3100 if(drive != NULL)
3101 ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2);
3102 if(ret<=0) {
3103 Xorriso_process_msg_queues(xorriso,0);
3104 sprintf(xorriso->info_text,
3105 "Cannot read freshly written ISO image head");
3106 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3107 return(0);
3108 }
3109 }
3110 }
3111
3112 /* patch ISO header */
3113 full_size= iso_lba + isosize;
3114 headpt= head_buffer + 32*1024;
3115 for(i=0;i<4;i++)
3116 headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
3117
3118 /* >>> What about Joliet et.al. ? */;
3119
3120 if(flag & 16) {
3121 /* Find relocated sb checksum tag */
3122 ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 1);
3123 if(ret > 0) {
3124 /* If it is recognizable then it matched in Xorriso_adjust_relocated_sb */
3125 checksum_block= ret - 1;
3126 ret= Xorriso_refresh_sb_tag(xorriso, head_buffer, checksum_block, 0);
3127 if(ret <= 0)
3128 return(0);
3129 }
3130 }
3131
3132 if(job != NULL) {
3133 /* This is a check_media superblock relocation:
3134 Invalidate eventual libisofs checksum tags.
3135 Write only up to PVD end plus eventual invalidated tag.
3136 */
3137 to_write= 2048 * 32;
3138 ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, 0);
3139 if(ret > 0) {
3140 if(!(flag & 16)) /* invalidate */
3141 memset(head_buffer + (ret - 1) * 2048, 0, 8);
3142 to_write= 2048 * ret;
3143 } else if(i > 0) {
3144 to_write= 2048 * (i + 1);
3145 }
3146 seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
3147 if(seek_ret == -1)
3148 ret= 0;
3149 else
3150 ret= write(job->data_to_fd, head_buffer, to_write);
3151 if(ret < to_write) {
3152 Xorriso_process_msg_queues(xorriso,0);
3153 sprintf(xorriso->info_text,
3154 "Cannot write ISO image head to file copy");
3155 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
3156 return(0);
3157 }
3158 } else {
3159 /* This is a regular superblock relocation. Write full 64 kB. */
3160 ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, 0, 0);
3161 if(ret <= 0)
3162 return(ret);
3163 }
3164 if(flag & 4) {
3165 sprintf(xorriso->info_text,
3166 "Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba);
3167 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
3168 }
3169 return(1);
3170 }
3171
3172
3173 /* @return 1= ok, 0= no match, -1= MD5 computation error,
3174 -2= MD5 clone or start error
3175 */
3176 int Xorriso_migrate_checksum_tag(struct XorrisO *xorriso, char *buffer,
3177 int buf_base, int start,
3178 int checksum_block, char md5_rec[16],
3179 void *ctx_unch, void *ctx_chng, int flag)
3180 {
3181 int ret, to_compute;
3182 char *headpt, md5_clone[16];
3183 void *ctx_clone= NULL;
3184 int field_end;
3185
3186 /* Checksum both up to before checksum tag */
3187 headpt= buffer + start * 2048;
3188 to_compute= (checksum_block - start) * 2048;
3189 if(to_compute > 0) {
3190 ret= iso_md5_compute(ctx_unch, headpt, to_compute);
3191 if(ret <= 0)
3192 {ret= -1; goto ex;}
3193 ret= iso_md5_compute(ctx_chng, headpt, to_compute);
3194 if(ret <= 0)
3195 {ret= -1; goto ex;}
3196 }
3197 /* Verify with unchanged checksum */
3198 ret= iso_md5_clone(ctx_unch, &ctx_clone);
3199 if(ret <= 0)
3200 {ret= -2; goto ex;}
3201 iso_md5_end(&ctx_clone, md5_clone);
3202 if(!iso_md5_match(md5_rec, md5_clone))
3203 {ret= 0; goto ex;}
3204 /* Compute unchanged rest of block range */
3205 headpt= buffer + checksum_block * 2048;
3206 to_compute= 2048;
3207 ret= iso_md5_compute(ctx_unch, headpt, to_compute);
3208 if(ret <= 0)
3209 {ret= -1; goto ex;}
3210 /* Replace checksum in tag by changed checksum */
3211 ret= iso_md5_clone(ctx_chng, &ctx_clone);
3212 if(ret <= 0)
3213 {ret= -2; goto ex;}
3214 Xorriso__set_iso_check_tag_md5(headpt, " md5=", &ctx_clone, &field_end, 0);
3215 /* Recompute and write self= checksum */
3216 ret= iso_md5_start(&ctx_clone);
3217 if(ret <= 0)
3218 {ret= -2; goto ex;}
3219 ret= iso_md5_compute(ctx_clone, headpt, field_end);
3220 if(ret <= 0)
3221 {ret= -1; goto ex;}
3222 Xorriso__set_iso_check_tag_md5(headpt, " self=", &ctx_clone, &field_end, 0);
3223 /* Add rest of head_buffer to changed checksum */
3224 ret= iso_md5_compute(ctx_chng, headpt, to_compute);
3225 if(ret <= 0)
3226 {ret= -1; goto ex;}
3227 ret= 1;
3228 ex:;
3229 if(ctx_clone != NULL)
3230 iso_md5_end(&ctx_clone, md5_clone);
3231 return(ret);
3232 }
3233
3234
3235 /* Verify and re-compute tree and session checksum tag */
3236 int Xorriso_refresh_ts_tags(struct XorrisO *xorriso,
3237 struct burn_drive *drive,
3238 void *ctx_unch, void *ctx_chng,
3239 int iso_lba, int session_size,
3240 int checksum_block, int flag)
3241 {
3242 int i, ret, tag_type, look_for_tag, check_start, look_from_block, was_change;
3243 off_t read_pos, to_read, data_count;
3244 uint32_t pos, range_start, range_size, next_tag;
3245 char md5_rec[16];
3246 char *buf= NULL;
3247
3248 look_for_tag= 3; /* tree tag */
3249 look_from_block= checksum_block + 1; /* first buffer is already partly done */
3250 Xorriso_alloc_meM(buf, char, 32 * 2048);
3251 for(read_pos= iso_lba; read_pos < iso_lba + session_size; read_pos+= 32) {
3252 was_change= 0;
3253 to_read= 32;
3254 if(read_pos + to_read > iso_lba + session_size)
3255 to_read= iso_lba + session_size - read_pos;
3256 ret= burn_read_data(drive, read_pos * (off_t) 2048, buf,
3257 to_read * (off_t) 2048, &data_count, 0);
3258 if(ret <= 0)
3259 {ret= 0; goto ex;}
3260 check_start= look_from_block;
3261 for(i= look_from_block; i < to_read; i++) {
3262 /* Watch out for tag */
3263 ret= iso_util_decode_md5_tag(buf + i * 2048,
3264 &tag_type, &pos, &range_start, &range_size,
3265 &next_tag, md5_rec, look_for_tag);
3266 if(ret < 0 ) {
3267 ret= 0; goto ex;
3268 } else if(ret == 1) {
3269 if(tag_type != look_for_tag) {
3270 sprintf(xorriso->info_text,
3271 "Encountered checksum tag type %d while looking for %d",
3272 tag_type, look_for_tag);
3273 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
3274 ret= 2; goto ex;
3275 }
3276 /* Checksum up to before tag, verify,
3277 if match replace checksum and write */
3278 ret= Xorriso_migrate_checksum_tag(xorriso, buf, read_pos, check_start,
3279 i, md5_rec, ctx_unch, ctx_chng, 0);
3280 if(ret == -2)
3281 goto ex;
3282 if(ret < 0)
3283 {ret= 0; goto ex;}
3284 if(ret == 0) {
3285 sprintf(xorriso->info_text,
3286 "Checksum tag MD5 mismatch in old session state");
3287 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
3288 ret= 2; goto ex;
3289 }
3290
3291 was_change= 1;
3292 if(look_for_tag == 3) {
3293 look_for_tag= 1; /* session tag */
3294 } else {
3295 look_for_tag= -1;
3296 break;
3297 }
3298 check_start= i + 1;
3299 }
3300 }
3301
3302 look_from_block= 0; /* all following buffer need processing from start */
3303
3304 if(was_change) {
3305 ret= burn_random_access_write(drive, (off_t) read_pos * (off_t) 2048,
3306 buf, to_read * (off_t) 2048, 1);
3307 if(ret <= 0) {
3308 Xorriso_process_msg_queues(xorriso, 0);
3309 sprintf(xorriso->info_text,
3310 "Cannot write new checksum tag data to LBA %d", (int) read_pos);
3311 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3312 ret= 0; goto ex;
3313 }
3314 }
3315
3316 if(look_for_tag < 0)
3317 {ret= 1; goto ex;}
3318
3319 /* Checksum what was not checksummed yet */
3320 if(to_read - check_start > 0) {
3321 ret= iso_md5_compute(ctx_unch, buf + 2048 * check_start,
3322 (to_read - check_start) * 2048);
3323 if(ret <= 0)
3324 {ret= 0; goto ex;}
3325 ret= iso_md5_compute(ctx_chng, buf + 2048 * check_start,
3326 (to_read - check_start) * 2048);
3327 if(ret <= 0)
3328 {ret= 0; goto ex;}
3329 }
3330 }
3331 ret= 1;
3332 ex:;
3333 Xorriso_free_meM(buf);
3334 return(ret);
3335 }
3336
3337
3338 int Xorriso_adjust_session_size(struct XorrisO *xorriso,
3339 struct burn_drive *drive,
3340 char *head_buffer,
3341 int iso_lba, int iso_size,
3342 int checksum_block, int session_size, int flag)
3343 {
3344 int i, ret, tag_type;
3345 uint32_t pos, range_start, range_size, next_tag;
3346 char *headpt, md5_unch[16], md5_chng[16], md5_clone[16], md5_rec[16];
3347 void *ctx_unch= NULL, *ctx_chng= NULL, *ctx_clone= NULL;
3348
3349 if(checksum_block > 0) {
3350 /* Obtain recorded superblock MD5 */
3351 ret= iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
3352 &tag_type, &pos, &range_start, &range_size,
3353 &next_tag, md5_rec, 0);
3354 if(ret <= 0 || tag_type != 2) {
3355 sprintf(xorriso->info_text,
3356 "Encountered checksum tag type %d while looking for 2", tag_type);
3357 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
3358 checksum_block= 0;
3359 }
3360 }
3361 if(checksum_block > 0) {
3362 /* Create md5 context for unchanged state */
3363 ret= iso_md5_start(&ctx_unch);
3364 if(ret <= 0) {
3365 no_ctx:;
3366 Xorriso_process_msg_queues(xorriso, 0);
3367 Xorriso_no_malloc_memory(xorriso, NULL, 0);
3368 goto ex;
3369 }
3370 /* Checksum up to before PVD */
3371 ret= iso_md5_compute(ctx_unch, head_buffer, 32768);
3372 if(ret <= 0)
3373 goto ex;
3374 /* Before the first change: obtain md5 object for changed state */
3375 ret= iso_md5_clone(ctx_unch, &ctx_chng);
3376 if(ret <= 0)
3377 goto no_ctx;
3378 /* Add PVD to unchanged checksum */
3379 ret= iso_md5_compute(ctx_unch, head_buffer + 32768, 2048);
3380 if(ret <= 0)
3381 goto ex;
3382 }
3383
3384 /* Update session PVD at iso_lba+16 to iso_size */
3385 headpt= head_buffer + 32 * 1024;
3386 for(i= 0; i < 4; i++)
3387 headpt[87 - i]= headpt[80 + i]= (iso_size >> (8 * i)) & 0xff;
3388
3389 if(checksum_block > 0) {
3390 /* Add changed PVD to changed checksum */
3391 ret= iso_md5_compute(ctx_chng, head_buffer + 32768, 2048);
3392 if(ret <= 0)
3393 goto ex;
3394 ret= Xorriso_migrate_checksum_tag(xorriso, head_buffer, iso_lba, 17,
3395 checksum_block, md5_rec,
3396 ctx_unch, ctx_chng, 0);
3397 if(ret == -2)
3398 goto no_ctx;
3399 if(ret < 0)
3400 {ret= 0; goto ex;}
3401 if(ret == 0) {
3402 sprintf(xorriso->info_text,
3403 "Superblock MD5 mismatch in old session state");
3404 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
3405 checksum_block= 0;
3406 }
3407 }
3408
3409 ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, iso_lba, 0);
3410 if(ret <= 0)
3411 goto ex;
3412
3413 if(checksum_block > 0) {
3414 /* Verify and re-compute existing checksum tree and session tag */
3415 ret= Xorriso_refresh_ts_tags(xorriso, drive, ctx_unch, ctx_chng,
3416 iso_lba, session_size, checksum_block, 0);
3417 if(ret == -2)
3418 goto no_ctx;
3419 if(ret <= 0)
3420 goto ex;
3421 }
3422
3423 ret= 1;
3424 ex:;
3425 Xorriso_process_msg_queues(xorriso, 0);
3426 if(ctx_unch != NULL)
3427 iso_md5_end(&ctx_unch, md5_unch);
3428 if(ctx_chng != NULL)
3429 iso_md5_end(&ctx_chng, md5_chng);
3430 if(ctx_clone != NULL)
3431 iso_md5_end(&ctx_clone, md5_clone);
3432 return(ret);
3433 }
3434
3435
3436 /* Read relocated superblock and patch in the VDs of the session superblock */
3437 int Xorriso_adjust_relocated_sb(struct XorrisO *xorriso,
3438 struct burn_drive *drive,
3439 char *head_buffer,
3440 char **sb_buffer,
3441 int flag)
3442 {
3443 int ret, old_size, i, vd_end, checksum_block= -1;
3444 char *buffer, *checksum= NULL;
3445
3446 *sb_buffer= NULL;
3447 Xorriso_alloc_meM(*sb_buffer, char, 32 * 2048);
3448 buffer= *sb_buffer;
3449 Xorriso_alloc_meM(checksum, char, 2048);
3450
3451 ret= isoburn_read_iso_head(drive, 0, &old_size, buffer, 2);
3452 if(ret <= 0)
3453 goto ex;
3454 ret= Xorriso_find_sb_checksum(xorriso, buffer, &vd_end, 0);
3455 if(ret <= 0)
3456 goto ex;
3457 if(ret > 0) {
3458 checksum_block= ret - 1;
3459 memcpy(checksum, buffer + checksum_block * 2048, 2048);
3460 ret= Xorriso_verify_sb_tag(xorriso, buffer, checksum_block, 0);
3461 if(ret <= 0) {
3462 checksum_block= -1;
3463 memset(checksum, 0, 8);
3464 }
3465 }
3466
3467 for(i= 16; i < 32; i++) {
3468 memcpy(buffer + i * 2048, head_buffer + i * 2048, 2048);
3469 if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
3470 strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0) {
3471 i++;
3472 break;
3473 }
3474 }
3475 if(checksum_block >= 0 && i < 32)
3476 memcpy(buffer + i * 2048, checksum, 2048);
3477
3478 ret= 1;
3479 ex:
3480 if(ret <= 0)
3481 Xorriso_free_meM(*sb_buffer);
3482 Xorriso_free_meM(checksum);
3483 return(ret);
3484 }
3485
3486
3487 int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
3488 char *adr_value, char *adjust, int flag)
3489 {
3490 int ret, iso_lba= 0, iso_session, iso_track, iso_size= 0, image_start_mode= 0;
3491 int old_size, new_size, blocks, was_indev= 0, checksum_block= 0, vd_end;
3492 int readable_blocks;
3493 char image_start_value[81], *head_buffer= NULL, iso_volid[33];
3494 char *sb_buffer= NULL;
3495 struct burn_drive_info *dinfo;
3496 struct burn_drive *drive = NULL, *in_drive = NULL;
3497 struct burn_multi_caps *caps= NULL;
3498
3499 Xorriso_alloc_meM(head_buffer, char, 32 * 2048);
3500
3501 if(Xorriso_change_is_pending(xorriso, 0)) {
3502 sprintf(xorriso->info_text,
3503 "-truncate_overwritable: Image changes pending. -commit or -rollback first");
3504 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3505 ret= 0; goto ex;
3506 }
3507 ret= Xorriso_may_burn(xorriso, 0);
3508 if(ret <= 0)
3509 goto ex;
3510 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
3511 "on attempt to activate an older session", 2);
3512 if(ret <= 0)
3513 goto ex;
3514
3515 /* Is it overwritable ? */
3516 ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
3517 if(ret > 0) {
3518 if(caps->start_adr == 0)
3519 ret= 0;
3520 }
3521 if(ret <= 0) {
3522 sprintf(xorriso->info_text,
3523 "-truncate_overwritable: Loaded medium is not random-access overwritable");
3524 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3525 goto ex;
3526 }
3527
3528 ret= Xorriso_reassure(xorriso, "-truncate_overwritable",
3529 "activates an older session and destroys newer ones", 0);
3530 if(ret <= 0)
3531 {ret= 2; goto ex;}
3532
3533 /* Learn old size */
3534 ret= isoburn_read_iso_head(drive, 0, &old_size, iso_volid, 0);
3535 if(ret <= 0) {
3536 sprintf(xorriso->info_text,
3537 "-truncate_overwritable: Cannot read ISO 9660 Volume Descriptor from LBA 0");
3538 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3539 goto ex;
3540 }
3541
3542 /* Check for PVD at image_start_value and learn new size */
3543 ret= Xorriso_decode_load_adr(xorriso, "-truncate_overwritable",
3544 adr_mode, adr_value, &image_start_mode,
3545 image_start_value, 0);
3546 if(ret <= 0)
3547 goto ex;
3548 ret= isoburn_get_mount_params(drive, image_start_mode, image_start_value,
3549 &iso_lba, &iso_track, &iso_session, iso_volid,
3550 0);
3551 if(ret <= 0)
3552 goto ex;
3553 if(ret != 1) {
3554 sprintf(xorriso->info_text,
3555 "-truncate_overwritable: Given address does not lead to ISO 9660 Volume Descriptor");
3556 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3557 ret= 0; goto ex;
3558 }
3559 if(iso_lba >= old_size) {
3560 sprintf(xorriso->info_text,
3561 "-truncate_overwritable: Given address is larger than current ISO size");
3562 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3563 ret= 0; goto ex;
3564 }
3565 ret= isoburn_read_iso_head(drive, iso_lba, &new_size, head_buffer, 2);
3566 if(ret <= 0)
3567 goto ex;
3568
3569 ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 0);
3570 if(ret > 0)
3571 checksum_block= ret - 1;
3572
3573 /* Default is "new" */
3574 iso_size= new_size;
3575 if(strcmp(adjust, "old") == 0) {
3576 /* ISO size before truncation */
3577 iso_size= old_size - iso_lba;
3578 } else if(adjust[0] == '+') {
3579 /* Add-on size to new */
3580 blocks= Scanf_io_size(adjust + 1, 0) / 2048;
3581 if(blocks < 0)
3582 goto wrong_adjust;
3583 iso_size+= blocks;
3584 } else if(adjust[0] >= '0' && adjust[0] <= '9') {
3585 /* Add-on size to new */
3586 blocks= Scanf_io_size(adjust, 0) / 2048;
3587 if(blocks < iso_lba + iso_size) {
3588 wrong_adjust:;
3589 sprintf(xorriso->info_text,
3590 "-truncate_overwritable: Given total filesystem size is smaller than new session size");
3591 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3592 ret= 0; goto ex;
3593 }
3594 iso_size= blocks - iso_lba;
3595 }
3596
3597 ret= burn_get_read_capacity(drive, &readable_blocks, 0);
3598 Xorriso_process_msg_queues(xorriso, 0);
3599 if(ret > 0) {
3600 if(iso_lba + iso_size > readable_blocks) {
3601 sprintf(xorriso->info_text, "-truncate_overwritable: Given total filesystem size is larger than formatted medium size");
3602 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3603 ret= 0; goto ex;
3604 }
3605 }
3606
3607 /* Give up possible input drive */
3608 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &in_drive, "", 16);
3609 if(ret < 0)
3610 goto ex;
3611 if(ret == 1) {
3612 ret= Xorriso_give_up_drive(xorriso, 1);
3613 if(ret<=0)
3614 goto ex;
3615 was_indev= 1;
3616 }
3617
3618 if(iso_size != new_size) {
3619 ret=Xorriso_adjust_session_size(xorriso, drive, head_buffer,
3620 iso_lba, iso_size, checksum_block,
3621 new_size, 0);
3622 if(ret <= 0)
3623 goto ex;
3624 }
3625
3626 /* Load first 64 kB and transfer VDs from head_buffer */
3627 ret= Xorriso_adjust_relocated_sb(xorriso, drive, head_buffer, &sb_buffer, 0);
3628 if(ret <= 0)
3629 goto ex;
3630
3631 /* Patch the size and write back */
3632 ret= Xorriso_update_iso_lba0(xorriso, iso_lba, iso_size, sb_buffer,
3633 NULL, 2 | 16);
3634 if(ret <= 0)
3635 goto ex;
3636
3637 ret= Xorriso_reaquire_outdev(xorriso, 2 + was_indev);
3638 if(ret <= 0)
3639 goto ex;
3640
3641 ret= 1;
3642 ex:
3643 if(caps!=NULL)
3644 burn_disc_free_multi_caps(&caps);
3645 Xorriso_free_meM(head_buffer);
3646 Xorriso_free_meM(sb_buffer);
3647 Xorriso_process_msg_queues(xorriso,0);
3648 return(ret);
3649 }
3650
3651
3652 int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag)
3653 {
3654 int ret;
3655 char *eff_src= NULL, *intvl;
3656 struct iso_interval_reader *ivr= NULL;
3657 off_t byte_count;
3658 IsoImage *img= NULL;
3659 struct burn_drive_info *source_dinfo;
3660 struct burn_drive *source_drive;
3661
3662 if(path[0] == 0) {
3663 xorriso->system_area_disk_path[0]= 0;
3664 {ret= 1; goto ex;}
3665 }
3666 Xorriso_alloc_meM(eff_src, char, SfileadrL);
3667
3668 intvl = path;
3669 ret = Xorriso_check_intvl_string(xorriso, &intvl, 0);
3670 if(ret > 0) {
3671 /* Check for syntactical correctness */
3672 if(xorriso->in_drive_handle != NULL) {
3673 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
3674 "on attempt to verify interval reader string", 0);
3675 if(ret<=0)
3676 goto ex;
3677 img= isoburn_get_attached_image(source_drive);
3678 }
3679 ret= iso_interval_reader_new(img, intvl, &ivr, &byte_count, 1);
3680 Xorriso_process_msg_queues(xorriso, 0);
3681 if(ret < 0) {
3682 sprintf(xorriso->info_text,
3683 "Given path for system area is not accepted by interval reader");
3684 Text_shellsafe(eff_src, xorriso->info_text, 1);
3685 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3686 {ret= 0; goto ex;}
3687 }
3688 iso_interval_reader_destroy(&ivr, 0);
3689 ret= Sfile_str(xorriso->system_area_disk_path, path, 0);
3690 if(ret <= 0)
3691 {ret= -1; goto ex;}
3692 ret= 1; goto ex;
3693 }
3694 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_src, 2|4|16);
3695 if(ret < 0)
3696 goto ex;
3697 if(ret == 0) {
3698 sprintf(xorriso->info_text,
3699 "Given path does not exist on disk: -boot_image system_area=");
3700 Text_shellsafe(eff_src, xorriso->info_text, 1);
3701 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3702 }
3703 if(ret == 2) {
3704 sprintf(xorriso->info_text,
3705 "Given path leads to a directory: -boot_image system_area=");
3706 Text_shellsafe(eff_src, xorriso->info_text, 1);
3707 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3708 {ret= 0; goto ex;}
3709 }
3710 ret= Sfile_str(xorriso->system_area_disk_path, eff_src, 0);
3711 if(ret <= 0)
3712 {ret= -1; goto ex;}
3713 ret= 1;
3714 ex:
3715 Xorriso_free_meM(eff_src);
3716 if(img != NULL)
3717 iso_image_unref(img);
3718 return(ret);
3719 }
3720
3721
3722 /* @param flag bit0=force burn_disc_close_damaged()
3723 */
3724 int Xorriso_close_damaged(struct XorrisO *xorriso, int flag)
3725 {
3726 int ret;
3727 struct burn_drive_info *dinfo;
3728 struct burn_drive *drive;
3729 struct burn_write_opts *burn_options= NULL;
3730
3731 if(Xorriso_change_is_pending(xorriso, 0)) {
3732 sprintf(xorriso->info_text,
3733 "Image changes pending. -commit or -rollback first");
3734 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3735 ret= 0; goto ex;
3736 }
3737 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
3738 "on attempt to close damaged session", 2);
3739 if(ret<=0)
3740 goto ex;
3741 ret= Xorriso_check_multi(xorriso, drive, 0);
3742 if(ret<=0)
3743 goto ex;
3744 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
3745 if(ret <= 0)
3746 goto ex;
3747 ret= burn_disc_close_damaged(burn_options, flag & 1);
3748 Xorriso_process_msg_queues(xorriso, 0);
3749 Xorriso_option_dev(xorriso, "", 3 | 4); /* Give up drives */
3750 if(ret <= 0)
3751 goto ex;
3752
3753 ret= 1;
3754 ex:;
3755 Xorriso_process_msg_queues(xorriso, 0);
3756 if(burn_options != NULL)
3757 burn_write_opts_free(burn_options);
3758 return(ret);
3759 }
3760
3761
3762 /* @param flag bit0= no error message
3763 */
3764 int Xorriso_parse_guid(struct XorrisO *xorriso, char *text,
3765 uint8_t guid[16], int flag)
3766 {
3767 int bin_count= 0, ret;
3768 uint8_t u[16], tr;
3769
3770 /* Try RFC 4122 : big endian XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
3771 Translate to UEFI: first three components to little-endian
3772 */
3773 if(strlen(text) == 36) {
3774 if(text[8] == '-' && text[13] == '-' && text[18] == '-' && text[23] == '-'){
3775 ret= Hex_to_bin(text, 4, &bin_count, u, 0);
3776 if(ret < 0 || bin_count != 4)
3777 goto malformed;
3778 tr= u[0]; u[0]= u[3]; u[3]= tr;
3779 tr= u[1]; u[1]= u[2]; u[2]= tr;
3780 ret= Hex_to_bin(text + 9, 2, &bin_count, u + 4, 0);
3781 if(ret < 0 || bin_count != 2)
3782 goto malformed;
3783 tr= u[4]; u[4]= u[5]; u[5]= tr;
3784 ret= Hex_to_bin(text + 14, 2, &bin_count, u + 6, 0);
3785 if(ret < 0 || bin_count != 2)
3786 goto malformed;
3787 tr= u[6]; u[6]= u[7]; u[7]= tr;
3788 ret= Hex_to_bin(text + 19, 2, &bin_count, u + 8, 0);
3789 if(ret < 0 || bin_count != 2)
3790 goto malformed;
3791 ret= Hex_to_bin(text + 24, 6, &bin_count, u + 10, 0);
3792 if(ret < 0 || bin_count != 6)
3793 goto malformed;
3794 memcpy(guid, u, 16);
3795 return(1);
3796 }
3797 }
3798 if(strlen(text) == 32) {
3799 ret= Hex_to_bin(text, 16, &bin_count, u, 0);
3800 if(ret < 0 || bin_count != 16)
3801 goto malformed;
3802 memcpy(guid, u, 16);
3803 return(1);
3804 }
3805
3806 malformed:;
3807 if(!(flag & 1)) {
3808 sprintf(xorriso->info_text, "Malformed GUID string: ");
3809 Text_shellsafe(text, xorriso->info_text, 1);
3810 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3811 }
3812 return(0);
3813 }
3814
3815
3816 int Xorriso_parse_gpt_guid(struct XorrisO *xorriso, char *text, int flag)
3817 {
3818 int ret;
3819
3820 if(strcmp(text, "random") == 0) {
3821 xorriso->gpt_guid_mode= 0;
3822 return(1);
3823 }
3824 if(strcmp(text, "modification-date") == 0 ||
3825 strcmp(text, "volume_date_uuid") == 0) {
3826 xorriso->gpt_guid_mode= 2;
3827 return(1);
3828 }
3829 ret= Xorriso_parse_guid(xorriso, text, xorriso->gpt_guid, 0);
3830 if(ret <= 0)
3831 return(ret);
3832 xorriso->gpt_guid_mode= 1;
3833 return(1);
3834 }
3835
3836 /* @return Tells the recognition status
3837 0= not recognized as GUID
3838 1= non-EFI type GUID
3839 2= EFI type GUID
3840 */
3841 int Xorriso_parse_type_guid(struct XorrisO *xorriso, char *text,
3842 uint8_t guid[16], int *mbr_type, int flag)
3843 {
3844 int j, ret;
3845 static uint8_t efi_sys_uuid[16] = {
3846 0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
3847 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
3848 };
3849
3850 ret= Xorriso_parse_guid(xorriso, text, guid, 1);
3851 if(ret > 0) {
3852 for(j= 0; j < 16; j++)
3853 if(guid[j] != efi_sys_uuid[j])
3854 break;
3855 if(j >= 16) {
3856 *mbr_type= 0xef;
3857 return(2);
3858 } else {
3859 *mbr_type= 0x83;
3860 return(1);
3861 }
3862 }
3863 return(0);
3864 }
3865