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